FEE emissions schedule
FEE is emitted on an immutable schedule defined in FEEEmissionCurve.sol. The schedule is front-loaded but not a simple exponential decay: emissions ramp up to a peak at month 12, then taper for about three more years before the cap is reached.
Allocation
Total FEE supply cap: 63,000,000 FEE, split into two equal "sides":
- 31,500,000 FEE per side, emitted independently on the same curve.
- The two sides fund SP issuance (Stability Pool incentives via
SpIssuance) and LP issuance (LP staking incentives viaLpIssuance).
The two sides are independent — SP depositors and LP stakers each draw from their own 31.5M-FEE budget on the same time profile.
Shape
The schedule is encoded as 48 month-end cumulative checkpoints (months 0–47). Within each month emissions are linear; across months they form a smooth curve.
Key milestones, per side:
| Month | Cumulative FEE | Monthly FEE | % of cap |
|---|---|---|---|
| 1 | 681,103 | 681,103 | 2.2% |
| 6 | 4,638,079 | 871,153 | 14.7% |
| 12 | 10,869,621 | 1,170,447 (peak) | 34.5% |
| 18 | 17,255,215 | 982,399 | 54.8% |
| 24 | 22,461,929 | 785,919 | 71.3% |
| 36 | 29,338,722 | 392,959 | 93.1% |
| 47 | 31,500,000 | 32,746 | 100% |
After month 47 (= 4 × SECONDS_PER_YEAR from deployment, the HOT_END constant), getCumulativeIssued returns the cap. No further FEE is emitted from this contract.
Monthly emissions (per side)
Month Monthly FEE
1 681,103 ████████▓
2 715,467 █████████
3 751,563 █████████▌
4 789,481 ██████████
5 829,312 ██████████▌
6 871,153 ███████████
7 915,104 ███████████▌
8 961,272 ████████████
9 1,009,772 ████████████▌
10 1,060,716 █████████████
11 1,114,231 █████████████▌
12 1,170,447 ██████████████ ← peak
13 1,146,132 █████████████▌
14 1,113,386 █████████████▌
15 1,080,639 █████████████
16 1,047,892 █████████████
17 1,015,146 ████████████▌
18 982,399 ████████████
19 949,652 ███████████▌
20 916,906 ███████████▌
21 884,159 ███████████
22 851,412 ██████████▌
23 818,666 ██████████
24 785,919 █████████▌
25 753,173 █████████▌
26 720,426 █████████
27 687,679 ████████▌
28 654,933 ████████
29 622,186 ███████▌
30 589,439 ███████▌
31 556,693 ███████
32 523,946 ██████▌
33 491,200 ██████
34 458,453 █████▌
35 425,706 █████
36 392,959 █████
37 360,213 ████▌
38 327,467 ████
39 294,719 ███▌
40 261,974 ███
41 229,226 ██▌
42 196,480 ██
43 163,733 ██
44 130,986 █▌
45 98,240 █
46 65,494 ▌
47 32,746 ▎
Each █ represents roughly 83,500 FEE/month.
Why this shape
Three reasons, in priority order:
- Front-loaded to bootstrap usage. The peak at month 12 (not month 1) gives initial depositors and LP stakers a chance to enter and accrue position before peak emissions hit. A pure-decay curve (highest at t=0) would over-reward whoever happens to be in the contract at the moment of deployment.
- No long tail. The curve reaches the cap in 47 months, not asymptotically. Once the cap is hit, the SP and LP issuance contracts are functionally complete — there's no slow drip of fresh FEE indefinitely diluting holders.
- Smooth and predictable. The schedule is purely a function of
block.timestamp − deploymentTime. No governance vote, no rate changes, no admin pause. Anyone can compute their share of upcoming emissions exactly.
Comparison with Liquity V1
Liquity V1 issued LQTY on a 1-year half-life exponential decay (the standard (1 − 0.5^t) curve). That's extremely front-loaded: ~50% of all LQTY is emitted in year 1, ~75% by year 2, and the long tail asymptotically approaches the cap forever.
RAI Dollar's curve is also front-loaded, but in a different shape:
- It ramps up to peak emissions at month 12 instead of starting at peak.
- It terminates cleanly at month 47 instead of decaying forever.
- The total cap is reached in finite time, not asymptotically.
In practice, both produce roughly comparable cumulative-emitted-by-year curves for the first few years, but RAI Dollar's avoids the "first-block farmers get everything" pattern that exponential decay rewards.
Reading it on-chain
The library exposes two view functions used by SpIssuance and LpIssuance:
FEEEmissionCurve.getCumulativeIssued(uint256 elapsed) returns (uint256)
FEEEmissionCurve.getCumulativeFraction(uint256 elapsed) returns (uint256)
Both take seconds elapsed since deployment and return the cumulative-emitted FEE (and the fraction of cap, respectively). The integral over any window is simply the difference of two getCumulativeIssued calls.
Constants
SECONDS_PER_YEAR = 31,536,000
MONTH_DURATION = SECONDS_PER_YEAR / 12
HOT_END = 4 × SECONDS_PER_YEAR (4 years, schedule complete)
FEE_SUPPLY_CAP = 31.5M × 1e18 (per side)
The full 48 month-end checkpoints are hardcoded as constants in FEEEmissionCurve._monthEndCumulative.