Skip to content

Commit

Permalink
Fix invalid issuer for MPT
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatcam committed Jan 5, 2024
1 parent 4ed11a6 commit 642fad0
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 16 deletions.
12 changes: 10 additions & 2 deletions src/ripple/app/tx/impl/Payment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,15 @@ Payment::preflight(PreflightContext const& ctx)
else if (saDstAmount.native())
maxSourceAmount = saDstAmount;
else
{
auto const& asset = saDstAmount.getAsset();
auto const iss = asset.isMPT() ? Issue{asset} : Issue{asset, account};
maxSourceAmount = STAmount(
{saDstAmount.getAsset(), account},
iss,
saDstAmount.mantissa(),
saDstAmount.exponent(),
saDstAmount < beast::zero);
}

auto const& uSrcCurrency = maxSourceAmount.getAsset();
auto const& uDstCurrency = saDstAmount.getAsset();
Expand Down Expand Up @@ -314,11 +318,15 @@ Payment::doApply()
else if (saDstAmount.native())
maxSourceAmount = saDstAmount;
else
{
auto const& asset = saDstAmount.getAsset();
auto const iss = asset.isMPT() ? Issue{asset} : Issue{asset, account_};
maxSourceAmount = STAmount(
{saDstAmount.getAsset(), account_},
iss,
saDstAmount.mantissa(),
saDstAmount.exponent(),
saDstAmount < beast::zero);
}

JLOG(j_.trace()) << "maxSourceAmount=" << maxSourceAmount.getFullText()
<< " saDstAmount=" << saDstAmount.getFullText();
Expand Down
41 changes: 28 additions & 13 deletions src/ripple/ledger/impl/View.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,14 @@ accountHolds(

if (asset.isMPT())
{
Issue iss{asset, issuer};
Issue iss{asset};
if (auto const sle = view.read(keylet::mptoken(asset, account)))
return STAmount{
iss,
sle->getFieldU64(sfMPTAmount) -
sle->getFieldU64(sfLockedAmount)};
{
auto const amt = sle->getFieldU64(sfMPTAmount);
auto const locked = sle->getFieldU64(sfLockedAmount);
if (amt > locked)
return STAmount{iss, amt - locked};
}
return STAmount{iss, 0};
}

Expand Down Expand Up @@ -1734,21 +1736,34 @@ rippleMPTCredit(
auto const mptokenID = keylet::mptoken(mptID.key, uSenderID);
if (auto sle = view.peek(mptokenID))
{
sle->setFieldU64(
sfMPTAmount,
sle->getFieldU64(sfMPTAmount) - saAmount.mpt().mpt());
view.update(sle);
auto const amt = sle->getFieldU64(sfMPTAmount);
auto const pay = saAmount.mpt().mpt();
if (amt >= pay)
{
if (amt == pay)
sle->makeFieldAbsent(sfMPTAmount);
else
sle->setFieldU64(sfMPTAmount, amt - pay);
view.update(sle);
}
else
return tecINSUFFICIENT_FUNDS;
}
}

if (uReceiverID == saAmount.getIssuer())
{
if (auto sle = view.peek(mptID))
{
sle->setFieldU64(
sfOutstandingAmount,
sle->getFieldU64(sfOutstandingAmount) - saAmount.mpt().mpt());
view.update(sle);
auto const outstanding = sle->getFieldU64(sfOutstandingAmount);
auto const redeem = saAmount.mpt().mpt();
if (outstanding >= redeem)
{
sle->setFieldU64(sfOutstandingAmount, outstanding - redeem);
view.update(sle);
}
else
return tecINSUFFICIENT_FUNDS;
}
else
return tecINTERNAL;
Expand Down
43 changes: 42 additions & 1 deletion src/test/app/MPToken_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ class MPToken_test : public beast::unit_test::suite
return amount == expectedAmount;
}

[[nodiscard]] bool
checkMPTokenOutstandingAmount(
test::jtx::Env const& env,
ripple::uint256 const mptIssuanceid,
std::uint64_t expectedAmount)
{
auto const sleMpt = env.le(keylet::mptIssuance(mptIssuanceid));
if (!sleMpt)
return false;

std::uint64_t const amount = (*sleMpt)[sfOutstandingAmount];
return amount == expectedAmount;
}

[[nodiscard]] bool
checkMPTokenIssuanceFlags(
test::jtx::Env const& env,
Expand Down Expand Up @@ -894,8 +908,9 @@ class MPToken_test : public beast::unit_test::suite
Env env{*this, features};
Account const alice("alice"); // issuer
Account const bob("bob"); // holder
Account const carol("carol"); // holder

env.fund(XRP(10000), alice, bob);
env.fund(XRP(10000), alice, bob, carol);
env.close();

BEAST_EXPECT(env.ownerCount(alice) == 0);
Expand All @@ -909,18 +924,44 @@ class MPToken_test : public beast::unit_test::suite

BEAST_EXPECT(env.ownerCount(alice) == 1);
BEAST_EXPECT(env.ownerCount(bob) == 0);
BEAST_EXPECT(env.ownerCount(carol) == 0);

// env(mpt::authorize(alice, id.key, std::nullopt));
// env.close();

env(mpt::authorize(bob, id, std::nullopt));
env.close();
env(mpt::authorize(carol, id, std::nullopt));
env.close();

// issuer to holder
env(pay(
alice, bob, ripple::test::jtx::MPT(alice.name(), mpt)(100)));
env.close();
BEAST_EXPECT(
checkMPTokenAmount(env, keylet::mptIssuance(id).key, bob, 100));
BEAST_EXPECT(checkMPTokenOutstandingAmount(
env, keylet::mptIssuance(id).key, 100));

// holder to issuer
env(pay(bob, alice, ripple::test::jtx::MPT(bob.name(), mpt)(100)));
env.close();
BEAST_EXPECT(
checkMPTokenAmount(env, keylet::mptIssuance(id).key, bob, 0));
BEAST_EXPECT(checkMPTokenOutstandingAmount(
env, keylet::mptIssuance(id).key, 0));

// holder to holder
env(pay(
alice, bob, ripple::test::jtx::MPT(alice.name(), mpt)(100)));
env(pay(bob, carol, ripple::test::jtx::MPT(alice.name(), mpt)(50)));
env.close();
BEAST_EXPECT(
checkMPTokenAmount(env, keylet::mptIssuance(id).key, bob, 50));
BEAST_EXPECT(checkMPTokenAmount(
env, keylet::mptIssuance(id).key, carol, 50));
BEAST_EXPECT(checkMPTokenOutstandingAmount(
env, keylet::mptIssuance(id).key, 100));
}
}

Expand Down

0 comments on commit 642fad0

Please sign in to comment.