From edb2f5c9a16013d32b1d5e4500f1b2ee30e01a6f Mon Sep 17 00:00:00 2001 From: DedicatedDev Date: Wed, 20 Mar 2024 15:13:55 +0200 Subject: [PATCH] change formula --- x/gmm/types/pool_weight.go | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/x/gmm/types/pool_weight.go b/x/gmm/types/pool_weight.go index 39440bc4..0cdd26ae 100644 --- a/x/gmm/types/pool_weight.go +++ b/x/gmm/types/pool_weight.go @@ -2,7 +2,6 @@ package types import ( fmt "fmt" - math "math" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -29,11 +28,8 @@ func (p *Pool) estimateShareWithSingleLiquidityInWeightPool(coin sdk.Coin) (sdk. decAsset := sdk.NewDecCoinFromCoin(asset.Token) weight := sdk.NewDecFromInt(*asset.Weight).Quo(sdk.NewDec(100)) // divide by 100 ratio := decToken.Amount.Quo(decAsset.Amount).Add(sdk.NewDec(1)) - exponent := (math.Pow(ratio.MustFloat64(), weight.MustFloat64()) - 1) * Multiplier - factor, err := sdk.NewDecFromStr(fmt.Sprintf("%f", exponent/Multiplier)) - if err != nil { - return sdk.Coin{}, err - } + + factor := (ApproximatePow(ratio, weight, 100).Sub(sdk.OneDec())) issueAmount := p.TotalShares.Amount.Mul(factor.RoundInt()).Quo(sdk.NewInt(1e10)) outputToken := sdk.Coin{ Amount: issueAmount, @@ -105,12 +101,22 @@ func (p *Pool) estimateSwapInWeightPool(amountIn sdk.Coin, denomOut string) (sdk oneMinusRatio := sdk.NewDec(1).Sub(ratio) power := weightIn.Quo(weightOut) - factor := math.Pow(oneMinusRatio.MustFloat64(), power.MustFloat64()) * Multiplier - finalFactor := factor / 1e8 - - amountOut := balanceOut.Mul(sdk.MustNewDecFromStr(fmt.Sprintf("%f", finalFactor))).Quo(sdk.NewDec(1e10)) + factor := ApproximatePow(oneMinusRatio, power, 100) // 100 iterations for example + amountOut := balanceOut.Mul(factor) return sdk.Coin{ Amount: amountOut.RoundInt(), Denom: denomOut, }, nil } + +// ApproximatePow approximates (base ^ exponent) using a series expansion. +// Here's a simple approximation; you might need a more accurate one depending on your needs. +func ApproximatePow(base sdk.Dec, exponent sdk.Dec, iterations int) sdk.Dec { + result := sdk.OneDec() // Start with 1 as the initial result + term := sdk.OneDec() // The current term starts at 1 (base^0) + for n := 1; n <= iterations; n++ { + term = term.Mul(base).Mul(exponent).QuoInt64(int64(n)) // term *= base * exponent / n + result = result.Sub(term) + } + return result +}