Skip to content

Commit

Permalink
[LSM] Scaffolding (#706)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Apr 6, 2023
1 parent 16dee3e commit 4c35885
Show file tree
Hide file tree
Showing 60 changed files with 5,366 additions and 571 deletions.
11 changes: 7 additions & 4 deletions app/upgrades/v5/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
recordtypes "github.com/Stride-Labs/stride/v8/x/records/types"
stakeibckeeper "github.com/Stride-Labs/stride/v8/x/stakeibc/keeper"
oldstakeibctypes "github.com/Stride-Labs/stride/v8/x/stakeibc/migrations/v2/types"
newstakeibctypes "github.com/Stride-Labs/stride/v8/x/stakeibc/migrations/v3/types"
stakeibctypes "github.com/Stride-Labs/stride/v8/x/stakeibc/types"
)

Expand Down Expand Up @@ -371,15 +372,17 @@ func (s *UpgradeTestSuite) SetupOldStakeibcStore(codec codec.Codec) func() {

// Callback to check stakeibc store after migration
return func() {
hostZone, found := s.App.StakeibcKeeper.GetHostZone(s.Ctx, hostZoneId)
s.Require().True(found, "host zone found")
hostZoneBz := hostzoneStore.Get([]byte(hostZone.ChainId))
var hostZone newstakeibctypes.HostZone
codec.MustUnmarshal(hostZoneBz, &hostZone)

s.Require().Equal(hostZone.ChainId, hostZoneId, "host zone chain id")

s.Require().Equal(hostZone.DelegationAccount.Address, delegationAddress, "delegation address")
s.Require().Equal(hostZone.RedemptionAccount.Address, redemptionAddress, "redemption address")

s.Require().Equal(hostZone.DelegationAccount.Target, stakeibctypes.ICAAccountType_DELEGATION, "delegation target")
s.Require().Equal(hostZone.RedemptionAccount.Target, stakeibctypes.ICAAccountType_REDEMPTION, "redemption target")
s.Require().Equal(hostZone.DelegationAccount.Target, newstakeibctypes.ICAAccountType_DELEGATION, "delegation target")
s.Require().Equal(hostZone.RedemptionAccount.Target, newstakeibctypes.ICAAccountType_REDEMPTION, "redemption target")

s.Require().Nil(hostZone.FeeAccount, "fee account")
s.Require().Nil(hostZone.WithdrawalAccount, "withdrawal account")
Expand Down
22 changes: 13 additions & 9 deletions proto/stride/stakeibc/callbacks.proto
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
syntax = "proto3";
package stride.stakeibc;
option go_package = "github.com/Stride-Labs/stride/v8/x/stakeibc/types";

import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "stride/stakeibc/lsm.proto";

option go_package = "github.com/Stride-Labs/stride/v8/x/stakeibc/types";

// ---------------------- Delegation Callbacks ---------------------- //
message SplitDelegation {
string validator = 1;
string amount = 2 [
Expand All @@ -19,15 +21,12 @@ message DelegateCallback {
repeated SplitDelegation split_delegations = 3;
}

// ---------------------- Claim Callbacks ---------------------- //

message ClaimCallback {
string user_redemption_record_id = 1;
string chain_id = 2;
uint64 epoch_number = 3;
}

// ---------------------- Reinvest Callback ---------------------- //
message ReinvestCallback {
cosmos.base.v1beta1.Coin reinvest_amount = 1 [
(gogoproto.nullable) = false,
Expand All @@ -36,21 +35,17 @@ message ReinvestCallback {
string host_zone_id = 3;
}

// ---------------------- Undelegation Callbacks ---------------------- //
message UndelegateCallback {
string host_zone_id = 1;
repeated SplitDelegation split_delegations = 2;
repeated uint64 epoch_unbonding_record_ids = 3;
}

// ---------------------- Redemption Callbacks ---------------------- //
message RedemptionCallback {
string host_zone_id = 1;
repeated uint64 epoch_unbonding_record_ids = 2;
}

// ---------------- Validator Rebalance Callbacks ---------------------- //

message Rebalancing {
string src_validator = 1;
string dst_validator = 2;
Expand All @@ -63,4 +58,13 @@ message Rebalancing {
message RebalanceCallback {
string host_zone_id = 1;
repeated Rebalancing rebalancings = 2;
}

message TransferLSMTokenCallback { LSMTokenDeposit deposit = 1; }

message DetokenizeSharesCallback { LSMTokenDeposit deposit = 1; }

message RebalanceTokenizedDepositsCallback {
string chain_id = 1;
repeated SplitDelegation split_delegations = 2;
}
11 changes: 6 additions & 5 deletions proto/stride/stakeibc/host_zone.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "cosmos_proto/cosmos.proto";

option go_package = "github.com/Stride-Labs/stride/v8/x/stakeibc/types";

// next id: 22
// next id: 23
message HostZone {
string chain_id = 1;
string connection_id = 2;
Expand All @@ -24,8 +24,6 @@ message HostZone {
string ibc_denom = 8;
// native denom on host zone
string host_denom = 9;
// TODO(TEST-68): Should we make this an array and store the last n redemption
// rates then calculate a TWARR?
string last_redemption_rate = 10 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
Expand All @@ -38,8 +36,11 @@ message HostZone {
];
// stores how many days we should wait before issuing unbondings
uint64 unbonding_frequency = 14;
// TODO(TEST-101) int to dec
string staked_bal = 13 [
string total_balanced_delegations = 13 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string total_unbalanced_delegations = 22 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
Expand Down
36 changes: 36 additions & 0 deletions proto/stride/stakeibc/lsm.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
syntax = "proto3";
package stride.stakeibc;

import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/Stride-Labs/stride/v8/x/stakeibc/types";

enum LSMDepositStatus {
option (gogoproto.goproto_enum_prefix) = false;

TRANSFER_IN_PROGRESS = 0;
TRANSFER_FAILED = 1;
DETOKENIZATION_QUEUE = 2;
DETOKENIZATION_IN_PROGRESS = 3;
DETOKENIZATION_FAILED = 4;
}

message LSMTokenDeposit {
string denom = 1;
string chain_id = 2;
string validator_address = 3;
string amount = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
LSMDepositStatus status = 5;
}

message LSMLiquidStake {
string staker = 1;
cosmos.base.v1beta1.Coin lsm_token = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"
];
}
16 changes: 11 additions & 5 deletions proto/stride/stakeibc/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "cosmos_proto/cosmos.proto";
// Msg defines the Msg service.
service Msg {
rpc LiquidStake(MsgLiquidStake) returns (MsgLiquidStakeResponse);
rpc LSMLiquidStake(MsgLSMLiquidStake) returns (MsgLSMLiquidStakeResponse);
rpc RedeemStake(MsgRedeemStake) returns (MsgRedeemStakeResponse);
rpc RegisterHostZone(MsgRegisterHostZone)
returns (MsgRegisterHostZoneResponse);
Expand All @@ -37,9 +38,18 @@ message MsgLiquidStake {
];
string host_denom = 3;
}

message MsgLiquidStakeResponse {}

message MsgLSMLiquidStake {
string creator = 1;
string amount = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string lsm_token_denom = 3;
}
message MsgLSMLiquidStakeResponse { bool transaction_complete = 1; }

message MsgClearBalance {
string creator = 1;
string chain_id = 2;
Expand All @@ -49,7 +59,6 @@ message MsgClearBalance {
];
string channel = 4;
}

message MsgClearBalanceResponse {}

message MsgRedeemStake {
Expand All @@ -61,7 +70,6 @@ message MsgRedeemStake {
string host_zone = 3;
string receiver = 4;
}

message MsgRedeemStakeResponse {}

// next: 15
Expand Down Expand Up @@ -89,7 +97,6 @@ message MsgRegisterHostZone {
(gogoproto.nullable) = false
];
}

message MsgRegisterHostZoneResponse {}

message MsgClaimUndelegatedTokens {
Expand All @@ -99,7 +106,6 @@ message MsgClaimUndelegatedTokens {
uint64 epoch = 3;
string sender = 4;
}

message MsgClaimUndelegatedTokensResponse {}

message MsgRebalanceValidators {
Expand Down
10 changes: 9 additions & 1 deletion proto/stride/stakeibc/validator.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ message ValidatorExchangeRate {
message Validator {
string name = 1;
string address = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
string delegation_amt = 5 [
string balanced_delegation = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string unbalanced_delegation = 8 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string progress_towards_exchange_rate_query = 9 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
Expand Down
27 changes: 27 additions & 0 deletions x/records/keeper/callback_lsm_transfer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package keeper

import (
"github.com/Stride-Labs/stride/v8/utils"
icacallbackstypes "github.com/Stride-Labs/stride/v8/x/icacallbacks/types"
"github.com/Stride-Labs/stride/v8/x/records/types"
stakeibctypes "github.com/Stride-Labs/stride/v8/x/stakeibc/types"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
channeltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types"
"github.com/golang/protobuf/proto" //nolint:staticcheck
)

func LSMTransferCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, ackResponse *icacallbackstypes.AcknowledgementResponse, args []byte) error {
// Fetch callback args
transferCallback := stakeibctypes.TransferLSMTokenCallback{}
if err := proto.Unmarshal(args, &transferCallback); err != nil {
return errorsmod.Wrapf(types.ErrUnmarshalFailure, "unable to unmarshal LSM transfer callback: %s", err.Error())
}
chainId := transferCallback.Deposit.ChainId
k.Logger(ctx).Info(utils.LogICACallbackWithHostZone(chainId, IBCCallbacksID_LSMTransfer, "Starting LSM transfer callback"))

// TODO [LSM]

return nil
}
File renamed without changes.
File renamed without changes.
7 changes: 5 additions & 2 deletions x/records/keeper/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
channeltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types"
)

const TRANSFER = "transfer"
const IBCCallbacksID_NativeTransfer = "transfer"
const IBCCallbacksID_LSMTransfer = "lsm-transfer"

// ICACallbacks wrapper struct for stakeibc keeper
type ICACallback func(Keeper, sdk.Context, channeltypes.Packet, *icacallbackstypes.AcknowledgementResponse, []byte) error
Expand Down Expand Up @@ -38,6 +39,8 @@ func (c ICACallbacks) AddICACallback(id string, fn interface{}) icacallbackstype
}

func (c ICACallbacks) RegisterICACallbacks() icacallbackstypes.ICACallbackHandler {
a := c.AddICACallback(TRANSFER, ICACallback(TransferCallback))
a := c.
AddICACallback(IBCCallbacksID_NativeTransfer, ICACallback(TransferCallback)).
AddICACallback(IBCCallbacksID_LSMTransfer, ICACallback(LSMTransferCallback))
return a.(ICACallbacks)
}
2 changes: 1 addition & 1 deletion x/records/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (k Keeper) Transfer(ctx sdk.Context, msg *ibctypes.MsgTransfer, depositReco
PortId: msg.SourcePort,
ChannelId: msg.SourceChannel,
Sequence: sequence,
CallbackId: TRANSFER,
CallbackId: IBCCallbacksID_NativeTransfer,
CallbackArgs: marshalledCallbackArgs,
}
k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId, "Storing callback data: %+v", callback))
Expand Down
1 change: 1 addition & 0 deletions x/stakeibc/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func GetTxCmd() *cobra.Command {
}

cmd.AddCommand(CmdLiquidStake())
cmd.AddCommand(CmdLSMLiquidStake())
cmd.AddCommand(CmdRegisterHostZone())
cmd.AddCommand(CmdRedeemStake())
cmd.AddCommand(CmdClaimUndelegatedTokens())
Expand Down
48 changes: 48 additions & 0 deletions x/stakeibc/client/cli/tx_lsm_liquid_stake.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cli

import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"

errorsmod "cosmossdk.io/errors"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/spf13/cobra"

"github.com/Stride-Labs/stride/v8/x/stakeibc/types"
)

func CmdLSMLiquidStake() *cobra.Command {
cmd := &cobra.Command{
Use: "lsm-liquid-stake [amount] [lsm-token-denom]",
Short: "Broadcast message lsm-liquid-stake",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) (err error) {
amount, found := sdk.NewIntFromString(args[0])
if !found {
return errorsmod.Wrap(sdkerrors.ErrInvalidType, "can not convert string to int")
}
denom := args[1]

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := types.NewMsgLSMLiquidStake(
clientCtx.GetFromAddress().String(),
amount,
denom,
)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}
1 change: 0 additions & 1 deletion x/stakeibc/client/cli/tx_register_host_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const (

var _ = strconv.Itoa(0)

// TODO(TEST-53): Remove this pre-launch (no need for clients to create / interact with ICAs)
func CmdRegisterHostZone() *cobra.Command {
cmd := &cobra.Command{
Use: "register-host-zone [connection-id] [host-denom] [bech32prefix] [ibc-denom] [channel-id] [unbonding-frequency]",
Expand Down
3 changes: 3 additions & 0 deletions x/stakeibc/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgLiquidStake:
res, err := msgServer.LiquidStake(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgLSMLiquidStake:
res, err := msgServer.LSMLiquidStake(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgClearBalance:
res, err := msgServer.ClearBalance(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
Expand Down
Loading

0 comments on commit 4c35885

Please sign in to comment.