aere-research/research/specs/spec-flywheel-economics.md
Aere Network 4a0b48588c Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:02:30 +03:00

24 KiB

AERE Token-Economic Mechanisms: Burn, Sink Flywheel, and Staking

Subsystem specification. AERE Network mainnet, Chain ID 2800 (Hyperledger Besu QBFT, 0.5-second blocks). Source of truth for addresses: aerenew/sdk-js/src/addresses.ts. Source of truth for logic: aerenew/contracts/contracts/. Solidity 0.8.23, OpenZeppelin 4.9.6.

Scope and honesty preface

This document specifies the on-chain money mechanisms that make AERE deflationary and that pay stakers:

  1. The validator-coinbase burn split (AereCoinbaseSplitter and its V2 successor).
  2. The permanent burn endpoint (AereFeeBurnVault).
  3. The immutable three-bucket revenue router (AereSink), configured 15/40/45 across BURN, BUYBACK, and STAKER-YIELD.
  4. The liquid-staking receipt token (sAERE, ERC-4626).
  5. The staking-reward products: delegated validator staking (AereStakingV2, 8% default APR) and fixed-term locked staking (AereLockedStaking, 10 to 30% APY).

Read the following honestly before the mechanism detail:

  • Fixed supply, no new issuance. Total supply is capped at 2,800,000,000 AERE at genesis-v2 (2026-05-07). None of the mechanisms below mint tokens. Staking rewards are paid out of pre-allocated genesis reserves that the Foundation seeds into each reward pool, not out of adaptive inflation. This is a deliberate design choice, not an oversight.
  • The APRs are a reserve-funded subsidy, not perpetual issuance. Because supply is fixed, the 8% delegated APR and the 10 to 30% locked APYs are finite: they draw down a Foundation-seeded reserve. They are sustainable only as long as that reserve funds them, or, in the long run, as far as real protocol-fee revenue routed through AereSink replaces the subsidy. The intended end-state is that the fee flywheel, not the reserve, pays stakers.
  • Realized throughput is thin. The chain runs with seven validators under one operator, one client, and no external audit. Burn and yield volume to date depend on validators actually running the coinbase-forwarder daemon and on real fee flow. This spec states parameters and formulas that are verifiable from source. It does not quote lifetime-burned, TVL, or yield figures; those are to be read live from the contracts' on-chain counters.
  • The base-fee framing is precise. AERE's QBFT chain does not run EIP-1559 protocol-level base-fee burning. The "37.5% burn" is applied to validator coinbase rewards by a splitter contract that validators call, operationalizing whitepaper section 3.3 at the coinbase layer rather than in consensus. Where this matters it is stated inline.

Native AERE is the gas and value token. WAERE (0x7e84d7d66d5da4cfE46Da67CDEeB05B323e1f5e8) is the ERC-20 wrapper, minted 1:1 by depositing native AERE (WETH9 design). Every ERC-20-facing mechanism below (the sink, sAERE) operates on WAERE; the splitter wraps native AERE into WAERE before routing it to the sink.

1. Fixed-supply foundation

Genesis-v2 allocations (from the registry header, chain 2800):

Allocation Amount Address
Strategic Investor (sold off-chain) 100M 0xaee2f3989f0AB23296Fa3b92247fe67587141311
Foundation (chain admin / contract owner) 180M 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3
Mining Reserve 1.4B 0x038f59A40ceeCd599A4588E4B0ff4642a0fbfFB8
Ecosystem Reserve 560M 0xB6a364F47d21DC2CbEB803565c111c1026e11C75
Team Reserve 420M 0x7968C438204a78B4e032fcFFd9A56Edb15fdCCdf
Airdrop Reserve 140M 0x261913fA73D6F109382F1aE98Ff6822ff03628B1

Total 2,800,000,000 AERE, capped. Every Ownable contract in this spec is owned by the Foundation account 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3 (a single-key Foundation-controlled account, not a deployed multisig). The economic thesis is monotone: the burn path only ever removes AERE from circulation against this fixed cap, and no path re-mints.

2. The validator-coinbase burn split

2.1 V1: AereCoinbaseSplitter

Address: 0xb4b0eCe9011613A5b84248a9B42a0f309E6F01Ec (owner = Foundation). Source: AereCoinbaseSplitter.sol.

A validator (or its forwarder daemon) calls splitAndDistribute(validator) or splitToSelf() with accumulated coinbase as msg.value. The contract atomically:

  1. Sends burnBps / 10000 of msg.value to AereFeeBurnVault.
  2. Sends the remainder back to the validator address.
  3. Increments cumulative counters (totalBurned, totalDistributed, and per-caller maps) and emits Burned / Distributed.

Parameters:

  • burnBps = 3750 (37.5%), matching whitepaper section 3.3.
  • Owner-adjustable via setBurnBps, hard-capped at 5000 (50%). The whitepaper wording is "up to 37.5%"; the 50% cap gives headroom while bounding abuse.
  • burnVault is owner-settable (setBurnVault, non-zero required).

The contract is ReentrancyGuard-protected and cannot custody funds across calls: every call fully dispatches msg.value. Anyone can call it (no burn allowlist), which is what lets a public explorer verify the deflation claim in O(1) reads from burnStats().

Note on the word "sealed": the burn rate is not immutable. It is owner-adjustable inside [0, 5000] bps. The truly sealed component of the token economy is AereSink (section 4), which has no owner at all.

2.2 V2: AereCoinbaseSplitterV2

Address: 0x8C1A48eFA57b66fEE743A00E3899c29ad3Fd27b4 (owner = Foundation). Source: AereCoinbaseSplitterV2.sol.

V2 replaces the two-way split with a three-way split that adds the sink bucket, so a slice of every validator reward feeds the sAERE flywheel instead of returning entirely to the validator.

Buckets (basis points, owner-configurable within hard caps):

Bucket Default Cap Destination
burnBps 3750 (37.5%) MAX_BURN_BPS = 5000 AereFeeBurnVault
sinkBps 1500 (15.0%) MAX_SINK_BPS = 3000 AereSink (via WAERE)
rebateBps (derived) 4750 (47.5%) 10000 - burn - sink validator

setBps(_burnBps, _sinkBps) enforces both caps and burn + sink <= 10000; rebateBps is a live-derived view. The sink share is routed by wrapping the native slice into WAERE (IWAERE.deposit), approving the sink, and calling IAereSink.flush(WAERE, sinkAmt) in the same transaction. If the sink call reverts, the whole split reverts and the validator retries.

Sink-rotation safety: the sink address is owner-settable but rate-limited. proposeSink starts a SINK_CHANGE_TIMELOCK = 7 days timer; acceptSink can only fire after it elapses; cancelPendingSink aborts. This gives validators seven days of warning before any sink swap.

Important operational caveat, stated honestly: the V2 constructor leaves sink unset. Until proposeSink + acceptSink wire a live sink, V2 behaves like V1 (the 15% sink slice is folded into the rebate, sinkAmt = 0). This spec documents the configured three-way design; whether the live V2 currently has its sink accepted and pointed at AereSink 0x69581B86A48161b067Ff4E01544780625B231676 is a Foundation operational state to confirm on-chain, not an invariant of the code. Validators migrate from V1 to V2 by repointing their off-chain forwarder daemon; V1 stays deployed and continues to honor V1 burn behavior for any flow still hitting it.

2.3 Deflation math (V2 default, worked)

For a validator coinbase reward R under the V2 defaults and the sink's 15/40/45 configuration (section 4):

  • Direct burn: 0.375 R.
  • Sink input: 0.15 R. Inside the sink, BURN (15%) plus BUYBACK (40%) are both AERE-destroying, so 0.55 x 0.15 R = 0.0825 R is burned, and STAKER-YIELD (45%) sends 0.45 x 0.15 R = 0.0675 R to sAERE holders.
  • Rebate to validator: 0.475 R.

Aggregating:

  • Total burned: 0.4575 R (45.75%).
  • Total to stakers (sAERE): 0.0675 R (6.75%).
  • Rebated to validator: 0.475 R (47.5%).
  • Protocol-directed (not rebated): 52.5%.

The "~52.5% net deflation" figure in the V2 source comment counts the entire sink slice as protocol-directed. The stricter, more honest number for actual token destruction is 45.75%, because 6.75% of the reward becomes staker yield rather than being burned. Both are stated so a reader can pick the definition they mean.

All of the above are default and design parameters. burnBps, sinkBps, and the sink's internal split determine the real numbers; the sink split is a deploy-time immutable (section 4).

3. The burn endpoint: AereFeeBurnVault

Address: 0x696afDF4f814e6Fd6aa45CE14C498ed9375fB2c6. Source: AereFeeBurnVault.sol. No owner, no admin.

A stateless sink with no withdraw function and no admin escape hatch. Native AERE arrives via receive() or burn(); ERC-20s arrive via burnToken(token, amount) (pull-via-approval). Counters totalBurnedAERE and totalBurnedToken[token] make deflation queryable in a single read.

Honesty on "obliteration": AERE that enters this vault is permanently removed from circulation because nothing can move it out. It is not literally sent to address(0) until someone calls the permissionless sweepToZero(), which forwards the whole native balance to address(0) (Besu QBFT permits this) and increments totalSentToZero. So there are two honest ways to describe the state: "removed from circulation on a no-withdraw contract" (always true on arrival) and "obliterated to the zero address" (true after sweepToZero). Both counters are exposed. ERC-20 burns stay on the contract forever (no zero-sweep for tokens).

4. The immutable flywheel: AereSink

Address: 0x69581B86A48161b067Ff4E01544780625B231676. Source: sink/AereSink.sol. No owner, no admin, no setters, no pause, no upgrade proxy.

AereSink is the single entry point for any protocol fee stream that should accrue to AERE holders. It splits every inflow across three buckets whose recipients and basis points are set once at deploy and are immutable thereafter. The constructor reverts unless BURN_BPS + BUYBACK_BPS + STAKER_YIELD_BPS == 10000.

Registry-documented deployed configuration: 15 / 40 / 45 (BURN / BUYBACK / STAKER-YIELD). Because these are constructor-set immutables, the specific values are not re-derivable from the source alone; the 15/40/45 figure is the canonical deployed split per the registry and the locked architecture design, and the code guarantees only that they sum to 10000 and can never change.

Buckets:

  1. BURN (15%): transferred to AereFeeBurnVault on top of the splitter's 37.5%.
  2. BUYBACK-and-burn (40%): non-AERE inflows are swapped to AERE via the DEX router, then sent to the burn vault. When the inflow is already AERE/WAERE (the normal case, since the splitter wraps before flushing), BURN and BUYBACK are merged into a single transfer to the burn vault, because buying AERE with AERE is a no-op.
  3. STAKER-YIELD (45%): transferred (or swapped) into the sAERE vault. A raw transfer into an ERC-4626 vault lifts totalAssets without minting shares, so the exchange rate appreciates for all sAERE holders. This is the flywheel's connection from fees to stakers.

Entry point: flush(token, amount). The caller approves the sink, then the sink pulls via transferFrom, computes the three parts (the staker part absorbs rounding residue so no dust accumulates on AERE inflows), and dispatches. After crediting the staker bucket it calls sAERE.sync() (best-effort) so the vault immediately begins linearly dripping the arrival rather than leaving a step-function price jump for a sandwicher to race.

Sandwich resistance on swaps: for non-AERE inflows, amountOutMin is computed from an external oracle price floor (_computeOracleFloor) rather than from the DEX pool reserves, because pool reserves can be manipulated by the same actor in one transaction. The oracle interface is compatible with AereLendingOracle.getPrice (AereLendingOracle at 0xc0f18A567067F1B84BDf75eDEbFaDdCBb70A4C49), normalized to 18 decimals, with an immutable MAX_SLIPPAGE_BPS tolerance. If the oracle is unset or reverts, the swap floor falls back to 1 (accept any non-zero output). The DEX router is the AERE V2-style AereSwapRouter (0x7526B2E5526EfA84018378b60F2844Dad77523D8).

Failure isolation: a failed swap (dead pair, slippage) does not revert the whole flush. The tokens stay as dust, a SwapFailed event fires, and the approval is cleared. Anyone can later call the permissionless sweepDust(token) to re-flush accumulated dust through the same three buckets. flush and sweepDust are both nonReentrant.

Immutability is the point. There is no setBucket, no setRecipient, no setRouter. If the router ever needs replacing, the sink is redeployed and fee sources are rewired. The absence of any admin key is the credibility anchor of the whole flywheel: holders can verify that the 15/40/45 split and the recipients cannot be changed under them.

Honest note on non-18-decimal tokens: the oracle floor math assumes 18-decimal tokens on both sides. A non-18-decimal fee token would be systematically mispriced by _computeOracleFloor; production integrations of exotic fee tokens should add a decimals-normalizing oracle wrapper. In practice the primary inflow is WAERE (18 decimals), which takes the no-swap path.

5. The liquid-staking receipt: sAERE

Address: 0xA2125bE9C6fd4196D9F94757Df18B3a2A5e650b0. Source: staking/sAERE.sol, an OpenZeppelin ERC-4626 vault over WAERE. No owner, no admin, no pause, no upgrade proxy, no parameter setters.

Depositors lock WAERE and receive sAERE. The WAERE-per-sAERE exchange rate drifts up as AereSink's STAKER-YIELD bucket routes fees in. This is "real yield": it comes from protocol fee inflows, not from issuance, and the provider does not choose whether, when, or how much (once funds arrive they vest mechanically). There is no fixed APR; the rate is whatever the fee flow produces.

Linear drip (audit fix R5, HIGH-1). Yield is not recognized as a step function the instant the sink transfers AERE in. Arrivals are folded into a reward reserve that vests linearly over DRIP_DURATION = 7 days:

  • totalAssets() returns the on-contract balance minus the still-unvested reserve, so share price grows continuously with time, not in blocks-sized jumps.
  • sync() is permissionless and idempotent; it is also called inside every deposit and withdraw. It detects arrivals since lastObservedBalance and (re)computes rewardRate and periodFinish.
  • Grief guard (audit fix R6, HIGH): a fresh drip period only restarts if arrivals are at least DRIP_RESTART_THRESHOLD_BPS = 100 (1%) of the unvested reserve, or there is no active period. Tiny 1-wei-per-block arrivals only top up rewardRate without extending periodFinish, so a griefer cannot indefinitely stall stakers' vesting.

Killing this drip is what defeats the flash-loan sandwich (deposit, flush the sink, redeem in one block): the share price cannot jump within a block.

Inflation-attack moat (audit fix R5, HIGH-4). _decimalsOffset() is overridden from OZ's default 0 to 6, giving a 1e6 virtual-share offset, which is the primary defense against the classic ERC-4626 first-depositor inflation attack. A dead-shares seed is also minted to 0x…dEaD at deploy. Honesty note for implementers: the contract's header comment describes a "1 WAERE" seed, but the compiled constant is DEAD_SHARES_SEED_WAERE = 1000 wei; the effective moat is the 1e6 decimals offset regardless of the seed size, so this documentation discrepancy does not affect safety.

Views for integrators: pricePerShare() (convertToAssets(1e18)), undistributedRewards(), and atomicState() (a single-block snapshot of balance, totalAssets, undistributed, supply, rewardRate, periodFinish, lastObservedBalance) for drift-free invariant checks.

Honest caveat on realized yield: sAERE only appreciates if fees actually flow through AereSink. With thin current usage, realized sAERE yield to date is minimal and should be read live from the exchange rate, not assumed. The mechanism is real and admin-free; the volume is early.

6. Staking-reward products

AERE has three distinct staking surfaces. They are frequently conflated; they are not the same and only sAERE is admin-free real-yield.

6.1 Delegated validator staking: AereStakingV2

Address: 0x1D95eF6D17aeAB732dF914Ba2d018c270BC155FC (owner = Foundation). Source: staking/AereStakingV2.sol. This is a bug-fix redeploy of V1 (0xAbDb01d9A4f41792129b2654Fb6DDB9689360DEc, deprecated, 0 validators / 0 staked / 0 balance). Do not use V1.

Model: token holders delegate native AERE to validators and earn APR; validators post a self-stake bond and take a commission on delegator rewards.

Parameters:

  • rewardRateBps = 800 (8% APR) default, owner-settable via setRewardRateBps in [1, 10000] bps. The registry flags this: the founder should confirm the intended live APR, since V1's effective rate was mis-scaled to roughly 1.6%.
  • MIN_VALIDATOR_SELF_STAKE = 500 ether (500 AERE).
  • MIN_DELEGATION = 1 ether (1 AERE).
  • UNBONDING_PERIOD = 7 days.
  • SLASH_RATE_BPS = 500 (5% of self-stake per slash, owner-only slash).
  • MAX_COMMISSION_BPS = 5000 (50% cap on validator commission).

Accrual is timestamp-based: reward = amount x rewardRateBps x secondsElapsed / (10000 x 365 days), which is immune to block-time changes (V1's bug divided by a hardcoded 0.1s-block count, underpaying roughly 5x). Every amount-changing path calls _settle first, so a top-up earns zero retroactive reward. Validator commission is split off gross and credited to commissionAccrued, claimable via claimCommission. Delegators claim via claimRewards; unbonding queues into a 7-day queue drained by claimUnbonded. A validator's own self-stake is a slashable bond that earns no reward; slashed AERE stays in the pool as surplus backing rewards, with no admin withdrawal of principal.

Honest funding caveat, stated in the source itself: rewards and commission are paid from this contract's native AERE balance. Because supply is fixed at 2.8B with no consensus-level minting, the pool must be seeded by the Foundation (out of genesis reserves) until protocol-level reward minting is wired to consensus, which is not built. claimRewards reverts with "pool insufficient (needs foundation top-up)" if the balance cannot cover the claim. So the 8% APR is a reserve-funded subsidy today, not native issuance.

6.2 Fixed-term locked staking: AereLockedStaking

Address: 0x21108c28A849b05aE6b7a3a5bc435C9Bc897E7Ad (owner = Foundation). Source: AereLockedStaking.sol.

Users lock native AERE for a fixed term and earn a fixed APY paid in AERE at maturity. Early exit forfeits all reward and returns principal only.

Tier Duration APY (APY_BPS)
0 30 days 10% (1000)
1 90 days 15% (1500)
2 180 days 22% (2200)
3 365 days 30% (3000)
  • MIN_STAKE = 1 ether, MAX_STAKE = 100_000 ether per lock.
  • Reward = principal x APY_BPS x duration / (365 days x 10000).
  • Principal protection: withdraw reverts unless balance >= total + totalPrincipal, so other stakers' locked principal can never be drained to pay a maturity. The reward reserve is balance - totalPrincipal, seeded by the Foundation via receive() (anyone can donate).

Honest sustainability note: a 30% APY on a 365-day lock, funded from a finite Foundation-seeded reserve against a fixed 2.8B cap, is a subsidy with a runway, not a perpetual rate. It is safe (principal is protected, and maturities that the reserve cannot cover simply cannot be withdrawn until topped up), but it is not self-funding until real fee revenue through the sink is large enough to underwrite it. This is the core tension of a fixed-supply chain paying staking yield, and it is by design that the sink flywheel, not the reserve, is meant to be the long-run funding source.

6.3 Governance staking: AereGovernanceStaked

Address: 0x8D77C888e439C4fADb2e23F1567a0A1965F80bCb. Source: AereGovernanceStaked.sol. Not a yield product; included for completeness because it reads staking state. Voting power equals the total AERE a holder has delegated across all validators in the staking contract (stake-to-vote). PROPOSAL_THRESHOLD = 100000 ether, QUORUM_PERCENTAGE = 20% of total staked, VOTING_PERIOD = 7 days, EXECUTION_DELAY = 2 days. The 7-day unbonding period makes vote-borrowing impractical.

7. End-to-end flywheel

validator coinbase reward R
        |
        v
AereCoinbaseSplitterV2  (37.5% burn / 15% sink / 47.5% rebate)
     |            |                     |
     |            |                     +--> validator (0.475 R)
     |            +--> wrap to WAERE --> AereSink.flush()
     |                                     |  (sink 15 / 40 / 45; 55% burn-eq + 45% yield)
     |                                     +--> BURN 15% + BUYBACK 40% --> AereFeeBurnVault
     |                                     +--> STAKER-YIELD 45% --> sAERE (rate appreciates)
     +--> AereFeeBurnVault (0.375 R, permanent)

Net per reward R (defaults): 0.4575 R burned, 0.0675 R to sAERE holders, 0.475 R rebated. The same AereSink is the intended router for other fee streams (fee-monetization, settlement, and similar), so as real usage grows, sAERE yield rises and burn accelerates without any parameter change and without any admin action, because the sink has no admin.

8. Honest limitations and open items

  • Sink wiring on V2 is an operational state, not a code invariant. The three-way split is only active once the Foundation runs proposeSink + acceptSink (7-day timelock) pointing V2 at AereSink. Confirm on-chain before quoting the 45.75% number as live.
  • Staking APRs are reserve-funded subsidies. No consensus-level reward minting exists; AereStakingV2 and AereLockedStaking pay from Foundation-seeded balances out of the fixed 2.8B. This is honest and on-strategy (no adaptive issuance), but it means the APR is bounded by the reserve until fee flow replaces it.
  • Splitter throughput depends on validators. Burn only happens when validators route coinbase through the splitter. With seven validators under one operator, realized burn volume is early; read totalBurned / burnStats() live rather than assuming.
  • No external audit. All fixes above are internal audit rounds (R5, R6, and the finding-numbered redeploys). The mechanisms are admin-minimized and reentrancy-guarded, but they have not had a third-party audit.
  • sAERE doc discrepancy. The header comment says a 1 WAERE dead-seed; the constant is 1000 wei. Safety rests on the 1e6 decimals offset, so this is cosmetic, but it should be reconciled in a future redeploy or doc pass.
  • AERE AereToken.sol note. The native token is AERE itself; AereToken.sol is only a governance-compatibility shim over WAERE. There is no separately mintable ERC-20 AERE.

9. Roadmap / in development

  • Consensus-wired reward minting is not built. Long-term, staking rewards should be funded by protocol-level mechanics rather than reserve top-ups. Today this is explicitly a roadmap item (the staking source comments say "until protocol-level minting is wired to consensus"). Any such change must respect the fixed 2.8B cap; adaptive issuance is off-strategy and out of scope.
  • Fee-source expansion into the sink. Broadening the set of contracts that flush into AereSink (beyond the coinbase splitter) is the primary lever to make sAERE yield and the burn self-sustaining. This is additive and requires no change to the immutable sink.
  • V1-to-V2 splitter migration completion. Once all validators point their forwarder daemons at AereCoinbaseSplitterV2, V1 burnBps can be set to 0 and V1 retired.

Appendix: address registry (verbatim, chain 2800)

Contract Address
WAERE 0x7e84d7d66d5da4cfE46Da67CDEeB05B323e1f5e8
AereCoinbaseSplitter (V1) 0xb4b0eCe9011613A5b84248a9B42a0f309E6F01Ec
AereCoinbaseSplitterV2 0x8C1A48eFA57b66fEE743A00E3899c29ad3Fd27b4
AereFeeBurnVault 0x696afDF4f814e6Fd6aa45CE14C498ed9375fB2c6
AereSink 0x69581B86A48161b067Ff4E01544780625B231676
sAERE 0xA2125bE9C6fd4196D9F94757Df18B3a2A5e650b0
AereStakingV2 0x1D95eF6D17aeAB732dF914Ba2d018c270BC155FC
AereStaking V1 (deprecated) 0xAbDb01d9A4f41792129b2654Fb6DDB9689360DEc
AereLockedStaking 0x21108c28A849b05aE6b7a3a5bc435C9Bc897E7Ad
AereGovernanceStaked 0x8D77C888e439C4fADb2e23F1567a0A1965F80bCb
AereSwapRouter (sink DEX router) 0x7526B2E5526EfA84018378b60F2844Dad77523D8
AereLendingOracle (sink swap-floor oracle) 0xc0f18A567067F1B84BDf75eDEbFaDdCBb70A4C49
Foundation (owner of Ownable contracts) 0x0243A4f47D44b40b65D33f20329dE20D00c6f3C3