rippled
AMMCreate.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2023 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/tx/impl/AMMCreate.h>
21 
22 #include <ripple/app/ledger/OrderBookDB.h>
23 #include <ripple/app/misc/AMMHelpers.h>
24 #include <ripple/app/misc/AMMUtils.h>
25 #include <ripple/ledger/Sandbox.h>
26 #include <ripple/ledger/View.h>
27 #include <ripple/protocol/AMMCore.h>
28 #include <ripple/protocol/Feature.h>
29 #include <ripple/protocol/STAccount.h>
30 #include <ripple/protocol/STIssue.h>
31 #include <ripple/protocol/TxFlags.h>
32 
33 namespace ripple {
34 
35 NotTEC
37 {
38  if (!ammEnabled(ctx.rules))
39  return temDISABLED;
40 
41  if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
42  return ret;
43 
44  if (ctx.tx.getFlags() & tfUniversalMask)
45  {
46  JLOG(ctx.j.debug()) << "AMM Instance: invalid flags.";
47  return temINVALID_FLAG;
48  }
49 
50  auto const amount = ctx.tx[sfAmount];
51  auto const amount2 = ctx.tx[sfAmount2];
52 
53  if (amount.issue() == amount2.issue())
54  {
55  JLOG(ctx.j.debug())
56  << "AMM Instance: tokens can not have the same currency/issuer.";
57  return temBAD_AMM_TOKENS;
58  }
59 
60  if (auto const err = invalidAMMAmount(amount))
61  {
62  JLOG(ctx.j.debug()) << "AMM Instance: invalid asset1 amount.";
63  return err;
64  }
65 
66  if (auto const err = invalidAMMAmount(amount2))
67  {
68  JLOG(ctx.j.debug()) << "AMM Instance: invalid asset2 amount.";
69  return err;
70  }
71 
73  {
74  JLOG(ctx.j.debug()) << "AMM Instance: invalid trading fee.";
75  return temBAD_FEE;
76  }
77 
78  return preflight2(ctx);
79 }
80 
82 AMMCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
83 {
84  // The fee required for AMMCreate is one owner reserve.
85  return view.fees().increment;
86 }
87 
88 TER
90 {
91  auto const accountID = ctx.tx[sfAccount];
92  auto const amount = ctx.tx[sfAmount];
93  auto const amount2 = ctx.tx[sfAmount2];
94 
95  // Check if AMM already exists for the token pair
96  if (auto const ammKeylet = keylet::amm(amount.issue(), amount2.issue());
97  ctx.view.read(ammKeylet))
98  {
99  JLOG(ctx.j.debug()) << "AMM Instance: ltAMM already exists.";
100  return tecDUPLICATE;
101  }
102 
103  if (auto const ter = requireAuth(ctx.view, amount.issue(), accountID);
104  ter != tesSUCCESS)
105  {
106  JLOG(ctx.j.debug())
107  << "AMM Instance: account is not authorized, " << amount.issue();
108  return ter;
109  }
110 
111  if (auto const ter = requireAuth(ctx.view, amount2.issue(), accountID);
112  ter != tesSUCCESS)
113  {
114  JLOG(ctx.j.debug())
115  << "AMM Instance: account is not authorized, " << amount2.issue();
116  return ter;
117  }
118 
119  // Globally or individually frozen
120  if (isFrozen(ctx.view, accountID, amount.issue()) ||
121  isFrozen(ctx.view, accountID, amount2.issue()))
122  {
123  JLOG(ctx.j.debug()) << "AMM Instance: involves frozen asset.";
124  return tecFROZEN;
125  }
126 
127  auto noDefaultRipple = [](ReadView const& view, Issue const& issue) {
128  if (isXRP(issue))
129  return false;
130 
131  if (auto const issuerAccount =
132  view.read(keylet::account(issue.account)))
133  return (issuerAccount->getFlags() & lsfDefaultRipple) == 0;
134 
135  return false;
136  };
137 
138  if (noDefaultRipple(ctx.view, amount.issue()) ||
139  noDefaultRipple(ctx.view, amount2.issue()))
140  {
141  JLOG(ctx.j.debug()) << "AMM Instance: DefaultRipple not set";
142  return terNO_RIPPLE;
143  }
144 
145  // Check the reserve for LPToken trustline
146  STAmount const xrpBalance = xrpLiquid(ctx.view, accountID, 1, ctx.j);
147  // Insufficient reserve
148  if (xrpBalance <= beast::zero)
149  {
150  JLOG(ctx.j.debug()) << "AMM Instance: insufficient reserves";
151  return tecINSUF_RESERVE_LINE;
152  }
153 
154  auto insufficientBalance = [&](STAmount const& asset) {
155  if (isXRP(asset))
156  return xrpBalance < asset;
157  return accountID != asset.issue().account &&
158  accountHolds(
159  ctx.view,
160  accountID,
161  asset.issue(),
162  FreezeHandling::fhZERO_IF_FROZEN,
163  ctx.j) < asset;
164  };
165 
166  if (insufficientBalance(amount) || insufficientBalance(amount2))
167  {
168  JLOG(ctx.j.debug())
169  << "AMM Instance: insufficient funds, " << amount << " " << amount2;
170  return tecUNFUNDED_AMM;
171  }
172 
173  auto isLPToken = [&](STAmount const& amount) -> bool {
174  if (auto const sle =
175  ctx.view.read(keylet::account(amount.issue().account)))
176  return (sle->getFlags() & lsfAMM);
177  return false;
178  };
179 
180  if (isLPToken(amount) || isLPToken(amount2))
181  {
182  JLOG(ctx.j.debug()) << "AMM Instance: can't create with LPTokens "
183  << amount << " " << amount2;
184  return tecAMM_INVALID_TOKENS;
185  }
186 
187  return tesSUCCESS;
188 }
189 
192  ApplyContext& ctx_,
193  Sandbox& sb,
194  AccountID const& account_,
195  beast::Journal j_)
196 {
197  auto const amount = ctx_.tx[sfAmount];
198  auto const amount2 = ctx_.tx[sfAmount2];
199 
200  auto const ammKeylet = keylet::amm(amount.issue(), amount2.issue());
201 
202  // Mitigate same account exists possibility
203  auto const ammAccount = [&]() -> Expected<AccountID, TER> {
204  std::uint16_t constexpr maxAccountAttempts = 256;
205  for (auto p = 0; p < maxAccountAttempts; ++p)
206  {
207  auto const ammAccount =
208  ammAccountID(p, sb.info().parentHash, ammKeylet.key);
209  if (!sb.read(keylet::account(ammAccount)))
210  return ammAccount;
211  }
212  return Unexpected(tecDUPLICATE);
213  }();
214 
215  // AMM account already exists (should not happen)
216  if (!ammAccount)
217  {
218  JLOG(j_.error()) << "AMM Instance: AMM already exists.";
219  return {ammAccount.error(), false};
220  }
221 
222  // LP Token already exists. (should not happen)
223  auto const lptIss = ammLPTIssue(
224  amount.issue().currency, amount2.issue().currency, *ammAccount);
225  if (sb.read(keylet::line(*ammAccount, lptIss)))
226  {
227  JLOG(j_.error()) << "AMM Instance: LP Token already exists.";
228  return {tecDUPLICATE, false};
229  }
230 
231  // Create AMM Root Account.
232  auto sleAMMRoot = std::make_shared<SLE>(keylet::account(*ammAccount));
233  sleAMMRoot->setAccountID(sfAccount, *ammAccount);
234  sleAMMRoot->setFieldAmount(sfBalance, STAmount{});
235  std::uint32_t const seqno{
237  ? ctx_.view().seq()
238  : 1};
239  sleAMMRoot->setFieldU32(sfSequence, seqno);
240  // Ignore reserves requirement, disable the master key, allow default
241  // rippling (AMM LPToken can be used as a token in another AMM, which must
242  // support payments and offer crossing), and enable deposit authorization to
243  // prevent payments into AMM.
244  // Note, that the trustlines created by AMM have 0 credit limit.
245  // This prevents shifting the balance between accounts via AMM,
246  // or sending unsolicited LPTokens. This is a desired behavior.
247  // A user can only receive LPTokens through affirmative action -
248  // either an AMMDeposit, TrustSet, crossing an offer, etc.
249  sleAMMRoot->setFieldU32(
251  sb.insert(sleAMMRoot);
252 
253  // Calculate initial LPT balance.
254  auto const lpTokens = ammLPTokens(amount, amount2, lptIss);
255 
256  // Create ltAMM
257  auto ammSle = std::make_shared<SLE>(ammKeylet);
258  if (ctx_.tx[sfTradingFee] != 0)
259  ammSle->setFieldU16(sfTradingFee, ctx_.tx[sfTradingFee]);
260  ammSle->setAccountID(sfAccount, *ammAccount);
261  ammSle->setFieldAmount(sfLPTokenBalance, lpTokens);
262  auto const& [issue1, issue2] = std::minmax(amount.issue(), amount2.issue());
263  ammSle->setFieldIssue(sfAsset, STIssue{sfAsset, issue1});
264  ammSle->setFieldIssue(sfAsset2, STIssue{sfAsset2, issue2});
265  // AMM creator gets the voting slot.
266  STArray voteSlots;
267  STObject voteEntry{sfVoteEntry};
268  if (ctx_.tx[sfTradingFee] != 0)
269  voteEntry.setFieldU16(sfTradingFee, ctx_.tx[sfTradingFee]);
270  voteEntry.setFieldU32(sfVoteWeight, 100000);
271  voteEntry.setAccountID(sfAccount, account_);
272  voteSlots.push_back(voteEntry);
273  ammSle->setFieldArray(sfVoteSlots, voteSlots);
274  // AMM creator gets the auction slot for free.
275  auto& auctionSlot = ammSle->peekFieldObject(sfAuctionSlot);
276  auctionSlot.setAccountID(sfAccount, account_);
277  // current + sec in 24h
278  auto const expiration =
279  std::chrono::duration_cast<std::chrono::seconds>(
281  .count() +
283  auctionSlot.setFieldU32(sfExpiration, expiration);
284  auctionSlot.setFieldAmount(sfPrice, STAmount{lpTokens.issue(), 0});
285  sb.insert(ammSle);
286 
287  // Add owner directory to link the root account and AMM object.
288  if (auto const page = sb.dirInsert(
289  keylet::ownerDir(*ammAccount),
290  ammSle->key(),
291  describeOwnerDir(*ammAccount));
292  !page)
293  {
294  JLOG(j_.debug()) << "AMM Instance: failed to insert owner dir";
295  return {tecDIR_FULL, false};
296  }
297 
298  // Send LPT to LP.
299  auto res = accountSend(sb, *ammAccount, account_, lpTokens, ctx_.journal);
300  if (res != tesSUCCESS)
301  {
302  JLOG(j_.debug()) << "AMM Instance: failed to send LPT " << lpTokens;
303  return {res, false};
304  }
305 
306  auto sendAndTrustSet = [&](STAmount const& amount) -> TER {
307  if (auto const res = accountSend(
308  sb,
309  account_,
310  *ammAccount,
311  amount,
312  ctx_.journal,
314  return res;
315  // Set AMM flag on AMM trustline
316  if (!isXRP(amount))
317  {
318  if (SLE::pointer sleRippleState =
319  sb.peek(keylet::line(*ammAccount, amount.issue()));
320  !sleRippleState)
321  return tecINTERNAL;
322  else
323  {
324  auto const flags = sleRippleState->getFlags();
325  sleRippleState->setFieldU32(sfFlags, flags | lsfAMMNode);
326  sb.update(sleRippleState);
327  }
328  }
329  return tesSUCCESS;
330  };
331 
332  // Send asset1.
333  res = sendAndTrustSet(amount);
334  if (res != tesSUCCESS)
335  {
336  JLOG(j_.debug()) << "AMM Instance: failed to send " << amount;
337  return {res, false};
338  }
339 
340  // Send asset2.
341  res = sendAndTrustSet(amount2);
342  if (res != tesSUCCESS)
343  {
344  JLOG(j_.debug()) << "AMM Instance: failed to send " << amount2;
345  return {res, false};
346  }
347 
348  JLOG(j_.debug()) << "AMM Instance: success " << *ammAccount << " "
349  << ammKeylet.key << " " << lpTokens << " " << amount << " "
350  << amount2;
351  auto addOrderBook =
352  [&](Issue const& issueIn, Issue const& issueOut, std::uint64_t uRate) {
353  Book const book{issueIn, issueOut};
354  auto const dir = keylet::quality(keylet::book(book), uRate);
355  if (auto const bookExisted = static_cast<bool>(sb.read(dir));
356  !bookExisted)
357  ctx_.app.getOrderBookDB().addOrderBook(book);
358  };
359  addOrderBook(amount.issue(), amount2.issue(), getRate(amount2, amount));
360  addOrderBook(amount2.issue(), amount.issue(), getRate(amount, amount2));
361 
362  return {res, res == tesSUCCESS};
363 }
364 
365 TER
367 {
368  // This is the ledger view that we work against. Transactions are applied
369  // as we go on processing transactions.
370  Sandbox sb(&ctx_.view());
371 
372  auto const result = applyCreate(ctx_, sb, account_, j_);
373  if (result.second)
374  sb.apply(ctx_.rawView());
375 
376  return result.first;
377 }
378 
379 } // namespace ripple
ripple::ReadView::info
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:304
ripple::tecFROZEN
@ tecFROZEN
Definition: TER.h:273
ripple::Application::getOrderBookDB
virtual OrderBookDB & getOrderBookDB()=0
ripple::preflight2
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
Definition: Transactor.cpp:130
ripple::tecUNFUNDED_AMM
@ tecUNFUNDED_AMM
Definition: TER.h:298
ripple::Issue
A currency issued by an account.
Definition: Issue.h:35
ripple::tecINSUF_RESERVE_LINE
@ tecINSUF_RESERVE_LINE
Definition: TER.h:258
ripple::sfAsset
const SF_ISSUE sfAsset
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:94
std::shared_ptr< STLedgerEntry >
ripple::LedgerInfo::parentHash
uint256 parentHash
Definition: ReadView.h:94
ripple::PreclaimContext::view
ReadView const & view
Definition: Transactor.h:56
ripple::AMMCreate::calculateBaseFee
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Definition: AMMCreate.cpp:82
ripple::accountSend
TER accountSend(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
Definition: View.cpp:1159
ripple::PreclaimContext::j
const beast::Journal j
Definition: Transactor.h:60
ripple::applyCreate
static std::pair< TER, bool > applyCreate(ApplyContext &ctx_, Sandbox &sb, AccountID const &account_, beast::Journal j_)
Definition: AMMCreate.cpp:191
ripple::lsfDisableMaster
@ lsfDisableMaster
Definition: LedgerFormats.h:235
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:347
ripple::sfAmount2
const SF_AMOUNT sfAmount2
ripple::describeOwnerDir
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Definition: View.cpp:765
ripple::sfAmount
const SF_AMOUNT sfAmount
ripple::Transactor::j_
const beast::Journal j_
Definition: Transactor.h:89
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:604
ripple::ammLPTIssue
Issue ammLPTIssue(Currency const &cur1, Currency const &cur2, AccountID const &ammAccountID)
Calculate LPT Issue from AMM asset pair.
Definition: AMMCore.cpp:56
ripple::Sandbox::apply
void apply(RawView &to)
Definition: Sandbox.h:55
ripple::sfVoteSlots
const SField sfVoteSlots
ripple::AMMCreate::preflight
static NotTEC preflight(PreflightContext const &ctx)
Definition: AMMCreate.cpp:36
std::pair
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::sfVoteEntry
const SField sfVoteEntry
ripple::sfLPTokenBalance
const SF_AMOUNT sfLPTokenBalance
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:243
ripple::ammEnabled
bool ammEnabled(Rules const &)
Return true if required AMM amendments are enabled.
Definition: AMMCore.cpp:126
ripple::keylet::amm
Keylet amm(Issue const &issue1, Issue const &issue2) noexcept
AMM entry.
Definition: Indexes.cpp:375
ripple::Unexpected
Unexpected(E(&)[N]) -> Unexpected< E const * >
ripple::detail::ApplyViewBase::update
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
Definition: ApplyViewBase.cpp:146
ripple::STArray::push_back
void push_back(STObject const &object)
Definition: STArray.h:212
ripple::ApplyContext::journal
const beast::Journal journal
Definition: ApplyContext.h:51
ripple::ApplyContext::rawView
RawView & rawView()
Definition: ApplyContext.h:67
ripple::terNO_RIPPLE
@ terNO_RIPPLE
Definition: TER.h:207
ripple::sfPrice
const SF_AMOUNT sfPrice
ripple::PreflightContext::j
const beast::Journal j
Definition: Transactor.h:38
ripple::sfVoteWeight
const SF_UINT32 sfVoteWeight
ripple::ammAccountID
AccountID ammAccountID(std::uint16_t prefix, uint256 const &parentHash, uint256 const &ammID)
Calculate AMM account ID.
Definition: AMMCore.cpp:30
ripple::preflight1
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
Definition: Transactor.cpp:78
ripple::lsfDepositAuth
@ lsfDepositAuth
Definition: LedgerFormats.h:240
ripple::sfTradingFee
const SF_UINT16 sfTradingFee
ripple::requireAuth
TER requireAuth(ReadView const &view, Issue const &issue, AccountID const &account)
Check if the account requires authorization.
Definition: View.cpp:1528
ripple::invalidAMMAmount
NotTEC invalidAMMAmount(STAmount const &amount, std::optional< std::pair< Issue, Issue >> const &pair=std::nullopt, bool validZero=false)
Validate the amount.
Definition: AMMCore.cpp:94
ripple::ApplyContext::app
Application & app
Definition: ApplyContext.h:47
ripple::featureDeletableAccounts
const uint256 featureDeletableAccounts
ripple::sfExpiration
const SF_UINT32 sfExpiration
ripple::Fees::increment
XRPAmount increment
Definition: ReadView.h:53
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:495
ripple::AMMCreate::preclaim
static TER preclaim(PreclaimContext const &ctx)
Definition: AMMCreate.cpp:89
ripple::Keylet::key
uint256 key
Definition: Keylet.h:40
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:82
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::temBAD_AMM_TOKENS
@ temBAD_AMM_TOKENS
Definition: TER.h:127
ripple::lsfDefaultRipple
@ lsfDefaultRipple
Definition: LedgerFormats.h:238
ripple::lsfAMMNode
@ lsfAMMNode
Definition: LedgerFormats.h:269
ripple::sfAsset2
const SF_ISSUE sfAsset2
ripple::Expected
Definition: Expected.h:132
ripple::detail::ApplyViewBase::info
LedgerInfo const & info() const override
Returns information about the ledger.
Definition: ApplyViewBase.cpp:40
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
std::minmax
T minmax(T... args)
ripple::tecDUPLICATE
@ tecDUPLICATE
Definition: TER.h:285
ripple::tecAMM_INVALID_TOKENS
@ tecAMM_INVALID_TOKENS
Definition: TER.h:301
ripple::TERSubset< CanCvtToTER >
ripple::STArray
Definition: STArray.h:28
ripple::Sandbox
Discardable, editable view to a ledger.
Definition: Sandbox.h:34
ripple::AMMCreate::doApply
TER doApply() override
Attempt to create the AMM instance.
Definition: AMMCreate.cpp:366
ripple::TER
TERSubset< CanCvtToTER > TER
Definition: TER.h:575
ripple::STAmount
Definition: STAmount.h:45
beast::Journal::error
Stream error() const
Definition: Journal.h:333
ripple::tecINTERNAL
@ tecINTERNAL
Definition: TER.h:280
ripple::xrpLiquid
XRPAmount xrpLiquid(ReadView const &view, AccountID const &id, std::int32_t ownerCountAdj, beast::Journal j)
Definition: View.cpp:363
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::STTx
Definition: STTx.h:45
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::ApplyContext
State information when applying a tx.
Definition: ApplyContext.h:35
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint16_t
ripple::keylet::book
static const book_t book
Definition: Indexes.h:101
ripple::keylet::line
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:194
ripple::temBAD_FEE
@ temBAD_FEE
Definition: TER.h:90
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::ApplyContext::view
ApplyView & view()
Definition: ApplyContext.h:54
ripple::STIssue
Definition: STIssue.h:31
ripple::PreclaimContext::tx
STTx const & tx
Definition: Transactor.h:58
ripple::tecDIR_FULL
@ tecDIR_FULL
Definition: TER.h:257
ripple::PreclaimContext
State information when determining if a tx is likely to claim a fee.
Definition: Transactor.h:52
ripple::detail::ApplyViewBase::insert
void insert(std::shared_ptr< SLE > const &sle) override
Insert a new state SLE.
Definition: ApplyViewBase.cpp:140
ripple::STObject
Definition: STObject.h:52
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:125
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::TRADING_FEE_THRESHOLD
constexpr std::uint16_t TRADING_FEE_THRESHOLD
Definition: AMMCore.h:31
ripple::TOTAL_TIME_SLOT_SECS
constexpr std::uint32_t TOTAL_TIME_SLOT_SECS
Definition: AMMCore.h:34
ripple::Transactor::view
ApplyView & view()
Definition: Transactor.h:107
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:193
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::ammLPTokens
STAmount ammLPTokens(STAmount const &asset1, STAmount const &asset2, Issue const &lptIssue)
Definition: AMMHelpers.cpp:25
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::Transactor::ctx_
ApplyContext & ctx_
Definition: Transactor.h:88
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::detail::ApplyViewBase::read
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Definition: ApplyViewBase.cpp:71
ripple::Book
Specifies an order book.
Definition: Book.h:33
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::detail::ApplyViewBase::peek
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
Definition: ApplyViewBase.cpp:128
ripple::lsfAMM
@ lsfAMM
Definition: LedgerFormats.h:252
ripple::keylet::quality
Keylet quality(Keylet const &k, std::uint64_t q) noexcept
The initial directory page for a specific quality.
Definition: Indexes.cpp:229
ripple::PreflightContext::tx
STTx const & tx
Definition: Transactor.h:35
ripple::PreflightContext
State information when preflighting a tx.
Definition: Transactor.h:31
ripple::ApplyView::dirInsert
std::optional< std::uint64_t > dirInsert(Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Insert an entry to a directory.
Definition: ApplyView.h:306
ripple::PreflightContext::rules
const Rules rules
Definition: Transactor.h:36
ripple::tfUniversalMask
constexpr std::uint32_t tfUniversalMask
Definition: TxFlags.h:60
ripple::sfAuctionSlot
const SField sfAuctionSlot
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:225
ripple::Transactor::account_
const AccountID account_
Definition: Transactor.h:91
ripple::isFrozen
bool isFrozen(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer)
Definition: View.cpp:220
ripple::ApplyContext::tx
STTx const & tx
Definition: ApplyContext.h:48
ripple::Issue::account
AccountID account
Definition: Issue.h:39
ripple::WaiveTransferFee::Yes
@ Yes
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NotTEC
TERSubset< CanCvtToNotTEC > NotTEC
Definition: TER.h:535
ripple::LedgerInfo::parentCloseTime
NetClock::time_point parentCloseTime
Definition: ReadView.h:84
ripple::OrderBookDB::addOrderBook
void addOrderBook(Book const &)
Definition: OrderBookDB.cpp:168