Skip to content

Commit

Permalink
feat: usdc pool check (#868)
Browse files Browse the repository at this point in the history
* feat: usdc pool check

* update

* update

* update

* update

* test(amm): add test cases

---------

Co-authored-by: Cosmic Vagabond <121588426+cosmic-vagabond@users.noreply.github.com>
  • Loading branch information
cryptokage1996 and cosmic-vagabond authored Oct 24, 2024
1 parent 65af35b commit 411c60b
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 38 deletions.
1 change: 1 addition & 0 deletions proto/elys/amm/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ message Params {
(gogoproto.nullable) = false
];
uint64 slippage_track_duration = 2; // default 1 week: 604,800
bool enable_base_currency_paired_pool_only = 3;
}
19 changes: 19 additions & 0 deletions x/amm/keeper/msg_server_create_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"context"
"strconv"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/amm/types"
assetprofiletypes "github.com/elys-network/elys/x/assetprofile/types"
ptypes "github.com/elys-network/elys/x/parameter/types"
)

Expand All @@ -19,6 +21,23 @@ func (k msgServer) CreatePool(goCtx context.Context, msg *types.MsgCreatePool) (
sender := sdk.MustAccAddressFromBech32(msg.Sender)
params := k.GetParams(ctx)

if params.EnableBaseCurrencyPairedPoolOnly {
baseCurrency, found := k.assetProfileKeeper.GetUsdcDenom(ctx)
if !found {
return nil, errorsmod.Wrapf(assetprofiletypes.ErrAssetProfileNotFound, "asset %s not found", ptypes.BaseCurrency)
}

is_base_curency_paired_pool := false
for _, asset := range msg.PoolAssets {
if asset.Token.Denom == baseCurrency {
is_base_curency_paired_pool = true
}
}
if !is_base_curency_paired_pool {
return nil, errorsmod.Wrapf(types.ErrOnlyBaseCurrencyPoolAllowed, "one of the asset must be %s", ptypes.BaseCurrency)
}
}

if !params.PoolCreationFee.IsNil() && params.PoolCreationFee.IsPositive() {
feeCoins := sdk.Coins{sdk.NewCoin(ptypes.Elys, params.PoolCreationFee)}
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, feeCoins); err != nil {
Expand Down
96 changes: 82 additions & 14 deletions x/amm/keeper/msg_server_create_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ import (

func (suite *KeeperTestSuite) TestMsgServerCreatePool() {
for _, tc := range []struct {
desc string
senderInitBalance sdk.Coins
poolParams types.PoolParams
poolAssets []types.PoolAsset
expSenderBalance sdk.Coins
expTotalLiquidity sdk.Coins
expLpCommitment sdk.Coin
expPass bool
desc string
senderInitBalance sdk.Coins
enableBaseCurrencyPairedPoolOnly bool
poolParams types.PoolParams
poolAssets []types.PoolAsset
expSenderBalance sdk.Coins
expTotalLiquidity sdk.Coins
expLpCommitment sdk.Coin
expPass bool
}{
{
desc: "zero tvl pool creation",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 11000000)},
desc: "zero tvl pool creation",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 11000000)},
enableBaseCurrencyPairedPoolOnly: false,
poolParams: types.PoolParams{
SwapFee: sdk.ZeroDec(),
ExitFee: sdk.ZeroDec(),
Expand All @@ -49,8 +51,9 @@ func (suite *KeeperTestSuite) TestMsgServerCreatePool() {
expPass: true,
},
{
desc: "positive tvl pool creation",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 10000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
desc: "positive tvl pool creation",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 10000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
enableBaseCurrencyPairedPoolOnly: false,
poolParams: types.PoolParams{
SwapFee: sdk.ZeroDec(),
ExitFee: sdk.ZeroDec(),
Expand All @@ -77,8 +80,9 @@ func (suite *KeeperTestSuite) TestMsgServerCreatePool() {
expPass: true,
},
{
desc: "not enough balance to create pool",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 10000000)},
desc: "not enough balance to create pool",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 10000000)},
enableBaseCurrencyPairedPoolOnly: false,
poolParams: types.PoolParams{
SwapFee: sdk.ZeroDec(),
ExitFee: sdk.ZeroDec(),
Expand All @@ -104,6 +108,64 @@ func (suite *KeeperTestSuite) TestMsgServerCreatePool() {
expLpCommitment: sdk.Coin{},
expPass: false,
},
{
desc: "base currency paired pool creation without base currency",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 10000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
enableBaseCurrencyPairedPoolOnly: true,
poolParams: types.PoolParams{
SwapFee: sdk.ZeroDec(),
ExitFee: sdk.ZeroDec(),
UseOracle: false,
WeightBreakingFeeMultiplier: sdk.ZeroDec(),
WeightBreakingFeeExponent: sdk.NewDecWithPrec(25, 1), // 2.5
ExternalLiquidityRatio: sdk.NewDec(1),
WeightRecoveryFeePortion: sdk.NewDecWithPrec(10, 2), // 10%
ThresholdWeightDifference: sdk.ZeroDec(),
FeeDenom: ptypes.BaseCurrency,
},
poolAssets: []types.PoolAsset{
{
Token: sdk.NewInt64Coin(ptypes.Eden, 1000000),
Weight: sdk.OneInt(),
},
{
Token: sdk.NewInt64Coin(ptypes.Elys, 1000000),
Weight: sdk.OneInt(),
},
},
expSenderBalance: sdk.Coins{},
expLpCommitment: sdk.NewCoin("amm/pool/1", sdk.NewInt(2).Mul(types.OneShare)),
expPass: false,
},
{
desc: "base currency paired pool creation with base currency",
senderInitBalance: sdk.Coins{sdk.NewInt64Coin(ptypes.Eden, 1000000), sdk.NewInt64Coin(ptypes.Elys, 10000000), sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000)},
enableBaseCurrencyPairedPoolOnly: true,
poolParams: types.PoolParams{
SwapFee: sdk.ZeroDec(),
ExitFee: sdk.ZeroDec(),
UseOracle: false,
WeightBreakingFeeMultiplier: sdk.ZeroDec(),
WeightBreakingFeeExponent: sdk.NewDecWithPrec(25, 1), // 2.5
ExternalLiquidityRatio: sdk.NewDec(1),
WeightRecoveryFeePortion: sdk.NewDecWithPrec(10, 2), // 10%
ThresholdWeightDifference: sdk.ZeroDec(),
FeeDenom: ptypes.BaseCurrency,
},
poolAssets: []types.PoolAsset{
{
Token: sdk.NewInt64Coin(ptypes.Eden, 1000000),
Weight: sdk.OneInt(),
},
{
Token: sdk.NewInt64Coin(ptypes.BaseCurrency, 1000000),
Weight: sdk.OneInt(),
},
},
expSenderBalance: sdk.Coins{},
expLpCommitment: sdk.NewCoin("amm/pool/1", sdk.NewInt(2).Mul(types.OneShare)),
expPass: true,
},
} {
suite.Run(tc.desc, func() {
suite.SetupTest()
Expand All @@ -120,6 +182,12 @@ func (suite *KeeperTestSuite) TestMsgServerCreatePool() {

// execute function
msgServer := keeper.NewMsgServerImpl(suite.app.AmmKeeper)

// set params
params := suite.app.AmmKeeper.GetParams(suite.ctx)
params.EnableBaseCurrencyPairedPoolOnly = tc.enableBaseCurrencyPairedPoolOnly
suite.app.AmmKeeper.SetParams(suite.ctx, params)

resp, err := msgServer.CreatePool(
sdk.WrapSDKContext(suite.ctx),
&types.MsgCreatePool{
Expand Down
16 changes: 16 additions & 0 deletions x/amm/migrations/v5_migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package migrations

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

func (m Migrator) V5Migration(ctx sdk.Context) error {
m.keeper.SetParams(ctx, types.Params{
PoolCreationFee: math.NewInt(10_000_000),
SlippageTrackDuration: 86400*7,
EnableBaseCurrencyPairedPoolOnly: false,
})
return nil
}
4 changes: 2 additions & 2 deletions x/amm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,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, 3, m.V4Migration)
err := cfg.RegisterMigration(types.ModuleName, 4, m.V5Migration)
if err != nil {
panic(err)
}
Expand All @@ -144,7 +144,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 4 }
func (AppModule) ConsensusVersion() uint64 { return 5 }

// BeginBlock contains the logic that is automatically triggered at the beginning of each block
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
Expand Down
1 change: 1 addition & 0 deletions x/amm/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
ErrFeeShouldNotBeNegative = errors.Register(ModuleName, 111, "fee should not be negative")
ErrInvalidShareAmountOut = errors.Register(ModuleName, 112, "invalid share amount out")
ErrPoolAssetsMustBeTwo = errors.Register(ModuleName, 113, "pool assets must be exactly two")
ErrOnlyBaseCurrencyPoolAllowed = errors.Register(ModuleName, 114, "Only USDC paired pool allowed")
)

const (
Expand Down
4 changes: 3 additions & 1 deletion x/amm/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
)

// NewParams creates a new Params instance
func NewParams(poolCreationFee math.Int, slippageTrackDuration uint64) Params {
func NewParams(poolCreationFee math.Int, slippageTrackDuration uint64, enable bool) Params {
return Params{
PoolCreationFee: poolCreationFee,
SlippageTrackDuration: slippageTrackDuration,
EnableBaseCurrencyPairedPoolOnly: enable,
}
}

Expand All @@ -19,6 +20,7 @@ func DefaultParams() Params {
return NewParams(
math.NewInt(10_000_000), // 10 ELYS
86400*7,
false,
)
}

Expand Down
84 changes: 64 additions & 20 deletions x/amm/types/params.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion x/amm/types/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func TestDefaultParams(t *testing.T) {
require.Equal(t, types.DefaultParams(), types.NewParams(math.NewInt(10_000_000), 86400*7))
require.Equal(t, types.DefaultParams(), types.NewParams(math.NewInt(10_000_000), 86400*7, false))
output, err := yaml.Marshal(types.DefaultParams())
require.NoError(t, err)
require.Equal(t, types.DefaultParams().String(), string(output))
Expand Down

0 comments on commit 411c60b

Please sign in to comment.