1#include <test/app/vault/VaultPrecisionFixture.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/amount.h>
4#include <test/jtx/envconfig.h>
5#include <test/jtx/ter.h>
6#include <test/jtx/vault.h>
8#include <xrpl/basics/Number.h>
9#include <xrpl/beast/unit_test/suite.h>
10#include <xrpl/beast/utility/Journal.h>
11#include <xrpl/protocol/Feature.h>
12#include <xrpl/protocol/MPTIssue.h>
13#include <xrpl/protocol/STAmount.h>
14#include <xrpl/protocol/TER.h>
41 bool const fixEnabled = features[fixCleanup3_4_0];
44 (fixEnabled ?
" (fixCleanup3_4_0)" :
" (pre-fix)"));
48 for (
auto const amount : kAmounts)
52 if (!f.asset || !f.broker)
54 BEAST_EXPECT(f.asset && f.broker);
57 auto const& asset = *f.asset;
59 auto const before =
read(env, f);
63 {.depositor = f.depositor,
64 .id = f.vaultKeylet.key,
65 .amount = asset(amount).value()}),
69 TER const actual = env.
ter();
75 "amount=" +
std::to_string(amount) +
" expected tesSUCCESS, got " +
79 Number const tDelta =
after.assetsTotal - before.assetsTotal;
80 Number const aDelta =
after.assetsAvailable - before.assetsAvailable;
81 Number const requested = asset(amount).number();
83 BEAST_EXPECT(tDelta <= requested);
85 Number const gap = tDelta > aDelta ? tDelta - aDelta : aDelta - tDelta;
92 "amount=" +
std::to_string(amount) +
" expected tecINVARIANT_FAILED, got " +
105 bool const fixEnabled = features[fixCleanup3_4_0];
108 (fixEnabled ?
" (fixCleanup3_4_0)" :
" (pre-fix)"));
111 99'999u, 100'001u, 333'333u, 1'234'567u, 142'857'142u, 333'333'333u};
117 if (!f.asset || !f.broker)
119 BEAST_EXPECT(f.asset && f.broker);
122 auto const& asset = *f.asset;
127 {.depositor = f.depositor,
128 .id = f.vaultKeylet.key,
129 .amount = asset(1'000'000).value()}),
133 for (
auto const count : kShareCounts)
135 auto const before =
read(env, f);
136 if (before.sharesTotal < count)
141 {.depositor = f.depositor, .id = f.vaultKeylet.key, .amount = shareAmount}),
145 TER const actual = env.
ter();
151 "shares=" +
std::to_string(count) +
" unexpected invariant failure");
156 Number const tDelta = before.assetsTotal -
after.assetsTotal;
157 Number const pDelta = before.pseudo -
after.pseudo;
158 Number const gap = tDelta > pDelta ? tDelta - pDelta : pDelta - tDelta;
161 BEAST_EXPECT(gap <=
oneUnit(asset, before.assetsTotal));
180 bool const fixEnabled = features[fixCleanup3_4_0];
183 (fixEnabled ?
" (fixCleanup3_4_0)" :
" (pre-fix)"));
189 if (!f.asset || !f.broker)
191 BEAST_EXPECT(f.asset && f.broker);
194 auto const& asset = *f.asset;
201 {.depositor = f.depositor,
202 .id = f.vaultKeylet.key,
203 .amount = asset(2'000).value()}),
207 for (
auto const amount : kAmounts)
209 auto const before =
read(env, f);
210 if (before.sharesTotal == 0)
215 .id = f.vaultKeylet.key,
216 .holder = f.depositor,
217 .amount = asset(amount).value()}),
221 TER const actual = env.
ter();
227 "amount=" +
std::to_string(amount) +
" unexpected invariant failure");
238 env(v.
clawback({.issuer = f.lender, .id = f.vaultKeylet.key, .holder = f.depositor}),
251 bool const fixEnabled = features[fixCleanup3_4_0];
254 (fixEnabled ?
" (fixCleanup3_4_0)" :
" (pre-fix)"));
258 for (
auto const amount : kAmounts)
262 if (!f.asset || !f.broker)
264 BEAST_EXPECT(f.asset && f.broker);
267 auto const& asset = *f.asset;
271 {.depositor = f.depositor,
272 .id = f.vaultKeylet.key,
273 .amount = asset(amount).value()}),
277 TER const actual = env.
ter();
283 "amount=" +
std::to_string(amount) +
" expected tesSUCCESS, got " +
295 "amount=" +
std::to_string(amount) +
" expected tecINVARIANT_FAILED, got " +
308 bool const fixEnabled = features[fixCleanup3_4_0];
311 (fixEnabled ?
" (fixCleanup3_4_0)" :
" (pre-fix)"));
333 for (
auto const amount : kAmounts)
337 if (!f.asset || !f.broker)
339 BEAST_EXPECT(f.asset && f.broker);
342 auto const& asset = *f.asset;
346 {.depositor = f.depositor,
347 .id = f.vaultKeylet.key,
348 .amount = asset(amount).value()}),
352 TER const actual = env.
ter();
358 "amount=" +
std::to_string(amount) +
" expected tesSUCCESS, got " +
363 bool const shouldFail =
370 " expected tecINVARIANT_FAILED, got " +
transToken(actual));
387 bool const fixEnabled = features[fixCleanup3_4_0];
390 (fixEnabled ?
" (fixCleanup3_4_0)" :
" (pre-fix)"));
393 1, 7, 100, 1'000, 10'000, 100'000, 1'000'000, 10'000'000, 99'999};
397 for (
auto const amount : kAmounts)
401 if (!f.asset || !f.broker)
403 BEAST_EXPECT(f.asset && f.broker);
406 auto const& asset = *f.asset;
410 {.depositor = f.depositor,
411 .id = f.vaultKeylet.key,
412 .amount = asset(amount).value()}),
416 TER const actual = env.
ter();
422 "amount=" +
std::to_string(amount) +
" expected tesSUCCESS, got " +
427 bool const shouldFail =
434 " expected tecINVARIANT_FAILED, got " +
transToken(actual));
444 for (
auto const& features : {
all_ - fixCleanup3_4_0,
all_})
TestcaseT testcase
Memberspace for declaring test cases.
Number is a floating point type that can represent a wide range of values.
void testWithdrawBoundaryInvariant(FeatureBitset features)
void testA1DepositMagnitudes(FeatureBitset features)
void testDepositBoundaryInvariant(FeatureBitset features)
void testA3DepositMagnitudes(FeatureBitset features)
void testClawbackBoundaryInvariant(FeatureBitset features)
void testLossInvariantA3(FeatureBitset features)
void run() override
Runs the suite.
static Number oneUnit(Asset const &asset, Number const &assetsTotalAfter)
static Numbers read(jtx::Env const &env, Fixture const &f)
static Fixture setupSingleLoanVault(jtx::Env &env, bool impairAndPaySibling, bool allowClawback=false)
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
TER ter() const
Return the TER for the last JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string transToken(TER code)
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
TERSubset< CanCvtToTER > TER
static json::Value withdraw(WithdrawArgs const &args)
static json::Value clawback(ClawbackArgs const &args)
static json::Value deposit(DepositArgs const &args)