diff --git a/app/setup_handlers.go b/app/setup_handlers.go index 9feb88cde6..a6d6fd61de 100644 --- a/app/setup_handlers.go +++ b/app/setup_handlers.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) -const releaseVersion = "0.13.0" +const releaseVersion = "0.13.1-rc1" func SetupHandlers(app *SifchainApp) { app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm m.VersionMap) (m.VersionMap, error) { diff --git a/version b/version index 54d1a4f2a4..eccb60dedf 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.13.0 +0.13.1-rc1 diff --git a/x/clp/handler_test.go b/x/clp/handler_test.go index 43a84b90b5..24c6850943 100644 --- a/x/clp/handler_test.go +++ b/x/clp/handler_test.go @@ -109,8 +109,8 @@ func TestAddLiquidity(t *testing.T) { require.NotNil(t, res) msg = clptypes.NewMsgAddLiquidity(signer, asset, sdk.ZeroUint(), addLiquidityAmount) res, err = handler(ctx, &msg) - require.NoError(t, err) - require.NotNil(t, res) + require.EqualError(t, err, "Cannot add liquidity asymmetrically") + require.Nil(t, res) // Subtracted twice , during create and add externalCoin = sdk.NewCoin(asset.Symbol, sdk.Int(initialBalance.Sub(addLiquidityAmount).Sub(addLiquidityAmount))) nativeCoin = sdk.NewCoin(clptypes.NativeSymbol, sdk.Int(initialBalance.Sub(addLiquidityAmount).Sub(sdk.ZeroUint()))) @@ -155,8 +155,8 @@ func TestAddLiquidity_LargeValue(t *testing.T) { require.NotNil(t, res) msg := clptypes.NewMsgAddLiquidity(signer, asset, addLiquidityAmountRowan, addLiquidityAmountCaCoin) res, err = handler(ctx, &msg) - require.NoError(t, err) - require.NotNil(t, res) + require.EqualError(t, err, "Cannot add liquidity asymmetrically") + require.Nil(t, res) } func TestRemoveLiquidity(t *testing.T) { @@ -194,8 +194,8 @@ func TestRemoveLiquidity(t *testing.T) { coins := CalculateWithdraw(t, clpKeeper, ctx, asset, signer.String(), wBasis.String(), asymmetry) msg = clptypes.NewMsgRemoveLiquidity(signer, asset, wBasis, asymmetry) res, err = handler(ctx, &msg) - require.NoError(t, err) - require.NotNil(t, res) + require.EqualError(t, err, "Cannot remove liquidity asymmetrically") + require.Nil(t, res) for _, coin := range coins { ok := clpKeeper.HasBalance(ctx, signer, coin) assert.True(t, ok, "") @@ -205,8 +205,8 @@ func TestRemoveLiquidity(t *testing.T) { coins = CalculateWithdraw(t, clpKeeper, ctx, asset, signer.String(), wBasis.String(), asymmetry) msg = clptypes.NewMsgRemoveLiquidity(signer, asset, wBasis, asymmetry) res, err = handler(ctx, &msg) - require.NoError(t, err) - require.NotNil(t, res) + require.EqualError(t, err, "Cannot remove liquidity asymmetrically") + require.Nil(t, res) for _, coin := range coins { ok := clpKeeper.HasBalance(ctx, signer, coin) assert.True(t, ok, "") @@ -227,8 +227,8 @@ func TestRemoveLiquidity(t *testing.T) { coins = CalculateWithdraw(t, clpKeeper, ctx, asset, signer.String(), wBasis.String(), asymmetry) msg = clptypes.NewMsgRemoveLiquidity(signer, asset, wBasis, asymmetry) res, err = handler(ctx, &msg) - require.NoError(t, err) - require.NotNil(t, res) + require.EqualError(t, err, "Cannot remove liquidity asymmetrically") + require.Nil(t, res) for _, coin := range coins { ok := clpKeeper.HasBalance(ctx, signer, coin) assert.True(t, ok, "") @@ -256,8 +256,8 @@ func TestRemoveLiquidity(t *testing.T) { msg = clptypes.NewMsgRemoveLiquidity(newLP, asset, wBasis, asymmetry) res, err = handler(ctx, &msg) - require.NoError(t, err) - require.NotNil(t, res, "Can withdraw now as new LP has added liquidity") + require.EqualError(t, err, "Cannot remove liquidity asymmetrically") + require.Nil(t, res, "Cannot withdraw now as new LP hasnt added liquidity") } func TestSwap(t *testing.T) { @@ -352,6 +352,11 @@ func TestDecommisionPool(t *testing.T) { msgrm := clptypes.NewMsgRemoveLiquidity(signer, asset, sdk.NewInt(5001), sdk.NewInt(1)) res, err = handler(ctx, &msgrm) + require.EqualError(t, err, "Cannot remove liquidity asymmetrically") + require.Nil(t, res) + + msgrm = clptypes.NewMsgRemoveLiquidity(signer, asset, sdk.NewInt(5001), sdk.NewInt(0)) + res, err = handler(ctx, &msgrm) require.NoError(t, err) require.NotNil(t, res) @@ -468,8 +473,14 @@ func TestUnlockLiquidity(t *testing.T) { msg = clptypes.NewMsgRemoveLiquidity(signer, asset, wBasis, asymmetry) res, err = handler(ctx, &msg) + require.EqualError(t, err, "Cannot remove liquidity asymmetrically") + require.Nil(t, res) + + msg = clptypes.NewMsgRemoveLiquidity(signer, asset, sdk.NewInt(5001), sdk.NewInt(0)) + res, err = handler(ctx, &msg) require.NoError(t, err) require.NotNil(t, res) + for _, coin := range coins { ok := clpKeeper.HasBalance(ctx, signer, coin) assert.True(t, ok, "") diff --git a/x/clp/keeper/calculations.go b/x/clp/keeper/calculations.go index 1672cf210c..46927b5ec7 100644 --- a/x/clp/keeper/calculations.go +++ b/x/clp/keeper/calculations.go @@ -281,6 +281,11 @@ func CalculatePoolUnits(oldPoolUnits, nativeAssetBalance, externalAssetBalance, slipAdjustment = r.Mul(A).Sub(R.Mul(a)).Quo(slipAdjDenominator) } slipAdjustment = sdk.NewDec(1).Sub(slipAdjustment) + + if !slipAdjustment.Equal(sdk.OneDec()) { + return sdk.ZeroUint(), sdk.ZeroUint(), types.ErrAsymmetricAdd + } + numerator := P.Mul(a.Mul(R).Add(A.Mul(r))) denominator := sdk.NewDec(2).Mul(A).Mul(R) stakeUnits := numerator.Quo(denominator).Mul(slipAdjustment) diff --git a/x/clp/keeper/calculations_test.go b/x/clp/keeper/calculations_test.go index 1bbe668852..e86cdec038 100644 --- a/x/clp/keeper/calculations_test.go +++ b/x/clp/keeper/calculations_test.go @@ -1074,7 +1074,7 @@ func TestKeeper_CalculatePoolUnits(t *testing.T) { lpunits: sdk.ZeroUint(), }, { - name: "successful", + name: "fail asymmetric", oldPoolUnits: sdk.ZeroUint(), nativeAssetBalance: sdk.NewUint(10000), externalAssetBalance: sdk.NewUint(100), @@ -1084,6 +1084,7 @@ func TestKeeper_CalculatePoolUnits(t *testing.T) { adjustExternalToken: false, poolUnits: sdk.ZeroUint(), lpunits: sdk.ZeroUint(), + errString: errors.New("Cannot add liquidity asymmetrically"), }, } diff --git a/x/clp/keeper/msg_server.go b/x/clp/keeper/msg_server.go index 98f5d4d911..a78b6fd8f4 100644 --- a/x/clp/keeper/msg_server.go +++ b/x/clp/keeper/msg_server.go @@ -469,6 +469,10 @@ func (k msgServer) RemoveLiquidity(goCtx context.Context, msg *types.MsgRemoveLi params := k.GetRewardsParams(ctx) k.PruneUnlockRecords(ctx, &lp, params.LiquidityRemovalLockPeriod, params.LiquidityRemovalCancelPeriod) + if !msg.Asymmetry.IsZero() { + return nil, types.ErrAsymmetricRemove + } + //Calculate amount to withdraw withdrawNativeAssetAmount, withdrawExternalAssetAmount, lpUnitsLeft, swapAmount := CalculateWithdrawal(pool.PoolUnits, pool.NativeAssetBalance.String(), pool.ExternalAssetBalance.String(), lp.LiquidityProviderUnits.String(), @@ -551,6 +555,7 @@ func (k msgServer) RemoveLiquidity(goCtx context.Context, msg *types.MsgRemoveLi sdk.NewEvent( types.EventTypeRemoveLiquidity, sdk.NewAttribute(types.AttributeKeyLiquidityProvider, lp.String()), + sdk.NewAttribute(types.AttributeKeyUnits, lp.LiquidityProviderUnits.Sub(lpUnitsLeft).String()), sdk.NewAttribute(types.AttributePmtpBlockRate, k.GetPmtpRateParams(ctx).PmtpPeriodBlockRate.String()), sdk.NewAttribute(types.AttributePmtpCurrentRunningRate, pmtpCurrentRunningRate.String()), sdk.NewAttribute(types.AttributeKeyHeight, strconv.FormatInt(ctx.BlockHeight(), 10)), @@ -629,6 +634,7 @@ func (k msgServer) RemoveLiquidityUnits(goCtx context.Context, msg *types.MsgRem sdk.NewEvent( types.EventTypeRemoveLiquidity, sdk.NewAttribute(types.AttributeKeyLiquidityProvider, lp.String()), + sdk.NewAttribute(types.AttributeKeyUnits, lp.LiquidityProviderUnits.Sub(lpUnitsLeft).String()), sdk.NewAttribute(types.AttributePmtpBlockRate, k.GetPmtpRateParams(ctx).PmtpPeriodBlockRate.String()), sdk.NewAttribute(types.AttributePmtpCurrentRunningRate, pmtpCurrentRunningRate.String()), sdk.NewAttribute(types.AttributeKeyHeight, strconv.FormatInt(ctx.BlockHeight(), 10)), @@ -734,6 +740,7 @@ func (k msgServer) AddLiquidity(goCtx context.Context, msg *types.MsgAddLiquidit sdk.NewEvent( types.EventTypeAddLiquidity, sdk.NewAttribute(types.AttributeKeyLiquidityProvider, lp.String()), + sdk.NewAttribute(types.AttributeKeyUnits, lpUnits.String()), sdk.NewAttribute(types.AttributeKeyHeight, strconv.FormatInt(ctx.BlockHeight(), 10)), ), sdk.NewEvent( diff --git a/x/clp/keeper/msg_server_test.go b/x/clp/keeper/msg_server_test.go index 09c9b6bf45..54dbdca6da 100644 --- a/x/clp/keeper/msg_server_test.go +++ b/x/clp/keeper/msg_server_test.go @@ -543,7 +543,7 @@ func TestMsgServer_RemoveLiquidity(t *testing.T) { Signer: "sif1syavy2npfyt9tcncdtsdzf7kny9lh777yqc2nd", ExternalAsset: &types.Asset{Symbol: "eth"}, WBasisPoints: sdk.NewInt(1), - Asymmetry: sdk.NewInt(1), + Asymmetry: sdk.NewInt(0), }, }, { @@ -566,6 +566,7 @@ func TestMsgServer_RemoveLiquidity(t *testing.T) { WBasisPoints: sdk.NewInt(1), Asymmetry: sdk.NewInt(1), }, + errString: errors.New("Cannot remove liquidity asymmetrically"), }, } diff --git a/x/clp/types/errors.go b/x/clp/types/errors.go index 017d68b62d..b1ec39100b 100644 --- a/x/clp/types/errors.go +++ b/x/clp/types/errors.go @@ -34,4 +34,6 @@ var ( ErrAmountTooLow = sdkerrors.Register(ModuleName, 32, "Tx amount is too low") ErrNotEnoughPermissions = sdkerrors.Register(ModuleName, 33, "Signer does not have permissions to execute this action") ErrCannotStartPolicy = sdkerrors.Register(ModuleName, 34, "A new policy can be started only after the current policy has ended") + ErrAsymmetricAdd = sdkerrors.Register(ModuleName, 35, "Cannot add liquidity asymmetrically") + ErrAsymmetricRemove = sdkerrors.Register(ModuleName, 36, "Cannot remove liquidity asymmetrically") )