mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
fix: Add AMMv1_3 amendment (#5203)
* Add AMM bid/create/deposit/swap/withdraw/vote invariants:
- Deposit, Withdrawal invariants: `sqrt(asset1Balance * asset2Balance) >= LPTokens`.
- Bid: `sqrt(asset1Balance * asset2Balance) > LPTokens` and the pool balances don't change.
- Create: `sqrt(asset1Balance * assetBalance2) == LPTokens`.
- Swap: `asset1BalanceAfter * asset2BalanceAfter >= asset1BalanceBefore * asset2BalanceBefore`
and `LPTokens` don't change.
- Vote: `LPTokens` and pool balances don't change.
- All AMM and swap transactions: amounts and tokens are greater than zero, except on withdrawal if all tokens
are withdrawn.
* Add AMM deposit and withdraw rounding to ensure AMM invariant:
- On deposit, tokens out are rounded downward and deposit amount is rounded upward.
- On withdrawal, tokens in are rounded upward and withdrawal amount is rounded downward.
* Add Order Book Offer invariant to verify consumed amounts. Consumed amounts are less than the offer.
* Fix Bid validation. `AuthAccount` can't have duplicate accounts or the submitter account.
This commit is contained in:
committed by
GitHub
parent
0a34b5c691
commit
621df422a7
@@ -20,6 +20,7 @@
|
||||
#include <test/jtx/AMM.h>
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
#include <xrpld/app/misc/AMMHelpers.h>
|
||||
#include <xrpld/app/misc/AMMUtils.h>
|
||||
#include <xrpld/rpc/detail/RPCHelpers.h>
|
||||
|
||||
@@ -39,12 +40,16 @@ number(STAmount const& a)
|
||||
return a;
|
||||
}
|
||||
|
||||
static IOUAmount
|
||||
initialTokens(STAmount const& asset1, STAmount const& asset2)
|
||||
IOUAmount
|
||||
AMM::initialTokens()
|
||||
{
|
||||
auto const product = number(asset1) * number(asset2);
|
||||
return (IOUAmount)(product.mantissa() >= 0 ? root2(product)
|
||||
: root2(-product));
|
||||
if (!env_.enabled(fixAMMv1_3))
|
||||
{
|
||||
auto const product = number(asset1_) * number(asset2_);
|
||||
return (IOUAmount)(product.mantissa() >= 0 ? root2(product)
|
||||
: root2(-product));
|
||||
}
|
||||
return getLPTokensBalance();
|
||||
}
|
||||
|
||||
AMM::AMM(
|
||||
@@ -65,7 +70,6 @@ AMM::AMM(
|
||||
, asset1_(asset1)
|
||||
, asset2_(asset2)
|
||||
, ammID_(keylet::amm(asset1_.issue(), asset2_.issue()).key)
|
||||
, initialLPTokens_(initialTokens(asset1, asset2))
|
||||
, log_(log)
|
||||
, doClose_(close)
|
||||
, lastPurchasePrice_(0)
|
||||
@@ -78,6 +82,7 @@ AMM::AMM(
|
||||
asset1_.issue().currency,
|
||||
asset2_.issue().currency,
|
||||
ammAccount_))
|
||||
, initialLPTokens_(initialTokens())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <test/jtx/AMM.h>
|
||||
#include <test/jtx/AMMTest.h>
|
||||
#include <test/jtx/CaptureLogs.h>
|
||||
#include <test/jtx/Env.h>
|
||||
#include <test/jtx/pay.h>
|
||||
|
||||
@@ -105,15 +106,31 @@ AMMTestBase::testAMM(
|
||||
std::uint16_t tfee,
|
||||
std::optional<jtx::ter> const& ter,
|
||||
std::vector<FeatureBitset> const& vfeatures)
|
||||
{
|
||||
testAMM(
|
||||
std::move(cb),
|
||||
TestAMMArg{
|
||||
.pool = pool, .tfee = tfee, .ter = ter, .features = vfeatures});
|
||||
}
|
||||
|
||||
void
|
||||
AMMTestBase::testAMM(
|
||||
std::function<void(jtx::AMM&, jtx::Env&)>&& cb,
|
||||
TestAMMArg const& arg)
|
||||
{
|
||||
using namespace jtx;
|
||||
|
||||
for (auto const& features : vfeatures)
|
||||
std::string logs;
|
||||
|
||||
for (auto const& features : arg.features)
|
||||
{
|
||||
Env env{*this, features};
|
||||
Env env{
|
||||
*this,
|
||||
features,
|
||||
arg.noLog ? std::make_unique<CaptureLogs>(&logs) : nullptr};
|
||||
|
||||
auto const [asset1, asset2] =
|
||||
pool ? *pool : std::make_pair(XRP(10000), USD(10000));
|
||||
arg.pool ? *arg.pool : std::make_pair(XRP(10000), USD(10000));
|
||||
auto tofund = [&](STAmount const& a) -> STAmount {
|
||||
if (a.native())
|
||||
{
|
||||
@@ -143,7 +160,7 @@ AMMTestBase::testAMM(
|
||||
alice,
|
||||
asset1,
|
||||
asset2,
|
||||
CreateArg{.log = false, .tfee = tfee, .err = ter});
|
||||
CreateArg{.log = false, .tfee = arg.tfee, .err = arg.ter});
|
||||
if (BEAST_EXPECT(
|
||||
ammAlice.expectBalances(asset1, asset2, ammAlice.tokens())))
|
||||
cb(ammAlice, env);
|
||||
|
||||
Reference in New Issue
Block a user