Skip to main content

Time-Locked Accounts

A time-locked account disallows payments that would reduce the balance below a minimum, which depends on the block height.

To create a time-lock, you must provide the configuration when creating a new account. This can happen only in the genesis ledger at the beginning of a network. In this section, we'll explore the mechanism behind time-locks and see how to interact with time-locked accounts.

tip

For the current release, values for time-locked accounts were assigned based on the order in which you signed up.

Understanding time-locks

A time-lock consists of the following fields initial_minimum_balance, cliff time, a vesting_period time, and a vesting_increment.

You can still use an account if it has a time-lock, as long as the account holds enough funds. The amount of funds that are time-locked starts off as initial_minimum_balance at the beginning of the network. Once the network reaches a block height equal to the cliff, the time-locked amount begins to decrease by the vesting_increment amount every vesting_period.

For a more technical explanaition of this process, please see RFC-0025 which has a more in-depth overview.

Liquid Balance Details:

If you'd like to expose liquid balances for vesting accounts at some particular time period it is governed by the following function (Note: this computes the locked portion of an account):

(*
* uint32 global_slot -- the "clock" it starts at 0 at the genesis block and ticks up every 3minutes.
* uint32 cliff_time -- the slot where the cliff is (similar to startup equity vesting)
* uint32 cliff_amount -- the amount that unlocks at the cliff
* amount vesting_increment -- unlock this amount every "period"
* uint32 vesting_period -- the period that we increment the unlocked amount
* balance initial_minimum_balance -- the total locked amount until the cliff
*)
let min_balance_at_slot ~global_slot ~cliff_time ~cliff_amount ~vesting_period
~vesting_increment ~initial_minimum_balance =
let open Unsigned in
if Global_slot.(global_slot < cliff_time) then initial_minimum_balance
else
match Balance.(initial_minimum_balance - cliff_amount) with
| None ->
Balance.zero
| Some min_balance_past_cliff -> (
(* take advantage of fact that global slots are uint32's *)
let num_periods =
UInt32.(
Infix.((global_slot - cliff_time) / vesting_period)
|> to_int64 |> UInt64.of_int64)
in
let vesting_decrement =
UInt64.Infix.(num_periods * Amount.to_uint64 vesting_increment)
|> Amount.of_uint64
in
match Balance.(min_balance_past_cliff - vesting_decrement) with
| None ->
Balance.zero
| Some amt ->
amt )

Creating a time-locked account

As of the current release, the only way to create a time-locked account is with the genesis ledger. In future releases we may add commands to mina client and the GraphQL API that will allow you to create a new time-locked account.