From d82b71b8c1990bf04a6df890cd298ab52c8bd386 Mon Sep 17 00:00:00 2001 From: Max Kupriianov Date: Mon, 11 Dec 2023 12:12:29 +0000 Subject: [PATCH] feat: liquidstake module (#684) * feat: stkxprt impl * fix: codec * chore: re-gen * feat: lsm-lp integration; some refactorings * fix: un-bump wasmd version * chore: fix proto files, update proto-builder to 0.14.0 and make proto-format. --- Makefile | 2 +- go.mod | 7 +- go.sum | 6 + .../pstake/liquidstake/v1beta1/genesis.proto | 20 + .../liquidstake/v1beta1/liquidstake.proto | 191 ++ proto/pstake/liquidstake/v1beta1/query.proto | 55 + proto/pstake/liquidstake/v1beta1/tx.proto | 102 + .../v1beta1/liquidstakeibc.proto | 48 +- .../pstake/liquidstakeibc/v1beta1/msgs.proto | 45 +- .../liquidstakeibc/v1beta1/params.proto | 11 +- .../pstake/liquidstakeibc/v1beta1/query.proto | 130 +- proto/pstake/lscosmos/v1beta1/query.proto | 47 +- x/liquidstake/abci.go | 21 + x/liquidstake/client/cli/query.go | 156 ++ x/liquidstake/client/cli/tx.go | 238 +++ x/liquidstake/handler.go | 35 + x/liquidstake/keeper/genesis.go | 42 + x/liquidstake/keeper/grpc_query.go | 50 + x/liquidstake/keeper/hooks.go | 22 + x/liquidstake/keeper/keeper.go | 97 + x/liquidstake/keeper/liquidstake.go | 646 ++++++ x/liquidstake/keeper/msg_server.go | 177 ++ x/liquidstake/keeper/rebalancing.go | 253 +++ x/liquidstake/module.go | 149 ++ x/liquidstake/types/codec.go | 46 + x/liquidstake/types/errors.go | 24 + x/liquidstake/types/events.go | 31 + x/liquidstake/types/expected_keepers.go | 101 + x/liquidstake/types/genesis.go | 34 + x/liquidstake/types/genesis.pb.go | 377 ++++ x/liquidstake/types/keys.go | 35 + x/liquidstake/types/liquidstake.go | 213 ++ x/liquidstake/types/liquidstake.pb.go | 1871 +++++++++++++++++ x/liquidstake/types/msgs.go | 226 ++ x/liquidstake/types/params.go | 155 ++ x/liquidstake/types/query.pb.go | 1222 +++++++++++ x/liquidstake/types/query.pb.gw.go | 283 +++ x/liquidstake/types/rebalancing.go | 52 + x/liquidstake/types/tx.pb.go | 1860 ++++++++++++++++ x/liquidstakeibc/client/query.go | 2 +- x/liquidstakeibc/client/tx.go | 2 +- x/liquidstakeibc/types/liquidstakeibc.pb.go | 13 +- x/liquidstakeibc/types/query.pb.go | 12 +- 43 files changed, 8954 insertions(+), 155 deletions(-) create mode 100644 proto/pstake/liquidstake/v1beta1/genesis.proto create mode 100644 proto/pstake/liquidstake/v1beta1/liquidstake.proto create mode 100644 proto/pstake/liquidstake/v1beta1/query.proto create mode 100644 proto/pstake/liquidstake/v1beta1/tx.proto create mode 100644 x/liquidstake/abci.go create mode 100644 x/liquidstake/client/cli/query.go create mode 100644 x/liquidstake/client/cli/tx.go create mode 100644 x/liquidstake/handler.go create mode 100644 x/liquidstake/keeper/genesis.go create mode 100644 x/liquidstake/keeper/grpc_query.go create mode 100644 x/liquidstake/keeper/hooks.go create mode 100644 x/liquidstake/keeper/keeper.go create mode 100644 x/liquidstake/keeper/liquidstake.go create mode 100644 x/liquidstake/keeper/msg_server.go create mode 100644 x/liquidstake/keeper/rebalancing.go create mode 100644 x/liquidstake/module.go create mode 100644 x/liquidstake/types/codec.go create mode 100644 x/liquidstake/types/errors.go create mode 100644 x/liquidstake/types/events.go create mode 100644 x/liquidstake/types/expected_keepers.go create mode 100644 x/liquidstake/types/genesis.go create mode 100644 x/liquidstake/types/genesis.pb.go create mode 100644 x/liquidstake/types/keys.go create mode 100644 x/liquidstake/types/liquidstake.go create mode 100644 x/liquidstake/types/liquidstake.pb.go create mode 100644 x/liquidstake/types/msgs.go create mode 100644 x/liquidstake/types/params.go create mode 100644 x/liquidstake/types/query.pb.go create mode 100644 x/liquidstake/types/query.pb.gw.go create mode 100644 x/liquidstake/types/rebalancing.go create mode 100644 x/liquidstake/types/tx.pb.go diff --git a/Makefile b/Makefile index 99a5a1377..47043a23f 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,7 @@ test-docker-push: test-docker ### Protobuf ### ############################################################################### -protoVer=0.13.5 +protoVer=0.14.0 protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer) protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) diff --git a/go.mod b/go.mod index 8400aad3f..523ac8f79 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( cosmossdk.io/api v0.3.1 cosmossdk.io/errors v1.0.0 cosmossdk.io/math v1.2.0 + github.com/CosmWasm/wasmd v0.40.2 github.com/cometbft/cometbft v0.37.2 github.com/cometbft/cometbft-db v0.9.1 github.com/cosmos/cosmos-proto v1.0.0-beta.2 @@ -25,6 +26,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 + gopkg.in/yaml.v2 v2.4.0 ) require ( @@ -41,6 +43,7 @@ require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/CosmWasm/wasmvm v1.2.4 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/aws/aws-sdk-go v1.44.203 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -69,6 +72,7 @@ require ( github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect @@ -125,6 +129,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/onsi/gomega v1.27.6 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect @@ -166,7 +171,6 @@ require ( google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.6 // indirect pgregory.net/rapid v0.5.5 // indirect @@ -182,6 +186,7 @@ replace ( // use persistence's forks with LSM implemented replace ( + github.com/CosmWasm/wasmd => github.com/persistenceOne/wasmd v0.40.2-lsm3 github.com/cosmos/cosmos-sdk => github.com/persistenceOne/cosmos-sdk v0.47.3-lsm4 github.com/cosmos/ibc-go/v7 => github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm3 ) diff --git a/go.sum b/go.sum index c8bae5c1c..de63eebc9 100644 --- a/go.sum +++ b/go.sum @@ -222,6 +222,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/CosmWasm/wasmvm v1.2.4 h1:6OfeZuEcEH/9iqwrg2pkeVtDCkMoj9U6PpKtcrCyVrQ= +github.com/CosmWasm/wasmvm v1.2.4/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= @@ -455,6 +457,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= @@ -1009,6 +1013,8 @@ github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm3 h1:U4NsRXpg9VHCFVyrk1JfG+sIA3frt github.com/persistenceOne/ibc-go/v7 v7.2.0-lsm3/go.mod h1:PDvFOPEd8Fz25qBmhX7KXSPX4COyGnytKweRdEP1yfA= github.com/persistenceOne/persistence-sdk/v2 v2.1.1 h1:fo8Og2QkjsqqhH/wiEiOSB99M2Jr0kLqirU2xhJRZfQ= github.com/persistenceOne/persistence-sdk/v2 v2.1.1/go.mod h1:6ufKMowypJB865CT5Gm6Gs42YCtSkX7k3ZqKzx63y+8= +github.com/persistenceOne/wasmd v0.40.2-lsm3 h1:JdUu2TNEA+rJVYX7gt7EP/WUUA78f67joBOWtWAEShg= +github.com/persistenceOne/wasmd v0.40.2-lsm3/go.mod h1:xF6v70lqO7+Ys2wsfAHybuQXQI7IOqGf2LCq/XK8Fk8= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= diff --git a/proto/pstake/liquidstake/v1beta1/genesis.proto b/proto/pstake/liquidstake/v1beta1/genesis.proto new file mode 100644 index 000000000..e8222af3c --- /dev/null +++ b/proto/pstake/liquidstake/v1beta1/genesis.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package pstake.liquidstake.v1beta1; + +import "gogoproto/gogo.proto"; +import "pstake/liquidstake/v1beta1/liquidstake.proto"; + +option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types"; +option (gogoproto.equal_all) = true; + +// GenesisState defines the liquidstake module's genesis state. +message GenesisState { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // params defines all the parameters for the liquidstake module + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated LiquidValidator liquid_validators = 2 + [ (gogoproto.nullable) = false ]; +} diff --git a/proto/pstake/liquidstake/v1beta1/liquidstake.proto b/proto/pstake/liquidstake/v1beta1/liquidstake.proto new file mode 100644 index 000000000..7f90d244e --- /dev/null +++ b/proto/pstake/liquidstake/v1beta1/liquidstake.proto @@ -0,0 +1,191 @@ +syntax = "proto3"; + +package pstake.liquidstake.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types"; + +// Params defines the set of params for the liquidstake module. +message Params { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // LiquidBondDenom specifies the denomination of the token receiving after + // liquid stake, The value is calculated through NetAmount. + string liquid_bond_denom = 1; + + // WhitelistedValidators specifies the validators elected to become Active + // Liquid Validators. + repeated WhitelistedValidator whitelisted_validators = 2 + [ (gogoproto.nullable) = false ]; + + // UnstakeFeeRate specifies the fee rate when liquid unstake is requested, + // unbonded by subtracting it from unbondingAmount + string unstake_fee_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // LsmDisabled allows to block any msgs that convert staked tokens into + // stkXPRT through LSM. + bool lsm_disabled = 4; + + // MinLiquidStakingAmount specifies the minimum number of coins to be staked + // to the active liquid validators on liquid staking to minimize decimal loss + // and consider gas efficiency. + string min_liquid_stake_amount = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // cw_locked_pool_address defines the bech32-encoded address of + // a CW smart-contract representing a time locked LP (e.g. Superfluid LP). + string cw_locked_pool_address = 6 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; +} + +// ValidatorStatus enumerates the status of a liquid validator. +enum ValidatorStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // VALIDATOR_STATUS_UNSPECIFIED defines the unspecified invalid status. + VALIDATOR_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "ValidatorStatusUnspecified" ]; + // VALIDATOR_STATUS_ACTIVE defines the active, valid status + VALIDATOR_STATUS_ACTIVE = 1 + [ (gogoproto.enumvalue_customname) = "ValidatorStatusActive" ]; + // VALIDATOR_STATUS_INACTIVE defines the inactive, invalid status + VALIDATOR_STATUS_INACTIVE = 2 + [ (gogoproto.enumvalue_customname) = "ValidatorStatusInactive" ]; +} + +// WhitelistedValidator consists of the validator operator address and the +// target weight, which is a value for calculating the real weight to be derived +// according to the active status. In the case of inactive, it is calculated as +// zero. +message WhitelistedValidator { + option (gogoproto.goproto_getters) = false; + + // validator_address defines the bech32-encoded address that whitelisted + // validator + string validator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + ; + + // target_weight specifies the target weight for liquid staking, unstaking + // amount, which is a value for calculating the real weight to be derived + // according to the active status + string target_weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// LiquidValidator defines a Validator that can be the target of LiquidStaking +// and LiquidUnstaking, Active, Weight, etc. fields are derived as functions to +// deal with by maintaining consistency with the state of the staking module. +message LiquidValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // operator_address defines the address of the validator's operator; bech + // encoded in JSON. + string operator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; +} + +// LiquidValidatorState is type LiquidValidator with state added to return to +// query results. +message LiquidValidatorState { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // operator_address defines the address of the validator's operator; bech + // encoded in JSON. + string operator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // weight specifies the weight for liquid staking, unstaking amount + string weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // status is the liquid validator status + ValidatorStatus status = 3; + + // del_shares define the delegation shares of the validator + string del_shares = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // liquid_tokens define the token amount worth of delegation shares of the + // validator (slashing applied amount) + string liquid_tokens = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// NetAmountState is type for net amount raw data and mint rate, This is a value +// that depends on the several module state every time, so it is used only for +// calculation and query and is not stored in kv. +message NetAmountState { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = true; + + // mint_rate is stkXPRTTotalSupply / NetAmount + string mint_rate = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // btoken_total_supply returns the total supply of stk/uxprt (stkXPRT denom) + string stkxprt_total_supply = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // net_amount is proxy account's native token balance + total liquid tokens + + // total remaining rewards + total unbonding balance + string net_amount = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // total_del_shares define the delegation shares of all liquid validators + string total_del_shares = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // total_liquid_tokens define the token amount worth of delegation shares of + // all liquid validator (slashing applied amount) + string total_liquid_tokens = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // total_remaining_rewards define the sum of remaining rewards of proxy + // account by all liquid validators + string total_remaining_rewards = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // total_unbonding_balance define the unbonding balance of proxy account by + // all liquid validator (slashing applied amount) + string total_unbonding_balance = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // proxy_acc_balance define the balance of proxy account for the native token + string proxy_acc_balance = 8 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} diff --git a/proto/pstake/liquidstake/v1beta1/query.proto b/proto/pstake/liquidstake/v1beta1/query.proto new file mode 100644 index 000000000..996090909 --- /dev/null +++ b/proto/pstake/liquidstake/v1beta1/query.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; +package pstake.liquidstake.v1beta1; + +import "google/api/annotations.proto"; +import "pstake/liquidstake/v1beta1/liquidstake.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types"; + +// Query defines the gRPC query service for the liquidstake module. +service Query { + // Params returns parameters of the liquidstake module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/pstake/liquidstake/v1beta1/params"; + } + + // LiquidValidators returns liquid validators with states of the liquidstake + // module. + rpc LiquidValidators(QueryLiquidValidatorsRequest) + returns (QueryLiquidValidatorsResponse) { + option (google.api.http).get = "/pstake/liquidstake/v1beta1/validators"; + } + + // States returns states of the liquidstake module. + rpc States(QueryStatesRequest) returns (QueryStatesResponse) { + option (google.api.http).get = "/pstake/liquidstake/v1beta1/states"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +// QueryLiquidValidatorsRequest is the request type for the +// Query/LiquidValidators RPC method. +message QueryLiquidValidatorsRequest {} + +// QueryLiquidValidatorsResponse is the response type for the +// Query/LiquidValidators RPC method. +message QueryLiquidValidatorsResponse { + repeated LiquidValidatorState liquid_validators = 1 + [ (gogoproto.nullable) = false ]; +} + +// QueryStatesRequest is the request type for the Query/States RPC method. +message QueryStatesRequest {} + +// QueryStatesResponse is the response type for the Query/States RPC method. +message QueryStatesResponse { + NetAmountState net_amount_state = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/pstake/liquidstake/v1beta1/tx.proto b/proto/pstake/liquidstake/v1beta1/tx.proto new file mode 100644 index 000000000..a0c3656fb --- /dev/null +++ b/proto/pstake/liquidstake/v1beta1/tx.proto @@ -0,0 +1,102 @@ +syntax = "proto3"; +package pstake.liquidstake.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/msg/v1/msg.proto"; +import "google/protobuf/timestamp.proto"; +import "pstake/liquidstake/v1beta1/liquidstake.proto"; + +option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types"; + +// Msg defines the liquid staking Msg service. +service Msg { + // LiquidStake defines a method for performing a delegation of coins + // from a delegator to whitelisted validators. + rpc LiquidStake(MsgLiquidStake) returns (MsgLiquidStakeResponse); + + // LiquidUnstake defines a method for performing an undelegation of liquid + // staking from a delegate. + rpc LiquidUnstake(MsgLiquidUnstake) returns (MsgLiquidUnstakeResponse); + + // StakeToLP defines a method for LSM-transfer of staked XPRT + // into stkXPRT with locking into an LP. + rpc StakeToLP(MsgStakeToLP) returns (MsgStakeToLPResponse); + + // UpdateParams defines a method to update the module params. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgLiquidStake defines a SDK message for performing a liquid stake of coins +// from a delegator to whitelisted validators. +message MsgLiquidStake { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "delegator_address"; + + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; +} + +// MsgLiquidStakeResponse defines the MsgLiquidStake response type. +message MsgLiquidStakeResponse {} + +// MsgStakeToLP defines a SDK message for performing an LSM-transfer of staked +// XPRT into stkXPRT with locking into an LP. +message MsgStakeToLP { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "delegator_address"; + + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + string validator_address = 2 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + cosmos.base.v1beta1.Coin staked_amount = 3 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin liquid_amount = 4 [ (gogoproto.nullable) = false ]; +} + +// MsgStakeToLPResponse defines the MsgStakeToLP response type. +message MsgStakeToLPResponse {} + +// MsgLiquidUnstake defines a SDK message for performing an undelegation of +// liquid staking from a delegate. +message MsgLiquidUnstake { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "delegator_address"; + + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; +} + +// MsgLiquidUnstakeResponse defines the MsgLiquidUnstake response type. +message MsgLiquidUnstakeResponse { + google.protobuf.Timestamp completion_time = 1 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; +} + +message MsgUpdateParams { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "authority"; + + // authority is the address that controls the module (defaults to x/gov unless + // overwritten). + string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [ (gogoproto.nullable) = false ]; +} + +// MsgUpdateParamsResponse defines the response structure for executing a +message MsgUpdateParamsResponse {} diff --git a/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto b/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto index b322239d8..3f9321914 100644 --- a/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto +++ b/proto/pstake/liquidstakeibc/v1beta1/liquidstakeibc.proto @@ -62,9 +62,7 @@ message HostChain { HostChainFlags flags = 16; } -message HostChainFlags { - bool lsm = 1; -} +message HostChainFlags { bool lsm = 1; } message HostChainLSParams { string deposit_fee = 1 [ @@ -102,7 +100,7 @@ message HostChainLSParams { (gogoproto.nullable) = false ]; // UndelegateEntries - uint32 max_entries = 8 ; + uint32 max_entries = 8; // amount skew that is acceptable before redelegating string redelegation_acceptable_delta = 9 [ (cosmos_proto.scalar) = "cosmos.Int", @@ -120,7 +118,7 @@ message ICAAccount { } // address of the ica on the controller chain - string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string address = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; // token balance of the ica cosmos.base.v1beta1.Coin balance = 2 [ (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin", @@ -133,7 +131,8 @@ message ICAAccount { message Validator { // valoper address - string operator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string operator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; // validator status string status = 2; // validator weight in the set @@ -148,7 +147,8 @@ message Validator { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false ]; - // the validator token exchange rate, total bonded tokens divided by total shares issued + // the validator token exchange rate, total bonded tokens divided by total + // shares issued string exchange_rate = 5 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", @@ -156,7 +156,8 @@ message Validator { ]; // the unbonding epoch number when the validator transitioned into the state int64 unbonding_epoch = 6; - // whether the validator can accept delegations or not, default true for non-lsm chains + // whether the validator can accept delegations or not, default true for + // non-lsm chains bool delegable = 7; } @@ -174,9 +175,7 @@ message Deposit { // deposit target chain string chain_id = 1; - cosmos.base.v1beta1.Coin amount = 2 [ - (gogoproto.nullable) = false - ]; + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; // epoch number of the deposit int64 epoch = 3; // state @@ -199,14 +198,15 @@ message LSMDeposit { // deposit target chain string chain_id = 1; - // this is calculated when liquid staking [lsm_shares * validator_exchange_rate] + // this is calculated when liquid staking [lsm_shares * + // validator_exchange_rate] string amount = 2 [ (cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false ]; - // LSM token shares, they are mapped 1:1 with the delegator shares that are tokenized - // https://github.com/iqlusioninc/cosmos-sdk/pull/19 + // LSM token shares, they are mapped 1:1 with the delegator shares that are + // tokenized https://github.com/iqlusioninc/cosmos-sdk/pull/19 string shares = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", @@ -246,11 +246,11 @@ message Unbonding { int64 epoch_number = 2; // time when the unbonding matures and can be collected google.protobuf.Timestamp mature_time = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; // stk token amount that is burned with the unbonding - cosmos.base.v1beta1.Coin burn_amount = 4 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin burn_amount = 4 [ (gogoproto.nullable) = false ]; // host token amount that is being unbonded - cosmos.base.v1beta1.Coin unbond_amount = 5 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin unbond_amount = 5 [ (gogoproto.nullable) = false ]; // sequence id of the ibc transaction string ibc_sequence_id = 6; // state of the unbonding during the process @@ -263,11 +263,11 @@ message UserUnbonding { // epoch when the unbonding started int64 epoch_number = 2; // address which requested the unbonding - string address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string address = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; // stk token amount that is being unbonded - cosmos.base.v1beta1.Coin stk_amount = 4 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin stk_amount = 4 [ (gogoproto.nullable) = false ]; // host token amount that is being unbonded - cosmos.base.v1beta1.Coin unbond_amount = 5 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin unbond_amount = 5 [ (gogoproto.nullable) = false ]; } message ValidatorUnbonding { @@ -277,11 +277,12 @@ message ValidatorUnbonding { int64 epoch_number = 2; // time when the unbonding matures and can be collected google.protobuf.Timestamp mature_time = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; // address of the validator that is being unbonded - string validator_address = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string validator_address = 4 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; // amount unbonded from the validator - cosmos.base.v1beta1.Coin amount = 5 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin amount = 5 [ (gogoproto.nullable) = false ]; // sequence id of the ibc transaction string ibc_sequence_id = 6; } @@ -296,7 +297,6 @@ message Redelegations { repeated cosmos.staking.v1beta1.Redelegation redelegations = 2; } - message RedelegateTx { enum RedelegateTxState { diff --git a/proto/pstake/liquidstakeibc/v1beta1/msgs.proto b/proto/pstake/liquidstakeibc/v1beta1/msgs.proto index 49a4aca9e..01ce9c43a 100644 --- a/proto/pstake/liquidstakeibc/v1beta1/msgs.proto +++ b/proto/pstake/liquidstakeibc/v1beta1/msgs.proto @@ -15,19 +15,23 @@ option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc // Msg defines the liquidstakeibc services. service Msg { - rpc RegisterHostChain(MsgRegisterHostChain) returns (MsgRegisterHostChainResponse); + rpc RegisterHostChain(MsgRegisterHostChain) + returns (MsgRegisterHostChainResponse); rpc UpdateHostChain(MsgUpdateHostChain) returns (MsgUpdateHostChainResponse); rpc LiquidStake(MsgLiquidStake) returns (MsgLiquidStakeResponse) { - option (google.api.http).post = "/pstake/liquidstakeibc/v1beta1/LiquidStake"; + option (google.api.http).post = + "/pstake/liquidstakeibc/v1beta1/LiquidStake"; } rpc LiquidStakeLSM(MsgLiquidStakeLSM) returns (MsgLiquidStakeLSMResponse) { - option (google.api.http).post = "/pstake/liquidstakeibc/v1beta1/LiquidStakeLSM"; + option (google.api.http).post = + "/pstake/liquidstakeibc/v1beta1/LiquidStakeLSM"; } rpc LiquidUnstake(MsgLiquidUnstake) returns (MsgLiquidUnstakeResponse) { - option (google.api.http).post = "/pstake/liquidstakeibc/v1beta1/LiquidUnstake"; + option (google.api.http).post = + "/pstake/liquidstakeibc/v1beta1/LiquidUnstake"; } rpc Redeem(MsgRedeem) returns (MsgRedeemResponse) { @@ -44,7 +48,7 @@ message MsgRegisterHostChain { option (amino.name) = "pstake/MsgRegisterHostChain"; // authority is the address of the governance account - string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; string connection_id = 2; string deposit_fee = 3 [ @@ -87,10 +91,10 @@ message MsgUpdateHostChain { option (cosmos.msg.v1.signer) = "authority"; option (amino.name) = "pstake/MsgUpdateHostChain"; // authority is the address of the governance account - string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; string chain_id = 2; - repeated KVUpdate updates = 3 [(amino.dont_omitempty) = true]; + repeated KVUpdate updates = 3 [ (amino.dont_omitempty) = true ]; } message MsgUpdateHostChainResponse {} @@ -99,8 +103,9 @@ message MsgLiquidStake { option (cosmos.msg.v1.signer) = "delegator_address"; option (amino.name) = "pstake/MsgLiquidStake"; - string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false]; + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; } message MsgLiquidStakeResponse {} @@ -109,8 +114,11 @@ message MsgLiquidStakeLSM { option (cosmos.msg.v1.signer) = "delegator_address"; option (amino.name) = "pstake/MsgLiquidStakeLSM"; - string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - repeated cosmos.base.v1beta1.Coin delegations = 2 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + repeated cosmos.base.v1beta1.Coin delegations = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" ]; } @@ -120,8 +128,9 @@ message MsgLiquidUnstake { option (cosmos.msg.v1.signer) = "delegator_address"; option (amino.name) = "pstake/MsgLiquidUnstake"; - string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false]; + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; } message MsgLiquidUnstakeResponse {} @@ -130,8 +139,9 @@ message MsgRedeem { option (cosmos.msg.v1.signer) = "delegator_address"; option (amino.name) = "pstake/MsgRedeem"; - string delegator_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false]; + string delegator_address = 1 + [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; } message MsgRedeemResponse {} @@ -143,8 +153,9 @@ message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; option (amino.name) = "pstake/MsgUpdateParams"; - string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - Params params = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; + string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + Params params = 2 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; } message MsgUpdateParamsResponse {} diff --git a/proto/pstake/liquidstakeibc/v1beta1/params.proto b/proto/pstake/liquidstakeibc/v1beta1/params.proto index 782e3aa18..0dd960470 100644 --- a/proto/pstake/liquidstakeibc/v1beta1/params.proto +++ b/proto/pstake/liquidstakeibc/v1beta1/params.proto @@ -11,13 +11,12 @@ option go_package = "github.com/persistenceOne/pstake-native/v2/x/liquidstakeibc message Params { option (amino.name) = "pstake/x/liquidstakeibc/Params"; - string admin_address = 1 [ - (cosmos_proto.scalar) = "cosmos.AddressString" - ]; // protocol admin address + string admin_address = 1 + [ (cosmos_proto.scalar) = + "cosmos.AddressString" ]; // protocol admin address - string fee_address = 2 [ - (cosmos_proto.scalar) = "cosmos.AddressString" - ]; // protocol fee address + string fee_address = 2 [ (cosmos_proto.scalar) = + "cosmos.AddressString" ]; // protocol fee address string upper_c_value_limit = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", diff --git a/proto/pstake/liquidstakeibc/v1beta1/query.proto b/proto/pstake/liquidstakeibc/v1beta1/query.proto index 9f006348a..6e805b697 100644 --- a/proto/pstake/liquidstakeibc/v1beta1/query.proto +++ b/proto/pstake/liquidstakeibc/v1beta1/query.proto @@ -23,7 +23,8 @@ service Query { // Queries a HostChain by id. rpc HostChain(QueryHostChainRequest) returns (QueryHostChainResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/host_chain/{chain_id}"; + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/host_chain/{chain_id}"; } // Queries for all the HostChains. @@ -33,136 +34,127 @@ service Query { // Queries for all the deposits for a host chain. rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/deposits/{chain_id}"; + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/deposits/{chain_id}"; } // Queries for all the deposits for a host chain. rpc LSMDeposits(QueryLSMDepositsRequest) returns (QueryLSMDepositsResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/lsm_deposits/{chain_id}"; + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/lsm_deposits/{chain_id}"; } // Queries all unbondings for a host chain. rpc Unbondings(QueryUnbondingsRequest) returns (QueryUnbondingsResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/unbondings/{chain_id}"; + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/unbondings/{chain_id}"; } // Queries an unbonding for a host chain. rpc Unbonding(QueryUnbondingRequest) returns (QueryUnbondingResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/unbonding/{chain_id}/{epoch}"; + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/unbonding/{chain_id}/{epoch}"; } // Queries all unbondings for a delegator address. - rpc UserUnbondings(QueryUserUnbondingsRequest) returns (QueryUserUnbondingsResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/user_unbondings/{address}"; + rpc UserUnbondings(QueryUserUnbondingsRequest) + returns (QueryUserUnbondingsResponse) { + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/user_unbondings/{address}"; } // Queries all validator unbondings for a host chain. - rpc ValidatorUnbondings(QueryValidatorUnbondingRequest) returns (QueryValidatorUnbondingResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/validator_unbondings/{chain_id}"; + rpc ValidatorUnbondings(QueryValidatorUnbondingRequest) + returns (QueryValidatorUnbondingResponse) { + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/validator_unbondings/{chain_id}"; } // Queries for a host chain deposit account balance. - rpc DepositAccountBalance(QueryDepositAccountBalanceRequest) returns (QueryDepositAccountBalanceResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/deposit_account_balance/{chain_id}"; + rpc DepositAccountBalance(QueryDepositAccountBalanceRequest) + returns (QueryDepositAccountBalanceResponse) { + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/deposit_account_balance/{chain_id}"; } - // Queries for a host chain exchange rate between the host token and the stk token. - rpc ExchangeRate(QueryExchangeRateRequest) returns (QueryExchangeRateResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/exchange_rate/{chain_id}"; + // Queries for a host chain exchange rate between the host token and the stk + // token. + rpc ExchangeRate(QueryExchangeRateRequest) + returns (QueryExchangeRateResponse) { + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/exchange_rate/{chain_id}"; } - // Queries for a host chain redelegation entries on the host token delegation acct. - rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/redelegations/{chain_id}"; + // Queries for a host chain redelegation entries on the host token delegation + // acct. + rpc Redelegations(QueryRedelegationsRequest) + returns (QueryRedelegationsResponse) { + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/redelegations/{chain_id}"; } // Queries for a host chain redelegation-txs for the host token. - rpc RedelegationTx(QueryRedelegationTxRequest) returns (QueryRedelegationTxResponse) { - option (google.api.http).get = "/pstake/liquidstakeibc/v1beta1/redelegation_tx/{chain_id}"; + rpc RedelegationTx(QueryRedelegationTxRequest) + returns (QueryRedelegationTxResponse) { + option (google.api.http).get = + "/pstake/liquidstakeibc/v1beta1/redelegation_tx/{chain_id}"; } } message QueryParamsRequest {} message QueryParamsResponse { - Params params = 1 [(gogoproto.nullable) = false]; + Params params = 1 [ (gogoproto.nullable) = false ]; } -message QueryHostChainRequest { - string chain_id = 1; -} +message QueryHostChainRequest { string chain_id = 1; } message QueryHostChainResponse { - HostChain host_chain = 1 [(gogoproto.nullable) = false]; + HostChain host_chain = 1 [ (gogoproto.nullable) = false ]; } -message QueryHostChainsRequest { -} +message QueryHostChainsRequest {} -message QueryHostChainsResponse { - repeated HostChain host_chains = 1; -} +message QueryHostChainsResponse { repeated HostChain host_chains = 1; } -message QueryDepositsRequest { - string chain_id = 1; -} +message QueryDepositsRequest { string chain_id = 1; } -message QueryDepositsResponse { - repeated Deposit deposits = 1; -} +message QueryDepositsResponse { repeated Deposit deposits = 1; } -message QueryLSMDepositsRequest { - string chain_id = 1; -} +message QueryLSMDepositsRequest { string chain_id = 1; } -message QueryLSMDepositsResponse { - repeated LSMDeposit deposits = 1; -} +message QueryLSMDepositsResponse { repeated LSMDeposit deposits = 1; } -message QueryUnbondingsRequest { - string chain_id = 1; -} +message QueryUnbondingsRequest { string chain_id = 1; } -message QueryUnbondingsResponse { - repeated Unbonding unbondings = 1; -} +message QueryUnbondingsResponse { repeated Unbonding unbondings = 1; } message QueryUnbondingRequest { string chain_id = 1; int64 epoch = 2; } -message QueryUnbondingResponse { - Unbonding unbonding = 1; -} +message QueryUnbondingResponse { Unbonding unbonding = 1; } -message QueryUserUnbondingsRequest { - string address = 1; -} +message QueryUserUnbondingsRequest { string address = 1; } message QueryUserUnbondingsResponse { repeated UserUnbonding user_unbondings = 1; } -message QueryValidatorUnbondingRequest { - string chain_id = 1; -} +message QueryValidatorUnbondingRequest { string chain_id = 1; } message QueryValidatorUnbondingResponse { repeated ValidatorUnbonding validator_unbondings = 1; } -message QueryDepositAccountBalanceRequest { - string chain_id = 1; -} +message QueryDepositAccountBalanceRequest { string chain_id = 1; } message QueryDepositAccountBalanceResponse { - cosmos.base.v1beta1.Coin balance = 1 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin balance = 1 [ (gogoproto.nullable) = false ]; } -message QueryExchangeRateRequest { - string chain_id = 1; -} +message QueryExchangeRateRequest { string chain_id = 1; } message QueryExchangeRateResponse { string rate = 1 [ @@ -172,18 +164,14 @@ message QueryExchangeRateResponse { ]; } -message QueryRedelegationsRequest { - string chain_id = 1; -} +message QueryRedelegationsRequest { string chain_id = 1; } message QueryRedelegationsResponse { - liquidstakeibc.v1beta1.Redelegations redelegations = 1 ; + liquidstakeibc.v1beta1.Redelegations redelegations = 1; } -message QueryRedelegationTxRequest { - string chain_id = 1; -} +message QueryRedelegationTxRequest { string chain_id = 1; } message QueryRedelegationTxResponse { - repeated liquidstakeibc.v1beta1.RedelegateTx redelegation_tx = 1 ; + repeated liquidstakeibc.v1beta1.RedelegateTx redelegation_tx = 1; } diff --git a/proto/pstake/lscosmos/v1beta1/query.proto b/proto/pstake/lscosmos/v1beta1/query.proto index 5fcc859af..1ca5fb55f 100644 --- a/proto/pstake/lscosmos/v1beta1/query.proto +++ b/proto/pstake/lscosmos/v1beta1/query.proto @@ -88,7 +88,7 @@ service Query { rpc DelegatorUnbondingEpochEntry(QueryDelegatorUnbondingEpochEntryRequest) returns (QueryDelegatorUnbondingEpochEntryResponse) { option (google.api.http).get = - "/pstake/lscosmos/v1beta1/delegator_unbonding_epoch_entry/" + "/pstake/lscosmos/v1beta1/delegator_unbonding_epoch_entry/" "{delegator_address}/{epoch_number}"; } @@ -107,7 +107,7 @@ service Query { QueryAllDelegatorUnbondingEpochEntriesRequest) returns (QueryAllDelegatorUnbondingEpochEntriesResponse) { option (google.api.http).get = - "/pstake/lscosmos/v1beta1/delegator_unbonding_epoch_entries/" + "/pstake/lscosmos/v1beta1/delegator_unbonding_epoch_entries/" "{delegator_address}"; } } @@ -118,17 +118,16 @@ message QueryParamsRequest {} // QueryParamsResponse is response type for the Query/Params RPC method. message QueryParamsResponse { // params holds all the parameters of this module. - Params params = 1 [(gogoproto.nullable) = false]; + Params params = 1 [ (gogoproto.nullable) = false ]; } - // QueryAllStateRequest is request type for the Query/AllState RPC method. message QueryAllStateRequest {} // QueryAllStateResponse is response type for the Query/AllState RPC method. message QueryAllStateResponse { // params holds all the parameters of this module. - GenesisState genesis = 1 [(gogoproto.nullable) = false]; + GenesisState genesis = 1 [ (gogoproto.nullable) = false ]; } // QueryHostChainParamsRequest is request for the Ouery/HostChainParams methods. @@ -137,7 +136,7 @@ message QueryHostChainParamsRequest {} // QueryHostChainParamsResponse is response for the Ouery/HostChainParams // methods. message QueryHostChainParamsResponse { - HostChainParams host_chain_params = 1 [(gogoproto.nullable) = false]; + HostChainParams host_chain_params = 1 [ (gogoproto.nullable) = false ]; } // QueryDelegationStateRequest is request for the Ouery/DelegationState methods. @@ -146,7 +145,7 @@ message QueryDelegationStateRequest {} // QueryDelegationStateResponse is response for the Ouery/DelegationState // methods. message QueryDelegationStateResponse { - DelegationState delegation_state = 1 [(gogoproto.nullable) = false]; + DelegationState delegation_state = 1 [ (gogoproto.nullable) = false ]; } // QueryListedValidatorsRequest is a request for the Query/AllowListedValidators @@ -157,7 +156,7 @@ message QueryAllowListedValidatorsRequest {} // Query/AllowListedValidators methods. message QueryAllowListedValidatorsResponse { AllowListedValidators allow_listed_validators = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryCValueRequest is a request for the Query/CValue methods. @@ -175,7 +174,7 @@ message QueryCValueResponse { message QueryModuleStateRequest {} // QueryModuleStateRequest is a response for the Query/ModuleState methods. -message QueryModuleStateResponse {bool module_state = 1;} +message QueryModuleStateResponse { bool module_state = 1; } // QueryIBCTransientStoreRequest is a request for the Query/IBCTransientStore // methods. @@ -185,58 +184,58 @@ message QueryIBCTransientStoreRequest {} // methods. message QueryIBCTransientStoreResponse { IBCAmountTransientStore i_b_c_transient_store = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryUnclaimedRequest is a request for the Query/Unclaimed methods. -message QueryUnclaimedRequest {string delegator_address = 1;} +message QueryUnclaimedRequest { string delegator_address = 1; } // QueryUnclaimedResponse is a response for the Query/Unclaimed methods. message QueryUnclaimedResponse { - repeated UnbondingEpochCValue unclaimed = 1 [(gogoproto.nullable) = false]; + repeated UnbondingEpochCValue unclaimed = 1 [ (gogoproto.nullable) = false ]; } // QueryFailedUnbondingsRequest is a request for the Query/FailedUnbondings // methods. -message QueryFailedUnbondingsRequest {string delegator_address = 1;} +message QueryFailedUnbondingsRequest { string delegator_address = 1; } // QueryFailedUnbondingsResponse a response for the Query/FailedUnbondings // methods. message QueryFailedUnbondingsResponse { repeated UnbondingEpochCValue failed_unbondings = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryPendingUnbondingsRequest is a request for the Query/PendingUnbondings // methods. -message QueryPendingUnbondingsRequest {string delegator_address = 1;} +message QueryPendingUnbondingsRequest { string delegator_address = 1; } // QueryPendingUnbondingsResponse is a response for the Query/PendingUnbondings // methods. message QueryPendingUnbondingsResponse { repeated UnbondingEpochCValue pending_unbondings = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryUnbondingEpochCValueRequest is a request for the // Query/UnbondingEpochCValue methods. -message QueryUnbondingEpochCValueRequest {int64 epoch_number = 1;} +message QueryUnbondingEpochCValueRequest { int64 epoch_number = 1; } // QueryUnbondingEpochCValueResponse is a response for the // Query/UnbondingEpochCValue methods. message QueryUnbondingEpochCValueResponse { UnbondingEpochCValue unbonding_epoch_c_value = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryHostAccountUndelegationRequest is a request for the // Query/HostAccountUndelegation methods. -message QueryHostAccountUndelegationRequest {int64 epoch_number = 1;} +message QueryHostAccountUndelegationRequest { int64 epoch_number = 1; } // QueryHostAccountUndelegationResponse is a response for the // Query/HostAccountUndelegation methods. message QueryHostAccountUndelegationResponse { HostAccountUndelegation host_account_undelegation = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryDelegatorUnbondingEpochEntryRequest is a request for the @@ -250,7 +249,7 @@ message QueryDelegatorUnbondingEpochEntryRequest { // Query/DelegatorUnbondingEpochEntry methods. message QueryDelegatorUnbondingEpochEntryResponse { DelegatorUnbondingEpochEntry delegator_unboding_epoch_entry = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } // QueryHostAccountsRequest is a request for the Query/HostAccounts methods. @@ -258,7 +257,7 @@ message QueryHostAccountsRequest {} // QueryHostAccountsResponse is a response for the Query/HostAccounts methods. message QueryHostAccountsResponse { - HostAccounts host_accounts = 1 [(gogoproto.nullable) = false]; + HostAccounts host_accounts = 1 [ (gogoproto.nullable) = false ]; } // QueryDepositModuleAccountRequest is a request for the @@ -268,7 +267,7 @@ message QueryDepositModuleAccountRequest {} // QueryDepositModuleAccountResponse is a response for the // Query/DepositModuleAccount methods. message QueryDepositModuleAccountResponse { - cosmos.base.v1beta1.Coin balance = 1 [(gogoproto.nullable) = false]; + cosmos.base.v1beta1.Coin balance = 1 [ (gogoproto.nullable) = false ]; } // QueryAllDelegatorUnbondingEpochEntriesRequest is a request for the @@ -281,5 +280,5 @@ message QueryAllDelegatorUnbondingEpochEntriesRequest { // Query/DelegatorUnbondingEpochEntries methods. message QueryAllDelegatorUnbondingEpochEntriesResponse { repeated DelegatorUnbondingEpochEntry delegator_unbonding_epoch_entries = 1 - [(gogoproto.nullable) = false]; + [ (gogoproto.nullable) = false ]; } diff --git a/x/liquidstake/abci.go b/x/liquidstake/abci.go new file mode 100644 index 000000000..e6cfce743 --- /dev/null +++ b/x/liquidstake/abci.go @@ -0,0 +1,21 @@ +package liquidstake + +import ( + "time" + + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/keeper" + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// BeginBlocker updates liquid validator set changes for the current block +func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) + + k.UpdateLiquidValidatorSet(ctx) + + whitelistedValsMap := types.GetWhitelistedValsMap(k.GetParams(ctx).WhitelistedValidators) + k.AutocompoundStakingRewards(ctx, whitelistedValsMap) +} diff --git a/x/liquidstake/client/cli/query.go b/x/liquidstake/client/cli/query.go new file mode 100644 index 000000000..e3e940f03 --- /dev/null +++ b/x/liquidstake/client/cli/query.go @@ -0,0 +1,156 @@ +package cli + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/version" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// GetQueryCmd returns a root CLI command handler for all x/liquidstake query commands. +func GetQueryCmd() *cobra.Command { + liquidValidatorQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Aliases: []string{"ls"}, + Short: "Querying commands for the liquidstake module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + liquidValidatorQueryCmd.AddCommand( + GetCmdQueryParams(), + GetCmdQueryLiquidValidators(), + GetCmdQueryStates(), + ) + + return liquidValidatorQueryCmd +} + +// GetCmdQueryParams implements the params query command. +func GetCmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Args: cobra.NoArgs, + Short: "Query the values set as liquidstake parameters", + Long: strings.TrimSpace( + fmt.Sprintf(`Query values set as liquidstake parameters. + +Example: +$ %s query %s params +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.Params( + cmd.Context(), + &types.QueryParamsRequest{}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(&res.Params) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryLiquidValidators implements the query liquidValidators command. +func GetCmdQueryLiquidValidators() *cobra.Command { + cmd := &cobra.Command{ + Use: "liquid-validators", + Args: cobra.NoArgs, + Short: "Query all liquid validators", + Long: strings.TrimSpace( + fmt.Sprintf(`Queries all liquid validators. + +Example: +$ %s query %s liquid-validators +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + if err != nil { + return err + } + + res, err := queryClient.LiquidValidators( + cmd.Context(), + &types.QueryLiquidValidatorsRequest{}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryStates implements the query states command. +func GetCmdQueryStates() *cobra.Command { + cmd := &cobra.Command{ + Use: "states", + Args: cobra.NoArgs, + Short: "Query states", + Long: strings.TrimSpace( + fmt.Sprintf(`Queries states about net amount, mint rate. + +Example: +$ %s query %s states +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.States( + cmd.Context(), + &types.QueryStatesRequest{}, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/liquidstake/client/cli/tx.go b/x/liquidstake/client/cli/tx.go new file mode 100644 index 000000000..2cd697087 --- /dev/null +++ b/x/liquidstake/client/cli/tx.go @@ -0,0 +1,238 @@ +package cli + +// DONTCOVER +// client is excluded from test coverage in MVP version + +import ( + "encoding/json" + "fmt" + "os" + "strings" + + "github.com/spf13/cobra" + + "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" + "github.com/cosmos/cosmos-sdk/version" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// GetTxCmd returns a root CLI command handler for all x/liquidstake transaction commands. +func GetTxCmd() *cobra.Command { + liquidstakeTxCmd := &cobra.Command{ + Use: types.ModuleName, + Aliases: []string{"ls"}, + Short: "XPRT liquid stake transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + liquidstakeTxCmd.AddCommand( + NewLiquidStakeCmd(), + NewStakeToLPCmd(), + NewLiquidUnstakeCmd(), + NewUpdateParamsCmd(), + ) + + return liquidstakeTxCmd +} + +// NewLiquidStakeCmd implements the liquid stake XPRT command handler. +func NewLiquidStakeCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "liquid-stake [amount]", + Args: cobra.ExactArgs(1), + Short: "Liquid-stake XPRT", + Long: strings.TrimSpace( + fmt.Sprintf(`Liquid-stake XPRT. + +Example: +$ %s tx %s liquid-stake 1000uxprt --from mykey +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + liquidStaker := clientCtx.GetFromAddress() + + stakingCoin, err := sdk.ParseCoinNormalized(args[0]) + if err != nil { + return err + } + + msg := types.NewMsgLiquidStake(liquidStaker, stakingCoin) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// NewStakeToLPCmd implements the liquid stake XPRT command handler. +func NewStakeToLPCmd() *cobra.Command { + bech32PrefixValAddr := sdk.GetConfig().GetBech32ValidatorAddrPrefix() + + cmd := &cobra.Command{ + Use: "stake-to-lp [validator-addr] [staked_amount] [liquid_amount]", + Args: cobra.RangeArgs(2, 3), + Short: "Convert delegation into stkXPRT and lock into LP.", + Long: strings.TrimSpace( + fmt.Sprintf(`Convert delegation into stkXPRT and lock into LP. +Allows to specify both staked and non-staked XPRT amounts to convert into stkXPRT and lock into LP. + +Examples: +$ %s tx %s stake-to-lp %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 1000uxprt --from mykey +$ %s tx %s stake-to-lp %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 1000uxprt 5000uxprt --from mykey +`, + version.AppName, types.ModuleName, bech32PrefixValAddr, + version.AppName, types.ModuleName, bech32PrefixValAddr, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + liquidStaker := clientCtx.GetFromAddress() + + valAddr, err := sdk.ValAddressFromBech32(args[0]) + if err != nil { + return err + } + + stakedCoin, err := sdk.ParseCoinNormalized(args[1]) + if err != nil { + return err + } + + var liquidCoin sdk.Coin + if len(args) > 2 { + liquidCoin, err = sdk.ParseCoinNormalized(args[2]) + if err != nil { + return err + } + } + + msg := types.NewMsgStakeToLP(liquidStaker, valAddr, stakedCoin, liquidCoin) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// NewLiquidUnstakeCmd implements the liquid unstake XPRT command handler. +func NewLiquidUnstakeCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "liquid-unstake [amount]", + Args: cobra.ExactArgs(1), + Short: "Liquid-unstake stkXPRT", + Long: strings.TrimSpace( + fmt.Sprintf(`Liquid-unstake stkXPRT. + +Example: +$ %s tx %s liquid-unstake 500stk/uxprt --from mykey +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + liquidStaker := clientCtx.GetFromAddress() + + unstakingCoin, err := sdk.ParseCoinNormalized(args[0]) + if err != nil { + return err + } + + msg := types.NewMsgLiquidUnstake(liquidStaker, unstakingCoin) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// NewUpdateParamsCmd implements the liquid unstake coin command handler. +func NewUpdateParamsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-params [params.json]", + Args: cobra.ExactArgs(1), + Short: "Update-params of liquidstake module.", + Long: strings.TrimSpace( + fmt.Sprintf(`update-params param-file. + +Example: +$ %s tx %s update-params ~/params.json --from mykey + +Example params.json +{ + "liquid_bond_denom": "stk/uxprt", + "whitelisted_validators": [ + { + "validator_address": "persistencevaloper1hcqg5wj9t42zawqkqucs7la85ffyv08lmnhye9", + "target_weight": "10" + } + ], + "lsm_disabled": false, + "unstake_fee_rate": "0.000000000000000000", + "min_liquid_staking_amount": "10000", + "min_liquid_staking_amount": "10000", + "cw_locked_pool_address": "persistence14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjvz4fk" +} +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + var params types.Params + + paramsInFile, err := os.ReadFile(args[0]) + if err != nil { + return err + } + + err = json.Unmarshal(paramsInFile, ¶ms) + if err != nil { + return err + } + authority := clientCtx.GetFromAddress() + + msg := types.NewMsgUpdateParams(authority, params) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/liquidstake/handler.go b/x/liquidstake/handler.go new file mode 100644 index 000000000..21c9253e1 --- /dev/null +++ b/x/liquidstake/handler.go @@ -0,0 +1,35 @@ +package liquidstake + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/keeper" + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// NewHandler returns a new msg handler. +func NewHandler(k keeper.Keeper) sdk.Handler { + msgServer := keeper.NewMsgServerImpl(k) + + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case *types.MsgLiquidStake: + res, err := msgServer.LiquidStake(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + + case *types.MsgLiquidUnstake: + res, err := msgServer.LiquidUnstake(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + + case *types.MsgUpdateParams: + res, err := msgServer.UpdateParams(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) + } + } +} diff --git a/x/liquidstake/keeper/genesis.go b/x/liquidstake/keeper/genesis.go new file mode 100644 index 000000000..1793ae34a --- /dev/null +++ b/x/liquidstake/keeper/genesis.go @@ -0,0 +1,42 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// InitGenesis initializes the liquidstake module's state from a given genesis state. +func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { + if err := types.ValidateGenesis(genState); err != nil { + panic(err) + } + // init to prevent nil slice, []types.WhitelistedValidator(nil) + if genState.Params.WhitelistedValidators == nil || len(genState.Params.WhitelistedValidators) == 0 { + genState.Params.WhitelistedValidators = []types.WhitelistedValidator{} + } + k.SetParams(ctx, genState.Params) + + for _, lv := range genState.LiquidValidators { + k.SetLiquidValidator(ctx, lv) + } + + moduleAcc := k.accountKeeper.GetModuleAccount(ctx, types.ModuleName) + if moduleAcc == nil { + panic(fmt.Sprintf("%s module account has not been set", types.ModuleName)) + } +} + +// ExportGenesis returns the liquidstake module's genesis state. +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + params := k.GetParams(ctx) + // init to prevent nil slice, []types.WhitelistedValidator(nil) + if params.WhitelistedValidators == nil || len(params.WhitelistedValidators) == 0 { + params.WhitelistedValidators = []types.WhitelistedValidator{} + } + + liquidValidators := k.GetAllLiquidValidators(ctx) + return types.NewGenesisState(params, liquidValidators) +} diff --git a/x/liquidstake/keeper/grpc_query.go b/x/liquidstake/keeper/grpc_query.go new file mode 100644 index 000000000..63a242871 --- /dev/null +++ b/x/liquidstake/keeper/grpc_query.go @@ -0,0 +1,50 @@ +package keeper + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper. +type Querier struct { + Keeper +} + +var _ types.QueryServer = Querier{} + +// Params queries the parameters of the liquidstake module. +func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + params := k.GetParams(ctx) + + return &types.QueryParamsResponse{Params: params}, nil +} + +// LiquidValidators queries all liquid validators. +func (k Querier) LiquidValidators(c context.Context, req *types.QueryLiquidValidatorsRequest) (*types.QueryLiquidValidatorsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + + return &types.QueryLiquidValidatorsResponse{LiquidValidators: k.GetAllLiquidValidatorStates(ctx)}, nil +} + +// States queries states of liquid staking module. +func (k Querier) States(c context.Context, req *types.QueryStatesRequest) (*types.QueryStatesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + + return &types.QueryStatesResponse{NetAmountState: k.GetNetAmountState(ctx)}, nil +} diff --git a/x/liquidstake/keeper/hooks.go b/x/liquidstake/keeper/hooks.go new file mode 100644 index 000000000..44fe49d27 --- /dev/null +++ b/x/liquidstake/keeper/hooks.go @@ -0,0 +1,22 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +// Wrapper struct +type Hooks struct { + k Keeper +} + +var _ govtypes.GovHooks = Hooks{} + +// Create new distribution hooks +func (k Keeper) Hooks() Hooks { return Hooks{k} } + +func (h Hooks) AfterProposalSubmission(_ sdk.Context, _ uint64) {} +func (h Hooks) AfterProposalDeposit(_ sdk.Context, _ uint64, _ sdk.AccAddress) {} +func (h Hooks) AfterProposalVote(_ sdk.Context, _ uint64, _ sdk.AccAddress) {} +func (h Hooks) AfterProposalFailedMinDeposit(_ sdk.Context, _ uint64) {} +func (h Hooks) AfterProposalVotingPeriodEnded(_ sdk.Context, _ uint64) {} diff --git a/x/liquidstake/keeper/keeper.go b/x/liquidstake/keeper/keeper.go new file mode 100644 index 000000000..91fafc4ba --- /dev/null +++ b/x/liquidstake/keeper/keeper.go @@ -0,0 +1,97 @@ +package keeper + +import ( + "fmt" + + "github.com/cometbft/cometbft/libs/log" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +// Keeper of the liquidstake store +type Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper + stakingKeeper types.StakingKeeper + distrKeeper types.DistrKeeper + slashingKeeper types.SlashingKeeper + + router *baseapp.MsgServiceRouter + authority string +} + +// NewKeeper returns a liquidstake keeper. +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + stakingKeeper types.StakingKeeper, + distrKeeper types.DistrKeeper, + slashingKeeper types.SlashingKeeper, + router *baseapp.MsgServiceRouter, + authority string, +) Keeper { + // ensure liquidstake module account is set + if addr := accountKeeper.GetModuleAddress(types.ModuleName); addr == nil { + panic(fmt.Sprintf("%s module account has not been set", types.ModuleName)) + } + + return Keeper{ + cdc: cdc, + storeKey: storeKey, + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + stakingKeeper: stakingKeeper, + distrKeeper: distrKeeper, + slashingKeeper: slashingKeeper, + router: router, + authority: authority, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", "x/"+types.ModuleName) +} + +// SetParams sets the auth module's parameters. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { + if err := params.Validate(); err != nil { + return err + } + + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set(types.ParamsKey, bz) + + return nil +} + +// GetParams gets the auth module's parameters. +func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { + store := ctx.KVStore(k.storeKey) + + bz := store.Get(types.ParamsKey) + if bz == nil { + return params + } + + k.cdc.MustUnmarshal(bz, ¶ms) + return params +} + +// GetCodec return codec.Codec object used by the keeper +func (k Keeper) GetCodec() codec.BinaryCodec { return k.cdc } + +// Router returns the keeper's msg router +func (k Keeper) Router() *baseapp.MsgServiceRouter { + return k.router +} diff --git a/x/liquidstake/keeper/liquidstake.go b/x/liquidstake/keeper/liquidstake.go new file mode 100644 index 000000000..5112bbc11 --- /dev/null +++ b/x/liquidstake/keeper/liquidstake.go @@ -0,0 +1,646 @@ +package keeper + +import ( + "encoding/json" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +func (k Keeper) LiquidBondDenom(ctx sdk.Context) string { + return k.GetParams(ctx).LiquidBondDenom +} + +// GetNetAmountState calculates the sum of bondedDenom balance, total delegation tokens(slash applied LiquidTokens), total remaining reward of types.LiquidStakeProxyAcc +// During liquid unstaking, stkxprt immediately burns and the unbonding queue belongs to the requester, so the liquid staker's unbonding values are excluded on netAmount +// It is used only for calculation and query and is not stored in kv. +func (k Keeper) GetNetAmountState(ctx sdk.Context) (nas types.NetAmountState) { + totalRemainingRewards, totalDelShares, totalLiquidTokens := k.CheckDelegationStates(ctx, types.LiquidStakeProxyAcc) + + totalUnbondingBalance := sdk.ZeroInt() + ubds := k.stakingKeeper.GetAllUnbondingDelegations(ctx, types.LiquidStakeProxyAcc) + for _, ubd := range ubds { + for _, entry := range ubd.Entries { + // use Balance(slashing applied) not InitialBalance(without slashing) + totalUnbondingBalance = totalUnbondingBalance.Add(entry.Balance) + } + } + + nas = types.NetAmountState{ + StkxprtTotalSupply: k.bankKeeper.GetSupply(ctx, k.LiquidBondDenom(ctx)).Amount, + TotalDelShares: totalDelShares, + TotalLiquidTokens: totalLiquidTokens, + TotalRemainingRewards: totalRemainingRewards, + TotalUnbondingBalance: totalUnbondingBalance, + ProxyAccBalance: k.GetProxyAccBalance(ctx, types.LiquidStakeProxyAcc).Amount, + } + + nas.NetAmount = nas.CalcNetAmount() + nas.MintRate = nas.CalcMintRate() + return +} + +// LiquidStake mints stkXPRT worth of staking coin value according to NetAmount and performs LiquidDelegate. +func (k Keeper) LiquidStake( + ctx sdk.Context, proxyAcc, liquidStaker sdk.AccAddress, stakingCoin sdk.Coin) (newShares sdk.Dec, stkXPRTMintAmount math.Int, err error) { + params := k.GetParams(ctx) + + // check minimum liquid staking amount + if stakingCoin.Amount.LT(params.MinLiquidStakeAmount) { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrLessThanMinLiquidStakeAmount + } + + // check bond denomination + bondDenom := k.stakingKeeper.BondDenom(ctx) + if stakingCoin.Denom != bondDenom { + return sdk.ZeroDec(), sdk.ZeroInt(), sdkerrors.Wrapf( + types.ErrInvalidBondDenom, "invalid coin denomination: got %s, expected %s", stakingCoin.Denom, bondDenom, + ) + } + + whitelistedValsMap := types.GetWhitelistedValsMap(params.WhitelistedValidators) + activeVals := k.GetActiveLiquidValidators(ctx, whitelistedValsMap) + if activeVals.Len() == 0 || !activeVals.TotalWeight(whitelistedValsMap).IsPositive() { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrActiveLiquidValidatorsNotExists + } + + // NetAmount must be calculated before send + nas := k.GetNetAmountState(ctx) + + // send staking coin to liquid staking proxy account to proxy delegation, need sufficient spendable balances + err = k.bankKeeper.SendCoins(ctx, liquidStaker, proxyAcc, sdk.NewCoins(stakingCoin)) + if err != nil { + return sdk.ZeroDec(), sdk.ZeroInt(), err + } + + // mint stkxprt, MintAmount = TotalSupply * StakeAmount/NetAmount + liquidBondDenom := k.LiquidBondDenom(ctx) + stkXPRTMintAmount = stakingCoin.Amount + if nas.StkxprtTotalSupply.IsPositive() { + stkXPRTMintAmount = types.NativeTokenToStkXPRT(stakingCoin.Amount, nas.StkxprtTotalSupply, nas.NetAmount) + } + + if !stkXPRTMintAmount.IsPositive() { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrTooSmallLiquidStakeAmount + } + + // mint on module acc and send + mintCoin := sdk.NewCoins(sdk.NewCoin(liquidBondDenom, stkXPRTMintAmount)) + err = k.bankKeeper.MintCoins(ctx, types.ModuleName, mintCoin) + if err != nil { + return sdk.ZeroDec(), stkXPRTMintAmount, err + } + err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, liquidStaker, mintCoin) + if err != nil { + return sdk.ZeroDec(), stkXPRTMintAmount, err + } + + newShares, err = k.LiquidDelegate(ctx, proxyAcc, activeVals, stakingCoin.Amount, whitelistedValsMap) + return newShares, stkXPRTMintAmount, err +} + +// LockOnLP sends tokens to CW contract (Superfluid LP) with time locking. +// It performs a CosmWasm execution through global message handler and may fail. +// Emits events on a successfull call. +func (k Keeper) LockOnLP(ctx sdk.Context, delegator sdk.AccAddress, amount sdk.Coin) ([]byte, error) { + params := k.GetParams(ctx) + + if len(params.CwLockedPoolAddress) == 0 { + return nil, types.ErrNoLPContractAddress + } else if amount.Denom != params.LiquidBondDenom { + return nil, types.ErrInvalidDenom.Wrapf("cannot lock any denom on LP except liquid bond denom: %s", params.LiquidBondDenom) + } + + msg := &LockLstAssetForUserMsg{ + Asset: Asset{ + Amount: amount.Amount.String(), + Info: AssetInfo{ + NativeToken: NativeTokenInfo{ + Denom: amount.Denom, + }, + }, + }, + + User: delegator.String(), + } + + callData, err := json.Marshal(&ExecMsg{ + LockLstAssetForUser: msg, + }) + if err != nil { + panic("failed to marshal CW contract call LockLstAssetForUser") + } + + cwMsg := &wasmtypes.MsgExecuteContract{ + Sender: delegator.String(), + Contract: k.GetParams(ctx).CwLockedPoolAddress, + Msg: wasmtypes.RawContractMessage(callData), + Funds: sdk.NewCoins(amount), + } + + handler := k.router.Handler(cwMsg) + if handler == nil { + return nil, sdkerrors.ErrUnknownRequest.Wrapf("unrecognized message route: %s", sdk.MsgTypeURL(cwMsg)) + } + + msgResp, err := handler(ctx, cwMsg) + if err != nil { + return nil, types.ErrLPContract.Wrapf("error: %s, message %v", err.Error(), cwMsg) + } + + // emit the events from the dispatched actions + events := msgResp.Events + sdkEvents := make([]sdk.Event, 0, len(events)) + for _, event := range events { + e := event + sdkEvents = append(sdkEvents, sdk.Event(e)) + } + + ctx.EventManager().EmitEvents(sdkEvents) + + return msgResp.Data, nil +} + +type ExecMsg struct { + LockLstAssetForUser *LockLstAssetForUserMsg `json:"lock_lst_asset_for_user,omitmepty"` +} + +type LockLstAssetForUserMsg struct { + Asset Asset `json:"asset"` + User string `json:"user"` +} + +type Asset struct { + Amount string `json:"amount"` + Info AssetInfo `json:"info"` +} + +type AssetInfo struct { + NativeToken NativeTokenInfo `json:"native_token"` +} + +type NativeTokenInfo struct { + Denom string `json:"denom"` +} + +// LSMDelegate captures a staked amount from existing delegation using LSM, re-stakes from proxyAcc and +// mints stkXPRT worth of stk coin value according to NetAmount and performs LiquidDelegate. +func (k Keeper) LSMDelegate( + ctx sdk.Context, + delegator sdk.AccAddress, + validator sdk.ValAddress, + proxyAcc sdk.AccAddress, + stakingCoin sdk.Coin, +) (newShares sdk.Dec, stkXPRTMintAmount math.Int, err error) { + params := k.GetParams(ctx) + + if params.LsmDisabled { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrDisabledLSM + } + + // check minimum liquid staking amount + if stakingCoin.Amount.LT(params.MinLiquidStakeAmount) { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrLessThanMinLiquidStakeAmount + } + + // check bond denomination + bondDenom := k.stakingKeeper.BondDenom(ctx) + if stakingCoin.Denom != bondDenom { + return sdk.ZeroDec(), sdk.ZeroInt(), sdkerrors.Wrapf( + types.ErrInvalidBondDenom, "invalid coin denomination: got %s, expected %s", stakingCoin.Denom, bondDenom, + ) + } + + whitelistedValsMap := types.GetWhitelistedValsMap(params.WhitelistedValidators) + activeVals := k.GetActiveLiquidValidators(ctx, whitelistedValsMap) + if activeVals.Len() == 0 || !activeVals.TotalWeight(whitelistedValsMap).IsPositive() { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrActiveLiquidValidatorsNotExists + } + + if !whitelistedValsMap.IsListed(validator.String()) { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrLiquidValidatorsNotExists.Wrap("delegation from a non allowed validator") + } + + // NetAmount must be calculated before send + nas := k.GetNetAmountState(ctx) + + // perform an LSM tokenize->bank send->redeem flow: moving delegation from user's account onto proxyAcc + + lsmTokenizeMsg := &stakingtypes.MsgTokenizeShares{ + DelegatorAddress: delegator.String(), + ValidatorAddress: validator.String(), + Amount: stakingCoin, + TokenizedShareOwner: proxyAcc.String(), + } + + handler := k.router.Handler(lsmTokenizeMsg) + if handler == nil { + return sdk.ZeroDec(), sdk.ZeroInt(), sdkerrors.ErrUnknownRequest.Wrapf("unrecognized message route: %s", sdk.MsgTypeURL(lsmTokenizeMsg)) + } + + // [1] tokenize delegation into LSM shares + msgResp, err := handler(ctx, lsmTokenizeMsg) + if err != nil { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrLSMTokenizeFailed.Wrapf("error: %s; message: %v", err.Error(), lsmTokenizeMsg) + } + + var lsmTokenizeResp stakingtypes.MsgTokenizeSharesResponse + if err := k.cdc.Unmarshal(msgResp.Data, &lsmTokenizeResp); err != nil { + panic("wrong data type: " + err.Error()) + } + + // [2] send LSM shares to proxyAcc + err = k.bankKeeper.SendCoins(ctx, delegator, proxyAcc, sdk.NewCoins(lsmTokenizeResp.Amount)) + if err != nil { + return sdk.ZeroDec(), stkXPRTMintAmount, err + } + + lsmRedeemMsg := &stakingtypes.MsgRedeemTokensForShares{ + DelegatorAddress: proxyAcc.String(), + Amount: lsmTokenizeResp.Amount, + } + + handler = k.router.Handler(lsmRedeemMsg) + if handler == nil { + return sdk.ZeroDec(), sdk.ZeroInt(), sdkerrors.ErrUnknownRequest.Wrapf("unrecognized message route: %s", sdk.MsgTypeURL(lsmRedeemMsg)) + } + + // [3] redeem LSM shares from proxyAcc, to obtain a delegation + msgResp, err = handler(ctx, lsmRedeemMsg) + if err != nil { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrLSMRedeemFailed.Wrapf("error: %s; message: %v", err.Error(), lsmRedeemMsg) + } + + var lsmRedeemResp stakingtypes.MsgRedeemTokensForSharesResponse + if err := k.cdc.Unmarshal(msgResp.Data, &lsmRedeemResp); err != nil { + panic("wrong data type: " + err.Error()) + } + + // obtained newShares from LSM + newShares = lsmRedeemResp.Amount.Amount.ToLegacyDec() + + // mint stkxprt, MintAmount = TotalSupply * StakeAmount/NetAmount + liquidBondDenom := k.LiquidBondDenom(ctx) + stkXPRTMintAmount = stakingCoin.Amount + if nas.StkxprtTotalSupply.IsPositive() { + stkXPRTMintAmount = types.NativeTokenToStkXPRT(stakingCoin.Amount, nas.StkxprtTotalSupply, nas.NetAmount) + } + + if !stkXPRTMintAmount.IsPositive() { + return sdk.ZeroDec(), sdk.ZeroInt(), types.ErrTooSmallLiquidStakeAmount + } + + // mint stkXPRT on module acc + mintCoin := sdk.NewCoins(sdk.NewCoin(liquidBondDenom, stkXPRTMintAmount)) + err = k.bankKeeper.MintCoins(ctx, types.ModuleName, mintCoin) + if err != nil { + return sdk.ZeroDec(), stkXPRTMintAmount, err + } + + // send stkXPRT to delegator acc + err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, delegator, mintCoin) + if err != nil { + return sdk.ZeroDec(), stkXPRTMintAmount, err + } + + // but immediately lock new stkXPRT into LP on behalf of the delegator + _, err = k.LockOnLP(ctx, delegator, sdk.NewCoin(liquidBondDenom, stkXPRTMintAmount)) + if err != nil { + return sdk.ZeroDec(), stkXPRTMintAmount, err + } + + return newShares, stkXPRTMintAmount, err +} + +// LiquidDelegate delegates staking amount to active validators by proxy account. +func (k Keeper) LiquidDelegate(ctx sdk.Context, proxyAcc sdk.AccAddress, activeVals types.ActiveLiquidValidators, stakingAmt math.Int, whitelistedValsMap types.WhitelistedValsMap) (newShares sdk.Dec, err error) { + totalNewShares := sdk.ZeroDec() + // crumb may occur due to a decimal point error in dividing the staking amount into the weight of liquid validators, It added on first active liquid validator + weightedAmt, crumb := types.DivideByWeight(activeVals, stakingAmt, whitelistedValsMap) + if len(weightedAmt) == 0 { + return sdk.ZeroDec(), types.ErrInvalidActiveLiquidValidators + } + weightedAmt[0] = weightedAmt[0].Add(crumb) + for i, val := range activeVals { + if !weightedAmt[i].IsPositive() { + continue + } + validator, _ := k.stakingKeeper.GetValidator(ctx, val.GetOperator()) + newShares, err = k.stakingKeeper.Delegate(ctx, proxyAcc, weightedAmt[i], stakingtypes.Unbonded, validator, true) + if err != nil { + return sdk.ZeroDec(), err + } + totalNewShares = totalNewShares.Add(newShares) + } + return totalNewShares, nil +} + +// LiquidUnstake burns unstakingStkXPRT and performs LiquidUnbond to active liquid validators with del shares worth of shares according to NetAmount with each validators current weight. +func (k Keeper) LiquidUnstake( + ctx sdk.Context, proxyAcc, liquidStaker sdk.AccAddress, unstakingStkXPRT sdk.Coin, +) (time.Time, math.Int, []stakingtypes.UnbondingDelegation, math.Int, error) { + + // check bond denomination + params := k.GetParams(ctx) + liquidBondDenom := k.LiquidBondDenom(ctx) + if unstakingStkXPRT.Denom != liquidBondDenom { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), sdkerrors.Wrapf( + types.ErrInvalidLiquidBondDenom, "invalid coin denomination: got %s, expected %s", unstakingStkXPRT.Denom, liquidBondDenom, + ) + } + + // Get NetAmount states + nas := k.GetNetAmountState(ctx) + + if unstakingStkXPRT.Amount.GT(nas.StkxprtTotalSupply) { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), types.ErrInvalidStkXPRTSupply + } + + // UnstakeAmount = NetAmount * StkXPRTAmount/TotalSupply * (1-UnstakeFeeRate) + unbondingAmount := types.StkXPRTToNativeToken(unstakingStkXPRT.Amount, nas.StkxprtTotalSupply, nas.NetAmount) + unbondingAmount = types.DeductFeeRate(unbondingAmount, params.UnstakeFeeRate) + unbondingAmountInt := unbondingAmount.TruncateInt() + + if !unbondingAmountInt.IsPositive() { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), types.ErrTooSmallLiquidUnstakingAmount + } + + // burn stkxprt + err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, liquidStaker, types.ModuleName, sdk.NewCoins(unstakingStkXPRT)) + if err != nil { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), err + } + err = k.bankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(liquidBondDenom, unstakingStkXPRT.Amount))) + if err != nil { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), err + } + + liquidVals := k.GetAllLiquidValidators(ctx) + totalLiquidTokens, liquidTokenMap := liquidVals.TotalLiquidTokens(ctx, k.stakingKeeper, false) + + // if no totalLiquidTokens, withdraw directly from balance of proxy acc + if !totalLiquidTokens.IsPositive() { + if nas.ProxyAccBalance.GTE(unbondingAmountInt) { + err = k.bankKeeper.SendCoins(ctx, types.LiquidStakeProxyAcc, liquidStaker, + sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), unbondingAmountInt))) + if err != nil { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), err + } else { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, unbondingAmountInt, nil + } + } else { + // error case where there is a quantity that are unbonding balance or remaining rewards that is not re-stake or withdrawn in netAmount. + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), types.ErrInsufficientProxyAccBalance + } + } + // fail when no liquid validators to unbond + if liquidVals.Len() == 0 { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), types.ErrLiquidValidatorsNotExists + } + + // crumb may occur due to a decimal error in dividing the unstaking stkXPRT into the weight of liquid validators, it will remain in the NetAmount + unbondingAmounts, crumb := types.DivideByCurrentWeight(liquidVals, unbondingAmount, totalLiquidTokens, liquidTokenMap) + if !unbondingAmount.Sub(crumb).IsPositive() { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), types.ErrTooSmallLiquidUnstakingAmount + } + totalReturnAmount := sdk.ZeroInt() + var ubdTime time.Time + var ubds []stakingtypes.UnbondingDelegation + for i, val := range liquidVals { + // skip zero weight liquid validator + if !unbondingAmounts[i].IsPositive() { + continue + } + var ubd stakingtypes.UnbondingDelegation + var returnAmount math.Int + var weightedShare sdk.Dec + // calculate delShares from tokens with validation + weightedShare, err = k.stakingKeeper.ValidateUnbondAmount(ctx, proxyAcc, val.GetOperator(), unbondingAmounts[i].TruncateInt()) + if err != nil { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), err + } + if !weightedShare.IsPositive() { + continue + } + // unbond with weightedShare + ubdTime, returnAmount, ubd, err = k.LiquidUnbond(ctx, proxyAcc, liquidStaker, val.GetOperator(), weightedShare, true) + if err != nil { + return time.Time{}, sdk.ZeroInt(), []stakingtypes.UnbondingDelegation{}, sdk.ZeroInt(), err + } + ubds = append(ubds, ubd) + totalReturnAmount = totalReturnAmount.Add(returnAmount) + } + return ubdTime, totalReturnAmount, ubds, sdk.ZeroInt(), nil +} + +// LiquidUnbond unbond delegation shares to active validators by proxy account. +func (k Keeper) LiquidUnbond( + ctx sdk.Context, proxyAcc, liquidStaker sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec, checkMaxEntries bool, +) (time.Time, math.Int, stakingtypes.UnbondingDelegation, error) { + validator, found := k.stakingKeeper.GetValidator(ctx, valAddr) + if !found { + return time.Time{}, sdk.ZeroInt(), stakingtypes.UnbondingDelegation{}, stakingtypes.ErrNoDelegatorForAddress + } + + // If checkMaxEntries is true, perform a maximum limit unbonding entries check. + if checkMaxEntries && k.stakingKeeper.HasMaxUnbondingDelegationEntries(ctx, liquidStaker, valAddr) { + return time.Time{}, sdk.ZeroInt(), stakingtypes.UnbondingDelegation{}, stakingtypes.ErrMaxUnbondingDelegationEntries + } + + // unbond from proxy account + returnAmount, err := k.stakingKeeper.Unbond(ctx, proxyAcc, valAddr, shares) + if err != nil { + return time.Time{}, sdk.ZeroInt(), stakingtypes.UnbondingDelegation{}, err + } + + // transfer the validator tokens to the not bonded pool + if validator.IsBonded() { + coins := sdk.NewCoins(sdk.NewCoin(k.stakingKeeper.BondDenom(ctx), returnAmount)) + if err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, coins); err != nil { + panic(err) + } + } + + // Unbonding from proxy account, but queues to liquid staker. + completionTime := ctx.BlockHeader().Time.Add(k.stakingKeeper.UnbondingTime(ctx)) + ubd := k.stakingKeeper.SetUnbondingDelegationEntry(ctx, liquidStaker, valAddr, ctx.BlockHeight(), completionTime, returnAmount) + k.stakingKeeper.InsertUBDQueue(ctx, ubd, completionTime) + + return completionTime, returnAmount, ubd, nil +} + +// CheckDelegationStates returns total remaining rewards, delshares, liquid tokens of delegations by proxy account +func (k Keeper) CheckDelegationStates(ctx sdk.Context, proxyAcc sdk.AccAddress) (sdk.Dec, sdk.Dec, math.Int) { + bondDenom := k.stakingKeeper.BondDenom(ctx) + totalRewards := sdk.ZeroDec() + totalDelShares := sdk.ZeroDec() + totalLiquidTokens := sdk.ZeroInt() + + // Cache ctx for calculate rewards + cachedCtx, _ := ctx.CacheContext() + k.stakingKeeper.IterateDelegations( + cachedCtx, proxyAcc, + func(_ int64, del stakingtypes.DelegationI) (stop bool) { + valAddr := del.GetValidatorAddr() + val := k.stakingKeeper.Validator(cachedCtx, valAddr) + endingPeriod := k.distrKeeper.IncrementValidatorPeriod(cachedCtx, val) + delReward := k.distrKeeper.CalculateDelegationRewards(cachedCtx, val, del, endingPeriod) + delShares := del.GetShares() + if delShares.IsPositive() { + totalDelShares = totalDelShares.Add(delShares) + liquidTokens := val.TokensFromSharesTruncated(delShares).TruncateInt() + totalLiquidTokens = totalLiquidTokens.Add(liquidTokens) + totalRewards = totalRewards.Add(delReward.AmountOf(bondDenom)) + } + return false + }, + ) + + return totalRewards, totalDelShares, totalLiquidTokens +} + +func (k Keeper) WithdrawLiquidRewards(ctx sdk.Context, proxyAcc sdk.AccAddress) math.Int { + totalRewards := sdk.ZeroInt() + bondDenom := k.stakingKeeper.BondDenom(ctx) + k.stakingKeeper.IterateDelegations( + ctx, proxyAcc, + func(_ int64, del stakingtypes.DelegationI) (stop bool) { + valAddr := del.GetValidatorAddr() + reward, err := k.distrKeeper.WithdrawDelegationRewards(ctx, proxyAcc, valAddr) + if err != nil { + panic(err) + } + totalRewards = totalRewards.Add(reward.AmountOf(bondDenom)) + return false + }, + ) + return totalRewards +} + +// GetLiquidValidator get a single liquid validator +func (k Keeper) GetLiquidValidator(ctx sdk.Context, addr sdk.ValAddress) (val types.LiquidValidator, found bool) { + store := ctx.KVStore(k.storeKey) + + value := store.Get(types.GetLiquidValidatorKey(addr)) + if value == nil { + return val, false + } + + val = types.MustUnmarshalLiquidValidator(k.cdc, value) + return val, true +} + +// SetLiquidValidator set the main record holding liquid validator details +func (k Keeper) SetLiquidValidator(ctx sdk.Context, val types.LiquidValidator) { + store := ctx.KVStore(k.storeKey) + bz := types.MustMarshalLiquidValidator(k.cdc, &val) + store.Set(types.GetLiquidValidatorKey(val.GetOperator()), bz) +} + +// RemoveLiquidValidator remove a liquid validator on kv store +func (k Keeper) RemoveLiquidValidator(ctx sdk.Context, val types.LiquidValidator) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.GetLiquidValidatorKey(val.GetOperator())) +} + +// GetAllLiquidValidators get the set of all liquid validators with no limits, used during genesis dump +func (k Keeper) GetAllLiquidValidators(ctx sdk.Context) (vals types.LiquidValidators) { + store := ctx.KVStore(k.storeKey) + vals = types.LiquidValidators{} + iterator := sdk.KVStorePrefixIterator(store, types.LiquidValidatorsKey) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + val := types.MustUnmarshalLiquidValidator(k.cdc, iterator.Value()) + vals = append(vals, val) + } + + return vals +} + +// GetActiveLiquidValidators get the set of active liquid validators. +func (k Keeper) GetActiveLiquidValidators(ctx sdk.Context, whitelistedValsMap types.WhitelistedValsMap) (vals types.ActiveLiquidValidators) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.LiquidValidatorsKey) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + val := types.MustUnmarshalLiquidValidator(k.cdc, iterator.Value()) + if k.IsActiveLiquidValidator(ctx, val, whitelistedValsMap) { + vals = append(vals, val) + } + } + return vals +} + +func (k Keeper) GetAllLiquidValidatorStates(ctx sdk.Context) (liquidValidatorStates []types.LiquidValidatorState) { + lvs := k.GetAllLiquidValidators(ctx) + whitelistedValsMap := k.GetParams(ctx).WhitelistedValsMap() + for _, lv := range lvs { + active := k.IsActiveLiquidValidator(ctx, lv, whitelistedValsMap) + lvState := types.LiquidValidatorState{ + OperatorAddress: lv.OperatorAddress, + Weight: lv.GetWeight(whitelistedValsMap, active), + Status: lv.GetStatus(active), + DelShares: lv.GetDelShares(ctx, k.stakingKeeper), + LiquidTokens: lv.GetLiquidTokens(ctx, k.stakingKeeper, false), + } + liquidValidatorStates = append(liquidValidatorStates, lvState) + } + return +} + +func (k Keeper) GetLiquidValidatorState(ctx sdk.Context, addr sdk.ValAddress) (liquidValidatorState types.LiquidValidatorState, found bool) { + lv, found := k.GetLiquidValidator(ctx, addr) + if !found { + return types.LiquidValidatorState{ + OperatorAddress: addr.String(), + Weight: sdk.ZeroInt(), + Status: types.ValidatorStatusUnspecified, + DelShares: sdk.ZeroDec(), + LiquidTokens: sdk.ZeroInt(), + }, false + } + whitelistedValsMap := k.GetParams(ctx).WhitelistedValsMap() + active := k.IsActiveLiquidValidator(ctx, lv, whitelistedValsMap) + return types.LiquidValidatorState{ + OperatorAddress: lv.OperatorAddress, + Weight: lv.GetWeight(whitelistedValsMap, active), + Status: lv.GetStatus(active), + DelShares: lv.GetDelShares(ctx, k.stakingKeeper), + LiquidTokens: lv.GetLiquidTokens(ctx, k.stakingKeeper, false), + }, true +} + +func (k Keeper) IsActiveLiquidValidator(ctx sdk.Context, lv types.LiquidValidator, whitelistedValsMap types.WhitelistedValsMap) bool { + val, found := k.stakingKeeper.GetValidator(ctx, lv.GetOperator()) + if !found { + return false + } + return types.ActiveCondition(val, whitelistedValsMap.IsListed(lv.OperatorAddress), k.IsTombstoned(ctx, val)) +} + +func (k Keeper) IsTombstoned(ctx sdk.Context, val stakingtypes.Validator) bool { + consPk, err := val.ConsPubKey() + if err != nil { + return false + } + return k.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(consPk.Address())) +} + +func (k Keeper) GetWeightMap(ctx sdk.Context, liquidVals types.LiquidValidators, whitelistedValsMap types.WhitelistedValsMap) (map[string]math.Int, math.Int) { + weightMap := map[string]math.Int{} + totalWeight := sdk.ZeroInt() + for _, val := range liquidVals { + weight := val.GetWeight(whitelistedValsMap, k.IsActiveLiquidValidator(ctx, val, whitelistedValsMap)) + totalWeight = totalWeight.Add(weight) + weightMap[val.OperatorAddress] = weight + } + return weightMap, totalWeight +} diff --git a/x/liquidstake/keeper/msg_server.go b/x/liquidstake/keeper/msg_server.go new file mode 100644 index 000000000..db745ace8 --- /dev/null +++ b/x/liquidstake/keeper/msg_server.go @@ -0,0 +1,177 @@ +package keeper + +// DONTCOVER + +// Although written in msg_server_test.go, it is approached at the keeper level rather than at the msgServer level +// so is not included in the coverage. + +import ( + "context" + "time" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the liquidstake MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} + +func (k msgServer) LiquidStake(goCtx context.Context, msg *types.MsgLiquidStake) (*types.MsgLiquidStakeResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + newShares, stkXPRTMintAmount, err := k.Keeper.LiquidStake(ctx, types.LiquidStakeProxyAcc, msg.GetDelegator(), msg.Amount) + if err != nil { + return nil, err + } + + liquidBondDenom := k.LiquidBondDenom(ctx) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + sdk.NewEvent( + types.EventTypeMsgLiquidStake, + sdk.NewAttribute(types.AttributeKeyDelegator, msg.DelegatorAddress), + sdk.NewAttribute(types.AttributeKeyLiquidAmount, msg.Amount.String()), + sdk.NewAttribute(types.AttributeKeyNewShares, newShares.String()), + sdk.NewAttribute(types.AttributeKeyStkXPRTMintedAmount, sdk.Coin{Denom: liquidBondDenom, Amount: stkXPRTMintAmount}.String()), + ), + }) + return &types.MsgLiquidStakeResponse{}, nil +} + +func (k msgServer) StakeToLP(goCtx context.Context, msg *types.MsgStakeToLP) (*types.MsgStakeToLPResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + newShares, stkXPRTMintAmount, err := k.LSMDelegate( + ctx, + msg.GetDelegator(), + msg.GetValidator(), + types.LiquidStakeProxyAcc, + msg.StakedAmount, + ) + if err != nil { + return nil, err + } + + liquidBondDenom := k.LiquidBondDenom(ctx) + stkXPRTMinted := sdk.Coin{ + Denom: liquidBondDenom, + Amount: stkXPRTMintAmount, + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + sdk.NewEvent( + types.EventTypeMsgStakeToLP, + sdk.NewAttribute(types.AttributeKeyDelegator, msg.DelegatorAddress), + sdk.NewAttribute(types.AttributeKeyStakedAmount, msg.LiquidAmount.String()), + sdk.NewAttribute(types.AttributeKeyNewShares, newShares.String()), + sdk.NewAttribute(types.AttributeKeyStkXPRTMintedAmount, stkXPRTMinted.String()), + ), + }) + + if msg.LiquidAmount.Amount.IsPositive() { + newShares, stkXPRTMintAmount, err := k.Keeper.LiquidStake(ctx, types.LiquidStakeProxyAcc, msg.GetDelegator(), msg.LiquidAmount) + if err != nil { + return nil, err + } + + stkXPRTMinted := sdk.Coin{ + Denom: liquidBondDenom, + Amount: stkXPRTMintAmount, + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + sdk.NewEvent( + types.EventTypeMsgStakeToLP, + sdk.NewAttribute(types.AttributeKeyDelegator, msg.DelegatorAddress), + sdk.NewAttribute(types.AttributeKeyLiquidAmount, msg.LiquidAmount.String()), + sdk.NewAttribute(types.AttributeKeyNewShares, newShares.String()), + sdk.NewAttribute(types.AttributeKeyStkXPRTMintedAmount, stkXPRTMinted.String()), + ), + }) + + _, err = k.LockOnLP(ctx, msg.GetDelegator(), stkXPRTMinted) + if err != nil { + return nil, err + } + } + + return &types.MsgStakeToLPResponse{}, nil +} + +func (k msgServer) LiquidUnstake(goCtx context.Context, msg *types.MsgLiquidUnstake) (*types.MsgLiquidUnstakeResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + completionTime, unbondingAmount, _, unbondedAmount, err := k.Keeper.LiquidUnstake(ctx, types.LiquidStakeProxyAcc, msg.GetDelegator(), msg.Amount) + if err != nil { + return nil, err + } + + bondDenom := k.stakingKeeper.BondDenom(ctx) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + sdk.NewEvent( + types.EventTypeMsgLiquidUnstake, + sdk.NewAttribute(types.AttributeKeyDelegator, msg.DelegatorAddress), + sdk.NewAttribute(types.AttributeKeyStakedAmount, msg.Amount.String()), + sdk.NewAttribute(types.AttributeKeyUnbondingAmount, sdk.Coin{Denom: bondDenom, Amount: unbondingAmount}.String()), + sdk.NewAttribute(types.AttributeKeyUnbondedAmount, sdk.Coin{Denom: bondDenom, Amount: unbondedAmount}.String()), + sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)), + ), + }) + return &types.MsgLiquidUnstakeResponse{ + CompletionTime: completionTime, + }, nil +} + +func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if msg.Authority != k.authority { + return nil, errorsmod.Wrapf(sdkerrors.ErrorInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) + } + + err := k.SetParams(ctx, msg.Params) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + sdk.NewEvent( + types.EventTypeMsgUpdateParams, + sdk.NewAttribute(types.AttributeKeyAuthority, msg.Authority), + sdk.NewAttribute(types.AttributeKeyUpdatedParams, msg.Params.String()), + ), + }) + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/liquidstake/keeper/rebalancing.go b/x/liquidstake/keeper/rebalancing.go new file mode 100644 index 000000000..fd5d5d014 --- /dev/null +++ b/x/liquidstake/keeper/rebalancing.go @@ -0,0 +1,253 @@ +package keeper + +import ( + "strconv" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +func (k Keeper) GetProxyAccBalance(ctx sdk.Context, proxyAcc sdk.AccAddress) (balance sdk.Coin) { + bondDenom := k.stakingKeeper.BondDenom(ctx) + return sdk.NewCoin(bondDenom, k.bankKeeper.SpendableCoins(ctx, proxyAcc).AmountOf(bondDenom)) +} + +// TryRedelegation attempts redelegation, which is applied only when successful through cached context because there is a constraint that fails if already receiving redelegation. +func (k Keeper) TryRedelegation(ctx sdk.Context, re types.Redelegation) (completionTime time.Time, err error) { + dstVal := re.DstValidator.GetOperator() + srcVal := re.SrcValidator.GetOperator() + + // check the source validator already has receiving transitive redelegation + hasReceiving := k.stakingKeeper.HasReceivingRedelegation(ctx, re.Delegator, srcVal) + if hasReceiving { + return time.Time{}, stakingtypes.ErrTransitiveRedelegation + } + + // calculate delShares from tokens with validation + shares, err := k.stakingKeeper.ValidateUnbondAmount( + ctx, re.Delegator, srcVal, re.Amount, + ) + if err != nil { + return time.Time{}, err + } + + // when last, full redelegation of shares from delegation + if re.Last { + shares = re.SrcValidator.GetDelShares(ctx, k.stakingKeeper) + } + cachedCtx, writeCache := ctx.CacheContext() + completionTime, err = k.stakingKeeper.BeginRedelegation(cachedCtx, re.Delegator, srcVal, dstVal, shares) + if err != nil { + return time.Time{}, err + } + writeCache() + return completionTime, nil +} + +// Rebalance argument liquidVals containing ValidatorStatusActive which is containing just added on whitelist(liquidToken 0) and ValidatorStatusInactive to delist +func (k Keeper) Rebalance(ctx sdk.Context, proxyAcc sdk.AccAddress, liquidVals types.LiquidValidators, whitelistedValsMap types.WhitelistedValsMap, rebalancingTrigger sdk.Dec) (redelegations []types.Redelegation) { + logger := k.Logger(ctx) + totalLiquidTokens, liquidTokenMap := liquidVals.TotalLiquidTokens(ctx, k.stakingKeeper, false) + if !totalLiquidTokens.IsPositive() { + return []types.Redelegation{} + } + + weightMap, totalWeight := k.GetWeightMap(ctx, liquidVals, whitelistedValsMap) + + // no active liquid validators + if !totalWeight.IsPositive() { + return []types.Redelegation{} + } + + // calculate rebalancing target map + targetMap := map[string]math.Int{} + totalTargetMap := sdk.ZeroInt() + for _, val := range liquidVals { + targetMap[val.OperatorAddress] = totalLiquidTokens.Mul(weightMap[val.OperatorAddress]).Quo(totalWeight) + totalTargetMap = totalTargetMap.Add(targetMap[val.OperatorAddress]) + } + crumb := totalLiquidTokens.Sub(totalTargetMap) + if !totalTargetMap.IsPositive() { + return []types.Redelegation{} + } + // crumb to first non zero liquid validator + for _, val := range liquidVals { + if targetMap[val.OperatorAddress].IsPositive() { + targetMap[val.OperatorAddress] = targetMap[val.OperatorAddress].Add(crumb) + break + } + } + + failCount := 0 + rebalancingThresholdAmt := rebalancingTrigger.Mul(sdk.NewDecFromInt(totalLiquidTokens)).TruncateInt() + + for i := 0; i < liquidVals.Len(); i++ { + // get min, max of liquid token gap + minVal, maxVal, amountNeeded, last := liquidVals.MinMaxGap(targetMap, liquidTokenMap) + if amountNeeded.IsZero() || (i == 0 && !amountNeeded.GT(rebalancingThresholdAmt)) { + break + } + + // sync liquidTokenMap applied rebalancing + liquidTokenMap[maxVal.OperatorAddress] = liquidTokenMap[maxVal.OperatorAddress].Sub(amountNeeded) + liquidTokenMap[minVal.OperatorAddress] = liquidTokenMap[minVal.OperatorAddress].Add(amountNeeded) + + // try redelegation from max validator to min validator + redelegation := types.Redelegation{ + Delegator: proxyAcc, + SrcValidator: maxVal, + DstValidator: minVal, + Amount: amountNeeded, + Last: last, + } + _, err := k.TryRedelegation(ctx, redelegation) + if err != nil { + redelegation.Error = err + failCount++ + } + redelegations = append(redelegations, redelegation) + } + if failCount > 0 { + logger.Error("rebalancing failed due to redelegation hopping", "redelegations", redelegations) + } + if len(redelegations) != 0 { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeBeginRebalancing, + sdk.NewAttribute(types.AttributeKeyDelegator, types.LiquidStakeProxyAcc.String()), + sdk.NewAttribute(types.AttributeKeyRedelegationCount, strconv.Itoa(len(redelegations))), + sdk.NewAttribute(types.AttributeKeyRedelegationFailCount, strconv.Itoa(failCount)), + ), + }) + logger.Info(types.EventTypeBeginRebalancing, + types.AttributeKeyDelegator, types.LiquidStakeProxyAcc.String(), + types.AttributeKeyRedelegationCount, strconv.Itoa(len(redelegations)), + types.AttributeKeyRedelegationFailCount, strconv.Itoa(failCount)) + } + return redelegations +} + +func (k Keeper) UpdateLiquidValidatorSet(ctx sdk.Context) []types.Redelegation { + logger := k.Logger(ctx) + params := k.GetParams(ctx) + liquidValidators := k.GetAllLiquidValidators(ctx) + liquidValsMap := liquidValidators.Map() + whitelistedValsMap := types.GetWhitelistedValsMap(params.WhitelistedValidators) + + // Set Liquid validators for added whitelist validators + for _, wv := range params.WhitelistedValidators { + if _, ok := liquidValsMap[wv.ValidatorAddress]; !ok { + lv := types.LiquidValidator{ + OperatorAddress: wv.ValidatorAddress, + } + if k.IsActiveLiquidValidator(ctx, lv, whitelistedValsMap) { + k.SetLiquidValidator(ctx, lv) + liquidValidators = append(liquidValidators, lv) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeAddLiquidValidator, + sdk.NewAttribute(types.AttributeKeyLiquidValidator, lv.OperatorAddress), + ), + }) + logger.Info(types.EventTypeAddLiquidValidator, types.AttributeKeyLiquidValidator, lv.OperatorAddress) + } + } + } + + // rebalancing based updated liquid validators status with threshold, try by cachedCtx + // tombstone status also handled on Rebalance + reds := k.Rebalance(ctx, types.LiquidStakeProxyAcc, liquidValidators, whitelistedValsMap, types.RebalancingTrigger) + + // unbond all delShares to proxyAcc if delShares exist on inactive liquid validators + for _, lv := range liquidValidators { + if !k.IsActiveLiquidValidator(ctx, lv, whitelistedValsMap) { + delShares := lv.GetDelShares(ctx, k.stakingKeeper) + if delShares.IsPositive() { + cachedCtx, writeCache := ctx.CacheContext() + completionTime, returnAmount, _, err := k.LiquidUnbond(cachedCtx, types.LiquidStakeProxyAcc, types.LiquidStakeProxyAcc, lv.GetOperator(), delShares, false) + if err != nil { + logger.Error("liquid unbonding of inactive liquid validator failed", "error", err) + continue + } + writeCache() + unbondingAmount := sdk.Coin{Denom: k.stakingKeeper.BondDenom(ctx), Amount: returnAmount}.String() + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeUnbondInactiveLiquidTokens, + sdk.NewAttribute(types.AttributeKeyLiquidValidator, lv.OperatorAddress), + sdk.NewAttribute(types.AttributeKeyUnbondingAmount, unbondingAmount), + sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)), + ), + }) + logger.Info(types.EventTypeUnbondInactiveLiquidTokens, + types.AttributeKeyLiquidValidator, lv.OperatorAddress, + types.AttributeKeyUnbondingAmount, unbondingAmount, + types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)) + } + _, found := k.stakingKeeper.GetDelegation(ctx, types.LiquidStakeProxyAcc, lv.GetOperator()) + if !found { + k.RemoveLiquidValidator(ctx, lv) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeRemoveLiquidValidator, + sdk.NewAttribute(types.AttributeKeyLiquidValidator, lv.OperatorAddress), + ), + }) + logger.Info(types.EventTypeRemoveLiquidValidator, types.AttributeKeyLiquidValidator, lv.OperatorAddress) + } + } + } + + return reds +} + +// AutocompoundStakingRewards withdraws staking rewards and re-stakes when over threshold. +func (k Keeper) AutocompoundStakingRewards(ctx sdk.Context, whitelistedValsMap types.WhitelistedValsMap) { + totalRemainingRewards, _, totalLiquidTokens := k.CheckDelegationStates(ctx, types.LiquidStakeProxyAcc) + + // checking over types.AutocompoundTrigger and execute GetRewards + proxyAccBalance := k.GetProxyAccBalance(ctx, types.LiquidStakeProxyAcc) + rewardsThreshold := types.AutocompoundTrigger.Mul(sdk.NewDecFromInt(totalLiquidTokens)) + + // skip If it doesn't exceed the rewards threshold + if !sdk.NewDecFromInt(proxyAccBalance.Amount).Add(totalRemainingRewards).GT(rewardsThreshold) { + return + } + + // Withdraw rewards of LiquidStakeProxyAcc and re-staking + k.WithdrawLiquidRewards(ctx, types.LiquidStakeProxyAcc) + + // re-staking with proxyAccBalance, due to auto-withdraw on add staking by f1 + proxyAccBalance = k.GetProxyAccBalance(ctx, types.LiquidStakeProxyAcc) + + // skip when no active liquid validator + activeVals := k.GetActiveLiquidValidators(ctx, whitelistedValsMap) + if len(activeVals) == 0 { + return + } + + // re-staking + cachedCtx, writeCache := ctx.CacheContext() + _, err := k.LiquidDelegate(cachedCtx, types.LiquidStakeProxyAcc, activeVals, proxyAccBalance.Amount, whitelistedValsMap) + if err != nil { + logger := k.Logger(ctx) + logger.Error("re-staking failed", "error", err) + return + } + writeCache() + logger := k.Logger(ctx) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeAutocompound, + sdk.NewAttribute(types.AttributeKeyDelegator, types.LiquidStakeProxyAcc.String()), + sdk.NewAttribute(sdk.AttributeKeyAmount, proxyAccBalance.String()), + ), + }) + logger.Info(types.EventTypeAutocompound, + types.AttributeKeyDelegator, types.LiquidStakeProxyAcc.String(), + sdk.AttributeKeyAmount, proxyAccBalance.String()) +} diff --git a/x/liquidstake/module.go b/x/liquidstake/module.go new file mode 100644 index 000000000..8ff27a6fa --- /dev/null +++ b/x/liquidstake/module.go @@ -0,0 +1,149 @@ +package liquidstake + +import ( + "context" + "encoding/json" + "fmt" + + abci "github.com/cometbft/cometbft/abci/types" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + sdkclient "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/client/cli" + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/keeper" + "github.com/persistenceOne/pstake-native/v2/x/liquidstake/types" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the liquidstake module. +type AppModuleBasic struct { + cdc codec.Codec +} + +// Name returns the liquidstake module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the liquidstake module's types for the given codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// DefaultGenesis returns default genesis state as raw bytes for the liquidstake +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the liquidstake module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config sdkclient.TxEncodingConfig, bz json.RawMessage) error { + var data types.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return types.ValidateGenesis(data) +} + +// RegisterRESTRoutes registers the REST routes for the liquidstake module. +func (AppModuleBasic) RegisterRESTRoutes(_ sdkclient.Context, _ *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the liquidstake module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx sdkclient.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } +} + +// GetTxCmd returns the root tx command for the liquidstake module. +// Modifying parameters of a liquidstake can be done through governance process, not through transaction level. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the root query command for the liquidstake module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +func (b AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// AppModule implements an application module for the liquidstake module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule( + keeper keeper.Keeper, +) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + keeper: keeper, + } +} + +// Name returns the liquidstake module's name. +func (AppModule) Name() string { + return types.ModuleName +} + +// RegisterInvariants registers the liquidstake module invariants. +func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} + +// QuerierRoute returns the liquidstake module's querier route name. +func (AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), keeper.Querier{Keeper: am.keeper}) +} + +// InitGenesis performs genesis initialization for the liquidstake module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + am.keeper.InitGenesis(ctx, genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the liquidstake +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(gs) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock returns the begin blocker for the liquidstake module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + BeginBlocker(ctx, am.keeper) +} + +// EndBlock returns the end blocker for the liquidstake module. It returns no validator +// updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} diff --git a/x/liquidstake/types/codec.go b/x/liquidstake/types/codec.go new file mode 100644 index 000000000..508255835 --- /dev/null +++ b/x/liquidstake/types/codec.go @@ -0,0 +1,46 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// RegisterLegacyAminoCodec registers the necessary x/liquidstake interfaces and concrete types +// on the provided LegacyAmino codec. These types are used for Amino JSON serialization. +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgLiquidStake{}, "liquidstake/MsgLiquidStake", nil) + cdc.RegisterConcrete(&MsgStakeToLP{}, "liquidstake/MsgStakeToLP", nil) + cdc.RegisterConcrete(&MsgLiquidUnstake{}, "liquidstake/MsgLiquidUnstake", nil) + cdc.RegisterConcrete(&MsgUpdateParams{}, "liquidstake/MsgUpdateParams", nil) +} + +// RegisterInterfaces registers the x/liquidstake interfaces types with the interface registry. +func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgLiquidStake{}, + &MsgStakeToLP{}, + &MsgLiquidUnstake{}, + &MsgUpdateParams{}, + ) +} + +var ( + amino = codec.NewLegacyAmino() + + // ModuleCdc references the global x/liquidstake module codec. Note, the codec + // should ONLY be used in certain instances of tests and for JSON encoding as Amino + // is still used for that purpose. + // + // The actual codec used for serialization should be provided to x/liquidstake and + // defined at the application level. + ModuleCdc = codec.NewAminoCodec(amino) +) + +func init() { + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + amino.Seal() +} diff --git a/x/liquidstake/types/errors.go b/x/liquidstake/types/errors.go new file mode 100644 index 000000000..1ec22b4f1 --- /dev/null +++ b/x/liquidstake/types/errors.go @@ -0,0 +1,24 @@ +package types + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +// Sentinel errors for the liquidstake module. +var ( + ErrActiveLiquidValidatorsNotExists = sdkerrors.Register(ModuleName, 2, "active liquid validators not exists") + ErrInvalidDenom = sdkerrors.Register(ModuleName, 3, "invalid denom") + ErrInvalidBondDenom = sdkerrors.Register(ModuleName, 4, "invalid bond denom") + ErrInvalidLiquidBondDenom = sdkerrors.Register(ModuleName, 5, "invalid liquid bond denom") + ErrNotImplementedYet = sdkerrors.Register(ModuleName, 6, "not implemented yet") + ErrLessThanMinLiquidStakeAmount = sdkerrors.Register(ModuleName, 7, "staking amount should be over params.min_liquid_stake_amount") + ErrInvalidStkXPRTSupply = sdkerrors.Register(ModuleName, 8, "invalid liquid bond denom supply") + ErrInvalidActiveLiquidValidators = sdkerrors.Register(ModuleName, 9, "invalid active liquid validators") + ErrLiquidValidatorsNotExists = sdkerrors.Register(ModuleName, 10, "liquid validators not exists") + ErrInsufficientProxyAccBalance = sdkerrors.Register(ModuleName, 11, "insufficient liquid tokens or balance of proxy account, need to wait for new liquid validator to be added or unbonding of proxy account to be completed") + ErrTooSmallLiquidStakeAmount = sdkerrors.Register(ModuleName, 12, "liquid staking amount is too small, the result becomes zero") + ErrTooSmallLiquidUnstakingAmount = sdkerrors.Register(ModuleName, 13, "liquid unstaking amount is too small, the result becomes zero") + ErrNoLPContractAddress = sdkerrors.Register(ModuleName, 14, "CW address of an LP contract is not set") + ErrDisabledLSM = sdkerrors.Register(ModuleName, 15, "LSM delegation is disabled") + ErrLSMTokenizeFailed = sdkerrors.Register(ModuleName, 16, "LSM tokenization failed") + ErrLSMRedeemFailed = sdkerrors.Register(ModuleName, 17, "LSM redemption failed") + ErrLPContract = sdkerrors.Register(ModuleName, 18, "CW contract execution failed") +) diff --git a/x/liquidstake/types/events.go b/x/liquidstake/types/events.go new file mode 100644 index 000000000..ff1d4825e --- /dev/null +++ b/x/liquidstake/types/events.go @@ -0,0 +1,31 @@ +package types + +// Event types for the liquidstake module. +const ( + EventTypeMsgLiquidStake = MsgTypeLiquidStake + EventTypeMsgLiquidUnstake = MsgTypeLiquidUnstake + EventTypeMsgStakeToLP = MsgTypeStakeToLP + EventTypeMsgUpdateParams = MsgTypeUpdateParams + EventTypeAddLiquidValidator = "add_liquid_validator" + EventTypeRemoveLiquidValidator = "remove_liquid_validator" + EventTypeBeginRebalancing = "begin_rebalancing" + EventTypeAutocompound = "autocompound" + EventTypeUnbondInactiveLiquidTokens = "unbond_inactive_liquid_tokens" + + AttributeKeyDelegator = "delegator" + AttributeKeyNewShares = "new_shares" + AttributeKeyStkXPRTMintedAmount = "stkxprt_minted_amount" + AttributeKeyCompletionTime = "completion_time" + AttributeKeyUnbondingAmount = "unbonding_amount" + AttributeKeyUnbondedAmount = "unbonded_amount" + AttributeKeyLiquidValidator = "liquid_validator" + AttributeKeyRedelegationCount = "redelegation_count" + AttributeKeyRedelegationFailCount = "redelegation_fail_count" + AttributeKeyLiquidAmount = "liquid_amount" + AttributeKeyStakedAmount = "staked_amount" + + AttributeKeyAuthority = "authority" + AttributeKeyUpdatedParams = "updated_params" + + AttributeValueCategory = ModuleName +) diff --git a/x/liquidstake/types/expected_keepers.go b/x/liquidstake/types/expected_keepers.go new file mode 100644 index 000000000..fec71ae38 --- /dev/null +++ b/x/liquidstake/types/expected_keepers.go @@ -0,0 +1,101 @@ +package types + +import ( + "time" + + "cosmossdk.io/math" + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// BankKeeper defines the expected bank send keeper +type BankKeeper interface { + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + + GetSupply(ctx sdk.Context, denom string) sdk.Coin + SendCoinsFromModuleToModule(ctx sdk.Context, senderPool, recipientPool string, amt sdk.Coins) error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error + MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins +} + +// AccountKeeper defines the expected account keeper +type AccountKeeper interface { + GetModuleAddress(name string) sdk.AccAddress + GetModuleAccount(ctx sdk.Context, moduleName string) authtypes.ModuleAccountI + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI +} + +// StakingKeeper expected staking keeper (noalias) +type StakingKeeper interface { + Validator(sdk.Context, sdk.ValAddress) stakingtypes.ValidatorI + ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI + GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) + + GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) + GetBondedValidatorsByPower(ctx sdk.Context) []stakingtypes.Validator + + GetLastTotalPower(ctx sdk.Context) math.Int + GetLastValidatorPower(ctx sdk.Context, valAddr sdk.ValAddress) int64 + + Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) stakingtypes.DelegationI + GetDelegation(ctx sdk.Context, + delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation stakingtypes.Delegation, found bool) + IterateDelegations(ctx sdk.Context, delegator sdk.AccAddress, + fn func(index int64, delegation stakingtypes.DelegationI) (stop bool)) + Delegate( + ctx sdk.Context, delAddr sdk.AccAddress, bondAmt math.Int, tokenSrc stakingtypes.BondStatus, + validator stakingtypes.Validator, subtractAccount bool, + ) (newShares sdk.Dec, err error) + + BondDenom(ctx sdk.Context) (res string) + Unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec) (amount math.Int, err error) + UnbondingTime(ctx sdk.Context) (res time.Duration) + SetUnbondingDelegationEntry( + ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, + creationHeight int64, minTime time.Time, balance math.Int, + ) stakingtypes.UnbondingDelegation + InsertUBDQueue(ctx sdk.Context, ubd stakingtypes.UnbondingDelegation, + completionTime time.Time) + ValidateUnbondAmount( + ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt math.Int, + ) (shares sdk.Dec, err error) + GetAllUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress) []stakingtypes.UnbondingDelegation + BeginRedelegation( + ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec, + ) (completionTime time.Time, err error) + GetAllRedelegations( + ctx sdk.Context, delegator sdk.AccAddress, srcValAddress, dstValAddress sdk.ValAddress, + ) []stakingtypes.Redelegation + HasReceivingRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool + BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate + HasMaxUnbondingDelegationEntries(ctx sdk.Context, + delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) bool +} + +// DistrKeeper expected distribution keeper (noalias) +type DistrKeeper interface { + IncrementValidatorPeriod(ctx sdk.Context, val stakingtypes.ValidatorI) uint64 + CalculateDelegationRewards(ctx sdk.Context, val stakingtypes.ValidatorI, del stakingtypes.DelegationI, endingPeriod uint64) (rewards sdk.DecCoins) + WithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) +} + +// SlashingKeeper expected slashing keeper (noalias) +type SlashingKeeper interface { + IsTombstoned(ctx sdk.Context, consAddr sdk.ConsAddress) bool +} + +// StakingHooks event hooks for staking validator object (noalias) +type StakingHooks interface { + AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created + AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is deleted + + BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation is created + BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation's shares are modified + AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) + BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) +} diff --git a/x/liquidstake/types/genesis.go b/x/liquidstake/types/genesis.go new file mode 100644 index 000000000..ae0c72304 --- /dev/null +++ b/x/liquidstake/types/genesis.go @@ -0,0 +1,34 @@ +package types + +import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + +// NewGenesisState returns new GenesisState instance. +func NewGenesisState(params Params, liquidValidators []LiquidValidator) *GenesisState { + return &GenesisState{ + Params: params, + LiquidValidators: liquidValidators, + } +} + +// DefaultGenesisState returns the default genesis state. +func DefaultGenesisState() *GenesisState { + return NewGenesisState( + DefaultParams(), + []LiquidValidator{}, + ) +} + +// ValidateGenesis validates GenesisState. +func ValidateGenesis(data GenesisState) error { + if err := data.Params.Validate(); err != nil { + return err + } + for _, lv := range data.LiquidValidators { + if err := lv.Validate(); err != nil { + return sdkerrors.Wrapf( + sdkerrors.ErrInvalidAddress, + "invalid liquid validator %s: %v", lv, err) + } + } + return nil +} diff --git a/x/liquidstake/types/genesis.pb.go b/x/liquidstake/types/genesis.pb.go new file mode 100644 index 000000000..b0073580e --- /dev/null +++ b/x/liquidstake/types/genesis.pb.go @@ -0,0 +1,377 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pstake/liquidstake/v1beta1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the liquidstake module's genesis state. +type GenesisState struct { + // params defines all the parameters for the liquidstake module + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + LiquidValidators []LiquidValidator `protobuf:"bytes,2,rep,name=liquid_validators,json=liquidValidators,proto3" json:"liquid_validators"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_bbc03e56b740bb6c, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GenesisState)(nil), "pstake.liquidstake.v1beta1.GenesisState") +} + +func init() { + proto.RegisterFile("pstake/liquidstake/v1beta1/genesis.proto", fileDescriptor_bbc03e56b740bb6c) +} + +var fileDescriptor_bbc03e56b740bb6c = []byte{ + // 279 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x28, 0x28, 0x2e, 0x49, + 0xcc, 0x4e, 0xd5, 0xcf, 0xc9, 0x2c, 0x2c, 0xcd, 0x4c, 0x81, 0xb0, 0xcb, 0x0c, 0x93, 0x52, 0x4b, + 0x12, 0x0d, 0xf5, 0xd3, 0x53, 0xf3, 0x52, 0x8b, 0x33, 0x8b, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, + 0x85, 0xa4, 0x20, 0x2a, 0xf5, 0x90, 0x54, 0xea, 0x41, 0x55, 0x4a, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, + 0x83, 0x95, 0xe9, 0x83, 0x58, 0x10, 0x1d, 0x52, 0x3a, 0x78, 0xcc, 0x46, 0x36, 0x05, 0xac, 0x5a, + 0x69, 0x17, 0x23, 0x17, 0x8f, 0x3b, 0xc4, 0xc6, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0x21, 0x07, 0x2e, + 0xb6, 0x82, 0xc4, 0xa2, 0xc4, 0xdc, 0x62, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x25, 0x3d, + 0xdc, 0x2e, 0xd0, 0x0b, 0x00, 0xab, 0x74, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0x4f, + 0x28, 0x8e, 0x4b, 0x10, 0xa2, 0x36, 0xbe, 0x2c, 0x31, 0x27, 0x33, 0x25, 0xb1, 0x24, 0xbf, 0xa8, + 0x58, 0x82, 0x49, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x1b, 0x9f, 0x61, 0x3e, 0x60, 0xb1, 0x30, 0x98, + 0x1e, 0xa8, 0xa9, 0x02, 0x39, 0xa8, 0xc2, 0xc5, 0x56, 0x1c, 0x1d, 0x0b, 0xe4, 0x19, 0x5e, 0x2c, + 0x90, 0x67, 0x70, 0x8a, 0x59, 0xf1, 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, + 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, + 0xe5, 0x18, 0xa2, 0xec, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x0b, + 0x52, 0x8b, 0x8a, 0x33, 0x8b, 0x4b, 0x52, 0xf3, 0x92, 0x53, 0xfd, 0xf3, 0x52, 0xf5, 0x21, 0xae, + 0xd0, 0xcd, 0x4b, 0x2c, 0xc9, 0x2c, 0x4b, 0xd5, 0x2f, 0x33, 0xd2, 0xaf, 0x40, 0x09, 0xae, 0x92, + 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0x70, 0x08, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x54, + 0xe3, 0xaa, 0x70, 0xad, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.LiquidValidators) > 0 { + for iNdEx := len(m.LiquidValidators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.LiquidValidators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.LiquidValidators) > 0 { + for _, e := range m.LiquidValidators { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidValidators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LiquidValidators = append(m.LiquidValidators, LiquidValidator{}) + if err := m.LiquidValidators[len(m.LiquidValidators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/liquidstake/types/keys.go b/x/liquidstake/types/keys.go new file mode 100644 index 000000000..7e2e7f00d --- /dev/null +++ b/x/liquidstake/types/keys.go @@ -0,0 +1,35 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" +) + +const ( + // ModuleName is the name of the liquidstake module + ModuleName = "liquidstake" + + // RouterKey is the message router key for the liquidstake module + RouterKey = ModuleName + + // StoreKey is the default store key for the liquidstake module + // To avoid collision with liquidstakeibc we make it xprtliquidstake + StoreKey = "xprt" + ModuleName + + // QuerierRoute is the querier route for the liquidstake module + QuerierRoute = ModuleName +) + +var ( + ParamsKey = []byte{0x01} + + // LiquidValidatorsKey defines prefix for each key to a liquid validator + LiquidValidatorsKey = []byte{0x02} +) + +// GetLiquidValidatorKey creates the key for the liquid validator with address +// VALUE: liquidstake/LiquidValidator +func GetLiquidValidatorKey(operatorAddr sdk.ValAddress) []byte { + tmp := append([]byte{}, LiquidValidatorsKey...) + return append(tmp, address.MustLengthPrefix(operatorAddr)...) +} diff --git a/x/liquidstake/types/liquidstake.go b/x/liquidstake/types/liquidstake.go new file mode 100644 index 000000000..1ffabfffb --- /dev/null +++ b/x/liquidstake/types/liquidstake.go @@ -0,0 +1,213 @@ +package types + +import ( + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +type WhitelistedValsMap map[string]WhitelistedValidator + +func (whitelistedValsMap WhitelistedValsMap) IsListed(operatorAddr string) bool { + if _, ok := whitelistedValsMap[operatorAddr]; ok { + return true + } else { + return false + } +} + +func GetWhitelistedValsMap(whitelistedValidators []WhitelistedValidator) WhitelistedValsMap { + whitelistedValsMap := make(WhitelistedValsMap) + for _, wv := range whitelistedValidators { + whitelistedValsMap[wv.ValidatorAddress] = wv + } + return whitelistedValsMap +} + +// Validate validates LiquidValidator. +func (v LiquidValidator) Validate() error { + _, valErr := sdk.ValAddressFromBech32(v.OperatorAddress) + if valErr != nil { + return valErr + } + return nil +} + +func (v LiquidValidator) GetOperator() sdk.ValAddress { + if v.OperatorAddress == "" { + return nil + } + addr, err := sdk.ValAddressFromBech32(v.OperatorAddress) + if err != nil { + panic(err) + } + return addr +} + +func (v LiquidValidator) GetDelShares(ctx sdk.Context, sk StakingKeeper) sdk.Dec { + del, found := sk.GetDelegation(ctx, LiquidStakeProxyAcc, v.GetOperator()) + if !found { + return sdk.ZeroDec() + } + return del.GetShares() +} + +func (v LiquidValidator) GetLiquidTokens(ctx sdk.Context, sk StakingKeeper, onlyBonded bool) math.Int { + delShares := v.GetDelShares(ctx, sk) + if !delShares.IsPositive() { + return sdk.ZeroInt() + } + val := sk.Validator(ctx, v.GetOperator()) + if onlyBonded && !val.IsBonded() { + return sdk.ZeroInt() + } + return val.TokensFromSharesTruncated(delShares).TruncateInt() +} + +func (v LiquidValidator) GetWeight(whitelistedValsMap WhitelistedValsMap, active bool) math.Int { + if wv, ok := whitelistedValsMap[v.OperatorAddress]; ok && active { + return wv.TargetWeight + } else { + return sdk.ZeroInt() + } +} + +func (v LiquidValidator) GetStatus(activeCondition bool) ValidatorStatus { + if activeCondition { + return ValidatorStatusActive + } else { + return ValidatorStatusInactive + } +} + +// ActiveCondition checks the liquid validator could be active by below cases +// - included on whitelist +// - existed valid validator on staking module ( existed, not nil del shares and tokens, valid exchange rate) +// - not tombstoned +func ActiveCondition(validator stakingtypes.Validator, whitelisted bool, tombstoned bool) bool { + return whitelisted && + !tombstoned && + // !Unspecified ==> Bonded, Unbonding, Unbonded + validator.GetStatus() != stakingtypes.Unspecified && + !validator.GetTokens().IsNil() && + !validator.GetDelegatorShares().IsNil() && + !validator.InvalidExRate() +} + +// LiquidValidators is a collection of LiquidValidator +type LiquidValidators []LiquidValidator +type ActiveLiquidValidators LiquidValidators + +// MinMaxGap Return the list of LiquidValidator with the maximum gap and minimum gap from the target weight of LiquidValidators, respectively. +func (vs LiquidValidators) MinMaxGap(targetMap, liquidTokenMap map[string]math.Int) (minGapVal LiquidValidator, maxGapVal LiquidValidator, amountNeeded math.Int, lastRedelegation bool) { + maxGap := sdk.ZeroInt() + minGap := sdk.ZeroInt() + + for _, val := range vs { + gap := liquidTokenMap[val.OperatorAddress].Sub(targetMap[val.OperatorAddress]) + if gap.GT(maxGap) { + maxGap = gap + maxGapVal = val + } + if gap.LT(minGap) { + minGap = gap + minGapVal = val + } + } + amountNeeded = sdk.MinInt(maxGap, minGap.Abs()) + // lastRedelegation when maxGap validator's liquid token == amountNeeded for redelegation all delShares + lastRedelegation = amountNeeded.IsPositive() && + !targetMap[maxGapVal.OperatorAddress].IsPositive() && + liquidTokenMap[maxGapVal.OperatorAddress].Equal(amountNeeded) + + return minGapVal, maxGapVal, amountNeeded, lastRedelegation +} + +func (vs LiquidValidators) Len() int { + return len(vs) +} + +func (vs LiquidValidators) TotalLiquidTokens(ctx sdk.Context, sk StakingKeeper, onlyBonded bool) (math.Int, map[string]math.Int) { + totalLiquidTokens := sdk.ZeroInt() + liquidTokenMap := map[string]math.Int{} + for _, lv := range vs { + liquidTokens := lv.GetLiquidTokens(ctx, sk, onlyBonded) + liquidTokenMap[lv.OperatorAddress] = liquidTokens + totalLiquidTokens = totalLiquidTokens.Add(liquidTokens) + } + return totalLiquidTokens, liquidTokenMap +} + +func (vs LiquidValidators) Map() map[string]struct{} { + valsMap := map[string]struct{}{} + for _, val := range vs { + valsMap[val.OperatorAddress] = struct{}{} + } + return valsMap +} + +func (avs ActiveLiquidValidators) Len() int { + return LiquidValidators(avs).Len() +} + +func (avs ActiveLiquidValidators) TotalActiveLiquidTokens(ctx sdk.Context, sk StakingKeeper, onlyBonded bool) (math.Int, map[string]math.Int) { + return LiquidValidators(avs).TotalLiquidTokens(ctx, sk, onlyBonded) +} + +// TotalWeight for active liquid validator +func (avs ActiveLiquidValidators) TotalWeight(whitelistedValsMap WhitelistedValsMap) math.Int { + totalWeight := sdk.ZeroInt() + for _, val := range avs { + totalWeight = totalWeight.Add(val.GetWeight(whitelistedValsMap, true)) + } + return totalWeight +} + +// NativeTokenToStkXPRT returns StkxprtTotalSupply * nativeTokenAmount / netAmount +func NativeTokenToStkXPRT(nativeTokenAmount, StkxprtTotalSupplyAmount math.Int, netAmount sdk.Dec) (stkXPRTAmount math.Int) { + return sdk.NewDecFromInt(StkxprtTotalSupplyAmount).MulTruncate(sdk.NewDecFromInt(nativeTokenAmount)).QuoTruncate(netAmount.TruncateDec()).TruncateInt() +} + +// StkXPRTToNativeToken returns stkXPRTAmount * netAmount / StkxprtTotalSupply with truncations +func StkXPRTToNativeToken(stkXPRTAmount, StkxprtTotalSupplyAmount math.Int, netAmount sdk.Dec) (nativeTokenAmount sdk.Dec) { + return sdk.NewDecFromInt(stkXPRTAmount).MulTruncate(netAmount).Quo(sdk.NewDecFromInt(StkxprtTotalSupplyAmount)).TruncateDec() +} + +// DeductFeeRate returns Input * (1-FeeRate) with truncations +func DeductFeeRate(input sdk.Dec, feeRate sdk.Dec) (feeDeductedOutput sdk.Dec) { + return input.MulTruncate(sdk.OneDec().Sub(feeRate)).TruncateDec() +} + +func (nas NetAmountState) CalcNetAmount() sdk.Dec { + return sdk.NewDecFromInt(nas.ProxyAccBalance.Add(nas.TotalLiquidTokens).Add(nas.TotalUnbondingBalance)).Add(nas.TotalRemainingRewards) +} + +func (nas NetAmountState) CalcMintRate() sdk.Dec { + if nas.NetAmount.IsNil() || !nas.NetAmount.IsPositive() { + return sdk.ZeroDec() + } + return sdk.NewDecFromInt(nas.StkxprtTotalSupply).QuoTruncate(nas.NetAmount) +} + +type LiquidValidatorStates []LiquidValidatorState + +func MustMarshalLiquidValidator(cdc codec.BinaryCodec, val *LiquidValidator) []byte { + return cdc.MustMarshal(val) +} + +// must unmarshal a liquid validator from a store value +func MustUnmarshalLiquidValidator(cdc codec.BinaryCodec, value []byte) LiquidValidator { + validator, err := UnmarshalLiquidValidator(cdc, value) + if err != nil { + panic(err) + } + + return validator +} + +// unmarshal a liquid validator from a store value +func UnmarshalLiquidValidator(cdc codec.BinaryCodec, value []byte) (val LiquidValidator, err error) { + err = cdc.Unmarshal(value, &val) + return val, err +} diff --git a/x/liquidstake/types/liquidstake.pb.go b/x/liquidstake/types/liquidstake.pb.go new file mode 100644 index 000000000..fe2f88c9a --- /dev/null +++ b/x/liquidstake/types/liquidstake.pb.go @@ -0,0 +1,1871 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pstake/liquidstake/v1beta1/liquidstake.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// ValidatorStatus enumerates the status of a liquid validator. +type ValidatorStatus int32 + +const ( + // VALIDATOR_STATUS_UNSPECIFIED defines the unspecified invalid status. + ValidatorStatusUnspecified ValidatorStatus = 0 + // VALIDATOR_STATUS_ACTIVE defines the active, valid status + ValidatorStatusActive ValidatorStatus = 1 + // VALIDATOR_STATUS_INACTIVE defines the inactive, invalid status + ValidatorStatusInactive ValidatorStatus = 2 +) + +var ValidatorStatus_name = map[int32]string{ + 0: "VALIDATOR_STATUS_UNSPECIFIED", + 1: "VALIDATOR_STATUS_ACTIVE", + 2: "VALIDATOR_STATUS_INACTIVE", +} + +var ValidatorStatus_value = map[string]int32{ + "VALIDATOR_STATUS_UNSPECIFIED": 0, + "VALIDATOR_STATUS_ACTIVE": 1, + "VALIDATOR_STATUS_INACTIVE": 2, +} + +func (x ValidatorStatus) String() string { + return proto.EnumName(ValidatorStatus_name, int32(x)) +} + +func (ValidatorStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8f87e6d47a5a3bba, []int{0} +} + +// Params defines the set of params for the liquidstake module. +type Params struct { + // LiquidBondDenom specifies the denomination of the token receiving after + // liquid stake, The value is calculated through NetAmount. + LiquidBondDenom string `protobuf:"bytes,1,opt,name=liquid_bond_denom,json=liquidBondDenom,proto3" json:"liquid_bond_denom,omitempty"` + // WhitelistedValidators specifies the validators elected to become Active + // Liquid Validators. + WhitelistedValidators []WhitelistedValidator `protobuf:"bytes,2,rep,name=whitelisted_validators,json=whitelistedValidators,proto3" json:"whitelisted_validators"` + // UnstakeFeeRate specifies the fee rate when liquid unstake is requested, + // unbonded by subtracting it from unbondingAmount + UnstakeFeeRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=unstake_fee_rate,json=unstakeFeeRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"unstake_fee_rate"` + // LsmDisabled allows to block any msgs that convert staked tokens into + // stkXPRT through LSM. + LsmDisabled bool `protobuf:"varint,4,opt,name=lsm_disabled,json=lsmDisabled,proto3" json:"lsm_disabled,omitempty"` + // MinLiquidStakingAmount specifies the minimum number of coins to be staked + // to the active liquid validators on liquid staking to minimize decimal loss + // and consider gas efficiency. + MinLiquidStakeAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,5,opt,name=min_liquid_stake_amount,json=minLiquidStakeAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"min_liquid_stake_amount"` + // cw_locked_pool_address defines the bech32-encoded address of + // a CW smart-contract representing a time locked LP (e.g. Superfluid LP). + CwLockedPoolAddress string `protobuf:"bytes,6,opt,name=cw_locked_pool_address,json=cwLockedPoolAddress,proto3" json:"cw_locked_pool_address,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_8f87e6d47a5a3bba, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +// WhitelistedValidator consists of the validator operator address and the +// target weight, which is a value for calculating the real weight to be derived +// according to the active status. In the case of inactive, it is calculated as +// zero. +type WhitelistedValidator struct { + // validator_address defines the bech32-encoded address that whitelisted + // validator + ValidatorAddress string `protobuf:"bytes,1,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + // target_weight specifies the target weight for liquid staking, unstaking + // amount, which is a value for calculating the real weight to be derived + // according to the active status + TargetWeight github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=target_weight,json=targetWeight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"target_weight"` +} + +func (m *WhitelistedValidator) Reset() { *m = WhitelistedValidator{} } +func (m *WhitelistedValidator) String() string { return proto.CompactTextString(m) } +func (*WhitelistedValidator) ProtoMessage() {} +func (*WhitelistedValidator) Descriptor() ([]byte, []int) { + return fileDescriptor_8f87e6d47a5a3bba, []int{1} +} +func (m *WhitelistedValidator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WhitelistedValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WhitelistedValidator.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WhitelistedValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_WhitelistedValidator.Merge(m, src) +} +func (m *WhitelistedValidator) XXX_Size() int { + return m.Size() +} +func (m *WhitelistedValidator) XXX_DiscardUnknown() { + xxx_messageInfo_WhitelistedValidator.DiscardUnknown(m) +} + +var xxx_messageInfo_WhitelistedValidator proto.InternalMessageInfo + +// LiquidValidator defines a Validator that can be the target of LiquidStaking +// and LiquidUnstaking, Active, Weight, etc. fields are derived as functions to +// deal with by maintaining consistency with the state of the staking module. +type LiquidValidator struct { + // operator_address defines the address of the validator's operator; bech + // encoded in JSON. + OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` +} + +func (m *LiquidValidator) Reset() { *m = LiquidValidator{} } +func (m *LiquidValidator) String() string { return proto.CompactTextString(m) } +func (*LiquidValidator) ProtoMessage() {} +func (*LiquidValidator) Descriptor() ([]byte, []int) { + return fileDescriptor_8f87e6d47a5a3bba, []int{2} +} +func (m *LiquidValidator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LiquidValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LiquidValidator.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LiquidValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_LiquidValidator.Merge(m, src) +} +func (m *LiquidValidator) XXX_Size() int { + return m.Size() +} +func (m *LiquidValidator) XXX_DiscardUnknown() { + xxx_messageInfo_LiquidValidator.DiscardUnknown(m) +} + +var xxx_messageInfo_LiquidValidator proto.InternalMessageInfo + +// LiquidValidatorState is type LiquidValidator with state added to return to +// query results. +type LiquidValidatorState struct { + // operator_address defines the address of the validator's operator; bech + // encoded in JSON. + OperatorAddress string `protobuf:"bytes,1,opt,name=operator_address,json=operatorAddress,proto3" json:"operator_address,omitempty"` + // weight specifies the weight for liquid staking, unstaking amount + Weight github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"weight"` + // status is the liquid validator status + Status ValidatorStatus `protobuf:"varint,3,opt,name=status,proto3,enum=pstake.liquidstake.v1beta1.ValidatorStatus" json:"status,omitempty"` + // del_shares define the delegation shares of the validator + DelShares github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=del_shares,json=delShares,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"del_shares"` + // liquid_tokens define the token amount worth of delegation shares of the + // validator (slashing applied amount) + LiquidTokens github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,5,opt,name=liquid_tokens,json=liquidTokens,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_tokens"` +} + +func (m *LiquidValidatorState) Reset() { *m = LiquidValidatorState{} } +func (m *LiquidValidatorState) String() string { return proto.CompactTextString(m) } +func (*LiquidValidatorState) ProtoMessage() {} +func (*LiquidValidatorState) Descriptor() ([]byte, []int) { + return fileDescriptor_8f87e6d47a5a3bba, []int{3} +} +func (m *LiquidValidatorState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LiquidValidatorState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LiquidValidatorState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LiquidValidatorState) XXX_Merge(src proto.Message) { + xxx_messageInfo_LiquidValidatorState.Merge(m, src) +} +func (m *LiquidValidatorState) XXX_Size() int { + return m.Size() +} +func (m *LiquidValidatorState) XXX_DiscardUnknown() { + xxx_messageInfo_LiquidValidatorState.DiscardUnknown(m) +} + +var xxx_messageInfo_LiquidValidatorState proto.InternalMessageInfo + +// NetAmountState is type for net amount raw data and mint rate, This is a value +// that depends on the several module state every time, so it is used only for +// calculation and query and is not stored in kv. +type NetAmountState struct { + // mint_rate is stkXPRTTotalSupply / NetAmount + MintRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=mint_rate,json=mintRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"mint_rate"` + // btoken_total_supply returns the total supply of stk/uxprt (stkXPRT denom) + StkxprtTotalSupply github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=stkxprt_total_supply,json=stkxprtTotalSupply,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"stkxprt_total_supply"` + // net_amount is proxy account's native token balance + total liquid tokens + + // total remaining rewards + total unbonding balance + NetAmount github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=net_amount,json=netAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"net_amount"` + // total_del_shares define the delegation shares of all liquid validators + TotalDelShares github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=total_del_shares,json=totalDelShares,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_del_shares"` + // total_liquid_tokens define the token amount worth of delegation shares of + // all liquid validator (slashing applied amount) + TotalLiquidTokens github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,5,opt,name=total_liquid_tokens,json=totalLiquidTokens,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_liquid_tokens"` + // total_remaining_rewards define the sum of remaining rewards of proxy + // account by all liquid validators + TotalRemainingRewards github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=total_remaining_rewards,json=totalRemainingRewards,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_remaining_rewards"` + // total_unbonding_balance define the unbonding balance of proxy account by + // all liquid validator (slashing applied amount) + TotalUnbondingBalance github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,7,opt,name=total_unbonding_balance,json=totalUnbondingBalance,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_unbonding_balance"` + // proxy_acc_balance define the balance of proxy account for the native token + ProxyAccBalance github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,8,opt,name=proxy_acc_balance,json=proxyAccBalance,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"proxy_acc_balance"` +} + +func (m *NetAmountState) Reset() { *m = NetAmountState{} } +func (m *NetAmountState) String() string { return proto.CompactTextString(m) } +func (*NetAmountState) ProtoMessage() {} +func (*NetAmountState) Descriptor() ([]byte, []int) { + return fileDescriptor_8f87e6d47a5a3bba, []int{4} +} +func (m *NetAmountState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NetAmountState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_NetAmountState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *NetAmountState) XXX_Merge(src proto.Message) { + xxx_messageInfo_NetAmountState.Merge(m, src) +} +func (m *NetAmountState) XXX_Size() int { + return m.Size() +} +func (m *NetAmountState) XXX_DiscardUnknown() { + xxx_messageInfo_NetAmountState.DiscardUnknown(m) +} + +var xxx_messageInfo_NetAmountState proto.InternalMessageInfo + +func init() { + proto.RegisterEnum("pstake.liquidstake.v1beta1.ValidatorStatus", ValidatorStatus_name, ValidatorStatus_value) + proto.RegisterType((*Params)(nil), "pstake.liquidstake.v1beta1.Params") + proto.RegisterType((*WhitelistedValidator)(nil), "pstake.liquidstake.v1beta1.WhitelistedValidator") + proto.RegisterType((*LiquidValidator)(nil), "pstake.liquidstake.v1beta1.LiquidValidator") + proto.RegisterType((*LiquidValidatorState)(nil), "pstake.liquidstake.v1beta1.LiquidValidatorState") + proto.RegisterType((*NetAmountState)(nil), "pstake.liquidstake.v1beta1.NetAmountState") +} + +func init() { + proto.RegisterFile("pstake/liquidstake/v1beta1/liquidstake.proto", fileDescriptor_8f87e6d47a5a3bba) +} + +var fileDescriptor_8f87e6d47a5a3bba = []byte{ + // 917 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x41, 0x4f, 0x1b, 0x47, + 0x14, 0xc7, 0xbd, 0x40, 0x5c, 0x98, 0x50, 0x6c, 0x26, 0x26, 0x18, 0xb7, 0x32, 0x2e, 0x87, 0x0a, + 0xa5, 0xc5, 0x6e, 0xa8, 0xd4, 0x03, 0x87, 0xaa, 0x36, 0x06, 0xc9, 0x2a, 0x21, 0x68, 0xd7, 0x90, + 0x28, 0x87, 0x4e, 0xc6, 0xbb, 0x0f, 0xb3, 0xf2, 0xee, 0xcc, 0x76, 0x67, 0x8c, 0xe1, 0x1b, 0x44, + 0x9c, 0x7a, 0xaa, 0x7a, 0x41, 0x8a, 0xd4, 0xaf, 0xd0, 0x43, 0x3f, 0x42, 0x2e, 0x95, 0xa2, 0x9e, + 0xaa, 0x1e, 0xa2, 0x08, 0x2e, 0xfd, 0x14, 0x55, 0x35, 0x33, 0x6b, 0x63, 0x9c, 0xb4, 0x15, 0x4e, + 0x4e, 0x5e, 0xcf, 0xdb, 0xff, 0xef, 0xff, 0xe6, 0xbd, 0x7d, 0xb3, 0x8b, 0x3e, 0x8f, 0x84, 0xa4, + 0x1d, 0xa8, 0x04, 0xfe, 0xf7, 0x5d, 0xdf, 0x33, 0xd7, 0xc7, 0xf7, 0x5b, 0x20, 0xe9, 0xfd, 0xe1, + 0xb5, 0x72, 0x14, 0x73, 0xc9, 0x71, 0xc1, 0xdc, 0x5d, 0x1e, 0x8e, 0x24, 0x77, 0x17, 0x72, 0x6d, + 0xde, 0xe6, 0xfa, 0xb6, 0x8a, 0xba, 0x32, 0x8a, 0xc2, 0x92, 0xcb, 0x45, 0xc8, 0x05, 0x31, 0x01, + 0xf3, 0xc7, 0x84, 0x56, 0x5e, 0x4f, 0xa2, 0xf4, 0x1e, 0x8d, 0x69, 0x28, 0xf0, 0x3d, 0x34, 0x6f, + 0x90, 0xa4, 0xc5, 0x99, 0x47, 0x3c, 0x60, 0x3c, 0xcc, 0x5b, 0x25, 0x6b, 0x75, 0xc6, 0xce, 0x98, + 0x40, 0x8d, 0x33, 0xaf, 0xae, 0x96, 0x71, 0x88, 0xee, 0xf6, 0x8e, 0x7c, 0x09, 0x81, 0x2f, 0x24, + 0x78, 0xe4, 0x98, 0x06, 0xbe, 0x47, 0x25, 0x8f, 0x45, 0x7e, 0xa2, 0x34, 0xb9, 0x7a, 0x7b, 0xfd, + 0x8b, 0xf2, 0xbf, 0x27, 0x59, 0x7e, 0x74, 0xa5, 0x3c, 0xe8, 0x0b, 0x6b, 0x53, 0x2f, 0x5e, 0x2d, + 0xa7, 0xec, 0x85, 0xde, 0x5b, 0x62, 0x02, 0x3f, 0x46, 0xd9, 0x2e, 0xd3, 0x10, 0x72, 0x08, 0x40, + 0x62, 0x2a, 0x21, 0x3f, 0xa9, 0x32, 0xab, 0x95, 0x95, 0xec, 0xcf, 0x57, 0xcb, 0x9f, 0xb6, 0x7d, + 0x79, 0xd4, 0x6d, 0x95, 0x5d, 0x1e, 0x26, 0x1b, 0x4c, 0x7e, 0xd6, 0x84, 0xd7, 0xa9, 0xc8, 0xd3, + 0x08, 0x44, 0xb9, 0x0e, 0xae, 0x3d, 0x97, 0x70, 0xb6, 0x01, 0x6c, 0x2a, 0x01, 0x7f, 0x82, 0x66, + 0x03, 0x11, 0x12, 0xcf, 0x17, 0xb4, 0x15, 0x80, 0x97, 0x9f, 0x2a, 0x59, 0xab, 0xd3, 0xf6, 0xed, + 0x40, 0x84, 0xf5, 0x64, 0x09, 0x03, 0x5a, 0x0c, 0x7d, 0x46, 0x92, 0xda, 0x98, 0x2c, 0x68, 0xc8, + 0xbb, 0x4c, 0xe6, 0x6f, 0xdd, 0x38, 0x87, 0x06, 0x93, 0x76, 0x2e, 0xf4, 0xd9, 0x8e, 0xa6, 0x39, + 0x0a, 0x56, 0xd5, 0x2c, 0xfc, 0x00, 0xdd, 0x75, 0x7b, 0x24, 0xe0, 0x6e, 0x07, 0x3c, 0x12, 0x71, + 0x1e, 0x10, 0xea, 0x79, 0x31, 0x08, 0x91, 0x4f, 0x6b, 0x97, 0xfc, 0xef, 0xbf, 0xac, 0xe5, 0x92, + 0xde, 0x55, 0x4d, 0xc4, 0x91, 0xb1, 0xcf, 0xda, 0xf6, 0x1d, 0xb7, 0xb7, 0xa3, 0x65, 0x7b, 0x9c, + 0x07, 0x49, 0x68, 0x63, 0xfa, 0xd9, 0xf3, 0xe5, 0xd4, 0x4f, 0xcf, 0x97, 0x53, 0x2b, 0xbf, 0x5a, + 0x28, 0xf7, 0xb6, 0x92, 0xe3, 0x2d, 0x34, 0x3f, 0x68, 0xdc, 0xc0, 0xcc, 0xfa, 0x1f, 0xb3, 0xec, + 0x40, 0x92, 0xac, 0x63, 0x07, 0x7d, 0x28, 0x69, 0xdc, 0x06, 0x49, 0x7a, 0xe0, 0xb7, 0x8f, 0x64, + 0x7e, 0x62, 0xac, 0xaa, 0xcc, 0x1a, 0xc8, 0x23, 0xcd, 0xd8, 0x98, 0x52, 0xe9, 0xaf, 0x3c, 0x45, + 0x19, 0x53, 0xa8, 0xab, 0xa4, 0x37, 0x51, 0x96, 0x47, 0x10, 0xdf, 0x28, 0xe7, 0x4c, 0x5f, 0x71, + 0xad, 0x38, 0x7f, 0x29, 0x87, 0x1f, 0x27, 0x51, 0x6e, 0xc4, 0xc2, 0x91, 0xea, 0xc1, 0x78, 0x1f, + 0x3e, 0x78, 0x1b, 0xa5, 0xdf, 0xa9, 0x26, 0x89, 0x1a, 0x6f, 0xa2, 0xb4, 0x90, 0x54, 0x76, 0x85, + 0x7e, 0xea, 0xe7, 0xd6, 0x3f, 0xfb, 0xaf, 0xf1, 0xba, 0xb6, 0x91, 0xae, 0xb0, 0x13, 0x29, 0x7e, + 0x80, 0x90, 0x07, 0x01, 0x11, 0x47, 0x34, 0x06, 0xa1, 0x1f, 0xf4, 0x9b, 0x8f, 0xcf, 0x8c, 0x07, + 0x81, 0xa3, 0x01, 0xaa, 0xed, 0xc9, 0x48, 0x48, 0xde, 0x01, 0x26, 0xc6, 0x1c, 0x86, 0x59, 0x03, + 0x69, 0x6a, 0xc6, 0x50, 0x63, 0xfe, 0xbe, 0x85, 0xe6, 0x76, 0x41, 0x9a, 0xe1, 0x30, 0x2d, 0xf9, + 0x16, 0xcd, 0x84, 0x3e, 0x93, 0x66, 0xfc, 0xad, 0xb1, 0xf2, 0x9f, 0x56, 0x00, 0x3d, 0xf8, 0x4f, + 0x51, 0x4e, 0xc8, 0xce, 0x49, 0x14, 0x4b, 0x22, 0xb9, 0xa4, 0x01, 0x11, 0xdd, 0x28, 0x0a, 0x4e, + 0xc7, 0x6c, 0x14, 0x4e, 0x58, 0x4d, 0x85, 0x72, 0x34, 0x49, 0xd5, 0x9b, 0x81, 0xec, 0x1f, 0x15, + 0xe3, 0x1d, 0x57, 0x33, 0xac, 0x5f, 0x02, 0x75, 0x06, 0x9a, 0x44, 0xdf, 0xb9, 0x89, 0x73, 0x9a, + 0x53, 0x1f, 0x74, 0xf2, 0x3b, 0x74, 0xc7, 0x90, 0xdf, 0x47, 0x3f, 0xe7, 0x35, 0x6a, 0x67, 0xa8, + 0xa9, 0xf8, 0x10, 0x2d, 0x1a, 0x7e, 0x0c, 0x21, 0xf5, 0x99, 0xcf, 0xda, 0x24, 0x86, 0x1e, 0x8d, + 0xbd, 0xfe, 0xd1, 0x76, 0xd3, 0x0d, 0x2c, 0x68, 0x9c, 0xdd, 0xa7, 0xd9, 0x06, 0x76, 0xe5, 0xd3, + 0x65, 0xea, 0x0d, 0xa6, 0x7c, 0x5a, 0x34, 0xa0, 0xcc, 0x85, 0xfc, 0x07, 0x63, 0xed, 0xc5, 0xf8, + 0xec, 0xf7, 0x69, 0x35, 0x03, 0xc3, 0x4f, 0xd0, 0x7c, 0x14, 0xf3, 0x93, 0x53, 0x42, 0x5d, 0x77, + 0xe0, 0x30, 0x3d, 0x96, 0x43, 0x46, 0x83, 0xaa, 0xae, 0x9b, 0xb0, 0xf5, 0x00, 0x58, 0x6a, 0x00, + 0xee, 0xfd, 0x66, 0xa1, 0xcc, 0xc8, 0x28, 0xe3, 0x6f, 0xd0, 0xc7, 0x07, 0xd5, 0x9d, 0x46, 0xbd, + 0xda, 0x7c, 0x68, 0x13, 0xa7, 0x59, 0x6d, 0xee, 0x3b, 0x64, 0x7f, 0xd7, 0xd9, 0xdb, 0xda, 0x6c, + 0x6c, 0x37, 0xb6, 0xea, 0xd9, 0x54, 0xa1, 0x78, 0x76, 0x5e, 0x2a, 0x8c, 0xc8, 0xf6, 0x99, 0x88, + 0xc0, 0xf5, 0x0f, 0x7d, 0xf0, 0xf0, 0x57, 0x68, 0xf1, 0x0d, 0x42, 0x75, 0xb3, 0xd9, 0x38, 0xd8, + 0xca, 0x5a, 0x85, 0xa5, 0xb3, 0xf3, 0xd2, 0xc2, 0x88, 0xb8, 0xea, 0x4a, 0xff, 0x18, 0xf0, 0x06, + 0x5a, 0x7a, 0x43, 0xd7, 0xd8, 0x4d, 0x94, 0x13, 0x85, 0x8f, 0xce, 0xce, 0x4b, 0x8b, 0x23, 0xca, + 0x06, 0xa3, 0x5a, 0x5b, 0x98, 0x7a, 0xf6, 0x73, 0x31, 0x55, 0x7b, 0xfc, 0xe2, 0xa2, 0x68, 0xbd, + 0xbc, 0x28, 0x5a, 0xaf, 0x2f, 0x8a, 0xd6, 0x0f, 0x97, 0xc5, 0xd4, 0xcb, 0xcb, 0x62, 0xea, 0x8f, + 0xcb, 0x62, 0xea, 0xc9, 0xd7, 0x43, 0xc5, 0x8a, 0x20, 0x16, 0xea, 0x35, 0xc5, 0x5c, 0x78, 0xc8, + 0xa0, 0x62, 0x8e, 0xb9, 0x35, 0x46, 0x15, 0xa8, 0x72, 0xbc, 0x5e, 0x39, 0xb9, 0xf6, 0x91, 0xa4, + 0x0b, 0xd9, 0x4a, 0xeb, 0x4f, 0x99, 0x2f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x62, 0xa0, + 0xc1, 0x47, 0x09, 0x00, 0x00, +} + +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CwLockedPoolAddress) > 0 { + i -= len(m.CwLockedPoolAddress) + copy(dAtA[i:], m.CwLockedPoolAddress) + i = encodeVarintLiquidstake(dAtA, i, uint64(len(m.CwLockedPoolAddress))) + i-- + dAtA[i] = 0x32 + } + { + size := m.MinLiquidStakeAmount.Size() + i -= size + if _, err := m.MinLiquidStakeAmount.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if m.LsmDisabled { + i-- + if m.LsmDisabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + { + size := m.UnstakeFeeRate.Size() + i -= size + if _, err := m.UnstakeFeeRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.WhitelistedValidators) > 0 { + for iNdEx := len(m.WhitelistedValidators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.WhitelistedValidators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.LiquidBondDenom) > 0 { + i -= len(m.LiquidBondDenom) + copy(dAtA[i:], m.LiquidBondDenom) + i = encodeVarintLiquidstake(dAtA, i, uint64(len(m.LiquidBondDenom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WhitelistedValidator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WhitelistedValidator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WhitelistedValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.TargetWeight.Size() + i -= size + if _, err := m.TargetWeight.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.ValidatorAddress) > 0 { + i -= len(m.ValidatorAddress) + copy(dAtA[i:], m.ValidatorAddress) + i = encodeVarintLiquidstake(dAtA, i, uint64(len(m.ValidatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LiquidValidator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LiquidValidator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LiquidValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.OperatorAddress) > 0 { + i -= len(m.OperatorAddress) + copy(dAtA[i:], m.OperatorAddress) + i = encodeVarintLiquidstake(dAtA, i, uint64(len(m.OperatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LiquidValidatorState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LiquidValidatorState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LiquidValidatorState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.LiquidTokens.Size() + i -= size + if _, err := m.LiquidTokens.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size := m.DelShares.Size() + i -= size + if _, err := m.DelShares.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if m.Status != 0 { + i = encodeVarintLiquidstake(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x18 + } + { + size := m.Weight.Size() + i -= size + if _, err := m.Weight.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.OperatorAddress) > 0 { + i -= len(m.OperatorAddress) + copy(dAtA[i:], m.OperatorAddress) + i = encodeVarintLiquidstake(dAtA, i, uint64(len(m.OperatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *NetAmountState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NetAmountState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NetAmountState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.ProxyAccBalance.Size() + i -= size + if _, err := m.ProxyAccBalance.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + { + size := m.TotalUnbondingBalance.Size() + i -= size + if _, err := m.TotalUnbondingBalance.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + { + size := m.TotalRemainingRewards.Size() + i -= size + if _, err := m.TotalRemainingRewards.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + { + size := m.TotalLiquidTokens.Size() + i -= size + if _, err := m.TotalLiquidTokens.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size := m.TotalDelShares.Size() + i -= size + if _, err := m.TotalDelShares.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size := m.NetAmount.Size() + i -= size + if _, err := m.NetAmount.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size := m.StkxprtTotalSupply.Size() + i -= size + if _, err := m.StkxprtTotalSupply.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.MintRate.Size() + i -= size + if _, err := m.MintRate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLiquidstake(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintLiquidstake(dAtA []byte, offset int, v uint64) int { + offset -= sovLiquidstake(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.LiquidBondDenom) + if l > 0 { + n += 1 + l + sovLiquidstake(uint64(l)) + } + if len(m.WhitelistedValidators) > 0 { + for _, e := range m.WhitelistedValidators { + l = e.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + } + } + l = m.UnstakeFeeRate.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + if m.LsmDisabled { + n += 2 + } + l = m.MinLiquidStakeAmount.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = len(m.CwLockedPoolAddress) + if l > 0 { + n += 1 + l + sovLiquidstake(uint64(l)) + } + return n +} + +func (m *WhitelistedValidator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorAddress) + if l > 0 { + n += 1 + l + sovLiquidstake(uint64(l)) + } + l = m.TargetWeight.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + return n +} + +func (m *LiquidValidator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OperatorAddress) + if l > 0 { + n += 1 + l + sovLiquidstake(uint64(l)) + } + return n +} + +func (m *LiquidValidatorState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OperatorAddress) + if l > 0 { + n += 1 + l + sovLiquidstake(uint64(l)) + } + l = m.Weight.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + if m.Status != 0 { + n += 1 + sovLiquidstake(uint64(m.Status)) + } + l = m.DelShares.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.LiquidTokens.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + return n +} + +func (m *NetAmountState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.MintRate.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.StkxprtTotalSupply.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.NetAmount.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.TotalDelShares.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.TotalLiquidTokens.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.TotalRemainingRewards.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.TotalUnbondingBalance.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + l = m.ProxyAccBalance.Size() + n += 1 + l + sovLiquidstake(uint64(l)) + return n +} + +func sovLiquidstake(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozLiquidstake(x uint64) (n int) { + return sovLiquidstake(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidBondDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LiquidBondDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WhitelistedValidators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WhitelistedValidators = append(m.WhitelistedValidators, WhitelistedValidator{}) + if err := m.WhitelistedValidators[len(m.WhitelistedValidators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnstakeFeeRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UnstakeFeeRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LsmDisabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.LsmDisabled = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinLiquidStakeAmount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MinLiquidStakeAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CwLockedPoolAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CwLockedPoolAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLiquidstake(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLiquidstake + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WhitelistedValidator) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WhitelistedValidator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WhitelistedValidator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetWeight", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TargetWeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLiquidstake(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLiquidstake + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LiquidValidator) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LiquidValidator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LiquidValidator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OperatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLiquidstake(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLiquidstake + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LiquidValidatorState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LiquidValidatorState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LiquidValidatorState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OperatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Weight", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Weight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= ValidatorStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelShares", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DelShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidTokens", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LiquidTokens.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLiquidstake(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLiquidstake + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetAmountState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetAmountState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetAmountState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MintRate", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MintRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StkxprtTotalSupply", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.StkxprtTotalSupply.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetAmount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NetAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalDelShares", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalDelShares.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalLiquidTokens", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalLiquidTokens.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalRemainingRewards", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalRemainingRewards.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalUnbondingBalance", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TotalUnbondingBalance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProxyAccBalance", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLiquidstake + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLiquidstake + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ProxyAccBalance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLiquidstake(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLiquidstake + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipLiquidstake(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowLiquidstake + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthLiquidstake + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupLiquidstake + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthLiquidstake + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthLiquidstake = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowLiquidstake = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupLiquidstake = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/liquidstake/types/msgs.go b/x/liquidstake/types/msgs.go new file mode 100644 index 000000000..c45ab9ea4 --- /dev/null +++ b/x/liquidstake/types/msgs.go @@ -0,0 +1,226 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var ( + _ sdk.Msg = (*MsgLiquidStake)(nil) + _ sdk.Msg = (*MsgLiquidUnstake)(nil) + _ sdk.Msg = (*MsgUpdateParams)(nil) +) + +// Message types for the liquidstake module +const ( + MsgTypeLiquidStake = "liquid_stake" + MsgTypeLiquidUnstake = "liquid_unstake" + MsgTypeStakeToLP = "stake_to_lp" + MsgTypeUpdateParams = "update_params" +) + +// NewMsgLiquidStake creates a new MsgLiquidStake. +func NewMsgLiquidStake( + liquidStaker sdk.AccAddress, + amount sdk.Coin, +) *MsgLiquidStake { + return &MsgLiquidStake{ + DelegatorAddress: liquidStaker.String(), + Amount: amount, + } +} + +func (m *MsgLiquidStake) Route() string { return RouterKey } + +func (m *MsgLiquidStake) Type() string { return MsgTypeLiquidStake } + +func (m *MsgLiquidStake) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.DelegatorAddress); err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid delegator address %q: %v", m.DelegatorAddress, err) + } + if ok := m.Amount.IsZero(); ok { + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "staking amount must not be zero") + } + if err := m.Amount.Validate(); err != nil { + return err + } + return nil +} + +func (m *MsgLiquidStake) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(m)) +} + +func (m *MsgLiquidStake) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.DelegatorAddress) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +func (m *MsgLiquidStake) GetDelegator() sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.DelegatorAddress) + if err != nil { + panic(err) + } + return addr +} + +// NewMsgStakeToLP creates a new MsgStakeToLP. +func NewMsgStakeToLP( + liquidStaker sdk.AccAddress, + validator sdk.ValAddress, + stakedAmount, + liquidAmount sdk.Coin, +) *MsgStakeToLP { + return &MsgStakeToLP{ + DelegatorAddress: liquidStaker.String(), + ValidatorAddress: validator.String(), + StakedAmount: stakedAmount, + LiquidAmount: liquidAmount, + } +} + +func (m *MsgStakeToLP) Route() string { return RouterKey } + +func (m *MsgStakeToLP) Type() string { return MsgTypeStakeToLP } + +func (m *MsgStakeToLP) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.DelegatorAddress); err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid delegator address %q: %v", m.DelegatorAddress, err) + } + if _, err := sdk.ValAddressFromBech32(m.ValidatorAddress); err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address %q: %v", m.ValidatorAddress, err) + } + if ok := m.StakedAmount.IsZero(); ok { + return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "staking amount must not be zero") + } + if err := m.StakedAmount.Validate(); err != nil { + return err + } + if err := m.LiquidAmount.Validate(); err != nil { + return err + } + return nil +} + +func (m *MsgStakeToLP) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(m)) +} + +func (m *MsgStakeToLP) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.DelegatorAddress) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +func (m *MsgStakeToLP) GetValidator() sdk.ValAddress { + addr, err := sdk.ValAddressFromBech32(m.ValidatorAddress) + if err != nil { + panic(err) + } + return addr +} + +func (m *MsgStakeToLP) GetDelegator() sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.DelegatorAddress) + if err != nil { + panic(err) + } + return addr +} + +// NewMsgLiquidUnstake creates a new MsgLiquidUnstake. +func NewMsgLiquidUnstake( + liquidStaker sdk.AccAddress, + amount sdk.Coin, +) *MsgLiquidUnstake { + return &MsgLiquidUnstake{ + DelegatorAddress: liquidStaker.String(), + Amount: amount, + } +} + +func (m *MsgLiquidUnstake) Route() string { return RouterKey } + +func (m *MsgLiquidUnstake) Type() string { return MsgTypeLiquidUnstake } + +func (m *MsgLiquidUnstake) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.DelegatorAddress); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid delegator address %q: %v", m.DelegatorAddress, err) + } + if ok := m.Amount.IsZero(); ok { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "unstaking amount must not be zero") + } + if err := m.Amount.Validate(); err != nil { + return err + } + return nil +} + +func (m *MsgLiquidUnstake) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(m)) +} + +func (m *MsgLiquidUnstake) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.DelegatorAddress) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +func (m *MsgLiquidUnstake) GetDelegator() sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.DelegatorAddress) + if err != nil { + panic(err) + } + return addr +} + +// NewMsgUpdateParams creates a new MsgUpdateParams. +func NewMsgUpdateParams(authority sdk.AccAddress, amount Params) *MsgUpdateParams { + return &MsgUpdateParams{ + Authority: authority.String(), + Params: amount, + } +} + +func (m *MsgUpdateParams) Route() string { + return RouterKey +} + +// Type should return the action +func (m *MsgUpdateParams) Type() string { + return MsgTypeUpdateParams +} + +// GetSignBytes encodes the message for signing +func (m *MsgUpdateParams) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(m)) +} + +// GetSigners defines whose signature is required +func (m *MsgUpdateParams) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(m.Authority) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +func (m *MsgUpdateParams) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { + return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid authority address %q: %v", m.Authority, err) + } + + err := m.Params.Validate() + if err != nil { + return err + } + return nil +} diff --git a/x/liquidstake/types/params.go b/x/liquidstake/types/params.go new file mode 100644 index 000000000..8439efab7 --- /dev/null +++ b/x/liquidstake/types/params.go @@ -0,0 +1,155 @@ +package types + +import ( + "fmt" + "strings" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "gopkg.in/yaml.v2" +) + +// Parameter store keys +var ( + DefaultLiquidBondDenom = "stk/uxprt" + + // DefaultUnstakeFeeRate is the default Unstake Fee Rate. + DefaultUnstakeFeeRate = sdk.ZeroDec() + + // DefaultMinLiquidStakeAmount is the default minimum liquid staking amount. + DefaultMinLiquidStakeAmount = sdk.NewInt(1000) + + // Const variables + + // RebalancingTrigger if the maximum difference and needed each redelegation amount exceeds it, asset rebalacing will be executed. + RebalancingTrigger = sdk.NewDecWithPrec(1, 3) // "0.001000000000000000" + + // AutocompoundTrigger If the sum of balance and the upcoming rewards of LiquidStakeProxyAcc exceeds it, + // the reward is automatically autocompounded, according to the weights. + AutocompoundTrigger = sdk.NewDecWithPrec(1, 3) // "0.001000000000000000" + + // LiquidStakeProxyAcc is a proxy reserve account for delegation and undelegation. + LiquidStakeProxyAcc = authtypes.NewModuleAddress(ModuleName + "-LiquidStakingProxyAcc") +) + +// DefaultParams returns the default liquidstake module parameters. +func DefaultParams() Params { + return Params{ + WhitelistedValidators: []WhitelistedValidator{}, + LiquidBondDenom: DefaultLiquidBondDenom, + UnstakeFeeRate: DefaultUnstakeFeeRate, + MinLiquidStakeAmount: DefaultMinLiquidStakeAmount, + } +} + +// String returns a human-readable string representation of the parameters. +func (p Params) String() string { + out, _ := yaml.Marshal(p) + return string(out) +} + +func (p Params) WhitelistedValsMap() WhitelistedValsMap { + return GetWhitelistedValsMap(p.WhitelistedValidators) +} + +// Validate validates parameters. +func (p Params) Validate() error { + for _, v := range []struct { + value interface{} + validator func(interface{}) error + }{ + {p.LiquidBondDenom, validateLiquidBondDenom}, + {p.WhitelistedValidators, validateWhitelistedValidators}, + {p.UnstakeFeeRate, validateUnstakeFeeRate}, + {p.MinLiquidStakeAmount, validateMinLiquidStakeAmount}, + } { + if err := v.validator(v.value); err != nil { + return err + } + } + return nil +} + +func validateLiquidBondDenom(i interface{}) error { + v, ok := i.(string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if strings.TrimSpace(v) == "" { + return fmt.Errorf("liquid bond denom cannot be blank") + } + + if err := sdk.ValidateDenom(v); err != nil { + return err + } + return nil +} + +// validateWhitelistedValidators validates liquidstake validator and total weight. +func validateWhitelistedValidators(i interface{}) error { + wvs, ok := i.([]WhitelistedValidator) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + valsMap := map[string]struct{}{} + for _, wv := range wvs { + _, valErr := sdk.ValAddressFromBech32(wv.ValidatorAddress) + if valErr != nil { + return valErr + } + + if wv.TargetWeight.IsNil() { + return fmt.Errorf("liquidstake validator target weight must not be nil") + } + + if !wv.TargetWeight.IsPositive() { + return fmt.Errorf("liquidstake validator target weight must be positive: %s", wv.TargetWeight) + } + + if _, ok := valsMap[wv.ValidatorAddress]; ok { + return fmt.Errorf("liquidstake validator cannot be duplicated: %s", wv.ValidatorAddress) + } + valsMap[wv.ValidatorAddress] = struct{}{} + } + return nil +} + +func validateUnstakeFeeRate(i interface{}) error { + v, ok := i.(sdk.Dec) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.IsNil() { + return fmt.Errorf("unstake fee rate must not be nil") + } + + if v.IsNegative() { + return fmt.Errorf("unstake fee rate must not be negative: %s", v) + } + + if v.GT(sdk.OneDec()) { + return fmt.Errorf("unstake fee rate too large: %s", v) + } + + return nil +} + +func validateMinLiquidStakeAmount(i interface{}) error { + v, ok := i.(math.Int) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.IsNil() { + return fmt.Errorf("min liquid staking amount must not be nil") + } + + if v.IsNegative() { + return fmt.Errorf("min liquid staking amount must not be negative: %s", v) + } + + return nil +} diff --git a/x/liquidstake/types/query.pb.go b/x/liquidstake/types/query.pb.go new file mode 100644 index 000000000..55b324d5a --- /dev/null +++ b/x/liquidstake/types/query.pb.go @@ -0,0 +1,1222 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pstake/liquidstake/v1beta1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_1badba19848dd753, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1badba19848dd753, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// QueryLiquidValidatorsRequest is the request type for the +// Query/LiquidValidators RPC method. +type QueryLiquidValidatorsRequest struct { +} + +func (m *QueryLiquidValidatorsRequest) Reset() { *m = QueryLiquidValidatorsRequest{} } +func (m *QueryLiquidValidatorsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryLiquidValidatorsRequest) ProtoMessage() {} +func (*QueryLiquidValidatorsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_1badba19848dd753, []int{2} +} +func (m *QueryLiquidValidatorsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryLiquidValidatorsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryLiquidValidatorsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryLiquidValidatorsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryLiquidValidatorsRequest.Merge(m, src) +} +func (m *QueryLiquidValidatorsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryLiquidValidatorsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryLiquidValidatorsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryLiquidValidatorsRequest proto.InternalMessageInfo + +// QueryLiquidValidatorsResponse is the response type for the +// Query/LiquidValidators RPC method. +type QueryLiquidValidatorsResponse struct { + LiquidValidators []LiquidValidatorState `protobuf:"bytes,1,rep,name=liquid_validators,json=liquidValidators,proto3" json:"liquid_validators"` +} + +func (m *QueryLiquidValidatorsResponse) Reset() { *m = QueryLiquidValidatorsResponse{} } +func (m *QueryLiquidValidatorsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryLiquidValidatorsResponse) ProtoMessage() {} +func (*QueryLiquidValidatorsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1badba19848dd753, []int{3} +} +func (m *QueryLiquidValidatorsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryLiquidValidatorsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryLiquidValidatorsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryLiquidValidatorsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryLiquidValidatorsResponse.Merge(m, src) +} +func (m *QueryLiquidValidatorsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryLiquidValidatorsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryLiquidValidatorsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryLiquidValidatorsResponse proto.InternalMessageInfo + +func (m *QueryLiquidValidatorsResponse) GetLiquidValidators() []LiquidValidatorState { + if m != nil { + return m.LiquidValidators + } + return nil +} + +// QueryStatesRequest is the request type for the Query/States RPC method. +type QueryStatesRequest struct { +} + +func (m *QueryStatesRequest) Reset() { *m = QueryStatesRequest{} } +func (m *QueryStatesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryStatesRequest) ProtoMessage() {} +func (*QueryStatesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_1badba19848dd753, []int{4} +} +func (m *QueryStatesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryStatesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryStatesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryStatesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryStatesRequest.Merge(m, src) +} +func (m *QueryStatesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryStatesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryStatesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryStatesRequest proto.InternalMessageInfo + +// QueryStatesResponse is the response type for the Query/States RPC method. +type QueryStatesResponse struct { + NetAmountState NetAmountState `protobuf:"bytes,1,opt,name=net_amount_state,json=netAmountState,proto3" json:"net_amount_state"` +} + +func (m *QueryStatesResponse) Reset() { *m = QueryStatesResponse{} } +func (m *QueryStatesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryStatesResponse) ProtoMessage() {} +func (*QueryStatesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1badba19848dd753, []int{5} +} +func (m *QueryStatesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryStatesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryStatesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryStatesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryStatesResponse.Merge(m, src) +} +func (m *QueryStatesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryStatesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryStatesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryStatesResponse proto.InternalMessageInfo + +func (m *QueryStatesResponse) GetNetAmountState() NetAmountState { + if m != nil { + return m.NetAmountState + } + return NetAmountState{} +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "pstake.liquidstake.v1beta1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "pstake.liquidstake.v1beta1.QueryParamsResponse") + proto.RegisterType((*QueryLiquidValidatorsRequest)(nil), "pstake.liquidstake.v1beta1.QueryLiquidValidatorsRequest") + proto.RegisterType((*QueryLiquidValidatorsResponse)(nil), "pstake.liquidstake.v1beta1.QueryLiquidValidatorsResponse") + proto.RegisterType((*QueryStatesRequest)(nil), "pstake.liquidstake.v1beta1.QueryStatesRequest") + proto.RegisterType((*QueryStatesResponse)(nil), "pstake.liquidstake.v1beta1.QueryStatesResponse") +} + +func init() { + proto.RegisterFile("pstake/liquidstake/v1beta1/query.proto", fileDescriptor_1badba19848dd753) +} + +var fileDescriptor_1badba19848dd753 = []byte{ + // 463 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcd, 0x8a, 0x13, 0x41, + 0x10, 0x4e, 0xbb, 0x9a, 0x43, 0x2f, 0x48, 0x6c, 0xf7, 0xb0, 0x0c, 0xeb, 0xb8, 0x0c, 0xb2, 0x84, + 0x45, 0xbb, 0xdd, 0x78, 0xd1, 0x8b, 0xe8, 0x9e, 0xc5, 0x9f, 0x15, 0x54, 0xf6, 0x12, 0x3a, 0xd9, + 0x62, 0x6c, 0x4c, 0xba, 0x27, 0xd3, 0x35, 0xc1, 0xbd, 0x8a, 0x0f, 0x20, 0x88, 0xcf, 0xe2, 0x2b, + 0xec, 0x71, 0xc1, 0x8b, 0x27, 0x91, 0xc4, 0x17, 0xf0, 0x0d, 0x24, 0xdd, 0xed, 0x98, 0x89, 0x64, + 0x1c, 0xbc, 0x15, 0xd5, 0x5f, 0xd5, 0xf7, 0xcd, 0x57, 0xdf, 0xd0, 0xbd, 0xcc, 0xa2, 0x7c, 0x03, + 0x62, 0xa4, 0x26, 0x85, 0x3a, 0xf1, 0xf5, 0xf4, 0x60, 0x00, 0x28, 0x0f, 0xc4, 0xa4, 0x80, 0xfc, + 0x94, 0x67, 0xb9, 0x41, 0xc3, 0x22, 0x8f, 0xe3, 0x4b, 0x38, 0x1e, 0x70, 0xd1, 0x4e, 0x6a, 0x4c, + 0x3a, 0x02, 0x21, 0x33, 0x25, 0xa4, 0xd6, 0x06, 0x25, 0x2a, 0xa3, 0xad, 0x9f, 0x8c, 0x6e, 0xd6, + 0x30, 0x2c, 0x6f, 0xf3, 0xe8, 0xad, 0xd4, 0xa4, 0xc6, 0x95, 0x62, 0x51, 0xf9, 0x6e, 0xb2, 0x45, + 0xd9, 0xb3, 0x85, 0x98, 0xa7, 0x32, 0x97, 0x63, 0x7b, 0x04, 0x93, 0x02, 0x2c, 0x26, 0x2f, 0xe9, + 0xd5, 0x4a, 0xd7, 0x66, 0x46, 0x5b, 0x60, 0x0f, 0x68, 0x3b, 0x73, 0x9d, 0x6d, 0xb2, 0x4b, 0xba, + 0x9b, 0xbd, 0x84, 0xaf, 0xd7, 0xce, 0xfd, 0xec, 0xe1, 0xc5, 0xb3, 0x6f, 0xd7, 0x5b, 0x47, 0x61, + 0x2e, 0x89, 0xe9, 0x8e, 0x5b, 0xfc, 0xc8, 0x0d, 0xbc, 0x90, 0x23, 0x75, 0x22, 0xd1, 0xe4, 0x25, + 0xf1, 0x7b, 0x42, 0xaf, 0xad, 0x01, 0x04, 0x0d, 0x43, 0x7a, 0xc5, 0xb3, 0xf5, 0xa7, 0xe5, 0xe3, + 0x36, 0xd9, 0xdd, 0xe8, 0x6e, 0xf6, 0x6e, 0xd7, 0xc9, 0x59, 0x59, 0xf8, 0x1c, 0x25, 0x42, 0x10, + 0xd7, 0x19, 0xad, 0x90, 0x95, 0xae, 0x38, 0x54, 0x29, 0x6e, 0x12, 0x5c, 0xf9, 0xdd, 0x0d, 0x8a, + 0x8e, 0x69, 0x47, 0x03, 0xf6, 0xe5, 0xd8, 0x14, 0x1a, 0xfb, 0x76, 0xf1, 0x18, 0xfc, 0xd9, 0xaf, + 0x13, 0xf4, 0x18, 0xf0, 0xa1, 0x1b, 0x59, 0x96, 0x72, 0x59, 0x57, 0xba, 0xbd, 0x9f, 0x1b, 0xf4, + 0x92, 0xe3, 0x64, 0x9f, 0x08, 0x6d, 0x7b, 0x4b, 0x19, 0xaf, 0x5b, 0xfb, 0xf7, 0x35, 0x23, 0xd1, + 0x18, 0xef, 0xbf, 0x28, 0xd9, 0x7f, 0xf7, 0xe5, 0xc7, 0xc7, 0x0b, 0x37, 0x58, 0x22, 0x6a, 0x12, + 0xe6, 0x2f, 0xca, 0x3e, 0x13, 0xda, 0x59, 0x3d, 0x16, 0xbb, 0xfb, 0x4f, 0xc6, 0x35, 0x01, 0x88, + 0xee, 0xfd, 0xc7, 0x64, 0x50, 0xcd, 0x9d, 0xea, 0x2e, 0xdb, 0xab, 0x53, 0xfd, 0x27, 0x34, 0xce, + 0x51, 0x7f, 0xca, 0x06, 0x8e, 0x56, 0x92, 0xd0, 0xc0, 0xd1, 0x6a, 0x46, 0x9a, 0x39, 0xea, 0xa2, + 0x63, 0x0f, 0x5f, 0x9d, 0xcd, 0x62, 0x72, 0x3e, 0x8b, 0xc9, 0xf7, 0x59, 0x4c, 0x3e, 0xcc, 0xe3, + 0xd6, 0xf9, 0x3c, 0x6e, 0x7d, 0x9d, 0xc7, 0xad, 0xe3, 0xfb, 0xa9, 0xc2, 0xd7, 0xc5, 0x80, 0x0f, + 0xcd, 0x58, 0x64, 0x90, 0x5b, 0x65, 0x11, 0xf4, 0x10, 0x9e, 0x68, 0x08, 0x6b, 0x6f, 0x69, 0x89, + 0x6a, 0x0a, 0x62, 0xda, 0x13, 0x6f, 0x2b, 0x14, 0x78, 0x9a, 0x81, 0x1d, 0xb4, 0xdd, 0x3f, 0x7f, + 0xe7, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x2b, 0x8a, 0x4b, 0x9b, 0x04, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Params returns parameters of the liquidstake module. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // LiquidValidators returns liquid validators with states of the liquidstake + // module. + LiquidValidators(ctx context.Context, in *QueryLiquidValidatorsRequest, opts ...grpc.CallOption) (*QueryLiquidValidatorsResponse, error) + // States returns states of the liquidstake module. + States(ctx context.Context, in *QueryStatesRequest, opts ...grpc.CallOption) (*QueryStatesResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) LiquidValidators(ctx context.Context, in *QueryLiquidValidatorsRequest, opts ...grpc.CallOption) (*QueryLiquidValidatorsResponse, error) { + out := new(QueryLiquidValidatorsResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Query/LiquidValidators", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) States(ctx context.Context, in *QueryStatesRequest, opts ...grpc.CallOption) (*QueryStatesResponse, error) { + out := new(QueryStatesResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Query/States", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Params returns parameters of the liquidstake module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // LiquidValidators returns liquid validators with states of the liquidstake + // module. + LiquidValidators(context.Context, *QueryLiquidValidatorsRequest) (*QueryLiquidValidatorsResponse, error) + // States returns states of the liquidstake module. + States(context.Context, *QueryStatesRequest) (*QueryStatesResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) LiquidValidators(ctx context.Context, req *QueryLiquidValidatorsRequest) (*QueryLiquidValidatorsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LiquidValidators not implemented") +} +func (*UnimplementedQueryServer) States(ctx context.Context, req *QueryStatesRequest) (*QueryStatesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method States not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_LiquidValidators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryLiquidValidatorsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).LiquidValidators(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Query/LiquidValidators", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).LiquidValidators(ctx, req.(*QueryLiquidValidatorsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_States_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryStatesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).States(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Query/States", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).States(ctx, req.(*QueryStatesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pstake.liquidstake.v1beta1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "LiquidValidators", + Handler: _Query_LiquidValidators_Handler, + }, + { + MethodName: "States", + Handler: _Query_States_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pstake/liquidstake/v1beta1/query.proto", +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryLiquidValidatorsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryLiquidValidatorsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryLiquidValidatorsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryLiquidValidatorsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryLiquidValidatorsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryLiquidValidatorsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.LiquidValidators) > 0 { + for iNdEx := len(m.LiquidValidators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.LiquidValidators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryStatesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryStatesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryStatesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryStatesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryStatesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryStatesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.NetAmountState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryLiquidValidatorsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryLiquidValidatorsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.LiquidValidators) > 0 { + for _, e := range m.LiquidValidators { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryStatesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryStatesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.NetAmountState.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryLiquidValidatorsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryLiquidValidatorsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryLiquidValidatorsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryLiquidValidatorsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryLiquidValidatorsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryLiquidValidatorsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidValidators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LiquidValidators = append(m.LiquidValidators, LiquidValidatorState{}) + if err := m.LiquidValidators[len(m.LiquidValidators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryStatesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryStatesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryStatesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryStatesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryStatesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryStatesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetAmountState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.NetAmountState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/liquidstake/types/query.pb.gw.go b/x/liquidstake/types/query.pb.gw.go new file mode 100644 index 000000000..6592e0113 --- /dev/null +++ b/x/liquidstake/types/query.pb.gw.go @@ -0,0 +1,283 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: pstake/liquidstake/v1beta1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_LiquidValidators_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryLiquidValidatorsRequest + var metadata runtime.ServerMetadata + + msg, err := client.LiquidValidators(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_LiquidValidators_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryLiquidValidatorsRequest + var metadata runtime.ServerMetadata + + msg, err := server.LiquidValidators(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_States_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryStatesRequest + var metadata runtime.ServerMetadata + + msg, err := client.States(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_States_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryStatesRequest + var metadata runtime.ServerMetadata + + msg, err := server.States(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LiquidValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_LiquidValidators_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LiquidValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_States_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_States_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_States_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LiquidValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_LiquidValidators_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LiquidValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_States_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_States_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_States_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"pstake", "liquidstake", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_LiquidValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"pstake", "liquidstake", "v1beta1", "validators"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_States_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"pstake", "liquidstake", "v1beta1", "states"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_LiquidValidators_0 = runtime.ForwardResponseMessage + + forward_Query_States_0 = runtime.ForwardResponseMessage +) diff --git a/x/liquidstake/types/rebalancing.go b/x/liquidstake/types/rebalancing.go new file mode 100644 index 000000000..004900f5a --- /dev/null +++ b/x/liquidstake/types/rebalancing.go @@ -0,0 +1,52 @@ +package types + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type Redelegation struct { + Delegator sdk.AccAddress + SrcValidator LiquidValidator + DstValidator LiquidValidator + Amount math.Int + Last bool + Error error +} + +// DivideByWeight divide the input value by the ratio of the param weight of the liquid validator and return it with crumb +// which is may occur while dividing according to the weight of active liquid validators by decimal error. +func DivideByWeight(avs ActiveLiquidValidators, input math.Int, whitelistedValsMap WhitelistedValsMap) (outputs []math.Int, crumb math.Int) { + totalWeight := avs.TotalWeight(whitelistedValsMap) + if !totalWeight.IsPositive() { + return []math.Int{}, sdk.ZeroInt() + } + + totalOutput := sdk.ZeroInt() + unitInput := sdk.NewDecFromInt(input).QuoTruncate(sdk.NewDecFromInt(totalWeight)) + for _, val := range avs { + output := unitInput.MulInt(val.GetWeight(whitelistedValsMap, true)).TruncateInt() + totalOutput = totalOutput.Add(output) + outputs = append(outputs, output) + } + + return outputs, input.Sub(totalOutput) +} + +// DivideByCurrentWeight divide the input value by the ratio of the weight of the liquid validator's liquid token and return it with crumb +// which is may occur while dividing according to the weight of liquid validators by decimal error, outputs is truncated decimal. +func DivideByCurrentWeight(lvs LiquidValidators, input sdk.Dec, totalLiquidTokens math.Int, liquidTokenMap map[string]math.Int) (outputs []sdk.Dec, crumb sdk.Dec) { + if !totalLiquidTokens.IsPositive() { + return []sdk.Dec{}, sdk.ZeroDec() + } + + totalOutput := sdk.ZeroDec() + unitInput := input.QuoTruncate(sdk.NewDecFromInt(totalLiquidTokens)) + for _, val := range lvs { + output := unitInput.MulTruncate(sdk.NewDecFromInt(liquidTokenMap[val.OperatorAddress])).TruncateDec() + totalOutput = totalOutput.Add(output) + outputs = append(outputs, output) + } + + return outputs, input.Sub(totalOutput) +} diff --git a/x/liquidstake/types/tx.pb.go b/x/liquidstake/types/tx.pb.go new file mode 100644 index 000000000..abb1ac96c --- /dev/null +++ b/x/liquidstake/types/tx.pb.go @@ -0,0 +1,1860 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pstake/liquidstake/v1beta1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgLiquidStake defines a SDK message for performing a liquid stake of coins +// from a delegator to whitelisted validators. +type MsgLiquidStake struct { + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount"` +} + +func (m *MsgLiquidStake) Reset() { *m = MsgLiquidStake{} } +func (m *MsgLiquidStake) String() string { return proto.CompactTextString(m) } +func (*MsgLiquidStake) ProtoMessage() {} +func (*MsgLiquidStake) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{0} +} +func (m *MsgLiquidStake) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgLiquidStake) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgLiquidStake.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgLiquidStake) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgLiquidStake.Merge(m, src) +} +func (m *MsgLiquidStake) XXX_Size() int { + return m.Size() +} +func (m *MsgLiquidStake) XXX_DiscardUnknown() { + xxx_messageInfo_MsgLiquidStake.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgLiquidStake proto.InternalMessageInfo + +// MsgLiquidStakeResponse defines the MsgLiquidStake response type. +type MsgLiquidStakeResponse struct { +} + +func (m *MsgLiquidStakeResponse) Reset() { *m = MsgLiquidStakeResponse{} } +func (m *MsgLiquidStakeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgLiquidStakeResponse) ProtoMessage() {} +func (*MsgLiquidStakeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{1} +} +func (m *MsgLiquidStakeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgLiquidStakeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgLiquidStakeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgLiquidStakeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgLiquidStakeResponse.Merge(m, src) +} +func (m *MsgLiquidStakeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgLiquidStakeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgLiquidStakeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgLiquidStakeResponse proto.InternalMessageInfo + +// MsgStakeToLP defines a SDK message for performing an LSM-transfer of staked +// XPRT into stkXPRT with locking into an LP. +type MsgStakeToLP struct { + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + StakedAmount types.Coin `protobuf:"bytes,3,opt,name=staked_amount,json=stakedAmount,proto3" json:"staked_amount"` + LiquidAmount types.Coin `protobuf:"bytes,4,opt,name=liquid_amount,json=liquidAmount,proto3" json:"liquid_amount"` +} + +func (m *MsgStakeToLP) Reset() { *m = MsgStakeToLP{} } +func (m *MsgStakeToLP) String() string { return proto.CompactTextString(m) } +func (*MsgStakeToLP) ProtoMessage() {} +func (*MsgStakeToLP) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{2} +} +func (m *MsgStakeToLP) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgStakeToLP) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgStakeToLP.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgStakeToLP) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgStakeToLP.Merge(m, src) +} +func (m *MsgStakeToLP) XXX_Size() int { + return m.Size() +} +func (m *MsgStakeToLP) XXX_DiscardUnknown() { + xxx_messageInfo_MsgStakeToLP.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgStakeToLP proto.InternalMessageInfo + +// MsgStakeToLPResponse defines the MsgStakeToLP response type. +type MsgStakeToLPResponse struct { +} + +func (m *MsgStakeToLPResponse) Reset() { *m = MsgStakeToLPResponse{} } +func (m *MsgStakeToLPResponse) String() string { return proto.CompactTextString(m) } +func (*MsgStakeToLPResponse) ProtoMessage() {} +func (*MsgStakeToLPResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{3} +} +func (m *MsgStakeToLPResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgStakeToLPResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgStakeToLPResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgStakeToLPResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgStakeToLPResponse.Merge(m, src) +} +func (m *MsgStakeToLPResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgStakeToLPResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgStakeToLPResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgStakeToLPResponse proto.InternalMessageInfo + +// MsgLiquidUnstake defines a SDK message for performing an undelegation of +// liquid staking from a delegate. +type MsgLiquidUnstake struct { + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + Amount types.Coin `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount"` +} + +func (m *MsgLiquidUnstake) Reset() { *m = MsgLiquidUnstake{} } +func (m *MsgLiquidUnstake) String() string { return proto.CompactTextString(m) } +func (*MsgLiquidUnstake) ProtoMessage() {} +func (*MsgLiquidUnstake) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{4} +} +func (m *MsgLiquidUnstake) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgLiquidUnstake) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgLiquidUnstake.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgLiquidUnstake) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgLiquidUnstake.Merge(m, src) +} +func (m *MsgLiquidUnstake) XXX_Size() int { + return m.Size() +} +func (m *MsgLiquidUnstake) XXX_DiscardUnknown() { + xxx_messageInfo_MsgLiquidUnstake.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgLiquidUnstake proto.InternalMessageInfo + +// MsgLiquidUnstakeResponse defines the MsgLiquidUnstake response type. +type MsgLiquidUnstakeResponse struct { + CompletionTime time.Time `protobuf:"bytes,1,opt,name=completion_time,json=completionTime,proto3,stdtime" json:"completion_time"` +} + +func (m *MsgLiquidUnstakeResponse) Reset() { *m = MsgLiquidUnstakeResponse{} } +func (m *MsgLiquidUnstakeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgLiquidUnstakeResponse) ProtoMessage() {} +func (*MsgLiquidUnstakeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{5} +} +func (m *MsgLiquidUnstakeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgLiquidUnstakeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgLiquidUnstakeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgLiquidUnstakeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgLiquidUnstakeResponse.Merge(m, src) +} +func (m *MsgLiquidUnstakeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgLiquidUnstakeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgLiquidUnstakeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgLiquidUnstakeResponse proto.InternalMessageInfo + +func (m *MsgLiquidUnstakeResponse) GetCompletionTime() time.Time { + if m != nil { + return m.CompletionTime + } + return time.Time{} +} + +type MsgUpdateParams struct { + // authority is the address that controls the module (defaults to x/gov unless + // overwritten). + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{6} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +// MsgUpdateParamsResponse defines the response structure for executing a +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d90501ae6d9f0009, []int{7} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgLiquidStake)(nil), "pstake.liquidstake.v1beta1.MsgLiquidStake") + proto.RegisterType((*MsgLiquidStakeResponse)(nil), "pstake.liquidstake.v1beta1.MsgLiquidStakeResponse") + proto.RegisterType((*MsgStakeToLP)(nil), "pstake.liquidstake.v1beta1.MsgStakeToLP") + proto.RegisterType((*MsgStakeToLPResponse)(nil), "pstake.liquidstake.v1beta1.MsgStakeToLPResponse") + proto.RegisterType((*MsgLiquidUnstake)(nil), "pstake.liquidstake.v1beta1.MsgLiquidUnstake") + proto.RegisterType((*MsgLiquidUnstakeResponse)(nil), "pstake.liquidstake.v1beta1.MsgLiquidUnstakeResponse") + proto.RegisterType((*MsgUpdateParams)(nil), "pstake.liquidstake.v1beta1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "pstake.liquidstake.v1beta1.MsgUpdateParamsResponse") +} + +func init() { + proto.RegisterFile("pstake/liquidstake/v1beta1/tx.proto", fileDescriptor_d90501ae6d9f0009) +} + +var fileDescriptor_d90501ae6d9f0009 = []byte{ + // 648 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0x3d, 0x6f, 0xd3, 0x4e, + 0x18, 0xb7, 0xdb, 0xaa, 0xfa, 0xf7, 0xfa, 0x6e, 0x55, 0x6d, 0xe2, 0xc1, 0xa9, 0xfc, 0x5f, 0xa2, + 0xd2, 0xda, 0x24, 0x45, 0x20, 0x75, 0x40, 0x24, 0xd0, 0xad, 0x11, 0x55, 0xda, 0x4a, 0x88, 0x25, + 0xba, 0xc4, 0xc7, 0xf5, 0x44, 0xec, 0x33, 0xbe, 0x4b, 0xd4, 0xae, 0x4c, 0x8c, 0xfd, 0x08, 0x95, + 0xf8, 0x02, 0x15, 0xe2, 0x23, 0x30, 0x64, 0xac, 0x98, 0x98, 0x00, 0x25, 0x03, 0x7c, 0x0c, 0x64, + 0xdf, 0xd9, 0xb1, 0x8b, 0x68, 0x5c, 0x89, 0x85, 0x29, 0x3e, 0xff, 0x5e, 0x9e, 0xe7, 0x7e, 0xbe, + 0xe7, 0x02, 0xfe, 0xf7, 0x19, 0x87, 0xaf, 0x91, 0xdd, 0x25, 0x6f, 0x7a, 0xc4, 0x11, 0xcf, 0xfd, + 0x4a, 0x1b, 0x71, 0x58, 0xb1, 0xf9, 0x99, 0xe5, 0x07, 0x94, 0x53, 0x4d, 0x17, 0x24, 0x2b, 0x45, + 0xb2, 0x24, 0x49, 0x5f, 0xc3, 0x14, 0xd3, 0x88, 0x66, 0x87, 0x4f, 0x42, 0xa1, 0x17, 0x3b, 0x94, + 0xb9, 0x94, 0xb5, 0x04, 0x20, 0x16, 0x12, 0x32, 0xc4, 0xca, 0x6e, 0x43, 0x36, 0x2e, 0xd5, 0xa1, + 0xc4, 0x93, 0xf8, 0x86, 0xc4, 0x5d, 0x86, 0xed, 0x7e, 0x25, 0xfc, 0x91, 0x40, 0x09, 0x53, 0x8a, + 0xbb, 0xc8, 0x8e, 0x56, 0xed, 0xde, 0x2b, 0x9b, 0x13, 0x17, 0x31, 0x0e, 0x5d, 0x5f, 0x12, 0xb6, + 0x6f, 0xd9, 0x4b, 0xba, 0xf5, 0x88, 0x6d, 0x5e, 0xa9, 0x60, 0xa9, 0xc1, 0xf0, 0x41, 0x04, 0x1c, + 0x85, 0x80, 0xb6, 0x0f, 0x56, 0x1d, 0xd4, 0x45, 0x18, 0x72, 0x1a, 0xb4, 0xa0, 0xe3, 0x04, 0x88, + 0xb1, 0x82, 0xba, 0xa9, 0x96, 0xe7, 0xea, 0x85, 0xcf, 0x1f, 0x77, 0xd6, 0xe4, 0x3e, 0x6a, 0x02, + 0x39, 0xe2, 0x01, 0xf1, 0x70, 0x73, 0x25, 0x91, 0xc8, 0xf7, 0xda, 0x23, 0x30, 0x0b, 0x5d, 0xda, + 0xf3, 0x78, 0x61, 0x6a, 0x53, 0x2d, 0xcf, 0x57, 0x8b, 0x96, 0x14, 0x86, 0x5b, 0x8e, 0x83, 0xb3, + 0x9e, 0x52, 0xe2, 0xd5, 0x67, 0x06, 0x5f, 0x4b, 0x4a, 0x53, 0xd2, 0xf7, 0x8c, 0x77, 0x97, 0x25, + 0xe5, 0xe7, 0x65, 0x49, 0x79, 0xfb, 0xe3, 0x6a, 0xeb, 0xf7, 0x56, 0xcc, 0x02, 0x58, 0xcf, 0x76, + 0xdc, 0x44, 0xcc, 0xa7, 0x1e, 0x43, 0xe6, 0x60, 0x0a, 0x2c, 0x34, 0x18, 0x8e, 0x5e, 0x1e, 0xd3, + 0x83, 0xc3, 0xbf, 0xb5, 0x95, 0x7d, 0xb0, 0xda, 0x87, 0x5d, 0xe2, 0x64, 0x6c, 0xa6, 0x26, 0xd9, + 0x24, 0x92, 0xd8, 0xe6, 0x19, 0x58, 0x8c, 0xa2, 0x77, 0x5a, 0x32, 0x98, 0xe9, 0x7c, 0xc1, 0x2c, + 0x08, 0x55, 0x2d, 0x12, 0x85, 0x2e, 0xe2, 0x33, 0xc6, 0x2e, 0x33, 0x39, 0x5d, 0x84, 0xaa, 0x96, + 0x2f, 0xe4, 0x75, 0xb0, 0x96, 0x4e, 0x32, 0x89, 0xf8, 0x83, 0x0a, 0x56, 0x92, 0xf4, 0x4f, 0x3c, + 0xf6, 0x4f, 0x9c, 0x18, 0x02, 0x0a, 0x37, 0x7b, 0x8e, 0x37, 0xa4, 0x35, 0xc0, 0x72, 0x87, 0xba, + 0x7e, 0x17, 0x71, 0x42, 0xbd, 0x56, 0x38, 0x4c, 0x51, 0xe7, 0xf3, 0x55, 0xdd, 0x12, 0x93, 0x66, + 0xc5, 0x93, 0x66, 0x1d, 0xc7, 0x93, 0x56, 0xff, 0x2f, 0x2c, 0x7f, 0xf1, 0xad, 0xa4, 0x36, 0x97, + 0xc6, 0xe2, 0x10, 0x36, 0xdf, 0xab, 0x60, 0xb9, 0xc1, 0xf0, 0x89, 0xef, 0x40, 0x8e, 0x0e, 0x61, + 0x00, 0x5d, 0xa6, 0x3d, 0x04, 0x73, 0xb0, 0xc7, 0x4f, 0x69, 0x40, 0xf8, 0xf9, 0xc4, 0x58, 0xc6, + 0x54, 0xed, 0x09, 0x98, 0xf5, 0x23, 0x07, 0x99, 0x87, 0x69, 0xfd, 0xf9, 0x06, 0xb2, 0x44, 0xad, + 0x38, 0x18, 0xa1, 0xdb, 0x5b, 0x4f, 0x07, 0x33, 0x76, 0x36, 0x8b, 0x60, 0xe3, 0x46, 0x93, 0x71, + 0x1e, 0xd5, 0x4f, 0xd3, 0x60, 0xba, 0xc1, 0xb0, 0xe6, 0x82, 0xf9, 0xf4, 0xa5, 0xb0, 0x75, 0x5b, + 0xed, 0xec, 0x38, 0xea, 0xd5, 0xfc, 0xdc, 0xe4, 0x33, 0x30, 0xb0, 0x98, 0x3d, 0x53, 0xdb, 0xb9, + 0x4c, 0x24, 0x5b, 0x7f, 0x70, 0x17, 0x76, 0x52, 0x14, 0x83, 0xb9, 0xf1, 0x5d, 0x51, 0x9e, 0x60, + 0x91, 0x30, 0xf5, 0xfb, 0x79, 0x99, 0x49, 0x21, 0x1f, 0x2c, 0x64, 0x4e, 0xc4, 0xbd, 0x09, 0x0e, + 0x69, 0xb2, 0xbe, 0x7b, 0x07, 0x72, 0x5c, 0xb1, 0xfe, 0x62, 0x30, 0x34, 0xd4, 0xeb, 0xa1, 0xa1, + 0x7e, 0x1f, 0x1a, 0xea, 0xc5, 0xc8, 0x50, 0xae, 0x47, 0x86, 0xf2, 0x65, 0x64, 0x28, 0x2f, 0x1f, + 0x63, 0xc2, 0x4f, 0x7b, 0x6d, 0xab, 0x43, 0x5d, 0xdb, 0x47, 0x01, 0x23, 0x8c, 0x23, 0xaf, 0x83, + 0x9e, 0x7b, 0xc8, 0x16, 0x75, 0x76, 0x3c, 0xc8, 0x49, 0x1f, 0xd9, 0xfd, 0xaa, 0x7d, 0x96, 0xf9, + 0x17, 0xe1, 0xe7, 0x3e, 0x62, 0xed, 0xd9, 0x68, 0x1e, 0x76, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, + 0x69, 0xe1, 0x65, 0x0f, 0x34, 0x07, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // LiquidStake defines a method for performing a delegation of coins + // from a delegator to whitelisted validators. + LiquidStake(ctx context.Context, in *MsgLiquidStake, opts ...grpc.CallOption) (*MsgLiquidStakeResponse, error) + // LiquidUnstake defines a method for performing an undelegation of liquid + // staking from a delegate. + LiquidUnstake(ctx context.Context, in *MsgLiquidUnstake, opts ...grpc.CallOption) (*MsgLiquidUnstakeResponse, error) + // StakeToLP defines a method for LSM-transfer of staked XPRT + // into stkXPRT with locking into an LP. + StakeToLP(ctx context.Context, in *MsgStakeToLP, opts ...grpc.CallOption) (*MsgStakeToLPResponse, error) + // UpdateParams defines a method to update the module params. + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) LiquidStake(ctx context.Context, in *MsgLiquidStake, opts ...grpc.CallOption) (*MsgLiquidStakeResponse, error) { + out := new(MsgLiquidStakeResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Msg/LiquidStake", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) LiquidUnstake(ctx context.Context, in *MsgLiquidUnstake, opts ...grpc.CallOption) (*MsgLiquidUnstakeResponse, error) { + out := new(MsgLiquidUnstakeResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Msg/LiquidUnstake", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) StakeToLP(ctx context.Context, in *MsgStakeToLP, opts ...grpc.CallOption) (*MsgStakeToLPResponse, error) { + out := new(MsgStakeToLPResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Msg/StakeToLP", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/pstake.liquidstake.v1beta1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // LiquidStake defines a method for performing a delegation of coins + // from a delegator to whitelisted validators. + LiquidStake(context.Context, *MsgLiquidStake) (*MsgLiquidStakeResponse, error) + // LiquidUnstake defines a method for performing an undelegation of liquid + // staking from a delegate. + LiquidUnstake(context.Context, *MsgLiquidUnstake) (*MsgLiquidUnstakeResponse, error) + // StakeToLP defines a method for LSM-transfer of staked XPRT + // into stkXPRT with locking into an LP. + StakeToLP(context.Context, *MsgStakeToLP) (*MsgStakeToLPResponse, error) + // UpdateParams defines a method to update the module params. + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) LiquidStake(ctx context.Context, req *MsgLiquidStake) (*MsgLiquidStakeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LiquidStake not implemented") +} +func (*UnimplementedMsgServer) LiquidUnstake(ctx context.Context, req *MsgLiquidUnstake) (*MsgLiquidUnstakeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LiquidUnstake not implemented") +} +func (*UnimplementedMsgServer) StakeToLP(ctx context.Context, req *MsgStakeToLP) (*MsgStakeToLPResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StakeToLP not implemented") +} +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_LiquidStake_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgLiquidStake) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).LiquidStake(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Msg/LiquidStake", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).LiquidStake(ctx, req.(*MsgLiquidStake)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_LiquidUnstake_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgLiquidUnstake) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).LiquidUnstake(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Msg/LiquidUnstake", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).LiquidUnstake(ctx, req.(*MsgLiquidUnstake)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_StakeToLP_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgStakeToLP) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).StakeToLP(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Msg/StakeToLP", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).StakeToLP(ctx, req.(*MsgStakeToLP)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pstake.liquidstake.v1beta1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "pstake.liquidstake.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "LiquidStake", + Handler: _Msg_LiquidStake_Handler, + }, + { + MethodName: "LiquidUnstake", + Handler: _Msg_LiquidUnstake_Handler, + }, + { + MethodName: "StakeToLP", + Handler: _Msg_StakeToLP_Handler, + }, + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pstake/liquidstake/v1beta1/tx.proto", +} + +func (m *MsgLiquidStake) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgLiquidStake) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgLiquidStake) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.DelegatorAddress) > 0 { + i -= len(m.DelegatorAddress) + copy(dAtA[i:], m.DelegatorAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgLiquidStakeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgLiquidStakeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgLiquidStakeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgStakeToLP) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgStakeToLP) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgStakeToLP) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.LiquidAmount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.StakedAmount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ValidatorAddress) > 0 { + i -= len(m.ValidatorAddress) + copy(dAtA[i:], m.ValidatorAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.ValidatorAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.DelegatorAddress) > 0 { + i -= len(m.DelegatorAddress) + copy(dAtA[i:], m.DelegatorAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgStakeToLPResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgStakeToLPResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgStakeToLPResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgLiquidUnstake) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgLiquidUnstake) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgLiquidUnstake) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.DelegatorAddress) > 0 { + i -= len(m.DelegatorAddress) + copy(dAtA[i:], m.DelegatorAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgLiquidUnstakeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgLiquidUnstakeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgLiquidUnstakeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err5 != nil { + return 0, err5 + } + i -= n5 + i = encodeVarintTx(dAtA, i, uint64(n5)) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgLiquidStake) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DelegatorAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Amount.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgLiquidStakeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgStakeToLP) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DelegatorAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ValidatorAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.StakedAmount.Size() + n += 1 + l + sovTx(uint64(l)) + l = m.LiquidAmount.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgStakeToLPResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgLiquidUnstake) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DelegatorAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Amount.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgLiquidUnstakeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime) + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgLiquidStake) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgLiquidStake: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgLiquidStake: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgLiquidStakeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgLiquidStakeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgLiquidStakeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgStakeToLP) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgStakeToLP: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStakeToLP: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StakedAmount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.StakedAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidAmount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LiquidAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgStakeToLPResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgStakeToLPResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgStakeToLPResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgLiquidUnstake) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgLiquidUnstake: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgLiquidUnstake: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgLiquidUnstakeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgLiquidUnstakeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgLiquidUnstakeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CompletionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.CompletionTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/liquidstakeibc/client/query.go b/x/liquidstakeibc/client/query.go index aa1984413..a975199b1 100644 --- a/x/liquidstakeibc/client/query.go +++ b/x/liquidstakeibc/client/query.go @@ -19,7 +19,7 @@ import ( func NewQueryCmd() *cobra.Command { cmd := &cobra.Command{ Use: types.ModuleName, - Aliases: []string{"liquidstake", "lsibc"}, + Aliases: []string{"lsibc"}, Short: "Querying commands for the pstake liquid staking ibc module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, diff --git a/x/liquidstakeibc/client/tx.go b/x/liquidstakeibc/client/tx.go index b34f00726..c4046fe39 100644 --- a/x/liquidstakeibc/client/tx.go +++ b/x/liquidstakeibc/client/tx.go @@ -21,7 +21,7 @@ import ( func NewTxCmd() *cobra.Command { txCmd := &cobra.Command{ Use: types.ModuleName, - Aliases: []string{"liquidstake", "lsibc"}, + Aliases: []string{"lsibc"}, Short: "Pstake liquid staking ibc transaction subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, diff --git a/x/liquidstakeibc/types/liquidstakeibc.pb.go b/x/liquidstakeibc/types/liquidstakeibc.pb.go index b0bf82018..d0c0eed05 100644 --- a/x/liquidstakeibc/types/liquidstakeibc.pb.go +++ b/x/liquidstakeibc/types/liquidstakeibc.pb.go @@ -531,11 +531,13 @@ type Validator struct { Weight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"weight"` // amount delegated by the module to the validator DelegatedAmount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=delegated_amount,json=delegatedAmount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"delegated_amount"` - // the validator token exchange rate, total bonded tokens divided by total shares issued + // the validator token exchange rate, total bonded tokens divided by total + // shares issued ExchangeRate github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=exchange_rate,json=exchangeRate,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"exchange_rate"` // the unbonding epoch number when the validator transitioned into the state UnbondingEpoch int64 `protobuf:"varint,6,opt,name=unbonding_epoch,json=unbondingEpoch,proto3" json:"unbonding_epoch,omitempty"` - // whether the validator can accept delegations or not, default true for non-lsm chains + // whether the validator can accept delegations or not, default true for + // non-lsm chains Delegable bool `protobuf:"varint,7,opt,name=delegable,proto3" json:"delegable,omitempty"` } @@ -683,10 +685,11 @@ func (m *Deposit) GetIbcSequenceId() string { type LSMDeposit struct { // deposit target chain ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - // this is calculated when liquid staking [lsm_shares * validator_exchange_rate] + // this is calculated when liquid staking [lsm_shares * + // validator_exchange_rate] Amount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount"` - // LSM token shares, they are mapped 1:1 with the delegator shares that are tokenized - // https://github.com/iqlusioninc/cosmos-sdk/pull/19 + // LSM token shares, they are mapped 1:1 with the delegator shares that are + // tokenized https://github.com/iqlusioninc/cosmos-sdk/pull/19 Shares github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=shares,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"shares"` // LSM token denom Denom string `protobuf:"bytes,4,opt,name=denom,proto3" json:"denom,omitempty"` diff --git a/x/liquidstakeibc/types/query.pb.go b/x/liquidstakeibc/types/query.pb.go index 40b6b44d2..d561b5dcd 100644 --- a/x/liquidstakeibc/types/query.pb.go +++ b/x/liquidstakeibc/types/query.pb.go @@ -1309,9 +1309,11 @@ type QueryClient interface { ValidatorUnbondings(ctx context.Context, in *QueryValidatorUnbondingRequest, opts ...grpc.CallOption) (*QueryValidatorUnbondingResponse, error) // Queries for a host chain deposit account balance. DepositAccountBalance(ctx context.Context, in *QueryDepositAccountBalanceRequest, opts ...grpc.CallOption) (*QueryDepositAccountBalanceResponse, error) - // Queries for a host chain exchange rate between the host token and the stk token. + // Queries for a host chain exchange rate between the host token and the stk + // token. ExchangeRate(ctx context.Context, in *QueryExchangeRateRequest, opts ...grpc.CallOption) (*QueryExchangeRateResponse, error) - // Queries for a host chain redelegation entries on the host token delegation acct. + // Queries for a host chain redelegation entries on the host token delegation + // acct. Redelegations(ctx context.Context, in *QueryRedelegationsRequest, opts ...grpc.CallOption) (*QueryRedelegationsResponse, error) // Queries for a host chain redelegation-txs for the host token. RedelegationTx(ctx context.Context, in *QueryRedelegationTxRequest, opts ...grpc.CallOption) (*QueryRedelegationTxResponse, error) @@ -1464,9 +1466,11 @@ type QueryServer interface { ValidatorUnbondings(context.Context, *QueryValidatorUnbondingRequest) (*QueryValidatorUnbondingResponse, error) // Queries for a host chain deposit account balance. DepositAccountBalance(context.Context, *QueryDepositAccountBalanceRequest) (*QueryDepositAccountBalanceResponse, error) - // Queries for a host chain exchange rate between the host token and the stk token. + // Queries for a host chain exchange rate between the host token and the stk + // token. ExchangeRate(context.Context, *QueryExchangeRateRequest) (*QueryExchangeRateResponse, error) - // Queries for a host chain redelegation entries on the host token delegation acct. + // Queries for a host chain redelegation entries on the host token delegation + // acct. Redelegations(context.Context, *QueryRedelegationsRequest) (*QueryRedelegationsResponse, error) // Queries for a host chain redelegation-txs for the host token. RedelegationTx(context.Context, *QueryRedelegationTxRequest) (*QueryRedelegationTxResponse, error)