Skip to content

Commit

Permalink
Merge pull request #2706 from Sifchain/feature/cancel-unbond
Browse files Browse the repository at this point in the history
Feature/cancel unbond
  • Loading branch information
timlind authored May 3, 2022
2 parents 9bcffe0 + ef4f574 commit 06cbc0b
Show file tree
Hide file tree
Showing 9 changed files with 671 additions and 105 deletions.
2 changes: 1 addition & 1 deletion app/setup_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

const releaseVersion = "0.13.1"
const releaseVersion = "0.13.2-rc.1"

func SetupHandlers(app *SifchainApp) {
app.UpgradeKeeper.SetUpgradeHandler(releaseVersion, func(ctx sdk.Context, plan types.Plan, vm m.VersionMap) (m.VersionMap, error) {
Expand Down
15 changes: 14 additions & 1 deletion proto/sifnode/clp/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ service Msg {
rpc UpdatePmtpParams(MsgUpdatePmtpParams) returns (MsgUpdatePmtpParamsResponse);
rpc UpdateStakingRewardParams(MsgUpdateStakingRewardParams) returns (MsgUpdateStakingRewardParamsResponse);
rpc SetSymmetryThreshold(MsgSetSymmetryThreshold) returns (MsgSetSymmetryThresholdResponse);
rpc CancelUnlockLiquidity(MsgCancelUnlock) returns (MsgCancelUnlockResponse);
}

//message MsgUpdateStakingRewardParams{
Expand Down Expand Up @@ -209,4 +210,16 @@ message MsgSetSymmetryThreshold {
];
}

message MsgSetSymmetryThresholdResponse {}
message MsgSetSymmetryThresholdResponse {}

message MsgCancelUnlock {
string signer = 1;
sifnode.clp.v1.Asset external_asset = 2
[ (gogoproto.moretags) = "yaml:\"external_asset\"" ];
string units = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint",
(gogoproto.nullable) = false
];
}

message MsgCancelUnlockResponse {}
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.13.1
0.13.2-rc.1
41 changes: 41 additions & 0 deletions x/clp/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func GetTxCmd() *cobra.Command {
GetCmdSwap(),
GetCmdDecommissionPool(),
GetCmdUnlockLiquidity(),
GetCmdCancelUnlockLiquidity(),
GetCmdUpdateRewardParams(),
GetCmdAddRewardPeriod(),
GetCmdModifyPmtpRates(),
Expand Down Expand Up @@ -582,3 +583,43 @@ func GetCmdUnlockLiquidity() *cobra.Command {

return cmd
}

func GetCmdCancelUnlockLiquidity() *cobra.Command {
cmd := &cobra.Command{
Use: "cancel-unbond",
Short: "Cancel unbonding of liquidity from a pool",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

externalAsset := types.NewAsset(viper.GetString(FlagAssetSymbol))
signer := clientCtx.GetFromAddress()
units := viper.GetUint64(FlagUnits)
unitsInt := sdk.NewUint(units)
msg := types.MsgCancelUnlock{
Signer: signer.String(),
ExternalAsset: &externalAsset,
Units: unitsInt,
}
if err := msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}
cmd.Flags().AddFlagSet(FsAssetSymbol)
cmd.Flags().AddFlagSet(FsUnits)
if err := cmd.MarkFlagRequired(FlagAssetSymbol); err != nil {
log.Println("MarkFlagRequired failed: ", err.Error())
}
if err := cmd.MarkFlagRequired(FlagUnits); err != nil {
log.Println("MarkFlagRequired failed: ", err.Error())
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}
51 changes: 41 additions & 10 deletions x/clp/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,45 @@ func (k msgServer) SetSymmetryThreshold(goCtx context.Context, threshold *types.
return &types.MsgSetSymmetryThresholdResponse{}, nil
}

// NewMsgServerImpl returns an implementation of the clp MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{Keeper: keeper}
}

var _ types.MsgServer = msgServer{}

func (k msgServer) CancelUnlockLiquidity(goCtx context.Context, request *types.MsgCancelUnlock) (*types.MsgCancelUnlockResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
lp, err := k.Keeper.GetLiquidityProvider(ctx, request.ExternalAsset.Symbol, request.Signer)
if err != nil {
return nil, types.ErrLiquidityProviderDoesNotExist
}
// Prune unlocks
params := k.GetRewardsParams(ctx)
k.PruneUnlockRecords(ctx, &lp, params.LiquidityRemovalLockPeriod, params.LiquidityRemovalCancelPeriod)

err = k.UseUnlockedLiquidity(ctx, lp, request.Units, true)
if err != nil {
return nil, err
}

ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeCancelUnlock,
sdk.NewAttribute(types.AttributeKeyLiquidityProvider, lp.String()),
sdk.NewAttribute(types.AttributeKeyPool, lp.Asset.Symbol),
sdk.NewAttribute(types.AttributeKeyUnits, request.Units.String()),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, request.Signer),
),
})
return &types.MsgCancelUnlockResponse{}, nil
}

func (k msgServer) UpdateStakingRewardParams(goCtx context.Context, msg *types.MsgUpdateStakingRewardParams) (*types.MsgUpdateStakingRewardParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
signer, err := sdk.AccAddressFromBech32(msg.Signer)
Expand Down Expand Up @@ -88,14 +127,6 @@ func (k msgServer) AddRewardPeriod(goCtx context.Context, msg *types.MsgAddRewar
return response, nil
}

// NewMsgServerImpl returns an implementation of the clp MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{Keeper: keeper}
}

var _ types.MsgServer = msgServer{}

func (k msgServer) UpdatePmtpParams(goCtx context.Context, msg *types.MsgUpdatePmtpParams) (*types.MsgUpdatePmtpParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
response := &types.MsgUpdatePmtpParamsResponse{}
Expand Down Expand Up @@ -493,7 +524,7 @@ func (k msgServer) RemoveLiquidity(goCtx context.Context, msg *types.MsgRemoveLi
pool.NativeAssetBalance.String(), pool.ExternalAssetBalance.String(), lp.LiquidityProviderUnits.String(),
msg.WBasisPoints.String(), msg.Asymmetry)

err = k.Keeper.UseUnlockedLiquidity(ctx, lp, lp.LiquidityProviderUnits.Sub(lpUnitsLeft))
err = k.Keeper.UseUnlockedLiquidity(ctx, lp, lp.LiquidityProviderUnits.Sub(lpUnitsLeft), false)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -620,7 +651,7 @@ func (k msgServer) RemoveLiquidityUnits(goCtx context.Context, msg *types.MsgRem
pool.NativeAssetBalance.String(), pool.ExternalAssetBalance.String(), lp.LiquidityProviderUnits.String(),
msg.WithdrawUnits)

err = k.Keeper.UseUnlockedLiquidity(ctx, lp, lp.LiquidityProviderUnits.Sub(lpUnitsLeft))
err = k.Keeper.UseUnlockedLiquidity(ctx, lp, lp.LiquidityProviderUnits.Sub(lpUnitsLeft), false)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions x/clp/keeper/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (k Keeper) DistributeDepthRewards(ctx sdk.Context, period *types.RewardPeri
return nil
}

func (k Keeper) UseUnlockedLiquidity(ctx sdk.Context, lp types.LiquidityProvider, units sdk.Uint) error {
func (k Keeper) UseUnlockedLiquidity(ctx sdk.Context, lp types.LiquidityProvider, units sdk.Uint, any bool) error {
// Ensure there is enough liquidity requested for unlock, and also passed lock period.
// Reduce liquidity in one or more unlock records.
// Remove unlock records with zero units remaining.
Expand All @@ -87,7 +87,7 @@ func (k Keeper) UseUnlockedLiquidity(ctx sdk.Context, lp types.LiquidityProvider

unitsLeftToUse := units
for _, record := range lp.Unlocks {
if record.RequestHeight+int64(lockPeriod) <= currentHeight {
if any || record.RequestHeight+int64(lockPeriod) <= currentHeight {
if unitsLeftToUse.GT(record.Units) {
// use all this record's unit's and continue with remaining
unitsLeftToUse = unitsLeftToUse.Sub(record.Units)
Expand Down
16 changes: 15 additions & 1 deletion x/clp/keeper/rewards_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func TestUseUnlockedLiquidity(t *testing.T) {
name string
height int64
use sdk.Uint
any bool
unlocks []*types.LiquidityUnlock
expected error
}{
Expand All @@ -102,6 +103,19 @@ func TestUseUnlockedLiquidity(t *testing.T) {
},
},
},
{
name: "Unlock in any state",
height: 5,
use: sdk.NewUint(1000),
any: true,
expected: nil,
unlocks: []*types.LiquidityUnlock{
{
RequestHeight: 1,
Units: sdk.NewUint(1000),
},
},
},
{
name: "Available via split",
height: 50,
Expand Down Expand Up @@ -136,7 +150,7 @@ func TestUseUnlockedLiquidity(t *testing.T) {
Unlocks: tc.unlocks,
}
app.ClpKeeper.SetLiquidityProvider(ctx, &lp)
err := app.ClpKeeper.UseUnlockedLiquidity(ctx, lp, sdk.NewUint(1000))
err := app.ClpKeeper.UseUnlockedLiquidity(ctx, lp, sdk.NewUint(1000), tc.any)
require.ErrorIs(t, err, tc.expected)
})
}
Expand Down
33 changes: 33 additions & 0 deletions x/clp/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var (
_ sdk.Msg = &MsgUpdatePmtpParams{}
_ sdk.Msg = &MsgUpdateStakingRewardParams{}
_ sdk.Msg = &MsgSetSymmetryThreshold{}
_ sdk.Msg = &MsgCancelUnlock{}

_ legacytx.LegacyMsg = &MsgRemoveLiquidity{}
_ legacytx.LegacyMsg = &MsgRemoveLiquidityUnits{}
Expand All @@ -36,8 +37,40 @@ var (
_ legacytx.LegacyMsg = &MsgModifyPmtpRates{}
_ legacytx.LegacyMsg = &MsgUpdatePmtpParams{}
_ legacytx.LegacyMsg = &MsgUpdateStakingRewardParams{}
_ legacytx.LegacyMsg = &MsgSetSymmetryThreshold{}
_ legacytx.LegacyMsg = &MsgCancelUnlock{}
)

func (m MsgCancelUnlock) Route() string {
return RouterKey
}

func (m MsgCancelUnlock) Type() string {
return "cancel_unlock"
}

func (m MsgCancelUnlock) ValidateBasic() error {
if len(m.Signer) == 0 {
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, m.Signer)
}
if !m.ExternalAsset.Validate() {
return sdkerrors.Wrap(ErrInValidAsset, m.ExternalAsset.Symbol)
}
return nil
}

func (m MsgCancelUnlock) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
}

func (m MsgCancelUnlock) GetSigners() []sdk.AccAddress {
addr, err := sdk.AccAddressFromBech32(m.Signer)
if err != nil {
panic(err)
}
return []sdk.AccAddress{addr}
}

func (m MsgUpdateStakingRewardParams) Route() string {
return RouterKey
}
Expand Down
Loading

0 comments on commit 06cbc0b

Please sign in to comment.