Skip to content

veNOTE

fact Source contracts/src/governance/veNOTE.sol. veNOTE is a non-transferable voting-weight record in the Curve tradition: you lock NOTE for a fixed term and receive weight that falls linearly to zero at the unlock time. It implements IVotes in timestamp mode and is the IVotes source for both governors and for gauge votes.

Weight
amount × (end − t) / MAXTIME
MAXTIME
4 × 365 days
Minimum term
1 week
Delegation
none
  • end is the unlock time you choose, floored to a week boundary (Thursday 00:00 UTC). A lock ending in 4 years from today has a weight of about 1 veNOTE per NOTE; a 1-year lock starts at about 0.25.
  • Weight decays every second. Nothing decays your principal: the NOTE amount stays fixed and is returned in full by withdraw() once the lock expires.
  • One lock per address. There is no delegation: delegates(a) returns a, and delegate or delegateBySig revert DelegationNotSupported.
  • Weight is exact: balanceOfAt and totalSupplyAt use a binary search on checkpointed points, so a governor snapshot at any past timestamp reads the true value at that instant.
100k 75k 50k 25k 0 now 1 y 2 y 3 y 4 y Alice · 100,000 NOTE · 4 years · 100,000 ve Bob · 60,000 NOTE · 2 years · 30,000 ve dashed: 60,000 NOTE · 1 year · 15,000 ve
Illustrative. Weight in veNOTE (y) against time (x). Each lock is a straight line from amount × (end − now) / MAXTIME at creation to zero at its unlock time. Longer locks start higher and fall more slowly in relative terms.

illustrative Same locks as the worked weekly example.

AliceBob
Locked100,000 NOTE60,000 NOTE
Term4 years (max)2 years
Slope amount / MAXTIME100,000e18 / 126,144,000 ≈ 7.93e11 per second60,000e18 / 126,144,000 ≈ 4.76e11 per second
Weight at lock100,000 × 4/4 = 100,000 ve60,000 × 2/4 = 30,000 ve
Weight after 1 week100,000 − 7.93e11 × 604,800 / 1e18 ≈ 99,520 ve30,000 − 4.76e11 × 604,800 / 1e18 ≈ 29,712 ve
Weight after 1 year75,000 ve15,000 ve
Weight at unlock00
Share of total (130,000 at lock)76.9%23.1%

Bob’s lock loses 0.96% of its weight in the first week; Alice’s loses 0.48%. The shorter lock decays faster in relative terms, so relative weights drift toward longer lockers between votes unless Bob extends.

fact

FunctionWhoReverts
createLock(amount, unlockTime)anyone, whenNotPausedZeroAmount, LockExists, UnlockTimeInPast, UnlockTimeTooFar (more than 4 years)
increaseAmount(amount)the lockerNoLock, LockExpired
depositFor(account, amount)anyoneadds NOTE to another address’s lock; NoLock, LockExpired
increaseUnlockTime(unlockTime)the lockerUnlockTimeNotIncreased, UnlockTimeTooFar, LockExpired
lockFromStaked(shares, unlockTime)anyonepulls sNOTE shares and credits their convertToAssets value; unlockTime must be non-zero for a new lock and 0 for a top-up (UnlockTimeMustBeZero)
withdraw()the locker, never pausableNoLock, LockNotExpired; returns NOTE and any escrowed sNOTE shares
checkpoint()anyonefills the global point history
balanceOf, balanceOfAt(account, ts), totalSupply, totalSupplyAt(ts)viewFutureLookup for ts > now
getVotes, getPastVotes, getPastTotalSupply, clock, CLOCK_MODEview (IVotes)getPast* need timepoint < clock()
locked, lockedEnd, getLastUserSlope, userPointHistory, pointHistory, userPointEpoch, epochview

Every mutating call re-checkpoints the user and the global supply, so totalSupply is never stale by more than the caller’s own change.

lockFromStaked does not redeem the vault shares (sNOTE withdrawals need requestWithdraw plus a cooldown). It escrows the shares inside veNOTE and credits the lock with their asset value at that moment. Voting weight is fixed at lock time and does not track later vault yield, which is the conservative choice; the shares, including any yield accrued while escrowed, come back with withdraw().

ConsumerReadsNote
NoteGovernorgetPastVotes(voter, snapshot), getPastTotalSupplySnapshot is proposal creation plus votingDelay (1 day). Proposal threshold is 0.5% of supply at clock() − 1.
UpgradeGovernorsameQuorum 8% of supply at snapshot.
GaugeControllergetLastUserSlope, lockedEndAllocates your slope across gauges; the lock must extend past the next week boundary (LockExpiresTooSoon).
  • No transfer, no wrapping, no delegation. Weight belongs to the address that locked.
  • No early exit. withdraw() reverts LockNotExpired until end.
  • Not a boost. sNOTE staking rewards are not multiplied by veNOTE in v1; bribe markets and lock boost are listed as future work in the contract documentation.
  • Pausable creation only. The guardian can pause createLock, increaseAmount, depositFor, increaseUnlockTime and lockFromStaked; withdraw always works.