Skip to content

Latest commit

 

History

History
98 lines (73 loc) · 3.86 KB

0025-time-locked-accounts.md

File metadata and controls

98 lines (73 loc) · 3.86 KB

Time-locked and time-vesting accounts

Accounts may contain funds that are available to send according to a vesting schedule.

Motivation

Time-locked accounts are useful to delay the availability of funds. Such accounts have been used in other cryptocurrencies to implement features such as payment channels. The locking feature can be used to create incentives; if the account holder performs a certain action, the account can be funded so that the locked funds are released.

Vesting schedules are a generalization of the time-locking mechanism, where funds become increasingly available over time. There are two times specified, one that indicates when some amount of funds becomes available to send, and another, later time that specifies when all funds become available to send. The amount available to send increases between those two times.

Detailed design

Accounts may have no timing restrictions, have a time lock, or a vesting schedule. In Coda, the type Account.t is a record type with several fields. An additional field timing could contain an element of a sum type with three alternatives: Untimed and Timed.

Untimed means there are no time restrictions on sending funds.

A Timed value contains an initial_minimum_balance, cliff time, a vesting_period time, and a vesting_increment. Until the cliff time has passed, the account can send only funds from its balance that are in excess of the initial minimum balance. After the cliff time has passed, more funds are available, by calculating a current minimum balance which decreases over time. The minimum balance decreases by the vesting increment for each vesting period:

  current_minimum_balance = 
    if global_slot < cliff_time 
	then 
	  initial_minimum_balance
	else 
	  max 0 (initial_minimum_balance - ((global_slot - cliff_time) / vesting_period) * vesting_increment))

(where / is integer division).

If a transaction amount would make the account balance less than the current minimum, the transaction is disallowed.

Nothing prevents sending funds to timed accounts. When timed accounts are created, the balance must be at least the initial minimum balance. The account can receive additional funds, and funds can be spent, as long as the minimum balance invariant is maintained.

A time-locked account time, can be created by using a vesting increment equal to the initial minimum balance and a vesting period of one slot. (In the calculation above, using a vesting period of zero would result in a division by zero.)

Implementation

The restrictions on sending funds need to be enforced in the transaction SNARK and out-of-SNARK. If the restrictions are violated, an error occurs.

For the out-of-SNARK transaction, the relevant code location to enforce the restrictions appears to be in Transaction_logic.apply_user_command_unchecked.

For the in-SNARK transaction, the restriction would be enforced in Transaction_snark.apply_tagged_transaction.

Drawbacks

Adding this feature makes the account data slightly larger, slows down the validation of transactions, and makes the implementation a bit more complex. Those considerations should be weighed against the utility of the feature to users.

Rationale and alternatives

Instead of using a global slot time, we could use block height. The global slot time is available via the protocol state, which will be made available to transactions.

Prior art

Bitcoin uses a block field nLockTime, denoting a block time, which can be used to time-lock individual transactions. There are many articles about time-locked accounts for Ethereum by programming smart contracts. See, for example: https://medium.com/bitfwd/time-locked-wallets-an-introduction-to-ethereum-smart-contracts-3dfccac0673c. Beyond cryptocurrencies, vesting of benefits is a well-established idea in employment.

Unresolved questions

Do timed accounts interact with staking in any way?