xrpld
Loading...
Searching...
No Matches
tx/paths/Offer.h
1#pragma once
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/beast/utility/Journal.h>
7#include <xrpl/beast/utility/Zero.h>
8#include <xrpl/ledger/ApplyView.h>
9#include <xrpl/ledger/helpers/TokenHelpers.h>
10#include <xrpl/protocol/AccountID.h>
11#include <xrpl/protocol/Concepts.h>
12#include <xrpl/protocol/Feature.h>
13#include <xrpl/protocol/Quality.h>
14#include <xrpl/protocol/Rules.h>
15#include <xrpl/protocol/SField.h>
16#include <xrpl/protocol/STLedgerEntry.h>
17#include <xrpl/protocol/TER.h>
18
19#include <cstdint>
20#include <optional>
21#include <ostream>
22#include <stdexcept>
23#include <string>
24#include <utility>
25
26namespace xrpl {
27
28template <StepAmount TIn, StepAmount TOut>
29class TOffer
30{
31private:
37
39 void
41
42public:
43 TOffer() = default;
44
46
57 [[nodiscard]] Quality
58 quality() const noexcept
59 {
60 return quality_;
61 }
62
66 [[nodiscard]] AccountID const&
67 owner() const
68 {
69 return accountID_;
70 }
71
76 [[nodiscard]] TAmounts<TIn, TOut> const&
77 amount() const
78 {
79 return amounts_;
80 }
81
85 [[nodiscard]] bool
87 {
88 if (amounts_.in <= beast::kZero)
89 return true;
90 if (amounts_.out <= beast::kZero)
91 return true;
92 return false;
93 }
94
98 void
99 consume(ApplyView& view, TAmounts<TIn, TOut> const& consumed)
100 {
101 if (consumed.in > amounts_.in)
102 Throw<std::logic_error>("can't consume more than is available.");
103
104 if (consumed.out > amounts_.out)
105 Throw<std::logic_error>("can't produce more than is available.");
106
107 amounts_ -= consumed;
109 view.update(entry_);
110 }
111
112 [[nodiscard]] std::string
113 id() const
114 {
115 return to_string(entry_->key());
116 }
117
118 [[nodiscard]] std::optional<uint256>
119 key() const
120 {
121 return entry_->key();
122 }
123
124 [[nodiscard]] Asset const&
125 assetIn() const;
126 [[nodiscard]] Asset const&
127 assetOut() const;
128
129 [[nodiscard]] TAmounts<TIn, TOut>
130 limitOut(TAmounts<TIn, TOut> const& offerAmount, TOut const& limit, bool roundUp) const;
131
132 [[nodiscard]] TAmounts<TIn, TOut>
133 limitIn(TAmounts<TIn, TOut> const& offerAmount, TIn const& limit, bool roundUp) const;
134
135 template <typename... Args>
136 static TER
137 send(Args&&... args);
138
139 [[nodiscard]] bool
140 isFunded() const
141 {
142 // Offer owner is issuer; they have unlimited funds if IOU
143 return accountID_ == assetOut_.getIssuer() && assetOut_.holds<Issue>();
144 }
145
148 {
149 // CLOB offer pays the transfer fee
150 return {ofrInRate, ofrOutRate};
151 }
152
157 [[nodiscard]] bool
159 {
160 if (!isFeatureEnabled(fixAMMv1_3))
161 return true;
162
163 if (consumed.in > amounts_.in || consumed.out > amounts_.out)
164 {
165 // LCOV_EXCL_START
166 JLOG(j.error()) << "AMMOffer::checkInvariant failed: consumed "
167 << to_string(consumed.in) << " " << to_string(consumed.out)
168 << " amounts " << to_string(amounts_.in) << " "
169 << to_string(amounts_.out);
170
171 return false;
172 // LCOV_EXCL_STOP
173 }
174
175 return true;
176 }
177};
178
179template <StepAmount TIn, StepAmount TOut>
181 : entry_(std::move(entry)), quality_(quality), accountID_(entry_->getAccountID(sfAccount))
182{
183 auto const tp = entry_->getFieldAmount(sfTakerPays);
184 auto const tg = entry_->getFieldAmount(sfTakerGets);
185 amounts_.in = toAmount<TIn>(tp);
186 amounts_.out = toAmount<TOut>(tg);
187 assetIn_ = tp.asset();
188 assetOut_ = tg.asset();
189}
190
191template <StepAmount TIn, StepAmount TOut>
192void
194{
195 if constexpr (std::is_same_v<TIn, XRPAmount>)
196 {
197 entry_->setFieldAmount(sfTakerPays, toSTAmount(amounts_.in));
198 }
199 else
200 {
201 entry_->setFieldAmount(sfTakerPays, toSTAmount(amounts_.in, assetIn_));
202 }
203
205 {
206 entry_->setFieldAmount(sfTakerGets, toSTAmount(amounts_.out));
207 }
208 else
209 {
210 entry_->setFieldAmount(sfTakerGets, toSTAmount(amounts_.out, assetOut_));
211 }
212}
213
214template <StepAmount TIn, StepAmount TOut>
216TOffer<TIn, TOut>::limitOut(TAmounts<TIn, TOut> const& offerAmount, TOut const& limit, bool roundUp)
217 const
218{
219 // It turns out that the ceil_out implementation has some slop in
220 // it, which ceil_out_strict removes.
221 return quality().ceilOutStrict(offerAmount, limit, roundUp);
222}
223
224template <StepAmount TIn, StepAmount TOut>
226TOffer<TIn, TOut>::limitIn(TAmounts<TIn, TOut> const& offerAmount, TIn const& limit, bool roundUp)
227 const
228{
229 if (auto const& rules = getCurrentTransactionRules();
230 rules && rules->enabled(fixReducedOffersV2))
231 {
232 // It turns out that the ceil_in implementation has some slop in
233 // it. ceil_in_strict removes that slop. But removing that slop
234 // affects transaction outcomes, so the change must be made using
235 // an amendment.
236 return quality().ceilInStrict(offerAmount, limit, roundUp);
237 }
238 return quality_.ceilIn(offerAmount, limit);
239}
240
241template <StepAmount TIn, StepAmount TOut>
242template <typename... Args>
243TER
249
250template <StepAmount TIn, StepAmount TOut>
251Asset const&
253{
254 return assetIn_;
255}
256
257template <StepAmount TIn, StepAmount TOut>
258Asset const&
260{
261 return assetOut_;
262}
263
264template <StepAmount TIn, StepAmount TOut>
267{
268 return os << offer.id();
269}
270
271} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
Stream error() const
Definition Journal.h:362
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:134
virtual void update(SLE::ref sle)=0
Indicate changes to a peeked SLE.
A currency issued by an account.
Definition Issue.h:18
Represents the logical ratio of output currency to input currency.
Definition Quality.h:90
std::shared_ptr< STLedgerEntry > pointer
static TER send(Args &&... args)
TAmounts< TIn, TOut > amounts_
AccountID const & owner() const
Returns the account id of the offer's owner.
void consume(ApplyView &view, TAmounts< TIn, TOut > const &consumed)
Adjusts the offer to indicate that we consumed some (or all) of it.
Asset const & assetIn() const
static std::pair< std::uint32_t, std::uint32_t > adjustRates(std::uint32_t ofrInRate, std::uint32_t ofrOutRate)
std::optional< uint256 > key() const
Quality quality() const noexcept
Returns the quality of the offer.
TOffer()=default
bool fullyConsumed() const
Returns true if no more funds can flow through this offer.
bool isFunded() const
TAmounts< TIn, TOut > limitOut(TAmounts< TIn, TOut > const &offerAmount, TOut const &limit, bool roundUp) const
bool checkInvariant(TAmounts< TIn, TOut > const &consumed, beast::Journal j) const
Check any required invariant.
void setFieldAmounts()
SLE::pointer entry_
TAmounts< TIn, TOut > const & amount() const
Returns the in and out amounts.
AccountID accountID_
Asset const & assetOut() const
std::string id() const
TAmounts< TIn, TOut > limitIn(TAmounts< TIn, TOut > const &offerAmount, TIn const &limit, bool roundUp) const
T forward(T... args)
T is_same_v
constexpr Zero kZero
Definition Zero.h:30
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool isFeatureEnabled(uint256 const &feature, bool resultIfNoRules)
Check whether a feature is enabled in the current ledger rules.
Definition Rules.cpp:197
TER accountSend(ApplyView &view, AccountID const &from, AccountID const &to, STAmount const &saAmount, beast::Journal j, SLE::ref sponsorSle={}, WaiveTransferFee waiveFee=WaiveTransferFee::No, AllowMPTOverflow allowOverflow=AllowMPTOverflow::No)
Calls static accountSendIOU if saAmount represents Issue.
std::optional< Rules > const & getCurrentTransactionRules()
Definition Rules.cpp:30
std::ostream & operator<<(std::ostream &out, BaseUInt< Bits, Tag > const &u)
Definition base_uint.h:666
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
T toAmount(STAmount const &amt)=delete
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
TERSubset< CanCvtToTER > TER
Definition TER.h:647
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
STAmount toSTAmount(IOUAmount const &iou, Asset const &asset)
Represents a pair of input and output currencies.
Definition Quality.h:29