Linear decay #
A quantity that decays linearly from peak at the start of a window to 0
at the end. Outside the window, the value is 0.
This pattern recurs across Solana DeFi:
- Withdrawal-penalty curves in farm contracts: penalty is
peakif you unstake at the start of the lock,0at maturity. - Linear vesting: complementary shape; the claimable amount is
peak − decay. - Liquidation-incentive bonuses that decay over time.
- Time-weighted voting power approaching a sunset.
The Lean model below is a single def over Nat (the spec layer); a
UInt64 wrapper plus the no-overflow proof lives in a follow-up file.
Main definitions #
Solanalib.Finance.LinearDecay.value— the decaying quantity at a given time.
Main statements #
value_le_peak— bounded above bypeak.value_antitone_in_window— within the window, value is non-increasing intNow.value_at_begin— at the left boundary, value equalspeak.value_at_end— at or after the right boundary, value is0.
Each theorem maps to a specific refactor-bug class:
| Theorem | Bug class it catches |
|---|---|
value_le_peak | Penalty growing larger than configured (mul/div re-ordering) |
value_antitone_in_window | Subtraction direction flipped in the numerator |
value_at_begin | Off-by-one on the lock-start guard |
value_at_end | Off-by-one on the maturity guard (> vs ≥) |
The function is not monotonically antitone globally — at tNow = tBegin
it jumps from 0 (outside-window) to peak (inside-window). The honest
monotonicity statement (value_antitone_in_window) restricts both
timestamps to the locking window.
The value of a linearly-decaying quantity at time tNow, given the
window [tBegin, tEnd) and the peak peak.
Inside the window, the value is peak * (tEnd - tNow) / (tEnd - tBegin).
Outside (before tBegin or at/after tEnd), it's 0.
Equations
Instances For
Theorems #
P1 — Bounded. The decay never exceeds the configured peak.
P2 — Antitone in tNow (within the window). If t₁ ≤ t₂ and
both fall inside the locking window, then value at t₂ is at most
value at t₁.
The global function is not monotonically antitone — at tNow = tBegin
it jumps from 0 (outside) to peak (inside). The honest statement
restricts to in-window timestamps.
P3b — Value at end. At or after the right boundary, the value
is 0.
WindowedDecay constructor #
LinearDecay.toWindowedDecay bundles the value function with its
four proof obligations into a WindowedDecay value. Every generic
theorem about WindowedDecay (e.g. WindowedDecay.complementary_*)
applies automatically to any value produced by this constructor.
Construct the bundled WindowedDecay view of a linear decay. The
function-side is value; the four proof obligations are discharged by
the corresponding value_* theorems.
Equations
- One or more equations did not get rendered due to their size.