Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

/p/g1magld5ptgzaktqcexxq0pgq5lmdf0kz6re8hlv/x/daily/cliffvesting/v1

Directory · 4 Files
README.md Open

gno.land/p/moul/x/daily/cliffvesting/v0

Cliff-then-linear vesting calculator — New, NewLinear, Vested, Unvested, Claimable, PercentVested, CliffAmount, IsFullyVested, Duration, HasCliff.

1import "gno.land/p/moul/x/daily/cliffvesting/v0"
2
3s, _ := cliffvesting.New(1200, 0, 3, 12) // total, start, cliff, end
4s.Vested(2)          // 0   — before the cliff
5s.Vested(3)          // 300 — the cliff releases the elapsed portion at once
6s.Vested(12)         // 1200
7s.Claimable(6, 300)  // 300 — vested minus already claimed

Pure. No state, no balances, no transfers. The arithmetic is the part that is easy to get subtly wrong and easy to test; custody belongs to the realm holding the coins.

The cliff is a step, not a ramp: nothing vests before it, then the whole elapsed portion unlocks at once, and the rest accrues linearly.

All integer arithmetic — no float ever reaches consensus state:

  • total*elapsed/duration, multiplying first. The reverse computes a per-tick rate that truncates to zero whenever total < duration, so nothing would ever vest. That is the classic vesting bug; it has its own test (7 tokens over 1000 ticks).
  • Rounding is down, so a beneficiary is never paid more than they earned, and the final instalment collects the remainder: 1000 over 3 periods is 333 + 333 + 334, and Vested(end) is exactly total, never total-1.
  • Claimable never returns negative, even if the caller's bookkeeping says more was claimed than has vested.

Times are int64, so the caller may use block heights or unix seconds — the unit only has to be consistent.

Live demo: r/moul/x/daily/cliffvestingdemo · render it at /r/moul/x/daily/cliffvestingdemo/v0.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.