Staking
The staking module processes various messages for validator and delegation management. Each message type has specific security considerations and validation requirements.
Additionally, within the scope of this audit, unlike the existing Cosmos SDK staking module, the system enhances the utility of locked-up staked assets by tokenizing them, even while they remain staked.
The following section outlines the recent updates to the staking module.
States
Added
TotalLiquidStakedTokens
Tracks the total amount of liquid staked tokens to monitor progress against the
GlobalLiquidStakingCap
.
PendingTokenizeShareAuthorizations
Stores a queue of addresses undergoing reactivation/unlocking for tokenized shares.
Modified
Two items have been added to Validator
.
ValidatorBondShares
Represents the number of shares self-bonded by the validator.
LiquidShares
Represents the number of shares either tokenized or owned by a liquid-staking provider.
BeginBlock
Added
RemoveExpiredTokenizeShareLocks
Finds and releases all expired
TokenizeShareLocks
up to the current block time.
Chain parameters
Added
ValidatorBondFactor
Defines the factor for validator bonds.
GlobalLiquidStakingCap
Sets the global cap for liquid staking.
ValidatorLiquidStakingCap
Sets the liquid-staking cap for individual validators.
Messages
Added
MsgTokenizeShares
Tokenizes a specified amount from an existing delegation.
Creates a new
TokenizeShareRecord
.Unbonds the specified amount from the existing delegation.
Transfers the unbonded tokens to the
ModuleAddress
specified in theTokenizeShareRecord
.Assigns tokenized shares to the delegator corresponding to the unbonded tokens.
Creates a new delegation between the
ModuleAddress
in theTokenizeShareRecord
and the validator.
MsgRedeemTokensForShares
Redeems tokenized shares to reclaim the originally delegated assets.
Unbonds the specified amount from the delegation between the
ModuleAddress
and validator. Deletes the delegation data if the entire amount is unbonded.Transfers the share tokens to the
NotBondedPool
and burns them.Transfers the corresponding original tokens to the delegator and updates delegation information between the validator and delegator.
MsgTransferTokenizeShareRecord
Transfers ownership of tokenized delegation to another user.
Removes the relationship between the existing
TokenizeShareRecord
and the current owner.Creates a new relationship between the
TokenizeShareRecord
and the new owner.
MsgEnableTokenizeShares
Initiates reauthorization for tokenization for a delegator’s address.
Adds a lock to
PendingTokenizeShareAuthorizations
that will be released after the unbonding period to allow tokenization.
MsgDisableTokenizeShares
Disables tokenization for a delegator’s address.
Removes expired locks from
PendingTokenizeShareAuthorizations
if they exist.Creates a new permanent lock and adds it to
PendingTokenizeShareAuthorizations
.
MsgUnbondValidator
Transitions the validator from the
Bonded
state toUnbonding
state.Sets the validator to a jail state and prepares it for unbonding.
MsgValidatorBond
Designates a specific delegation as a validator bond, allowing the validator to receive additional liquid-staking delegations.
Marks a specific delegation as the validator’s
ValidatorBond
.
Modified
MsgDelegate
Increases
TotalLiquidStakedTokens
by the amount of tokens delegated, if the delegator is a liquid staker.Increases the validator’s
LiquidShares
by the number of shares delegated, if the delegator is a liquid staker.Increases the validator’s
ValidatorShares
by the newly delegated shares, if the existing delegation’sValidatorBond
is true.
MsgBeginRedelegate
Deducts the redelegated amount converted to validator shares from
ValidatorBondShares
, if the source delegation’sValidatorBond
is true.Adds the shares calculated by the destination validator for the redelegated amount to the destination validator’s
LiquidShares
and removes it from the source validator’sLiquidShares
, if the delegator is a liquid staker.Increases the destination validator’s
ValidatorBondShares
by the redelegated amount converted to shares, if the destination delegation’sValidatorBond
is true.
MsgUndelegate
Deducts the undelegated amount converted to validator shares from
ValidatorBondShares
, if the specified delegation’sValidatorBond
is true.Decreases
TotalLiquidStakedTokens
by the amount of tokens undelegated, if the delegator is a liquid staker.Decreases the validator’s
LiquidShares
by the number of shares undelegated, if the delegator is a liquid staker.
MsgCancelUnbondingDelegation
Increases
TotalLiquidStakedTokens
by the amount of tokens for which unbonding is canceled, if the delegator is a liquid staker.Increases the validator’s
LiquidShares
by the number of shares for which unbonding is canceled, if the delegator is a liquid staker.Increases the validator’s
ValidatorShares
by the number of shares for which unbonding is canceled, if the existing delegation’sValidatorBond
is true.
Invariants
This section describes new/removed invariants compared to the existing staking module.
Validator-management messages
MsgEditValidator
Validation for
msg.MinSelfDelegation
has been removed (as it was not actually used).
MsgUnbondValidator
The
msg.ValidatorAddress
must have been registered through a priorMsgCreateValidator
.The
msg.ValidatorAddress
must not already be in jail.
MsgValidatorBond
The
msg.ValidatorAddress
must have been registered through a priorMsgCreateValidator
.The
msg.DelegatorAddress
must have delegated self-staked tokens to the validator in advance.The
msg.DelegatorAddress
must not be a liquid staker.The delegation between
msg.ValidatorAddress
andmsg.DelegatorAddress
must not already be set as a validator bond.
Share-tokenization messages
MsgTokenizeShares
The
msg.Amount.Amount
must be greater than zero and not nil.The
msg.Amount.Denom
must match the regular expression[a-zA-Z][a-zA-Z0-9/:._-]{2,127}
.The
msg.Amount.Amount
cannot exceed the number of tokens owned by the delegator formsg.Amount.Denom
.The tokenize-share lock for
msg.DelegatorAddress
must not be inTOKENIZE_SHARE_LOCK_STATUS_LOCKED
orTOKENIZE_SHARE_LOCK_STATUS_LOCK_EXPIRING
.A delegation must exist between the validator specified by
msg.ValidatorAddress
and the delegator specified bymsg.DelegatorAddress
.The delegation’s
ValidatorBond
must not be true.The
msg.Amount.Denom
must match the denom specified in the chain parameters.If the delegator specified by
msg.DelegatorAddress
is a vesting account, the tokenized shares must not exceed the amount available for use after the vesting period.The delegator specified by
msg.DelegatorAddress
must not be in the middle of a redelegation process.The shares to be unbonded by the delegator specified by
msg.DelegatorAddress
must not exceed the delegation’s total shares.
MsgRedeemTokensForShares
The
msg.Amount.Amount
must be greater than zero and not nil.The
msg.Amount.Denom
must match the regular expression[a-zA-Z][a-zA-Z0-9/:._-]{2,127}
.The
msg.Amount.Amount
cannot exceed the number of tokens owned by the delegator formsg.Amount.Denom
.A
TokenizeShareRecord
related tomsg.Amount.Denom
must exist.The validator in the
TokenizeShareRecord
must have been registered through a priorMsgCreateValidator
.A delegation relationship must exist between the
Module Address
in theTokenizeShareRecord
and the validator.The shares calculated for the
msg.Amount.Amount
based on the validator in theTokenizeShareRecord
must not be zero.The shares to be unbonded by the delegator specified by
msg.DelegatorAddress
must not exceed the delegation’s total shares.
MsgTransferTokenizeShareRecord
The
msg.Sender
must be therecord.Owner
.
MsgEnableTokenizeShares
The tokenize-share lock related to
msg.DelegatorAddress
must not be inTOKENIZE_SHARE_LOCK_STATUS_UNLOCKED
.The tokenize-share lock related to
msg.DelegatorAddress
must not be inTOKENIZE_SHARE_LOCK_STATUS_LOCK_EXPIRING
.
MsgDisableTokenizeShares
The tokenize-share lock related to
msg.DelegatorAddress
must not be inTOKENIZE_SHARE_LOCK_STATUS_LOCKED
.