Skip to content

Commit

Permalink
Swap fee exclusion when weight is improving (#1091)
Browse files Browse the repository at this point in the history
* swap fee exclusion when improving weight

* default values

* swap fee in a query

* tests

* fix

---------

Co-authored-by: Abhinav Kumar <[email protected]>
  • Loading branch information
amityadav0 and avkr003 authored Jan 2, 2025
1 parent 2fc6e9a commit 2dc4524
Show file tree
Hide file tree
Showing 20 changed files with 1,382 additions and 272 deletions.
973 changes: 826 additions & 147 deletions api/elys/amm/params.pulsar.go

Large diffs are not rendered by default.

33 changes: 32 additions & 1 deletion proto/elys/amm/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,33 @@ message LegacyParams {
(gogoproto.nullable) = false
];
uint64 slippage_track_duration = 2; // default 1 week: 604,800
bool enable_base_currency_paired_pool_only = 3;
repeated string base_assets = 3;
string weight_breaking_fee_exponent = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
string weight_breaking_fee_multiplier = 5 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
string weight_breaking_fee_portion = 6 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
string weight_recovery_fee_portion = 7 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
string threshold_weight_difference = 8 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
repeated string allowed_pool_creators = 9;
}

message Params {
Expand Down Expand Up @@ -51,4 +77,9 @@ message Params {
(gogoproto.nullable) = false
];
repeated string allowed_pool_creators = 9;
string threshold_weight_difference_swap_fee = 10 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}
8 changes: 4 additions & 4 deletions x/amm/keeper/calc_in_route_spot_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,17 @@ func (k Keeper) CalcInRouteSpotPrice(ctx sdk.Context,
// Apply discount to swap fee
swapFee = types.ApplyDiscount(swapFee, discount)

// Calculate the total discounted swap fee
totalDiscountedSwapFee = totalDiscountedSwapFee.Add(swapFee)

// Estimate swap
snapshot := k.GetAccountedPoolSnapshotOrSet(ctx, pool)
cacheCtx, _ := ctx.CacheContext()
tokenOut, swapSlippage, _, weightBalanceBonus, _, err := k.SwapOutAmtGivenIn(cacheCtx, pool.PoolId, k.oracleKeeper, &snapshot, tokensIn, tokenOutDenom, swapFee, sdkmath.LegacyOneDec())
tokenOut, swapSlippage, _, weightBalanceBonus, _, swapFee, err := k.SwapOutAmtGivenIn(cacheCtx, pool.PoolId, k.oracleKeeper, &snapshot, tokensIn, tokenOutDenom, swapFee, sdkmath.LegacyOneDec())
if err != nil {
return sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), err
}

// Calculate the total discounted swap fee
totalDiscountedSwapFee = totalDiscountedSwapFee.Add(swapFee)

if tokenOut.IsZero() {
return sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), types.ErrAmountTooLow
}
Expand Down
8 changes: 4 additions & 4 deletions x/amm/keeper/calc_out_route_spot_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ func (k Keeper) CalcOutRouteSpotPrice(ctx sdk.Context, tokenOut sdk.Coin, routes
// Apply discount
swapFee = types.ApplyDiscount(swapFee, discount)

// Calculate the total discounted swap fee
totalDiscountedSwapFee = totalDiscountedSwapFee.Add(swapFee)

// Estimate swap
snapshot := k.GetAccountedPoolSnapshotOrSet(ctx, pool)
cacheCtx, _ := ctx.CacheContext()
swapResult, swapSlippage, _, weightBalanceBonus, _, err := k.SwapInAmtGivenOut(cacheCtx, pool.PoolId, k.oracleKeeper, &snapshot, tokensOut, tokenInDenom, swapFee, sdkmath.LegacyOneDec())
swapResult, swapSlippage, _, weightBalanceBonus, _, swapFee, err := k.SwapInAmtGivenOut(cacheCtx, pool.PoolId, k.oracleKeeper, &snapshot, tokensOut, tokenInDenom, swapFee, sdkmath.LegacyOneDec())
if err != nil {
return sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), err
}

// Calculate the total discounted swap fee
totalDiscountedSwapFee = totalDiscountedSwapFee.Add(swapFee)

if swapResult.IsZero() {
return sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), types.ErrAmountTooLow
}
Expand Down
2 changes: 1 addition & 1 deletion x/amm/keeper/fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (k Keeper) SwapFeesToRevenueToken(ctx sdk.Context, pool types.Pool, fee sdk
// Executes the swap in the pool and stores the output. Updates pool assets but
// does not actually transfer any tokens to or from the pool.
snapshot := k.GetAccountedPoolSnapshotOrSet(ctx, pool)
tokenOutCoin, _, _, _, oracleOutAmount, err := pool.SwapOutAmtGivenIn(ctx, k.oracleKeeper, &snapshot, sdk.Coins{tokenIn}, pool.PoolParams.FeeDenom, sdkmath.LegacyZeroDec(), k.accountedPoolKeeper, sdkmath.LegacyOneDec(), params)
tokenOutCoin, _, _, _, oracleOutAmount, _, err := pool.SwapOutAmtGivenIn(ctx, k.oracleKeeper, &snapshot, sdk.Coins{tokenIn}, pool.PoolParams.FeeDenom, sdkmath.LegacyZeroDec(), k.accountedPoolKeeper, sdkmath.LegacyOneDec(), params)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion x/amm/keeper/keeper_swap_exact_amount_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (k Keeper) InternalSwapExactAmountIn(
// Executes the swap in the pool and stores the output. Updates pool assets but
// does not actually transfer any tokens to or from the pool.
snapshot := k.GetAccountedPoolSnapshotOrSet(ctx, pool)
tokenOutCoin, _, slippageAmount, weightBalanceBonus, oracleOutAmount, err := pool.SwapOutAmtGivenIn(ctx, k.oracleKeeper, &snapshot, tokensIn, tokenOutDenom, swapFee, k.accountedPoolKeeper, math.LegacyOneDec(), params)
tokenOutCoin, _, slippageAmount, weightBalanceBonus, oracleOutAmount, swapFee, err := pool.SwapOutAmtGivenIn(ctx, k.oracleKeeper, &snapshot, tokensIn, tokenOutDenom, swapFee, k.accountedPoolKeeper, math.LegacyOneDec(), params)
if err != nil {
return math.Int{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/amm/keeper/keeper_swap_exact_amount_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (k Keeper) InternalSwapExactAmountOut(

params := k.GetParams(ctx)
snapshot := k.GetAccountedPoolSnapshotOrSet(ctx, pool)
tokenIn, _, slippageAmount, weightBalanceBonus, oracleInAmount, err := pool.SwapInAmtGivenOut(ctx, k.oracleKeeper, &snapshot, sdk.Coins{tokenOut}, tokenInDenom, swapFee, k.accountedPoolKeeper, math.LegacyOneDec(), params)
tokenIn, _, slippageAmount, weightBalanceBonus, oracleInAmount, swapFee, err := pool.SwapInAmtGivenOut(ctx, k.oracleKeeper, &snapshot, sdk.Coins{tokenOut}, tokenInDenom, swapFee, k.accountedPoolKeeper, math.LegacyOneDec(), params)
if err != nil {
return math.Int{}, err
}
Expand Down
12 changes: 12 additions & 0 deletions x/amm/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ func (k Keeper) CheckBaseAssetExist(ctx sdk.Context, denom string) bool {
return found
}

func (k Keeper) GetLegacyParams(ctx sdk.Context) (params types.LegacyParams) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))

b := store.Get([]byte(types.ParamsKey))
if b == nil {
return
}

k.cdc.MustUnmarshal(b, &params)
return
}

func (k Keeper) V8Migrate(ctx sdk.Context) error {
baseCurrencyDenom, found := k.assetProfileKeeper.GetUsdcDenom(ctx)
if !found {
Expand Down
7 changes: 4 additions & 3 deletions x/amm/keeper/swap_in_amt_given_out.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package keeper

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

"cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/amm/types"
)
Expand All @@ -13,11 +14,11 @@ import (
func (k Keeper) SwapInAmtGivenOut(
ctx sdk.Context, poolId uint64, oracleKeeper types.OracleKeeper, snapshot *types.Pool,
tokensOut sdk.Coins, tokenInDenom string, swapFee math.LegacyDec, weightBreakingFeePerpetualFactor math.LegacyDec) (
tokenIn sdk.Coin, slippage, slippageAmount math.LegacyDec, weightBalanceBonus math.LegacyDec, oracleInAmount math.LegacyDec, err error,
tokenIn sdk.Coin, slippage, slippageAmount math.LegacyDec, weightBalanceBonus math.LegacyDec, oracleInAmount math.LegacyDec, swapFeeFinal math.LegacyDec, err error,
) {
ammPool, found := k.GetPool(ctx, poolId)
if !found {
return sdk.Coin{}, math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec(), fmt.Errorf("invalid pool: %d", poolId)
return sdk.Coin{}, math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec(), fmt.Errorf("invalid pool: %d", poolId)
}
params := k.GetParams(ctx)
return ammPool.SwapInAmtGivenOut(ctx, oracleKeeper, snapshot, tokensOut, tokenInDenom, swapFee, k.accountedPoolKeeper, weightBreakingFeePerpetualFactor, params)
Expand Down
4 changes: 2 additions & 2 deletions x/amm/keeper/swap_out_amt_given_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ func (k Keeper) SwapOutAmtGivenIn(
tokenOutDenom string,
swapFee sdkmath.LegacyDec,
weightBreakingFeePerpetualFactor sdkmath.LegacyDec,
) (tokenOut sdk.Coin, slippage sdkmath.LegacyDec, slippageAmount sdkmath.LegacyDec, weightBalanceBonus sdkmath.LegacyDec, oracleOutAmount sdkmath.LegacyDec, err error) {
) (tokenOut sdk.Coin, slippage sdkmath.LegacyDec, slippageAmount sdkmath.LegacyDec, weightBalanceBonus sdkmath.LegacyDec, oracleOutAmount sdkmath.LegacyDec, swapFeeFinal sdkmath.LegacyDec, err error) {
ammPool, found := k.GetPool(ctx, poolId)
if !found {
return sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), fmt.Errorf("invalid pool: %d", poolId)
return sdk.Coin{}, sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), sdkmath.LegacyZeroDec(), fmt.Errorf("invalid pool: %d", poolId)
}
params := k.GetParams(ctx)
return ammPool.SwapOutAmtGivenIn(ctx, oracleKeeper, snapshot, tokensIn, tokenOutDenom, swapFee, k.accountedPoolKeeper, weightBreakingFeePerpetualFactor, params)
Expand Down
26 changes: 26 additions & 0 deletions x/amm/migrations/v10_migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package migrations

import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/amm/types"
)

func (m Migrator) V10Migration(ctx sdk.Context) error {
legacyParams := m.keeper.GetLegacyParams(ctx)
params := types.Params{
PoolCreationFee: legacyParams.PoolCreationFee,
SlippageTrackDuration: legacyParams.SlippageTrackDuration,
BaseAssets: legacyParams.BaseAssets,
WeightBreakingFeeExponent: legacyParams.WeightBreakingFeeExponent,
WeightBreakingFeeMultiplier: legacyParams.WeightBreakingFeeMultiplier,
WeightBreakingFeePortion: legacyParams.WeightBreakingFeePortion,
WeightRecoveryFeePortion: legacyParams.WeightRecoveryFeePortion,
ThresholdWeightDifference: legacyParams.ThresholdWeightDifference,
AllowedPoolCreators: legacyParams.AllowedPoolCreators,
ThresholdWeightDifferenceSwapFee: math.LegacyMustNewDecFromStr("0.125"),
}

m.keeper.SetParams(ctx, params)
return nil
}
4 changes: 2 additions & 2 deletions x/amm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
m := migrations.NewMigrator(am.keeper)
err := cfg.RegisterMigration(types.ModuleName, 8, m.V9Migration)
err := cfg.RegisterMigration(types.ModuleName, 9, m.V10Migration)
if err != nil {
panic(err)
}
Expand All @@ -159,7 +159,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
}

// ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1
func (AppModule) ConsensusVersion() uint64 { return 9 }
func (AppModule) ConsensusVersion() uint64 { return 10 }

// BeginBlock contains the logic that is automatically triggered at the beginning of each block
func (am AppModule) BeginBlock(_ context.Context) error {
Expand Down
22 changes: 12 additions & 10 deletions x/amm/types/params.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package types

import (
"cosmossdk.io/math"
"errors"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
Expand All @@ -11,15 +12,16 @@ import (
// NewParams creates a new Params instance
func NewParams(poolCreationFee math.Int, slippageTrackDuration uint64, baseAssets []string) Params {
return Params{
PoolCreationFee: poolCreationFee,
SlippageTrackDuration: slippageTrackDuration,
BaseAssets: baseAssets,
WeightBreakingFeeExponent: math.LegacyMustNewDecFromStr("2.5"),
WeightBreakingFeeMultiplier: math.LegacyMustNewDecFromStr("0.0005"),
WeightBreakingFeePortion: math.LegacyMustNewDecFromStr("0.5"),
WeightRecoveryFeePortion: math.LegacyMustNewDecFromStr("0.1"),
ThresholdWeightDifference: math.LegacyMustNewDecFromStr("0.3"),
AllowedPoolCreators: []string{authtypes.NewModuleAddress(govtypes.ModuleName).String()},
PoolCreationFee: poolCreationFee,
SlippageTrackDuration: slippageTrackDuration,
BaseAssets: baseAssets,
WeightBreakingFeeExponent: math.LegacyMustNewDecFromStr("2.5"),
WeightBreakingFeeMultiplier: math.LegacyMustNewDecFromStr("0.0005"),
WeightBreakingFeePortion: math.LegacyMustNewDecFromStr("0.5"),
WeightRecoveryFeePortion: math.LegacyMustNewDecFromStr("0.1"),
ThresholdWeightDifference: math.LegacyMustNewDecFromStr("0.3"),
AllowedPoolCreators: []string{authtypes.NewModuleAddress(govtypes.ModuleName).String()},
ThresholdWeightDifferenceSwapFee: math.LegacyMustNewDecFromStr("1.0"),
}
}

Expand Down
Loading

0 comments on commit 2dc4524

Please sign in to comment.