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

fix(amm): support 18 decimals assets #1099

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
10 changes: 1 addition & 9 deletions x/amm/keeper/estimate_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,11 @@ func (k Keeper) CalcAmmPrice(ctx sdk.Context, denom string, decimal uint64) sdkm
}

routes := resp.InRoute
tokenIn := sdk.NewCoin(denom, sdkmath.NewInt(Pow10(decimal).TruncateInt64()))
tokenIn := sdk.NewCoin(denom, sdkmath.NewInt(types.Pow10(decimal).TruncateInt64()))
discount := sdkmath.LegacyNewDec(1)
spotPrice, _, _, _, _, _, _, _, err := k.CalcInRouteSpotPrice(ctx, tokenIn, routes, discount, sdkmath.LegacyZeroDec())
if err != nil {
return sdkmath.LegacyZeroDec()
}
return spotPrice.Mul(usdcPrice)
}

func Pow10(decimal uint64) (value sdkmath.LegacyDec) {
value = sdkmath.LegacyNewDec(1)
for i := 0; i < int(decimal); i++ {
value = value.Mul(sdkmath.LegacyNewDec(10))
}
return
}
9 changes: 5 additions & 4 deletions x/amm/types/amm_price.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package types

import (
sdkmath "cosmossdk.io/math"
"fmt"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand All @@ -27,14 +28,14 @@ func (p *Pool) GetTokenARate(
), nil
}

priceA := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenA)
priceA, decimalA := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenA)
if priceA.IsZero() {
return sdkmath.LegacyZeroDec(), fmt.Errorf("token price not set: %s", tokenA)
}
priceB := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenB)
priceB, decimalB := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenB)
if priceB.IsZero() {
return sdkmath.LegacyZeroDec(), fmt.Errorf("token price not set: %s", tokenB)
}

return priceA.Quo(priceB), nil
return priceA.Mul(Pow10(decimalB)).Quo(Pow10(decimalA).Mul(priceB)), nil
}
1 change: 1 addition & 0 deletions x/amm/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type BankKeeper interface {
type OracleKeeper interface {
GetAssetPrice(ctx sdk.Context, asset string) (oracletypes.Price, bool)
GetAssetPriceFromDenom(ctx sdk.Context, denom string) sdkmath.LegacyDec
GetRawAssetPriceFromDenom(ctx sdk.Context, denom string) (sdkmath.LegacyDec, uint64)
GetPriceFeeder(ctx sdk.Context, feeder sdk.AccAddress) (val oracletypes.PriceFeeder, found bool)
}

Expand Down
4 changes: 2 additions & 2 deletions x/amm/types/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func (p *Pool) TVL(ctx sdk.Context, oracleKeeper OracleKeeper, accountedPoolKeep
totalWeight := sdkmath.ZeroInt()
oracleAssetsWeight := sdkmath.ZeroInt()
for _, asset := range p.PoolAssets {
tokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, asset.Token.Denom)
tokenPrice, decimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, asset.Token.Denom)
totalWeight = totalWeight.Add(asset.Weight)
if tokenPrice.IsZero() {
if p.PoolParams.UseOracle {
Expand All @@ -315,7 +315,7 @@ func (p *Pool) TVL(ctx sdk.Context, oracleKeeper OracleKeeper, accountedPoolKeep
amount = accountedPoolAmt
}
}
v := amount.ToLegacyDec().Mul(tokenPrice)
v := amount.ToLegacyDec().Quo(Pow10(decimal)).Mul(tokenPrice)
oracleAssetsTVL = oracleAssetsTVL.Add(v)
oracleAssetsWeight = oracleAssetsWeight.Add(asset.Weight)
}
Expand Down
11 changes: 10 additions & 1 deletion x/amm/types/pow.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package types

import (
sdkmath "cosmossdk.io/math"
"fmt"

sdkmath "cosmossdk.io/math"
)

// Pow computes base^(exp)
Expand Down Expand Up @@ -37,3 +38,11 @@ func Pow(base sdkmath.LegacyDec, exp sdkmath.LegacyDec) sdkmath.LegacyDec {

return integerPow.Mul(fractionalPow)
}

func Pow10(decimal uint64) (value sdkmath.LegacyDec) {
value = sdkmath.LegacyNewDec(1)
for i := 0; i < int(decimal); i++ {
value = value.Mul(sdkmath.LegacyNewDec(10))
}
return
}
12 changes: 6 additions & 6 deletions x/amm/types/swap_in_amt_given_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ func (p Pool) CalcGivenOutSlippage(
}

// ensure token prices for in/out tokens set properly
inTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenInDenom)
inTokenPrice, inTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenInDenom)
if inTokenPrice.IsZero() {
return sdkmath.LegacyZeroDec(), fmt.Errorf("price for inToken not set: %s", poolAssetIn.Token.Denom)
}
outTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenOut.Denom)
outTokenPrice, outTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenOut.Denom)
if outTokenPrice.IsZero() {
return sdkmath.LegacyZeroDec(), fmt.Errorf("price for outToken not set: %s", poolAssetOut.Token.Denom)
}

// in amount is calculated in this formula
oracleInAmount := sdkmath.LegacyNewDecFromInt(tokenOut.Amount).Mul(outTokenPrice).Quo(inTokenPrice)
oracleInAmount := sdkmath.LegacyNewDecFromInt(tokenOut.Amount).Quo(Pow10(outTokenDecimal)).Mul(Pow10(inTokenDecimal)).Mul(outTokenPrice).Quo(inTokenPrice)
balancerIn := sdkmath.LegacyNewDecFromInt(balancerInCoin.Amount)
balancerSlippage := balancerIn.Sub(oracleInAmount)
if balancerSlippage.IsNegative() {
Expand Down Expand Up @@ -71,11 +71,11 @@ func (p *Pool) SwapInAmtGivenOut(
}

// ensure token prices for in/out tokens set properly
inTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenInDenom)
inTokenPrice, inTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenInDenom)
if inTokenPrice.IsZero() {
return sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), fmt.Errorf("price for inToken not set: %s", poolAssetIn.Token.Denom)
}
outTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenOut.Denom)
outTokenPrice, outTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenOut.Denom)
if outTokenPrice.IsZero() {
return sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), fmt.Errorf("price for outToken not set: %s", poolAssetOut.Token.Denom)
}
Expand All @@ -87,7 +87,7 @@ func (p *Pool) SwapInAmtGivenOut(
// balancer slippage amount = Max(oracleOutAmount-balancerOutAmount, 0)
// resizedAmount = tokenIn / externalLiquidityRatio
// actualSlippageAmount = balancer slippage(resizedAmount)
oracleInAmount = sdkmath.LegacyNewDecFromInt(tokenOut.Amount).Mul(outTokenPrice).Quo(inTokenPrice)
oracleInAmount = sdkmath.LegacyNewDecFromInt(tokenOut.Amount).Quo(Pow10(outTokenDecimal)).Mul(Pow10(inTokenDecimal)).Mul(outTokenPrice).Quo(inTokenPrice)

externalLiquidityRatio, err := p.GetAssetExternalLiquidityRatio(tokenOut.Denom)
if err != nil {
Expand Down
16 changes: 8 additions & 8 deletions x/amm/types/swap_out_amt_given_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ func GetOraclePoolNormalizedWeights(ctx sdk.Context, poolId uint64, oracleKeeper
oraclePoolWeights := []AssetWeight{}
totalWeight := sdkmath.LegacyZeroDec()
for _, asset := range poolAssets {
tokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, asset.Token.Denom)
tokenPrice, decimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, asset.Token.Denom)
if tokenPrice.IsZero() {
return oraclePoolWeights, fmt.Errorf("price for token not set: %s", asset.Token.Denom)
}
amount := asset.Token.Amount
weight := amount.ToLegacyDec().Mul(tokenPrice)
weight := amount.ToLegacyDec().Quo(Pow10(decimal)).Mul(tokenPrice)
oraclePoolWeights = append(oraclePoolWeights, AssetWeight{
Asset: asset.Token.Denom,
Weight: weight,
Expand Down Expand Up @@ -150,16 +150,16 @@ func (p Pool) CalcGivenInSlippage(
}

// ensure token prices for in/out tokens set properly
inTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenIn.Denom)
inTokenPrice, inTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenIn.Denom)
if inTokenPrice.IsZero() {
return sdkmath.LegacyZeroDec(), fmt.Errorf("price for inToken not set: %s", poolAssetIn.Token.Denom)
}
outTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenOutDenom)
outTokenPrice, outTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenOutDenom)
if outTokenPrice.IsZero() {
return sdkmath.LegacyZeroDec(), fmt.Errorf("price for outToken not set: %s", poolAssetOut.Token.Denom)
}

oracleOutAmount := sdkmath.LegacyNewDecFromInt(tokenIn.Amount).Mul(inTokenPrice).Quo(outTokenPrice)
oracleOutAmount := sdkmath.LegacyNewDecFromInt(tokenIn.Amount).Quo(Pow10(inTokenDecimal)).Mul(Pow10(outTokenDecimal)).Mul(inTokenPrice).Quo(outTokenPrice)
balancerOut := sdkmath.LegacyNewDecFromInt(balancerOutCoin.Amount)
slippageAmount := oracleOutAmount.Sub(balancerOut)
if slippageAmount.IsNegative() {
Expand Down Expand Up @@ -205,11 +205,11 @@ func (p *Pool) SwapOutAmtGivenIn(
}

// ensure token prices for in/out tokens set properly
inTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenIn.Denom)
inTokenPrice, inTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenIn.Denom)
if inTokenPrice.IsZero() {
return sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), fmt.Errorf("price for inToken not set: %s", poolAssetIn.Token.Denom)
}
outTokenPrice := oracleKeeper.GetAssetPriceFromDenom(ctx, tokenOutDenom)
outTokenPrice, outTokenDecimal := oracleKeeper.GetRawAssetPriceFromDenom(ctx, tokenOutDenom)
if outTokenPrice.IsZero() {
return sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), fmt.Errorf("price for outToken not set: %s", poolAssetOut.Token.Denom)
}
Expand All @@ -221,7 +221,7 @@ func (p *Pool) SwapOutAmtGivenIn(
// balancer slippage amount = Max(oracleOutAmount-balancerOutAmount, 0)
// resizedAmount = tokenIn / externalLiquidityRatio
// actualSlippageAmount = balancer slippage(resizedAmount)
oracleOutAmount = sdkmath.LegacyNewDecFromInt(tokenIn.Amount).Mul(inTokenPrice).Quo(outTokenPrice)
oracleOutAmount = sdkmath.LegacyNewDecFromInt(tokenIn.Amount).Quo(Pow10(inTokenDecimal)).Mul(Pow10(outTokenDecimal)).Mul(inTokenPrice).Quo(outTokenPrice)

externalLiquidityRatio, err := p.GetAssetExternalLiquidityRatio(tokenOutDenom)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions x/masterchef/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type AmmKeeper interface {
type OracleKeeper interface {
GetAssetPrice(ctx sdk.Context, asset string) (oracletypes.Price, bool)
GetAssetPriceFromDenom(ctx sdk.Context, denom string) math.LegacyDec
GetRawAssetPriceFromDenom(ctx sdk.Context, denom string) (math.LegacyDec, uint64)
GetPriceFeeder(ctx sdk.Context, feeder sdk.AccAddress) (val oracletypes.PriceFeeder, found bool)
}

Expand Down
12 changes: 12 additions & 0 deletions x/oracle/keeper/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,15 @@ func (k Keeper) GetAssetPriceFromDenom(ctx sdk.Context, denom string) sdkmath.Le
}
return price.Price.Quo(Pow10(info.Decimal))
}

func (k Keeper) GetRawAssetPriceFromDenom(ctx sdk.Context, denom string) (sdkmath.LegacyDec, uint64) {
info, found := k.GetAssetInfo(ctx, denom)
if !found {
return sdkmath.LegacyZeroDec(), 0
}
price, found := k.GetAssetPrice(ctx, info.Display)
if !found {
return sdkmath.LegacyZeroDec(), 0
}
return price.Price, info.Decimal
}
1 change: 1 addition & 0 deletions x/perpetual/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type AssetProfileKeeper interface {
type OracleKeeper interface {
GetAssetPrice(ctx sdk.Context, asset string) (oracletypes.Price, bool)
GetAssetPriceFromDenom(ctx sdk.Context, denom string) math.LegacyDec
GetRawAssetPriceFromDenom(ctx sdk.Context, denom string) (math.LegacyDec, uint64)
GetPriceFeeder(ctx sdk.Context, feeder sdk.AccAddress) (val oracletypes.PriceFeeder, found bool)
GetAssetInfo(ctx sdk.Context, denom string) (val oracletypes.AssetInfo, found bool)
}
2 changes: 1 addition & 1 deletion x/tier/keeper/query_get_consolidated_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (k Keeper) GetAllPrices(goCtx context.Context, req *types.QueryGetAllPrices
if assetEntry.Denom == ptypes.Eden {
denom = ptypes.Elys
}
tokenPriceOracle := k.oracleKeeper.GetAssetPriceFromDenom(ctx, denom).Mul(oracle.Pow10(assetEntry.Decimals))
tokenPriceOracle, _ := k.oracleKeeper.GetRawAssetPriceFromDenom(ctx, denom)
tokenPriceAmm := k.amm.CalcAmmPrice(ctx, denom, assetEntry.Decimals).Mul(oracle.Pow10(assetEntry.Decimals))
prices = append(prices, &types.Price{
Denom: assetEntry.Denom,
Expand Down
1 change: 1 addition & 0 deletions x/tier/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type OracleKeeper interface {
GetAssetInfo(ctx sdk.Context, denom string) (val oracletypes.AssetInfo, found bool)
GetAssetPrice(ctx sdk.Context, asset string) (oracletypes.Price, bool)
GetAssetPriceFromDenom(ctx sdk.Context, denom string) math.LegacyDec
GetRawAssetPriceFromDenom(ctx sdk.Context, denom string) (math.LegacyDec, uint64)
GetPriceFeeder(ctx sdk.Context, feeder sdk.AccAddress) (val oracletypes.PriceFeeder, found bool)
}

Expand Down
Loading