2#include <test/jtx/AMM.h>
3#include <test/jtx/AMMTest.h>
5#include <xrpl/protocol/jss.h>
23 enum TestAccount {
None, Alice, Bogie };
36 auto const USD =
gw[
"USD"];
38 BEAST_EXPECT(jv[jss::error_message] ==
"Account not found.");
44 BEAST_EXPECT(jv[jss::error_message] ==
"Account malformed.");
57 for (
auto const& [iss1, iss2, acct, ignoreParams] : invalidParams)
61 BEAST_EXPECT(jv[jss::error_message] ==
"Invalid parameters.");
67 for (
auto const& [iss1, iss2, acct, ignoreParams] : invalidParams)
74 accountId(ammAlice, acct),
76 BEAST_EXPECT(jv[jss::error_message] ==
"Invalid parameters.");
82 for (
auto const& [iss1, iss2, acct, ignoreParams] : invalidParams)
89 accountId(ammAlice, acct),
92 BEAST_EXPECT(jv[jss::error_message] ==
"Account malformed.");
99 BEAST_EXPECT(jv[jss::error_message] ==
"Account malformed.");
103 invalidParamsBadAccount = {
113 for (
auto const& [iss1, iss2, acct, ignoreParams] : invalidParamsBadAccount)
117 BEAST_EXPECT(jv[jss::error_message] ==
"Invalid parameters.");
123 for (
auto const& [iss1, iss2, acct, ignoreParams] : invalidParamsBadAccount)
128 jv[jss::error_message] ==
154 [&](
AMM& ammAlice,
Env& env) {
158 for (
int i = 0; i < 7; ++i)
162 if (!features[fixAMMv1_3])
163 fund(env,
gw, {a}, {
USD(10000)}, Fund::Acct);
165 fund(env,
gw, {a}, {
USD(10001)}, Fund::Acct);
167 ammAlice.
vote(a, 50 * (i + 1));
173 env(ammAlice.
bid({.bidMin = 100, .authAccounts = {carol, bob, ed, bill}}));
174 if (!features[fixAMMv1_3])
190 for (
auto i = 0; i < 2; ++i)
194 auto const ammInfo = i
198 auto const& amm = ammInfo[jss::amm];
202 auto const voteSlots = amm[jss::vote_slots];
203 auto votesCopy = votes;
207 votes[voteSlots[i][jss::account].asString()] ==
208 voteSlots[i][jss::trading_fee].asUInt() &&
209 voteSlots[i][jss::vote_weight].asUInt() == 12500))
211 votes.erase(voteSlots[i][jss::account].asString());
213 if (!BEAST_EXPECT(votes.empty()))
218 auto const auctionSlot = amm[jss::auction_slot];
222 authAccounts.
contains(auctionSlot[jss::auth_accounts][i][jss::account].asString())))
224 authAccounts.
erase(auctionSlot[jss::auth_accounts][i][jss::account].asString());
226 if (!BEAST_EXPECT(authAccounts.
empty()))
229 auctionSlot[jss::account].asString() ==
alice.
human() &&
230 auctionSlot[jss::discounted_fee].asUInt() == 17 &&
231 auctionSlot[jss::price][jss::value].asString() ==
"5600" &&
232 auctionSlot[jss::price][jss::currency].asString() ==
252 testAMM([&](
AMM& ammAlice,
Env& env) {
255 auto test = [&](
bool freeze) {
257 BEAST_EXPECT(info[jss::amm][jss::asset2_frozen].asBool() ==
freeze);
270 testcase(
"Invalid amm field");
272 testAMM([&](
AMM& amm,
Env&) {
274 BEAST_EXPECT(resp.isMember(
"error") && resp[
"error"] ==
"actNotFound");
286 testVoteAndBid(
all - fixAMMv1_3);
288 testInvalidAmmField();
testcase_t testcase
Memberspace for declaring test cases.
void fail(String const &reason, char const *file, int line)
Record a failure.
Floating point representation of amounts with high dynamic range.
void testInvalidAmmField()
void run() override
Runs the suite.
void testVoteAndBid(FeatureBitset features)
void testAMM(std::function< void(jtx::AMM &, jtx::Env &)> &&cb, std::optional< std::pair< STAmount, STAmount > > const &pool=std::nullopt, std::uint16_t tfee=0, std::optional< jtx::ter > const &ter=std::nullopt, std::vector< FeatureBitset > const &features={testable_amendments()})
testAMM() funds 30,000XRP and 30,000IOU for each non-XRP asset to Alice and Carol
Convenience class to test AMM functionality.
bool expectTradingFee(std::uint16_t fee) const
void vote(std::optional< Account > const &account, std::uint32_t feeVal, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< jtx::seq > const &seq=std::nullopt, std::optional< std::pair< Issue, Issue > > const &assets=std::nullopt, std::optional< ter > const &ter=std::nullopt)
bool expectAmmRpcInfo(STAmount const &asset1, STAmount const &asset2, IOUAmount const &balance, std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledger_index=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt) const
IOUAmount deposit(std::optional< Account > const &account, LPToken tokens, std::optional< STAmount > const &asset1InDetails=std::nullopt, std::optional< std::uint32_t > const &flags=std::nullopt, std::optional< ter > const &ter=std::nullopt)
AccountID const & ammAccount() const
Json::Value ammRpcInfo(std::optional< AccountID > const &account=std::nullopt, std::optional< std::string > const &ledgerIndex=std::nullopt, std::optional< Issue > issue1=std::nullopt, std::optional< Issue > issue2=std::nullopt, std::optional< AccountID > const &ammAccount=std::nullopt, bool ignoreParams=false, unsigned apiVersion=RPC::apiInvalidVersion) const
Send amm_info RPC command.
Json::Value bid(BidArg const &arg)
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
AccountID id() const
Returns the Account ID.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Set the expected result code for a JTx The test will fail if the code doesn't match.
void fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
FeatureBitset testable_amendments()
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfGlobalFreeze
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
std::string to_string(base_uint< Bits, Tag > const &a)