mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-04 01:06:48 +00:00
fix: An incorrect available XRP balance check in AMM deposit allows reserve-locked funds to be used as adding liquidity
This commit is contained in:
@@ -239,6 +239,15 @@ AMMDeposit::preclaim(PreclaimContext const& ctx)
|
||||
|
||||
auto const sponsorSle = getTxReserveSponsor(ctx.view, ctx.tx);
|
||||
auto const accountSle = ctx.view.read(keylet::account(accountID));
|
||||
auto const reserveAdj = (sponsorSle || sle) ? 0 : 1;
|
||||
|
||||
if (xrpLiquid(ctx.view, accountID, reserveAdj, ctx.j) < deposit)
|
||||
{
|
||||
if (sle)
|
||||
return tecUNFUNDED_AMM;
|
||||
return tecINSUF_RESERVE_LINE;
|
||||
}
|
||||
|
||||
if (auto const ret = checkInsufficientReserve(
|
||||
ctx.view,
|
||||
ctx.tx,
|
||||
@@ -247,11 +256,10 @@ AMMDeposit::preclaim(PreclaimContext const& ctx)
|
||||
sponsorSle,
|
||||
1,
|
||||
!sle);
|
||||
isTesSuccess(ret))
|
||||
return TER(tesSUCCESS);
|
||||
if (sle)
|
||||
return tecUNFUNDED_AMM;
|
||||
return tecINSUF_RESERVE_LINE;
|
||||
sponsorSle && !isTesSuccess(ret))
|
||||
return tecINSUF_RESERVE_LINE;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
return accountFunds(
|
||||
ctx.view,
|
||||
@@ -556,9 +564,8 @@ AMMDeposit::deposit(
|
||||
// Adjust the reserve if LP doesn't have LPToken trustline
|
||||
auto const trustlineExists =
|
||||
view.exists(keylet::line(account_, lpIssue.account, lpIssue.currency));
|
||||
auto const ownerCountAdj = trustlineExists ? 0 : 1;
|
||||
if (xrpLiquid(view, sponsor.value_or(account_), sponsor ? ownerCountAdj : 0, j_) >=
|
||||
depositAmount)
|
||||
auto const reserveAdj = (sponsor || trustlineExists) ? 0 : 1;
|
||||
if (xrpLiquid(view, account_, reserveAdj, j_) >= depositAmount)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
else if (
|
||||
|
||||
@@ -2182,6 +2182,47 @@ public:
|
||||
submit(ammDeposit(env, bob, USD(100), EUR(100)));
|
||||
});
|
||||
}
|
||||
{
|
||||
// AMMDeposit single-asset XRP: reserve sponsor covers LP trustline reserve
|
||||
// but depositor's own liquid XRP is insufficient for the deposit → tecUNFUNDED_AMM
|
||||
Env env{*this, testable_amendments()};
|
||||
env.fund(XRP(10000), alice, bob, gw, sponsor);
|
||||
env.close();
|
||||
|
||||
env(trust(bob, USD(10000)));
|
||||
env(trust(alice, USD(10000)));
|
||||
env.close();
|
||||
env(pay(gw, bob, USD(1000)));
|
||||
env.close();
|
||||
|
||||
AMM amm(env, bob, XRP(1000), USD(100));
|
||||
|
||||
// alice has 1 owner object (USD trust line); give her reserve + 5 XRP liquid
|
||||
adjustAccountXRPBalance(env, alice, reserve(env, ownerCount(env, alice)) + XRP(5));
|
||||
|
||||
auto const jv = AMM::depositJv(
|
||||
{.account = alice,
|
||||
.asset1In = XRP(10),
|
||||
.assets = std::make_pair(Asset{xrpIssue()}, Asset{USD.issue()})});
|
||||
|
||||
if (cosigning)
|
||||
{
|
||||
env(jv,
|
||||
sponsor::as(sponsor, spfSponsorReserve),
|
||||
sig(sfSponsorSignature, sponsor),
|
||||
ter(tecINSUF_RESERVE_LINE));
|
||||
}
|
||||
else
|
||||
{
|
||||
env(sponsor::set_reserve(sponsor, 0, 1), sponsor::sponseeAcc(alice));
|
||||
env.close();
|
||||
env(jv, sponsor::as(sponsor, spfSponsorReserve), ter(tecINSUF_RESERVE_LINE));
|
||||
env(sponsor::del(sponsor), sponsor::sponseeAcc(alice));
|
||||
}
|
||||
env.close();
|
||||
|
||||
BEAST_EXPECT(ownerCount(env, alice) == 1); // no LP token was created
|
||||
}
|
||||
{
|
||||
// AMMWithdraw
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user