Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] try: sdk.Uint for perp AMM reserves #1489

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions proto/nibiru/perp/v2/state.proto
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ message AMM {

// the amount of base reserves this AMM has
string base_reserve = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false
];

// the amount of quote reserves this AMM has
string quote_reserve = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false
];

Expand All @@ -139,13 +139,13 @@ message AMM {

// Total long refers to the sum of long open notional in base.
string total_long = 6 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false
];

// Total short refers to the sum of short open notional in base.
string total_short = 7 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.Uint",
(gogoproto.nullable) = false
];
}
Expand Down
132 changes: 67 additions & 65 deletions x/perp/v2/types/amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
)

func (amm AMM) Validate() error {
if amm.BaseReserve.LTE(sdk.ZeroDec()) {
return fmt.Errorf("init pool token supply must be > 0")
if amm.BaseReserve.IsNil() || amm.BaseReserve.IsZero() {
return fmt.Errorf("base reserves must be > 0")
}

if amm.QuoteReserve.LTE(sdk.ZeroDec()) {
return fmt.Errorf("init pool token supply must be > 0")
if amm.QuoteReserve.IsNil() || amm.QuoteReserve.IsZero() {
return fmt.Errorf("quote reserves must be > 0")
}

if amm.PriceMultiplier.LTE(sdk.ZeroDec()) {
Expand All @@ -29,10 +29,6 @@
return fmt.Errorf("init sqrt depth must be > 0")
}

if !amm.QuoteReserve.IsPositive() || !amm.BaseReserve.IsPositive() {
return ErrInvalidAmmReserves.Wrapf("amm %s has invalid reserves", amm.String())
}

computedSqrtDepth, err := amm.ComputeSqrtDepth()
if err != nil {
return err
Expand All @@ -52,13 +48,13 @@
}

// returns the amount of quote reserve equivalent to the amount of quote asset given
func (amm AMM) FromQuoteAssetToReserve(quoteAsset sdk.Dec) sdk.Dec {
return quoteAsset.Quo(amm.PriceMultiplier)
func (amm AMM) FromQuoteAssetToReserve(quoteAsset sdkmath.Uint) sdkmath.Uint {
return sdkmath.NewUintFromBigInt(amm.PriceMultiplier.QuoInt64(int64(quoteAsset.Uint64())).BigInt())
}

// returns the amount of quote asset equivalent to the amount of quote reserve given
func (amm AMM) FromQuoteReserveToAsset(quoteReserve sdk.Dec) sdk.Dec {
return quoteReserve.Mul(amm.PriceMultiplier)
func (amm AMM) FromQuoteReserveToAsset(quoteReserve sdkmath.Uint) sdkmath.Uint {
return sdkmath.NewUintFromBigInt(amm.PriceMultiplier.MulInt64(int64(quoteReserve.Uint64())).BigInt())
}

// Returns the amount of base reserve equivalent to the amount of quote reserve given
Expand All @@ -68,36 +64,37 @@
// - dir: the direction of the trade
//
// returns:
// - baseReserveDelta: the amount of base reserve after the trade, unsigned
// - baseReserveDelta: the amount of base reserve after the trade, always positive
// - err: error
//
// NOTE: baseReserveDelta is always positive
// Throws an error if input quoteReserveAmt is negative, or if the final quote reserve is not positive
// Throws an error if the final quote reserve is not positive
func (amm AMM) GetBaseReserveAmt(
quoteReserveAmt sdk.Dec, // unsigned
quoteReserveAmt sdkmath.Uint, // unsigned
dir Direction,
) (baseReserveDelta sdk.Dec, err error) {
if quoteReserveAmt.IsNegative() {
return sdk.Dec{}, ErrInputQuoteAmtNegative
}

) (baseReserveDelta sdkmath.Uint, err error) {
invariant := amm.QuoteReserve.Mul(amm.BaseReserve) // x * y = k

var quoteReservesAfter sdk.Dec
var quoteReservesAfter sdkmath.Uint
if dir == Direction_LONG {
quoteReservesAfter = amm.QuoteReserve.Add(quoteReserveAmt)
} else {
quoteReservesAfter = amm.QuoteReserve.Sub(quoteReserveAmt)
}
if quoteReserveAmt.GT(amm.QuoteReserve) {
return sdkmath.ZeroUint(), ErrQuoteReserveAtZero.Wrapf(
"quote reserves below zero after trying to swap %s quote reserves. there are only %s quote reserves in the pool",
quoteReserveAmt.String(), amm.QuoteReserve.String(),
)
}

if !quoteReservesAfter.IsPositive() {
return sdk.Dec{}, ErrQuoteReserveAtZero
quoteReservesAfter = amm.QuoteReserve.Sub(quoteReserveAmt)
}

baseReservesAfter := invariant.Quo(quoteReservesAfter)
baseReserveDelta = baseReservesAfter.Sub(amm.BaseReserve).Abs()

return baseReserveDelta, nil
if baseReservesAfter.GT(amm.BaseReserve) {
return baseReservesAfter.Sub(amm.BaseReserve), nil
}

return amm.BaseReserve.Sub(baseReservesAfter), nil
}

// returns the amount of quote reserve equivalent to the amount of base asset given
Expand All @@ -112,33 +109,32 @@
//
// NOTE: quoteReserveDelta is always positive
func (amm AMM) GetQuoteReserveAmt(
baseReserveAmt sdk.Dec,
baseReserveAmt sdkmath.Uint,
dir Direction,
) (quoteReserveDelta sdk.Dec, err error) {
if baseReserveAmt.IsNegative() {
return sdk.Dec{}, ErrInputBaseAmtNegative
}

) (quoteReserveDelta sdkmath.Uint, err error) {
invariant := amm.QuoteReserve.Mul(amm.BaseReserve) // x * y = k

var baseReservesAfter sdk.Dec
var baseReservesAfter sdkmath.Uint
if dir == Direction_LONG {
if baseReserveAmt.GT(amm.BaseReserve) {
return sdkmath.ZeroUint(), ErrBaseReserveAtZero.Wrapf(
"base reserves below zero after trying to swap %s base reserves. there are only %s base reserves in the pool",
baseReserveAmt.String(), amm.BaseReserve.String(),
)
}

baseReservesAfter = amm.BaseReserve.Sub(baseReserveAmt)
} else {
baseReservesAfter = amm.BaseReserve.Add(baseReserveAmt)
}

if !baseReservesAfter.IsPositive() {
return sdk.Dec{}, ErrBaseReserveAtZero.Wrapf(
"base assets below zero after trying to swap %s base assets",
baseReserveAmt.String(),
)
}

quoteReservesAfter := invariant.Quo(baseReservesAfter)
quoteReserveDelta = quoteReservesAfter.Sub(amm.QuoteReserve).Abs()

return quoteReserveDelta, nil
if quoteReservesAfter.GT(amm.QuoteReserve) {
return quoteReservesAfter.Sub(amm.QuoteReserve), nil
}

return amm.QuoteReserve.Sub(quoteReservesAfter), nil
}

// Returns the instantaneous mark price of the trading pair
Expand All @@ -148,7 +144,11 @@
return sdk.ZeroDec()
}

return amm.QuoteReserve.Quo(amm.BaseReserve).Mul(amm.PriceMultiplier)
return amm.PriceMultiplier.MulInt(
sdkmath.NewIntFromUint64(
amm.QuoteReserve.Quo(amm.BaseReserve).Uint64(),
),
)
}

// Returns the sqrt k of the reserves
Expand All @@ -160,7 +160,7 @@
return sdk.Dec{}, ErrLiquidityDepthOverflow
}

liqDepth := amm.QuoteReserve.Mul(amm.BaseReserve)
liqDepth := sdkmath.LegacyNewDecFromBigInt(amm.QuoteReserve.Mul(amm.BaseReserve).BigInt())
return common.SqrtDec(liqDepth)
}

Expand All @@ -169,12 +169,12 @@
return amm
}

func (amm *AMM) WithBaseReserve(baseReserve sdk.Dec) *AMM {
func (amm *AMM) WithBaseReserve(baseReserve sdkmath.Uint) *AMM {
amm.BaseReserve = baseReserve
return amm
}

func (amm *AMM) WithQuoteReserve(quoteReserve sdk.Dec) *AMM {
func (amm *AMM) WithQuoteReserve(quoteReserve sdkmath.Uint) *AMM {
amm.QuoteReserve = quoteReserve
return amm
}
Expand All @@ -184,12 +184,12 @@
return amm
}

func (amm *AMM) WithTotalLong(totalLong sdk.Dec) *AMM {
func (amm *AMM) WithTotalLong(totalLong sdkmath.Uint) *AMM {
amm.TotalLong = totalLong
return amm
}

func (amm *AMM) WithTotalShort(totalShort sdk.Dec) *AMM {
func (amm *AMM) WithTotalShort(totalShort sdkmath.Uint) *AMM {
amm.TotalShort = totalShort
return amm
}
Expand All @@ -211,13 +211,13 @@
//
// NOTE: baseAssetDelta is always positive
func (amm *AMM) SwapQuoteAsset(
quoteAssetAmt sdk.Dec, // unsigned
quoteAssetAmt sdkmath.Uint, // unsigned
dir Direction,
) (baseAssetDelta sdk.Dec, err error) {
) (baseAssetDelta sdkmath.Uint, err error) {
quoteReserveAmt := amm.FromQuoteAssetToReserve(quoteAssetAmt)
baseReserveDelta, err := amm.GetBaseReserveAmt(quoteReserveAmt, dir)
if err != nil {
return sdk.Dec{}, err
return sdkmath.ZeroUint(), err
}

if dir == Direction_LONG {
Expand All @@ -244,10 +244,10 @@
// - err: error if any
//
// Note: quoteAssetDelta is always positive
func (amm *AMM) SwapBaseAsset(baseAssetAmt sdk.Dec, dir Direction) (quoteAssetDelta sdk.Dec, err error) {
func (amm *AMM) SwapBaseAsset(baseAssetAmt sdkmath.Uint, dir Direction) (quoteAssetDelta sdkmath.Uint, err error) {
quoteReserveDelta, err := amm.GetQuoteReserveAmt(baseAssetAmt, dir)
if err != nil {
return sdk.Dec{}, err
return sdkmath.ZeroUint(), err
}

if dir == Direction_LONG {
Expand All @@ -267,8 +267,8 @@
Bias returns the bias of the market in the base asset. It's the net amount of base assets for longs minus the net
amount of base assets for shorts.
*/
func (amm *AMM) Bias() (bias sdk.Dec) {
return amm.TotalLong.Sub(amm.TotalShort)
func (amm *AMM) Bias() (bias sdkmath.Int) {
return sdkmath.NewIntFromUint64(amm.TotalLong.Uint64()).Sub(sdkmath.NewIntFromUint64(amm.TotalShort.Uint64()))
}

/*
Expand All @@ -292,12 +292,12 @@
dir = Direction_LONG
}

biasInQuoteReserve, err := amm.GetQuoteReserveAmt(bias.Abs(), dir)
biasInQuoteReserve, err := amm.GetQuoteReserveAmt(sdkmath.NewUintFromBigInt(bias.Abs().BigInt()), dir)
if err != nil {
return sdkmath.Int{}, err
}

costDec := biasInQuoteReserve.Mul(newPriceMultiplier.Sub(amm.PriceMultiplier))
costDec := (newPriceMultiplier.Sub(amm.PriceMultiplier)).MulInt64(int64(biasInQuoteReserve.Uint64()))

if bias.IsNegative() {
costDec = costDec.Neg()
Expand All @@ -309,11 +309,11 @@
// returns the amount of quote assets the amm has to pay out if all longs and shorts close out their positions
// positive value means the amm has to pay out quote assets
// negative value means the amm has to receive quote assets
func (amm AMM) GetMarketValue() (sdk.Dec, error) {
func (amm AMM) GetMarketValue() (sdkmath.Int, error) {
bias := amm.Bias()

if bias.IsZero() {
return sdk.ZeroDec(), nil
return sdkmath.ZeroInt(), nil
}

var dir Direction
Expand All @@ -323,16 +323,18 @@
dir = Direction_LONG
}

marketValueInReserves, err := amm.GetQuoteReserveAmt(bias.Abs(), dir)
marketValueInReserves, err := amm.GetQuoteReserveAmt(sdkmath.NewUintFromBigInt(bias.Abs().BigInt()), dir)
if err != nil {
return sdk.Dec{}, err
return sdkmath.ZeroInt(), err
}

marketValueInAssets := amm.FromQuoteReserveToAsset(marketValueInReserves)

if bias.IsNegative() {
marketValueInReserves = marketValueInReserves.Neg()
return sdkmath.NewIntFromUint64(marketValueInAssets.Uint64()).Neg(), nil
}

return amm.FromQuoteReserveToAsset(marketValueInReserves), nil
return sdkmath.NewIntFromUint64(marketValueInAssets.Uint64()), nil
}

/*
Expand Down Expand Up @@ -364,7 +366,7 @@

cost := marketValueAfter.Sub(marketValueBefore)

return cost.Ceil().TruncateInt(), nil

Check failure on line 369 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / build

cost.Ceil undefined (type "cosmossdk.io/math".Int has no field or method Ceil)

Check failure on line 369 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / integration-tests

cost.Ceil undefined (type "cosmossdk.io/math".Int has no field or method Ceil)

Check failure on line 369 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / unit-tests

cost.Ceil undefined (type "cosmossdk.io/math".Int has no field or method Ceil)

Check failure on line 369 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / test-sim-nondeterminism

cost.Ceil undefined (type "cosmossdk.io/math".Int has no field or method Ceil)
}

// UpdateSwapInvariant updates the swap invariant of the amm
Expand All @@ -378,8 +380,8 @@
// Change the swap invariant while holding price constant.
// Multiplying by the same factor to both of the reserves won't affect price.
amm.SqrtDepth = newSqrtDepth
amm.BaseReserve = amm.BaseReserve.Mul(multiplier)

Check failure on line 383 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / build

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.BaseReserve.Mul

Check failure on line 383 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / integration-tests

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.BaseReserve.Mul

Check failure on line 383 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / unit-tests

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.BaseReserve.Mul

Check failure on line 383 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / test-sim-nondeterminism

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.BaseReserve.Mul
amm.QuoteReserve = amm.QuoteReserve.Mul(multiplier)

Check failure on line 384 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / build

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.QuoteReserve.Mul

Check failure on line 384 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / integration-tests

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.QuoteReserve.Mul

Check failure on line 384 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / unit-tests

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.QuoteReserve.Mul

Check failure on line 384 in x/perp/v2/types/amm.go

View workflow job for this annotation

GitHub Actions / test-sim-nondeterminism

cannot use multiplier (variable of type "cosmossdk.io/math".LegacyDec) as type "cosmossdk.io/math".Uint in argument to amm.QuoteReserve.Mul

return amm.Validate()
}
Loading
Loading