Skip to content

Commit

Permalink
fix(amm): collect half weight breaking fee
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmic-vagabond committed Dec 2, 2024
1 parent eb4bf9f commit 7dabb7e
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 23 deletions.
4 changes: 2 additions & 2 deletions x/amm/keeper/keeper_swap_exact_amount_in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ func (suite *AmmKeeperTestSuite) TestSwapExactAmountIn() {
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1009969)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990031)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990028)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000003)},
expPass: true,
},
{
Expand Down
4 changes: 2 additions & 2 deletions x/amm/keeper/keeper_swap_exact_amount_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ func (suite *AmmKeeperTestSuite) TestSwapExactAmountOut() {
useNewRecipient: false,
expSenderBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 788591), sdk.NewInt64Coin(ptypes.BaseCurrency, 1200000)},
expRecipientBalance: sdk.Coins{},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1211409), sdk.NewInt64Coin(ptypes.BaseCurrency, 800000)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1211409), sdk.NewInt64Coin(ptypes.BaseCurrency, 799859)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin("uusda", 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000141)},
expPass: true,
},
{
Expand Down
45 changes: 37 additions & 8 deletions x/amm/keeper/update_pool_for_swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,29 @@ func (k Keeper) UpdatePoolForSwap(
}
}

// init weightRecoveryFeeAmount to zero
weightRecoveryFeeAmount := sdkmath.ZeroInt()

// send half (weight breaking fee portion) of weight breaking fee to rebalance treasury
if !weightBalanceBonus.IsPositive() {
params := k.GetParams(ctx)
rebalanceTreasury := sdk.MustAccAddressFromBech32(pool.GetRebalanceTreasury())
weightRecoveryFee := weightBalanceBonus.Abs().Mul(params.WeightBreakingFeePortion)

// weight recovery fee must be positive
if weightRecoveryFee.IsPositive() {
weightRecoveryFeeAmount = tokenOut.Amount.ToLegacyDec().Mul(weightRecoveryFee).RoundInt()

// send weight recovery fee to rebalance treasury if weight recovery fee amount is positive
if weightRecoveryFeeAmount.IsPositive() {
err = k.bankKeeper.SendCoins(ctx, poolAddr, rebalanceTreasury, sdk.Coins{sdk.NewCoin(tokenOut.Denom, weightRecoveryFeeAmount)})
if err != nil {
return sdkmath.ZeroInt(), err
}

Check warning on line 73 in x/amm/keeper/update_pool_for_swap.go

View check run for this annotation

Codecov / codecov/patch

x/amm/keeper/update_pool_for_swap.go#L72-L73

Added lines #L72 - L73 were not covered by tests
}
}
}

// Send coins to recipient
err = k.bankKeeper.SendCoins(ctx, poolAddr, recipient, sdk.Coins{tokenOut})
if err != nil {
Expand All @@ -78,18 +101,24 @@ func (k Keeper) UpdatePoolForSwap(
// calculate total swap fee
swapFeeCoins := swapFeeInCoins.Add(swapFeeOutCoins...)

// init bonusTokenAmount to zero
bonusTokenAmount := sdkmath.ZeroInt()

// calculate bonus token amount if weightBalanceBonus is positive
if weightBalanceBonus.IsPositive() {
// get treasury balance
rebalanceTreasuryAddr := sdk.MustAccAddressFromBech32(pool.GetRebalanceTreasury())
treasuryTokenAmount := k.bankKeeper.GetBalance(ctx, rebalanceTreasuryAddr, tokenOut.Denom).Amount

// bonus token amount is the tokenOut amount times weightBalanceBonus
bonusTokenAmount = sdkmath.LegacyNewDecFromInt(tokenOut.Amount).Mul(weightBalanceBonus).RoundInt()
bonusTokenAmount := sdkmath.LegacyNewDecFromInt(tokenOut.Amount).Mul(weightBalanceBonus).RoundInt()

// if treasury balance is less than bonusTokenAmount, set bonusTokenAmount to treasury balance
if treasuryTokenAmount.LT(bonusTokenAmount) {
bonusTokenAmount = treasuryTokenAmount
}

// send bonusTokenAmount from pool addr to recipient addr, we are shortcutting the rebalance treasury address to optimize gas
if bonusTokenAmount.IsPositive() {
bonusToken := sdk.NewCoin(tokenOut.Denom, bonusTokenAmount)
err = k.bankKeeper.SendCoins(ctx, poolAddr, recipient, sdk.Coins{bonusToken})
err = k.bankKeeper.SendCoins(ctx, rebalanceTreasuryAddr, recipient, sdk.Coins{bonusToken})
if err != nil {
return sdkmath.ZeroInt(), err
}
Expand Down Expand Up @@ -123,9 +152,9 @@ func (k Keeper) UpdatePoolForSwap(
return sdkmath.Int{}, err
}

// record bonus token amount as total liquidity decrease
bonusToken := sdk.NewCoin(tokenOut.Denom, bonusTokenAmount)
err = k.RecordTotalLiquidityDecrease(ctx, sdk.Coins{bonusToken})
// record weight recovery fee amount as total liquidity decrease
weightRecoveryToken := sdk.NewCoin(tokenOut.Denom, weightRecoveryFeeAmount)
err = k.RecordTotalLiquidityDecrease(ctx, sdk.Coins{weightRecoveryToken})
if err != nil {
return sdkmath.Int{}, err
}
Expand Down
10 changes: 5 additions & 5 deletions x/amm/keeper/update_pool_for_swap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ func (suite *AmmKeeperTestSuite) TestUpdatePoolForSwap() {
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 10000),
weightBalanceBonus: sdkmath.LegacyNewDecWithPrec(3, 1), // 30% bonus
expSenderBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1013000)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 987000)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990000)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 997000)},
expPass: true,
},
{
Expand All @@ -110,9 +110,9 @@ func (suite *AmmKeeperTestSuite) TestUpdatePoolForSwap() {
tokenIn: sdk.NewInt64Coin(ptypes.Elys, 10000),
tokenOut: sdk.NewInt64Coin(ptypes.BaseCurrency, 10000),
weightBalanceBonus: sdkmath.LegacyNewDecWithPrec(3, 1), // 30% bonus
expSenderBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1013000)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 987000)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 100)},
expSenderBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 990000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1010100)},
expPoolBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1010000), sdk.NewInt64Coin(ptypes.BaseCurrency, 990000)},
expTreasuryBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Elys, 1000000)},
expPass: true,
},
} {
Expand Down
4 changes: 2 additions & 2 deletions x/amm/types/pool_join_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ func (p *Pool) JoinPool(
weightOut := sdkmath.LegacyOneDec().Sub(weightIn)
weightBreakingFee := GetWeightBreakingFee(weightIn, weightOut, targetWeightIn, targetWeightOut, distanceDiff, params)

// weight recovery reward = weight breaking fee * weight recovery fee portion
weightRecoveryReward := weightBreakingFee.Mul(params.WeightRecoveryFeePortion)
// weight recovery reward = weight breaking fee * weight breaking fee portion
weightRecoveryReward := weightBreakingFee.Mul(params.WeightBreakingFeePortion)

Check warning on line 202 in x/amm/types/pool_join_pool.go

View check run for this annotation

Codecov / codecov/patch

x/amm/types/pool_join_pool.go#L201-L202

Added lines #L201 - L202 were not covered by tests

// bonus is valid when distance is lower than original distance and when threshold weight reached
weightBalanceBonus = weightBreakingFee.Neg()
Expand Down
5 changes: 3 additions & 2 deletions x/amm/types/swap_in_amt_given_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ func (p *Pool) SwapInAmtGivenOut(

// weightBreakingFeePerpetualFactor is 1 if not send by perpetual
weightBreakingFee = weightBreakingFee.Mul(weightBreakingFeePerpetualFactor)
// weight recovery reward = weight breaking fee * weight recovery fee portion
weightRecoveryReward := weightBreakingFee.Mul(params.WeightRecoveryFeePortion)

// weight recovery reward = weight breaking fee * weight breaking fee portion
weightRecoveryReward := weightBreakingFee.Mul(params.WeightBreakingFeePortion)

// bonus is valid when distance is lower than original distance and when threshold weight reached
weightBalanceBonus = weightBreakingFee.Neg()
Expand Down
4 changes: 2 additions & 2 deletions x/amm/types/swap_out_amt_given_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ func (p *Pool) SwapOutAmtGivenIn(
// weightBreakingFeePerpetualFactor is 1 if not send by perpetual
weightBreakingFee = weightBreakingFee.Mul(weightBreakingFeePerpetualFactor)

// weight recovery reward = weight breaking fee * weight recovery fee portion
weightRecoveryReward := weightBreakingFee.Mul(params.WeightRecoveryFeePortion)
// weight recovery reward = weight breaking fee * weight breaking fee portion
weightRecoveryReward := weightBreakingFee.Mul(params.WeightBreakingFeePortion)

// bonus is valid when distance is lower than original distance and when threshold weight reached
weightBalanceBonus = weightBreakingFee.Neg()
Expand Down

0 comments on commit 7dabb7e

Please sign in to comment.