Skip to content
This repository was archived by the owner on Mar 19, 2025. It is now read-only.

Commit edb2f5c

Browse files
committed
change formula
1 parent fd2882c commit edb2f5c

1 file changed

Lines changed: 16 additions & 10 deletions

File tree

x/gmm/types/pool_weight.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package types
22

33
import (
44
fmt "fmt"
5-
math "math"
65

76
sdk "github.com/cosmos/cosmos-sdk/types"
87
)
@@ -29,11 +28,8 @@ func (p *Pool) estimateShareWithSingleLiquidityInWeightPool(coin sdk.Coin) (sdk.
2928
decAsset := sdk.NewDecCoinFromCoin(asset.Token)
3029
weight := sdk.NewDecFromInt(*asset.Weight).Quo(sdk.NewDec(100)) // divide by 100
3130
ratio := decToken.Amount.Quo(decAsset.Amount).Add(sdk.NewDec(1))
32-
exponent := (math.Pow(ratio.MustFloat64(), weight.MustFloat64()) - 1) * Multiplier
33-
factor, err := sdk.NewDecFromStr(fmt.Sprintf("%f", exponent/Multiplier))
34-
if err != nil {
35-
return sdk.Coin{}, err
36-
}
31+
32+
factor := (ApproximatePow(ratio, weight, 100).Sub(sdk.OneDec()))
3733
issueAmount := p.TotalShares.Amount.Mul(factor.RoundInt()).Quo(sdk.NewInt(1e10))
3834
outputToken := sdk.Coin{
3935
Amount: issueAmount,
@@ -105,12 +101,22 @@ func (p *Pool) estimateSwapInWeightPool(amountIn sdk.Coin, denomOut string) (sdk
105101
oneMinusRatio := sdk.NewDec(1).Sub(ratio)
106102

107103
power := weightIn.Quo(weightOut)
108-
factor := math.Pow(oneMinusRatio.MustFloat64(), power.MustFloat64()) * Multiplier
109-
finalFactor := factor / 1e8
110-
111-
amountOut := balanceOut.Mul(sdk.MustNewDecFromStr(fmt.Sprintf("%f", finalFactor))).Quo(sdk.NewDec(1e10))
104+
factor := ApproximatePow(oneMinusRatio, power, 100) // 100 iterations for example
105+
amountOut := balanceOut.Mul(factor)
112106
return sdk.Coin{
113107
Amount: amountOut.RoundInt(),
114108
Denom: denomOut,
115109
}, nil
116110
}
111+
112+
// ApproximatePow approximates (base ^ exponent) using a series expansion.
113+
// Here's a simple approximation; you might need a more accurate one depending on your needs.
114+
func ApproximatePow(base sdk.Dec, exponent sdk.Dec, iterations int) sdk.Dec {
115+
result := sdk.OneDec() // Start with 1 as the initial result
116+
term := sdk.OneDec() // The current term starts at 1 (base^0)
117+
for n := 1; n <= iterations; n++ {
118+
term = term.Mul(base).Mul(exponent).QuoInt64(int64(n)) // term *= base * exponent / n
119+
result = result.Sub(term)
120+
}
121+
return result
122+
}

0 commit comments

Comments
 (0)