20 #include <ripple/app/tx/impl/AMMBid.h>
22 #include <ripple/app/misc/AMMHelpers.h>
23 #include <ripple/app/misc/AMMUtils.h>
24 #include <ripple/ledger/Sandbox.h>
25 #include <ripple/ledger/View.h>
26 #include <ripple/protocol/AMMCore.h>
27 #include <ripple/protocol/Feature.h>
28 #include <ripple/protocol/STAccount.h>
29 #include <ripple/protocol/TER.h>
30 #include <ripple/protocol/TxFlags.h>
45 JLOG(ctx.
j.
debug()) <<
"AMM Bid: invalid flags.";
51 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid asset pair.";
59 JLOG(ctx.
j.
debug()) <<
"AMM Bid: invalid min slot price.";
68 JLOG(ctx.
j.
debug()) <<
"AMM Bid: invalid max slot price.";
78 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid number of AuthAccounts.";
93 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid asset pair.";
98 if (lpTokensBalance == beast::zero)
107 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid Account.";
113 auto const lpTokens =
116 if (lpTokens == beast::zero)
118 JLOG(ctx.
j.
debug()) <<
"AMM Bid: account is not LP.";
126 if (bidMin->issue() != lpTokens.issue())
128 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid LPToken.";
131 if (*bidMin > lpTokens || *bidMin >= lpTokensBalance)
133 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid Tokens.";
141 if (bidMax->issue() != lpTokens.issue())
143 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid LPToken.";
146 if (*bidMax > lpTokens || *bidMax >= lpTokensBalance)
148 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid Tokens.";
153 if (bidMin && bidMax && bidMin > bidMax)
155 JLOG(ctx.
j.
debug()) <<
"AMM Bid: Invalid Max/MinSlotPrice.";
180 duration_cast<seconds>(
184 auto const discountedFee =
188 auto const minSlotPrice =
198 auto validOwner = [&](
AccountID const& account) {
201 return timeSlot && *timeSlot < tailingSlot &&
208 auctionSlot.setAccountID(
sfAccount, account_);
214 auctionSlot.setFieldAmount(
217 auctionSlot.setFieldArray(
224 if (saBurn >= lptAMMBalance)
228 <<
"AMM Bid: LP Token burn exceeds AMM balance " << burn <<
" "
236 JLOG(ctx_.
journal.
debug()) <<
"AMM Bid: failed to redeem.";
253 if (bidMin && bidMax)
255 if (computedPrice <= *bidMax)
258 <<
"AMM Bid: not in range " << computedPrice <<
" "
259 << *bidMin <<
" " << *bidMax;
269 if (computedPrice <= *bidMax)
270 return computedPrice;
272 << computedPrice <<
" " << *bidMax;
276 return computedPrice;
280 else if (payPrice > lpTokens)
286 if (
auto const acct = auctionSlot[~
sfAccount]; !acct || !validOwner(*acct))
288 if (
auto const payPrice = getPayPrice(minSlotPrice); !payPrice)
289 return {payPrice.error(),
false};
291 res = updateSlot(discountedFee, *payPrice, *payPrice);
298 auto const fractionUsed =
300 auto const fractionRemaining =
Number(1) - fractionUsed;
301 auto const computedPrice = [&]() ->
Number {
302 auto const p1_05 =
Number(105, -2);
305 return pricePurchased * p1_05 + minSlotPrice;
307 return pricePurchased * p1_05 * (1 -
power(fractionUsed, 60)) +
311 auto const payPrice = getPayPrice(computedPrice);
314 return {payPrice.error(),
false};
318 auto const refund = fractionRemaining * pricePurchased;
319 if (refund > *payPrice)
322 JLOG(ctx_.
journal.
fatal()) <<
"AMM Bid: refund exceeds payPrice "
323 << refund <<
" " << *payPrice;
334 JLOG(ctx_.
journal.
debug()) <<
"AMM Bid: failed to refund.";
338 auto const burn = *payPrice - refund;
339 res = updateSlot(discountedFee, *payPrice, burn);
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
const STArray & getFieldArray(SField const &field) const
NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
const SF_UINT16 sfDiscountedFee
static std::pair< TER, bool > applyBid(ApplyContext &ctx_, Sandbox &sb, AccountID const &account_, beast::Journal j_)
TER accountSend(ApplyView &view, AccountID const &uSenderID, AccountID const &uReceiverID, STAmount const &saAmount, beast::Journal j, WaiveTransferFee waiveFee)
Issue const & issue() const
constexpr std::uint16_t AUCTION_SLOT_TIME_INTERVALS
const SF_AMOUNT sfLPTokenBalance
constexpr std::uint32_t AUCTION_SLOT_DISCOUNTED_FEE_FRACTION
bool ammEnabled(Rules const &)
Return true if required AMM amendments are enabled.
Keylet amm(Issue const &issue1, Issue const &issue2) noexcept
AMM entry.
static NotTEC preflight(PreflightContext const &ctx)
Unexpected(E(&)[N]) -> Unexpected< E const * >
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
Number getFee(std::uint16_t tfee)
Convert to the fee from the basis points.
const beast::Journal journal
NotTEC preflight1(PreflightContext const &ctx)
Performs early sanity checks on the account and fee fields.
const SF_UINT16 sfTradingFee
NotTEC invalidAMMAmount(STAmount const &amount, std::optional< std::pair< Issue, Issue >> const &pair=std::nullopt, bool validZero=false)
Validate the amount.
const SF_UINT32 sfExpiration
constexpr std::uint32_t AUCTION_SLOT_MIN_FEE_FRACTION
Integers of any length that is a multiple of 32-bits.
T time_since_epoch(T... args)
Keylet account(AccountID const &id) noexcept
AccountID root.
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
const SField sfAuthAccounts
Discardable, editable view to a ledger.
TERSubset< CanCvtToTER > TER
std::uint32_t getFlags() const
@ current
This was a new validation and was added.
State information when applying a tx.
A generic endpoint for log messages.
NotTEC invalidAMMAssetPair(Issue const &issue1, Issue const &issue2, std::optional< std::pair< Issue, Issue >> const &pair=std::nullopt)
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
Number power(Number const &f, unsigned n)
State information when determining if a tx is likely to claim a fee.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t TOTAL_TIME_SLOT_SECS
TER redeemIOU(ApplyView &view, AccountID const &account, STAmount const &amount, Issue const &issue, beast::Journal j)
bool isFieldPresent(SField const &field) const
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.
constexpr std::uint16_t AUCTION_SLOT_MAX_AUTH_ACCOUNTS
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
const SF_ACCOUNT sfAccount
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
static TER preclaim(PreclaimContext const &ctx)
State information when preflighting a tx.
STAmount adjustLPTokens(STAmount const &lptAMMBalance, STAmount const &lpTokens, bool isDeposit)
constexpr std::uint32_t tfUniversalMask
const SField sfAuctionSlot
std::optional< std::uint8_t > ammAuctionTimeSlot(std::uint64_t current, STObject const &auctionSlot)
Get time slot of the auction slot.
TERSubset< CanCvtToNotTEC > NotTEC