Vesting

Abstract

The x/vesting module provides functionality for creating and managing vesting accounts within the blockchain. Vesting accounts are special accounts that release tokens over a specified period, ensuring a controlled distribution of tokens. This module allows token holders to:

  1. Create new continuous vesting accounts funded with a specified amount of tokens.

  2. Split locked tokens from an existing vesting account into a new vesting account, preserving vesting schedules and token release speeds.

By doing so, this module facilitates controlled token distributions and token holder-driven vesting processes.

Note: This module is based on an open source project from Chain4Energy (Apache License).

Contents

State

The x/vesting module manages vesting accounts, which are derived from the Cosmos SDK continuous vesting accounts. The state includes:

  • Vesting Accounts: Accounts that hold locked funds, releasing them linearly between a start and end time.

  • Keys: The module defines:

    • ModuleName = \"empevesting\"

    • StoreKey = ModuleName These keys are used for the store and routing messages.

No custom parameters are introduced by this module. The state is updated whenever a new vesting account is created or split.

Keepers

The x/vesting module depends on two keepers:

  • AccountKeeper (from x/auth): To create and manage continuous vesting accounts.

  • BankKeeper (from x/bank): For sending coins from one account to another and handling locked coins.

The x/vesting module does not provide additional keeper interfaces for other modules to consume directly. Instead, it relies on these keepers to perform account-related and balance-related operations.

Messages

The x/vesting module defines two main messages:

MsgCreateVestingAccount

Type: create_vesting_account

Allows any account holder to create a new continuous vesting account and send tokens into it. The tokens will vest linearly from a specified start_time to end_time.

Fields:

  • FromAddress: The creator/funder of the vesting account.

  • ToAddress: The address of the new continuous vesting account.

  • Amount: The tokens to lock in the vesting account.

  • StartTime: UNIX timestamp when vesting starts.

  • EndTime: UNIX timestamp when all tokens are fully vested.

State Modifications:

  • Creates a new continuous vesting account associated with ToAddress.

  • Transfers Amount from FromAddress to ToAddress.

  • Sets up a vesting schedule from StartTime to EndTime.

Failure Cases:

  • Invalid addresses.

  • Insufficient funds in FromAddress.

  • ToAddress account already exists.

  • StartTime > EndTime.

MsgSplitVestingAccount

Type: split_vesting_account

Splits locked tokens from an existing vesting account into a new vesting account. This preserves the overall vesting schedule properties but allows partial transfer of locked tokens to a new account with adjusted start/end times.

Fields:

  • FromAddress: The owner of the existing vesting account.

  • ToAddress: The address of the new vesting account to be created.

  • Amount: The amount of locked tokens to split off.

  • StartTime: Vesting start time for the new account (must be >= the block time and >= original start time).

  • EndTime: Vesting end time for the new account (must be >= original end time).

State Modifications:

  • Unlocks the specified Amount of locked tokens from the FromAddress vesting account.

  • Creates a new continuous vesting account at ToAddress.

  • Transfers the Amount from FromAddress to ToAddress.

Failure Cases:

  • Invalid addresses.

  • FromAddress is not a continuous vesting account.

  • Insufficient locked tokens to split.

  • ToAddress account already exists.

  • Invalid times (new start time before block time/original start time, or new end time before original end time).

Events

MsgCreateVestingAccount Events

Type
Attribute Key
Attribute Value

EventNewVestingAccount

address

{new_vesting_account_address}

message

action

/empevesting.MsgCreateVestingAccount

message

sender

{from_address}

transfer

recipient

{to_address}

transfer

sender

{from_address}

transfer

amount

{amount}

MsgSplitVestingAccount Events

Type
Attribute Key
Attribute Value

EventVestingSplit

source

{from_account_address}

EventVestingSplit

destination

{new_vesting_account_address}

EventNewVestingAccount

address

{new_vesting_account_address}

message

action

/empevesting.MsgSplitVestingAccount

message

sender

{from_address}

transfer

recipient

{to_address}

transfer

sender

{from_address}

transfer

amount

{amount}

Errors

Common errors include:

  • ErrAlreadyExists: Attempted to create a vesting account for an address that already has an account.

  • ErrAmountValidationFailed: Invalid amounts (e.g., negative, zero, duplicate denominations).

  • ErrParsing: Invalid address parsing.

  • ErrStartTimeBeforeEndTime: StartTime > EndTime.

  • ErrStartTimeBeforeBlockTime: StartTime is before the current block time when splitting.

  • ErrNewStartTimeBeforeOriginalStartTime: New start time is earlier than the original vesting start time.

  • ErrNewEndTimeBeforeOriginalEndTime: New end time is before the original vesting end time.

  • ErrAccountNotFound: Attempting to split from a non-existent account.

  • ErrNotEnoughCoinsToUnlock: Not enough locked coins to unlock for splitting.

Client

CLI

The x/vesting module provides CLI commands to interact with it:

  • create-vesting-account [to-address] [amount] [start-time] [end-time]

  • split-vesting-account [to-address] [amount] [start-time] [end-time]

Users must provide:

  • Valid to-address.

  • amount of coins (e.g. 1000uempe).

  • start-time and end-time as UNIX timestamps.

Example:

emped tx vesting create-vesting-account empe1xyz... 1000uempe 1672531200 1704067200 --from mykey

This creates a vesting account starting at UNIX time 1672531200 and ending at 1704067200.

Transactions

  • Create Vesting Account: Uses MsgCreateVestingAccount.

  • Split Vesting Account: Uses MsgSplitVestingAccount.

Query

Currently, the x/vesting module does not define its own query endpoints. Users should query the underlying state via x/auth and x/bank modules to inspect account balances and vesting details.

gRPC

The x/vesting module does not provide its own gRPC query services. It relies on the standard Cosmos SDK queries (e.g. x/auth, x/bank, x/authz) and any queries related to vesting accounts can be observed by querying the account type and its associated balances.

Last updated