Skip to content
TimeVault

A promise with a clock in it

What happens inside a vault, from lock to claim.

The life of a vault

  1. 1. Lock

    The funder deposits the full amount into the vault.

  2. 2. Wait

    Nothing to do. Anyone can see what unlocks when.

  3. 3. Unlock

    As dates pass, funds unlock. No transaction needed.

  4. 4. Claim

    The recipient withdraws what has unlocked, whenever they like.

Reviewers approve (optional)Revoke (optional)

Three schedules, one example

One 12,000 tUSDC grant, released three ways.

  • On a date

    unlocked(t) = t ≥ date ? total : 0

    12,000 on day 365

  • Monthly steps

    Equal tranches; rounding leftovers go to the last one.

    1,000 on the same day each month

  • Gradually, with a cliff

    After the cliff: total × (t − start) ÷ (end − start).

    3,000 at month 3, then about 33 a day

Cliffs, revocation and reviewers

Cliff
A waiting period before anything unlocks.
Revocation
Unlocked funds stay claimable; only the still-locked part returns to the funder.
Reviewer approval
N of M named reviewers must approve before anything is claimable.
Stays with the recipient · 4,964 tUSDCReturns to the funder · 7,035 tUSDC

Diagram: revoking at month 5 of a 12-month grant. Unlocked stays with the recipient, the rest returns to the funder.

Why recipients claim, instead of being paid

A contract can't move money on its own. Claiming lets the recipient pick the moment; a missed month simply waits.

Time on a blockchain

Contracts read the block timestamp, accurate to seconds. The demo's clock can fast-forward; Reset demo returns to today.

For developers

The demo's data layer is shaped like the contract, so real chain calls wouldn't touch the UI.

Show the contract interface

Contract interface (sketch)

interface ITimeVault {
    struct Schedule { uint8 kind; uint64 start; uint64 cliff; uint64 end; uint16 steps; }

    /// Deploys a vault and pulls `total` of `token` from the funder.
    function lock(address recipient, IERC20 token, uint256 total,
                  Schedule calldata schedule, bool revocable,
                  address[] calldata reviewers, uint8 required)
        external returns (address vault);

    function unlocked(uint64 at) external view returns (uint256);
    function claimable() external view returns (uint256);

    function claim() external;   // recipient only
    function approve() external; // named reviewers only
    function revoke() external;  // funder only, if revocable

    event Locked(address indexed funder, address indexed recipient, uint256 total);
    event Claimed(address indexed recipient, uint256 amount);
    event Approved(address indexed reviewer, uint8 count);
    event Revoked(uint256 kept, uint256 returned);
}

How the demo mirrors it

src/lib/demo/vesting.ts
unlocked() and claimable(), as pure functions.
src/lib/demo/ops.ts
lock, claim, approve, revoke state changes.
src/lib/demo/chain.ts
Simulated wallet prompt, pending, confirmed or reverted.
src/lib/demo/store.ts
Saved state and the demo clock.

See it unlock

Launch the demo