Overview
Token distributions often require vesting schedules — linear or cliff-based unlocking over a ledger period. A VestingWallet contract enables SmartDrop to distribute tokens that unlock progressively, rather than all at once.
Vesting Models
| Type |
Description |
| Linear |
Tokens unlock proportionally over vesting_period ledgers |
| Cliff + Linear |
No unlock before cliff_ledger; linear thereafter |
| Step (milestone) |
Discrete chunks unlock at defined ledgers |
Contract Design
VestingWallet
├── initialize(beneficiary, token, total_amount, start_ledger, cliff_ledger, end_ledger)
├── release() — transfers vested-but-unclaimed tokens to beneficiary
├── revoke(admin) — admin: cancels unvested portion, returns to admin
├── vested_amount() -> i128
├── released_amount() -> i128
└── releasable() -> i128 — vested - released
Vested Amount Formula (linear)
fn vested_amount(env: &Env) -> i128 {
let current = env.ledger().sequence() as i128;
let start = get_start_ledger(env) as i128;
let end = get_end_ledger(env) as i128;
let cliff = get_cliff_ledger(env) as i128;
let total = get_total_amount(env);
if current < cliff { return 0; }
if current >= end { return total; }
total * (current - start) / (end - start)
}
Revocation
If revocable flag set at init: admin can call revoke to transfer the unvested balance back. Already-vested (but unclaimed) tokens remain claimable by the beneficiary.
Acceptance Criteria
Overview
Token distributions often require vesting schedules — linear or cliff-based unlocking over a ledger period. A
VestingWalletcontract enables SmartDrop to distribute tokens that unlock progressively, rather than all at once.Vesting Models
vesting_periodledgerscliff_ledger; linear thereafterContract Design
Vested Amount Formula (linear)
Revocation
If
revocableflag set at init: admin can callrevoketo transfer the unvested balance back. Already-vested (but unclaimed) tokens remain claimable by the beneficiary.Acceptance Criteria
contracts/vesting-wallet/contract createdreleasetransfers correct amount and updatesreleased_amountrevokeonly callable by admin and only whenrevocable = truevested_amountreturns 0 before cliff, proportional amount during vesting, total after end