From 52e7cdc24dbc0448907e2167b16b0e3e7cf1734e Mon Sep 17 00:00:00 2001 From: tequ Date: Tue, 21 Apr 2026 13:48:07 +0900 Subject: [PATCH] fix: Sponsored account creation double-counts base reserve #6894 --- .../tx/transactors/payment/Payment.cpp | 3 +-- src/test/app/Sponsor_test.cpp | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/libxrpl/tx/transactors/payment/Payment.cpp b/src/libxrpl/tx/transactors/payment/Payment.cpp index 4475bbd761..81f0b06dc2 100644 --- a/src/libxrpl/tx/transactors/payment/Payment.cpp +++ b/src/libxrpl/tx/transactors/payment/Payment.cpp @@ -611,8 +611,7 @@ Payment::doApply() // the number of reserves in this ledger for this account that require a // reserve. - auto const reserve = calculateReserve(sleSrc, view().fees()) + - (((txFlags & tfSponsorCreatedAccount) != 0u) ? view().fees().reserve : beast::zero); + auto const reserve = calculateReserve(sleSrc, view().fees()); // In a delegated payment, the fee payer is the delegated account, // not the source account (account_). diff --git a/src/test/app/Sponsor_test.cpp b/src/test/app/Sponsor_test.cpp index 41b5e88b65..3cbb4d16fa 100644 --- a/src/test/app/Sponsor_test.cpp +++ b/src/test/app/Sponsor_test.cpp @@ -1710,8 +1710,10 @@ public: Account const alice("alice"); Account const sponsor("sponsor"); Account const sponsor2("sponsor2"); + Account const sponsor3("sponsor3"); Account const bob("bob"); Account const charlie("charlie"); + Account const dave("dave"); Account const gw("gw"); auto const USD = gw["USD"]; @@ -1725,7 +1727,7 @@ public: } Env env{*this, testable_amendments()}; - env.fund(XRP(10000), alice, sponsor, sponsor2); + env.fund(XRP(10000), alice, sponsor, sponsor2, sponsor3); env.close(); // Invalid flags @@ -1788,6 +1790,26 @@ public: // verify sponsor balance decreased by payment + fee BEAST_EXPECT(env.balance(sponsor2) == sponsor2BalanceBefore - drops(1) - XRP(1)); } + { + // insufficient reserve to sponsor acount + + auto const sendAmount = drops(1); + // 2 account reserve + send amount + auto const requireBalance = accountReserve(env, 2) + sendAmount; + adjustAccountXRPBalance(env, sponsor3, requireBalance - drops(1)); + env(pay(sponsor3, dave, sendAmount), + txflags(tfSponsorCreatedAccount), + fee(XRP(1)), + ter(tecUNFUNDED_PAYMENT)); + env.close(); + + adjustAccountXRPBalance(env, sponsor3, requireBalance); + env(pay(sponsor3, dave, sendAmount), + txflags(tfSponsorCreatedAccount), + fee(XRP(1)), + ter(tesSUCCESS)); + env.close(); + } } void