WO-07 — Emission, pools, E46i

8 October 2026 · Branch wo-07-emission, based on wo-06-header at c069788.

Status: DONE

Implemented the integer emission schedule, per-block reward split, bounded pool accounting, and lazy E46i spend calculation in C++ with an independent Python reference and frozen vectors in e46/golden/wo07-golden.json. Decision #17 is resolved: E46i has ordinary 100-block coinbase maturity and no 100-block expiry; its value changes only by the §5.3a epoch shift. Earlier golden files were not changed.

Rules and implementation

  • Epoch length is 17,280 blocks; the reward is max(max(T − E, 0) >> 20, 1) base units. T is 4,600,000,000,000,000 base units. Emitted supply is clamped at T; the one-unit neutrino tail continues thereafter as specified.

  • Each block assigns r / 10 to each pool and gives the miner the remainder, so the integer sum is exactly r, including tiny rewards. Pool balances carry forward, checked additions reject overflow, and claims cannot exceed balances. N stake caps use 576 × origin subsidy; each Z finder is capped at collision subsidy / 10, with excess retained in the Z pool.

  • E46i spends require 100-block coinbase maturity. The spend value is amount >> elapsed_epochs; shifts of 64 or more return zero without an invalid C++ shift. The difference is burned. Ordinary E46 does not decay. A golden vector spends after 1,000 blocks in the same epoch and confirms the full amount remains available, directly covering the no-expiry decision.

  • At the one-base-unit tail the pool shares round to zero, so the entire reward goes to the miner while existing pool balances remain available to claim.

Emission results

The design tables count 12 monthly epochs as one year. In base units, the 100-table-year simulation produced:

Share

Simulated total

Spec table

Miner

3,680,000,009,867,520

36.8M E46

N-pool

459,999,989,781,120

4.6M E46

Z-pool

459,999,989,781,120

4.6M E46

Total

4,599,999,989,429,760

≈45,999,999.89 E46

These round to the specified 36.8M / 4.6M / 4.6M totals; the remaining amount at year 100 is 10,570,240 base units. The 1,000-table-year run covers 207,360,000 blocks and checks miner + N + Z == reward at every block. It produces 3,680,000,203,040,640 miner units, 459,999,989,798,400 units in each pool, and 4,600,000,182,637,440 units total. The total exceeds T because the spec continues the one-unit-per-block neutrino tail after T is reached.

The first one-unit reward is epoch 1,311. T is reached at height 24,722,559, which is 119.17 design-table years (12 epochs/year) or 117.53 years at the 150-second target spacing using 365-day calendar years. That agrees with the spec’s approximate “year 118” statement. Years 100, 114, and 118 and the post-T tail are included in the golden boundary vectors; remaining supply uses a guarded subtraction and never underflows.

Verification

  • python3 e46/golden/generate_wo07.py --check: pass; golden file reproduces.

  • Release configure/build with the repository’s warning-as-error settings: pass.

  • ctest --preset release --output-on-failure: 25/25 passed.

  • Fresh differential run against the Python reference: 4,875 comparisons, including random heights, rewards, pool operations, caps and E46i spends; 0 mismatches. The run also checked the 1,000-table-year per-block invariant.

  • Additional surprise differential run against the Python reference: 2,100 fresh comparisons with an unrecorded random seed; 0 mismatches.

  • ctest --preset sanitize --output-on-failure: 25/25 passed under AddressSanitizer and UndefinedBehaviorSanitizer.

  • After adding the explicit no-expiry vector, the three WO-07 tests passed in both release and sanitizer builds.

  • Clang 22.1.8 libFuzzer target emission_fuzz: 2,486,622 executions in 31 seconds; no crash, sanitizer finding, or artifact. The runtime reported that atos could not symbolize two newly covered standard-library exception symbols; fuzzing continued normally and completed without a finding.

  • No SHA-2 code or dependency was added.

Scope notes

The simulation uses the 12-epoch design-table year, matching the emission tables. The calendar-year conversion above uses the specified 150-second target spacing; actual block timestamps can vary. Pool claim code enforces available balances and the stated caps; collision discovery, stake weighting, and pro-rata payout construction remain responsibilities of their later callers.

Existing owner edits under MAPS/ and DECISIONS-NEEDED.md decision #17 were preserved. No other work-order files or frozen golden files were changed. No commit, push, merge, history rewrite, or deletion was performed.