Skip to content

Commit

Permalink
Fix SendMax with no transfer fee
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatcam committed Oct 7, 2024
1 parent aacb1c8 commit 560cf91
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
24 changes: 24 additions & 0 deletions src/test/app/MPToken_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,30 @@ class MPToken_test : public beast::unit_test::suite
env(pay(bob, carol, MPT(100)), sendmax(MPT(115)));
}

// Insufficient SendMax with no transfer fee
{
Env env{*this, features};

MPTTester mptAlice(env, alice, {.holders = {&bob, &carol}});

mptAlice.create(
{.ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer});

// Holders create MPToken
mptAlice.authorize({.account = &bob});
mptAlice.authorize({.account = &carol});
mptAlice.pay(alice, bob, 1'000);

auto const MPT = mptAlice["MPT"];
// SendMax is less than the amount
env(pay(bob, carol, MPT(100)),
sendmax(MPT(99)),
ter(tecPATH_PARTIAL));

// Payment succeeds if sufficient SendMax is included.
env(pay(bob, carol, MPT(100)), sendmax(MPT(100)));
}

// Issuer fails trying to send more than the maximum amount allowed
{
Env env{*this, features};
Expand Down
15 changes: 8 additions & 7 deletions src/xrpld/app/tx/detail/Payment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,13 +686,14 @@ applyHelper<MPTIssue>(ApplyContext& ctx, XRPAmount const&, XRPAmount const&)
isFrozen(ctx.view(), uDstAccountID, mpt))
return tecLOCKED;

auto const sendMax(ctx.tx[~sfSendMax]);
// If the transfer fee is included then SendMax has to be included
// and be large enough to cover the fee. The payment can still fail if
// the sender has insufficient funds.
if (auto const rate = transferRate(ctx.view(), mpt.getMptID());
rate != parityRate &&
(!sendMax || multiply(saDstAmount, rate) > *sendMax))
auto const sendMax = ctx.tx[~sfSendMax].value_or(saDstAmount);
// If SendMax is included then it should be greater or equal to
// the send amount plus the transfer fees if applicable.
// The payment can still fail if the sender has insufficient funds.
auto const amount =
multiply(saDstAmount, transferRate(ctx.view(), mpt.getMptID()));
if (multiply(saDstAmount, transferRate(ctx.view(), mpt.getMptID())) >
sendMax)
return tecPATH_PARTIAL;
}

Expand Down

0 comments on commit 560cf91

Please sign in to comment.