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 the TokenizeShareRecord.

    • Assigns tokenized shares to the delegator corresponding to the unbonded tokens.

    • Creates a new delegation between the ModuleAddress in the TokenizeShareRecord 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 to Unbonding 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’s ValidatorBond is true.

  • MsgBeginRedelegate

    • Deducts the redelegated amount converted to validator shares from ValidatorBondShares, if the source delegation’s ValidatorBond 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’s LiquidShares, if the delegator is a liquid staker.

    • Increases the destination validator’s ValidatorBondShares by the redelegated amount converted to shares, if the destination delegation’s ValidatorBond is true.

  • MsgUndelegate

    • Deducts the undelegated amount converted to validator shares from ValidatorBondShares, if the specified delegation’s ValidatorBond 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’s ValidatorBond 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 prior MsgCreateValidator.

    • The msg.ValidatorAddress must not already be in jail.

  • MsgValidatorBond

    • The msg.ValidatorAddress must have been registered through a prior MsgCreateValidator.

    • 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 and msg.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 for msg.Amount.Denom.

    • The tokenize-share lock for msg.DelegatorAddress must not be in TOKENIZE_SHARE_LOCK_STATUS_LOCKED or TOKENIZE_SHARE_LOCK_STATUS_LOCK_EXPIRING.

    • A delegation must exist between the validator specified by msg.ValidatorAddress and the delegator specified by msg.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 for msg.Amount.Denom.

    • A TokenizeShareRecord related to msg.Amount.Denom must exist.

    • The validator in the TokenizeShareRecord must have been registered through a prior MsgCreateValidator.

    • A delegation relationship must exist between the Module Address in the TokenizeShareRecord and the validator.

    • The shares calculated for the msg.Amount.Amount based on the validator in the TokenizeShareRecord 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 the record.Owner.

  • MsgEnableTokenizeShares

    • The tokenize-share lock related to msg.DelegatorAddress must not be in TOKENIZE_SHARE_LOCK_STATUS_UNLOCKED.

    • The tokenize-share lock related to msg.DelegatorAddress must not be in TOKENIZE_SHARE_LOCK_STATUS_LOCK_EXPIRING.

  • MsgDisableTokenizeShares

    • The tokenize-share lock related to msg.DelegatorAddress must not be in TOKENIZE_SHARE_LOCK_STATUS_LOCKED.

Zellic © 2025Back to top ↑