20#include <xrpld/app/misc/AMMHelpers.h> 
   21#include <xrpld/app/misc/AMMUtils.h> 
   23#include <xrpl/basics/Log.h> 
   24#include <xrpl/ledger/Sandbox.h> 
   25#include <xrpl/protocol/AMMCore.h> 
   26#include <xrpl/protocol/STObject.h> 
   39    auto const assetInBalance =
 
   40        accountHolds(view, ammAccountID, issue1, freezeHandling, j);
 
   41    auto const assetOutBalance =
 
   42        accountHolds(view, ammAccountID, issue2, freezeHandling, j);
 
 
   46Expected<std::tuple<STAmount, STAmount, STAmount>, 
TER>
 
   56        auto const issue1 = ammSle[sfAsset].get<
Issue>();
 
   57        auto const issue2 = ammSle[sfAsset2].get<
Issue>();
 
   58        if (optIssue1 && optIssue2)
 
   67                JLOG(j.
debug()) << 
"ammHolds: Invalid optIssue1 or optIssue2 " 
   68                                << *optIssue1 << 
" " << *optIssue2;
 
   74        auto const singleIssue =
 
   75            [&issue1, &issue2, &j](
 
   78            if (checkIssue == issue1)
 
   80            else if (checkIssue == issue2)
 
   85                << 
"ammHolds: Invalid " << label << 
" " << checkIssue;
 
   91            return singleIssue(*optIssue1, 
"optIssue1");
 
   96            return singleIssue(*optIssue2, 
"optIssue2");  
 
 
  133        JLOG(j.
trace()) << 
"ammLPHolds: no SLE " 
  137    else if (
isFrozen(view, lpAccount, currency, ammAccount))
 
  140        JLOG(j.
trace()) << 
"ammLPHolds: frozen currency " 
  146        amount = sle->getFieldAmount(sfBalance);
 
  147        if (lpAccount > ammAccount)
 
  154        JLOG(j.
trace()) << 
"ammLPHolds:" 
  159    return view.
balanceHook(lpAccount, ammAccount, amount);
 
 
  171        ammSle[sfAsset].get<Issue>().currency,
 
  172        ammSle[sfAsset2].get<Issue>().currency,
 
 
  185        "ripple::getTradingFee : auction present");
 
  188        auto const& auctionSlot =
 
  191        if (
auto const expiration = auctionSlot[~sfExpiration];
 
  192            duration_cast<seconds>(
 
  194                .count() < expiration)
 
  196            if (auctionSlot[~sfAccount] == account)
 
  197                return auctionSlot[sfDiscountedFee];
 
  198            if (auctionSlot.isFieldPresent(sfAuthAccounts))
 
  200                for (
auto const& acct :
 
  201                     auctionSlot.getFieldArray(sfAuthAccounts))
 
  202                    if (acct[~sfAccount] == account)
 
  203                        return auctionSlot[sfDiscountedFee];
 
  207    return ammSle[sfTradingFee];
 
 
  219            return (*sle)[sfBalance];
 
  221    else if (
auto const sle = view.
read(
 
  226        auto amount = (*sle)[sfBalance];
 
  227        if (ammAccountID > issue.
account)
 
  229        amount.setIssuer(issue.
account);
 
 
  250            if (nodeType == LedgerEntryType::ltAMM)
 
  253            if (nodeType != LedgerEntryType::ltRIPPLE_STATE)
 
  257                    << 
"deleteAMMTrustLines: deleting non-trustline " 
  264            if (sleItem->getFieldAmount(sfBalance) != beast::zero)
 
  268                    << 
"deleteAMMTrustLines: deleting trustline with " 
  279        maxTrustlinesToDelete);
 
 
  293        JLOG(j.
error()) << 
"deleteAMMAccount: AMM object does not exist " 
  294                        << asset << 
" " << asset2;
 
  299    auto const ammAccountID = (*ammSle)[sfAccount];
 
  304        JLOG(j.
error()) << 
"deleteAMMAccount: AMM account does not exist " 
  317            ownerDirKeylet, (*ammSle)[sfOwnerNode], ammSle->key(), 
false))
 
  320        JLOG(j.
error()) << 
"deleteAMMAccount: failed to remove dir link";
 
  327        JLOG(j.
error()) << 
"deleteAMMAccount: cannot delete root dir node of " 
  334    sb.
erase(sleAMMRoot);
 
 
  344    Issue const& lptIssue,
 
  347    auto const& rules = view.
rules();
 
  356    ammSle->setFieldArray(sfVoteSlots, voteSlots);
 
  360    if (rules.enabled(fixInnerObjTemplate) &&
 
  361        !ammSle->isFieldPresent(sfAuctionSlot))
 
  364        ammSle->set(std::move(auctionSlot));
 
  366    STObject& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
 
  369    auto const expiration = std::chrono::duration_cast<std::chrono::seconds>(
 
  377        ammSle->setFieldU16(sfTradingFee, tfee);
 
  378    else if (ammSle->isFieldPresent(sfTradingFee))
 
  379        ammSle->makeFieldAbsent(sfTradingFee);  
 
 
  389    Issue const& ammIssue,
 
  407    auto currentIndex = 
root;
 
  412        auto const ownerDir = view.
read(currentIndex);
 
  415        for (
auto const& key : ownerDir->getFieldV256(sfIndexes))
 
  421            if (sle->getFieldU16(sfLedgerEntryType) == ltAMM)
 
  428            if (sle->getFieldU16(sfLedgerEntryType) != ltRIPPLE_STATE)
 
  430            auto const lowLimit = sle->getFieldAmount(sfLowLimit);
 
  431            auto const highLimit = sle->getFieldAmount(sfHighLimit);
 
  432            auto const isLPTrustline = lowLimit.getIssuer() == lpAccount ||
 
  433                highLimit.getIssuer() == lpAccount;
 
  434            auto const isLPTokenTrustline =
 
  435                lowLimit.issue() == ammIssue || highLimit.issue() == ammIssue;
 
  441                if (isLPTokenTrustline)
 
  443                    if (++nLPTokenTrustLines > 1)
 
  446                else if (++nIOUTrustLines > 2)
 
  450            else if (isLPTokenTrustline)
 
  452            else if (++nIOUTrustLines > 2)
 
  455        auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
 
  458            if (nLPTokenTrustLines != 1 || nIOUTrustLines == 0 ||
 
 
  478    else if (res.value())
 
  482                ammSle->getFieldAmount(sfLPTokenBalance),
 
  485            ammSle->setFieldAmount(sfLPTokenBalance, lpTokens);
 
 
A generic endpoint for log messages.
 
Stream trace() const
Severity stream access functions.
 
Writeable view to a ledger, for applying a transaction.
 
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
 
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
 
A currency issued by an account.
 
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
 
virtual STAmount balanceHook(AccountID const &account, AccountID const &issuer, STAmount const &amount) const
 
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
 
virtual Rules const & rules() const =0
Returns the tx processing rules.
 
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
 
void setIssuer(AccountID const &uIssuer)
 
Issue const & issue() const
 
std::string getFullText() const override
 
void push_back(STObject const &object)
 
AccountID getAccountID(SField const &field) const
 
void makeFieldAbsent(SField const &field)
 
void setFieldU16(SField const &field, std::uint16_t)
 
void setFieldAmount(SField const &field, STAmount const &)
 
bool isFieldPresent(SField const &field) const
 
static STObject makeInnerObject(SField const &name)
 
void setAccountID(SField const &field, AccountID const &)
 
void setFieldU32(SField const &field, std::uint32_t)
 
STBase const & peekAtField(SField const &field) const
 
Discardable, editable view to a ledger.
 
void erase(std::shared_ptr< SLE > const &sle) override
Remove a peeked SLE.
 
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
 
bool exists(Keylet const &k) const override
Determine if a state item exists.
 
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
 
T make_optional(T... args)
 
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
 
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
 
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
 
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
 
FreezeHandling
Controls the treatment of frozen account balances.
 
std::uint32_t constexpr TOTAL_TIME_SLOT_SECS
 
bool isXRP(AccountID const &c)
 
Currency ammLPTCurrency(Currency const &cur1, Currency const &cur2)
Calculate Liquidity Provider Token (LPT) Currency.
 
std::uint16_t getTradingFee(ReadView const &view, SLE const &ammSle, AccountID const &account)
Get AMM trading fee for the given account.
 
TER deleteAMMAccount(Sandbox &view, Issue const &asset, Issue const &asset2, beast::Journal j)
Delete trustlines to AMM.
 
Expected< bool, TER > isOnlyLiquidityProvider(ReadView const &view, Issue const &ammIssue, AccountID const &lpAccount)
Return true if the Liquidity Provider is the only AMM provider, false otherwise.
 
TER cleanupOnAccountDelete(ApplyView &view, Keylet const &ownerDirKeylet, EntryDeleter const &deleter, beast::Journal j, std::optional< std::uint16_t > maxNodesToDelete=std::nullopt)
Cleanup owner directory entries on account delete.
 
Expected< bool, TER > verifyAndAdjustLPTokenBalance(Sandbox &sb, STAmount const &lpTokens, std::shared_ptr< SLE > &ammSle, AccountID const &account)
Due to rounding, the LPTokenBalance of the last LP might not match the LP's trustline balance.
 
bool isFrozen(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer)
 
void initializeFeeAuctionVote(ApplyView &view, std::shared_ptr< SLE > &ammSle, AccountID const &account, Issue const &lptIssue, std::uint16_t tfee)
Initialize Auction and Voting slots and set the trading/discounted fee.
 
STAmount ammLPHolds(ReadView const &view, Currency const &cur1, Currency const &cur2, AccountID const &ammAccount, AccountID const &lpAccount, beast::Journal const j)
Get the balance of LP tokens.
 
std::pair< STAmount, STAmount > ammPoolHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue1, Issue const &issue2, FreezeHandling freezeHandling, beast::Journal const j)
Get AMM pool balances.
 
static TER deleteAMMTrustLines(Sandbox &sb, AccountID const &ammAccountID, std::uint16_t maxTrustlinesToDelete, beast::Journal j)
 
std::uint32_t constexpr VOTE_WEIGHT_SCALE_FACTOR
 
NotTEC invalidAMMAssetPair(Issue const &issue1, Issue const &issue2, std::optional< std::pair< Issue, Issue > > const &pair=std::nullopt)
 
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
 
Expected< std::tuple< STAmount, STAmount, STAmount >, TER > ammHolds(ReadView const &view, SLE const &ammSle, std::optional< Issue > const &optIssue1, std::optional< Issue > const &optIssue2, FreezeHandling freezeHandling, beast::Journal const j)
Get AMM pool and LP token balances.
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
LedgerEntryType
Identifiers for on-ledger objects.
 
STAmount ammAccountHolds(ReadView const &view, AccountID const &ammAccountID, Issue const &issue)
Returns total amount held by AMM for the given token.
 
Number root(Number f, unsigned d)
 
TER deleteAMMTrustLine(ApplyView &view, std::shared_ptr< SLE > sleState, std::optional< AccountID > const &ammAccountID, beast::Journal j)
Delete trustline to AMM.
 
std::uint16_t constexpr maxDeletableAMMTrustLines
The maximum number of trustlines to delete as part of AMM account deletion cleanup.
 
TERSubset< CanCvtToTER > TER
 
bool withinRelativeDistance(Quality const &calcQuality, Quality const &reqQuality, Number const &dist)
Check if the relative distance between the qualities is within the requested distance.
 
std::uint32_t constexpr AUCTION_SLOT_DISCOUNTED_FEE_FRACTION
 
T time_since_epoch(T... args)