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

Math Refactor #740

Merged
merged 7 commits into from
Jan 19, 2022
Merged
Changes from 1 commit
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
166 changes: 97 additions & 69 deletions x/gamm/keeper/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ func calcSpotPriceWithSwapFee(
return spotPrice.Mul(scale)
}

func calcTokenGivenToken(
mconcat marked this conversation as resolved.
Show resolved Hide resolved
tokenBalanceFixed,
tokenWeightFixed,
tokenBalanceUnknown,
tokenWeightUnknown,
tokenAmountFixed sdk.Dec,
) sdk.Dec {
weightRatio := tokenWeightFixed.Quo(tokenWeightUnknown)
y := tokenBalanceFixed.Quo(tokenBalanceFixed.Add(tokenAmountFixed))
foo := osmomath.Pow(y, weightRatio)

multiplier := sdk.OneDec().Sub(foo)
return tokenBalanceUnknown.Mul(multiplier)
}

// aO
func calcOutGivenIn(
tokenBalanceIn,
Expand All @@ -63,13 +78,10 @@ func calcOutGivenIn(
tokenAmountIn,
swapFee sdk.Dec,
) sdk.Dec {
weightRatio := tokenWeightIn.Quo(tokenWeightOut)
adjustedIn := sdk.OneDec().Sub(swapFee)
adjustedIn = tokenAmountIn.Mul(adjustedIn)
y := tokenBalanceIn.Quo(tokenBalanceIn.Add(adjustedIn))
foo := osmomath.Pow(y, weightRatio)
bar := sdk.OneDec().Sub(foo)
return tokenBalanceOut.Mul(bar)
// deduct swapfee on the in asset
tokenAmountIn = tokenAmountIn.Mul(sdk.OneDec().Sub(swapFee))
tokenAmountOut := calcTokenGivenToken(tokenBalanceIn, tokenWeightIn, tokenBalanceOut, tokenWeightOut, tokenAmountIn)
return tokenAmountOut
}

// aI
Expand All @@ -81,36 +93,54 @@ func calcInGivenOut(
tokenAmountOut,
swapFee sdk.Dec,
) sdk.Dec {
weightRatio := tokenWeightOut.Quo(tokenWeightIn)
diff := tokenBalanceOut.Sub(tokenAmountOut)
y := tokenBalanceOut.Quo(diff)
foo := osmomath.Pow(y, weightRatio)
foo = foo.Sub(one)
tokenAmountIn := sdk.OneDec().Sub(swapFee)
return (tokenBalanceIn.Mul(foo)).Quo(tokenAmountIn)
// provide negative tokenOutAmount as it decreases pool liquidity
tokenAmountOut = tokenAmountOut.Neg()
tokenAmountIn := calcTokenGivenToken(tokenBalanceOut, tokenWeightOut, tokenBalanceIn, tokenWeightIn, tokenAmountOut).Neg()
// deduct swapfee on the in asset
mconcat marked this conversation as resolved.
Show resolved Hide resolved
tokenAmountInBeforeFee := tokenAmountIn.Quo(sdk.OneDec().Sub(swapFee))
return tokenAmountInBeforeFee

}

// pAo
func calcPoolOutGivenSingleIn(
tokenBalanceIn,
tokenWeightIn,
poolSupply,
func weightDelta(
mconcat marked this conversation as resolved.
Show resolved Hide resolved
normalizedWeight,
beforeWeight,
afterWeight sdk.Dec,
) (unknownNewBalance sdk.Dec) {
deltaRatio := afterWeight.Quo(beforeWeight)
// newBalTo = poolRatio^(1/weightTo) * balTo;
return osmomath.Pow(deltaRatio, normalizedWeight)
}

func feeRatio(
tokenWeight,
totalWeight,
tokenAmountIn,
swapFee sdk.Dec,
) sdk.Dec {
normalizedWeight := tokenWeightIn.Quo(totalWeight)
zaz := (sdk.OneDec().Sub(normalizedWeight)).Mul(swapFee)
tokenAmountInAfterFee := tokenAmountIn.Mul(sdk.OneDec().Sub(zaz))
normalizedWeight := tokenWeight.Quo(totalWeight)
zar := (sdk.OneDec().Sub(normalizedWeight)).Mul(swapFee)
return sdk.OneDec().Sub(zar)
}

newTokenBalanceIn := tokenBalanceIn.Add(tokenAmountInAfterFee)
tokenInRatio := newTokenBalanceIn.Quo(tokenBalanceIn)
func tokenDiffGivenPoolDiff(
mconcat marked this conversation as resolved.
Show resolved Hide resolved
tokenBalance,
tokenWeight,
poolSupply,
totalWeight,
poolAmount sdk.Dec,
) sdk.Dec {
normalizedWeight := tokenWeight.Quo(totalWeight)
newPoolSupply := poolSupply.Add(poolAmount)

// uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;
poolRatio := osmomath.Pow(tokenInRatio, normalizedWeight)
newPoolSupply := poolRatio.Mul(poolSupply)
return newPoolSupply.Sub(poolSupply)
poolSupplyDelta := weightDelta(
sdk.OneDec().Quo(normalizedWeight), poolSupply, newPoolSupply)

newTokenBalance := tokenBalance.Mul(poolSupplyDelta)

// Do reverse order of fees charged in joinswap_ExternAmountIn, this way
// ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```
//uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;
return newTokenBalance.Sub(tokenBalance)
}

//tAi
Expand All @@ -122,20 +152,9 @@ func calcSingleInGivenPoolOut(
poolAmountOut,
swapFee sdk.Dec,
) sdk.Dec {
normalizedWeight := tokenWeightIn.Quo(totalWeight)
newPoolSupply := poolSupply.Add(poolAmountOut)
poolRatio := newPoolSupply.Quo(poolSupply)

//uint newBalTi = poolRatio^(1/weightTi) * balTi;
boo := sdk.OneDec().Quo(normalizedWeight)
tokenInRatio := osmomath.Pow(poolRatio, boo)
newTokenBalanceIn := tokenInRatio.Mul(tokenBalanceIn)
tokenAmountInAfterFee := newTokenBalanceIn.Sub(tokenBalanceIn)
// Do reverse order of fees charged in joinswap_ExternAmountIn, this way
// ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```
//uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;
zar := (sdk.OneDec().Sub(normalizedWeight)).Mul(swapFee)
return tokenAmountInAfterFee.Quo(sdk.OneDec().Sub(zar))
tokenAmountIn := tokenDiffGivenPoolDiff(tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, poolAmountOut)
tokenAmountInBeforeFee := tokenAmountIn.Quo(feeRatio(tokenWeightIn, totalWeight, swapFee))
return tokenAmountInBeforeFee
}

// tAo
Expand All @@ -148,25 +167,44 @@ func calcSingleOutGivenPoolIn(
swapFee sdk.Dec,
exitFee sdk.Dec,
) sdk.Dec {
normalizedWeight := tokenWeightOut.Quo(totalWeight)
// charge exit fee on the pool token side
// pAiAfterExitFee = pAi*(1-exitFee)
poolAmountInAfterExitFee := poolAmountIn.Mul(sdk.OneDec().Sub(exitFee))
newPoolSupply := poolSupply.Sub(poolAmountInAfterExitFee)
poolRatio := newPoolSupply.Quo(poolSupply)
tokenAmountOut := tokenDiffGivenPoolDiff(tokenBalanceOut, tokenWeightOut, poolSupply, totalWeight, poolAmountInAfterExitFee.Neg()).Neg()
tokenAmountOutAfterFee := tokenAmountOut.Mul(feeRatio(tokenWeightOut, totalWeight, swapFee))
return tokenAmountOutAfterFee
}

// newBalTo = poolRatio^(1/weightTo) * balTo;
func poolDiffGivenTokenDiff(
tokenBalance,
tokenWeight,
poolSupply,
totalWeight,
tokenAmount sdk.Dec,
) sdk.Dec {
normalizedWeight := tokenWeight.Quo(totalWeight)

tokenOutRatio := osmomath.Pow(poolRatio, sdk.OneDec().Quo(normalizedWeight))
newTokenBalanceOut := tokenOutRatio.Mul(tokenBalanceOut)
newTokenBalance := tokenBalance.Add(tokenAmount)

tokenAmountOutBeforeSwapFee := tokenBalanceOut.Sub(newTokenBalanceOut)
tokenDelta := weightDelta(
normalizedWeight, tokenBalance, newTokenBalance)
newPoolSupply := poolSupply.Mul(tokenDelta)

// charge swap fee on the output token side
//uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)
zaz := (sdk.OneDec().Sub(normalizedWeight)).Mul(swapFee)
tokenAmountOut := tokenAmountOutBeforeSwapFee.Mul(sdk.OneDec().Sub(zaz))
return tokenAmountOut
return newPoolSupply.Sub(poolSupply)
}

// pAo
func calcPoolOutGivenSingleIn(
tokenBalanceIn,
tokenWeightIn,
poolSupply,
totalWeight,
tokenAmountIn,
swapFee sdk.Dec,
) sdk.Dec {
tokenAmountInAfterFee := tokenAmountIn.Mul(feeRatio(tokenWeightIn, totalWeight, swapFee))
poolAmountOut := poolDiffGivenTokenDiff(tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, tokenAmountInAfterFee)
return poolAmountOut
}

// pAi
Expand All @@ -179,22 +217,12 @@ func calcPoolInGivenSingleOut(
swapFee sdk.Dec,
exitFee sdk.Dec,
) sdk.Dec {
// charge swap fee on the output token side
normalizedWeight := tokenWeightOut.Quo(totalWeight)
//uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;
zoo := sdk.OneDec().Sub(normalizedWeight)
zar := zoo.Mul(swapFee)
tokenAmountOutBeforeSwapFee := tokenAmountOut.Quo(sdk.OneDec().Sub(zar))

newTokenBalanceOut := tokenBalanceOut.Sub(tokenAmountOutBeforeSwapFee)
tokenOutRatio := newTokenBalanceOut.Quo(tokenBalanceOut)
tokenAmountOutBeforeFee := tokenAmountOut.Quo(feeRatio(tokenWeightOut, totalWeight, swapFee))

//uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;
poolRatio := osmomath.Pow(tokenOutRatio, normalizedWeight)
newPoolSupply := poolRatio.Mul(poolSupply)
poolAmountInAfterExitFee := poolSupply.Sub(newPoolSupply)
poolAmountIn := poolDiffGivenTokenDiff(tokenBalanceOut, tokenWeightOut, poolSupply, totalWeight, tokenAmountOutBeforeFee.Neg()).Neg()

// charge exit fee on the pool token side
// pAi = pAiAfterExitFee/(1-exitFee)
return poolAmountInAfterExitFee.Quo(sdk.OneDec().Sub(exitFee))
poolAmountInBeforeFee := poolAmountIn.Quo(sdk.OneDec().Sub(exitFee))
return poolAmountInBeforeFee
}