Third-party audit scope¶
ELI5: Package for an external auditor — every contract, seam, invariant, and known internal finding in one place. Submit this with source access before mainnet.
Engagement goal¶
Prove the four-protocol FLYWHEEL 2.0 stack is safe to deploy on Ethereum mainnet at the parameter envelope in mainnet parameters. Focus on composition (cross-repo routers) as much as single-contract logic.
In-scope contracts (14 + routers)¶
| # | Contract | Repo | Source | Value path? |
|---|---|---|---|---|
| 1 | TareToken |
TARE-Stablecoin | src/tare_token.vy |
Yes (minter set) |
| 2 | TareEngine |
TARE-Stablecoin | src/tare_engine.vy |
Yes (CDP) |
| 3 | sTARE |
TARE-Stablecoin | src/stare.vy |
Yes (saver funds) |
| 4 | SurplusSplitter |
TARE-Stablecoin | src/SurplusSplitter.vy |
Yes (skim path) |
| 5 | CoilFeeRouter |
TARE-Stablecoin | src/CoilFeeRouter.vy |
No (earned fees only) |
| 6 | PegKeeper |
TARE-Stablecoin | src/peg_keeper.vy |
Yes (unbacked mint cap) |
| 7 | AuctionHouse |
TARE-Stablecoin | src/auction_house.vy |
Yes (seized collateral) |
| 8 | Coil |
Coil-DEX | src/Coil.vy |
No (settlement) |
| 9 | MultiStrategyVault |
khomdev-keep | src/MultiStrategyVault.vy |
Yes (depositor TVL) |
| 10 | CoilMakerStrategy |
khomdev-keep | src/strategies/CoilMakerStrategy.vy |
Yes |
| 11 | Fallback strategies | khomdev-keep | src/strategies/*.vy |
Yes |
| 12 | VotingEscrow |
khomdev-veforge | src/VotingEscrow.vy |
No |
| 13 | GaugeController + GaugeWeightRouter |
khomdev-veforge | src/*.vy |
Partial (allocations) |
| 14 | BribeDistributor + EmissionRouter |
khomdev-veforge | src/*.vy |
No (bribe accounting) |
Out of scope: AGENTS_FLYWHEEL/ (read-only agents), tribute/, SnekSentry/, off-chain Rust solver (review separately if in engagement).
Core invariant (must hold)¶
No vote, keeper, admin, or caller may move a solvent user's collateral, mint on a bad price, or alter live debt. Routers only move value already released or earned.
See Core invariant. Scope limit: TareEngine only — Keep STRATEGY_MANAGER is a separate depositor-risk surface.
Composition seams (priority review)¶
| ID | Seam | Risk |
|---|---|---|
| S1 | Coil → CoilFeeRouter → CoilMaker / BribeDistributor / surplus | Mis-wiring wastes yield; bare vault transfer doesn't credit total_idle |
| S2 | Engine surplus → SurplusSplitter → sTARE + CoilMaker | Wrong emission_sink strands TARE |
| S3 | GaugeController → GaugeWeightRouter → Keep set_allocations |
COMP-2: allocator cannot add strategies |
| S4 | CoilMaker → Coil EIP-1271 intents | Solver drain vs maker_margin_bps floor (H-2) |
| S5 | PegKeeper + CurveTAREStrategy on shared pool | Keeper mint on bad EMA; strategy LP shifts pool balance |
| S6 | PegKeeper unbacked mint | Dilution up to debt_ceiling |
Diagram: Composition seams.
Threat model highlights¶
- Oracle manipulation — Chainlink staleness/deviation halts; Curve EMA used for peg keeper gate and CoilMaker floor.
- Solver / keeper trust — Whitelist solver holds inventory; keepers are permissionless but operational.
- Admin compromise — Keep strategy manager can repoint depositor capital; must be timelock/multisig on mainnet.
- CDP cascade — Liquidation bonus 10%, bad debt → surplus burn then
total_bad_debt. - Governance override —
GaugeController.change_gauge_weightbypasses voters.
Internal pre-audit artifacts (provide to auditor)¶
| Artifact | Location |
|---|---|
| Stateful fuzz | ./script/nightly_fuzz.sh across four submodules |
| Composition auditor | AGENTS_FLYWHEEL/agents/security/composition_auditor/ |
| Deploy verifier | AGENTS_FLYWHEEL/agents/security/deploy_verifier/ |
| StressSim adversarial economics | AGENTS_FLYWHEEL/agents/security/stresssim/ |
| Per-protocol SECURITY.md / SPEC.md | Each submodule root |
Known internal findings (verify fixed before audit sign-off)¶
| ID | Topic | Status |
|---|---|---|
| TARE-7 | CoilFeeRouter.max_swap_in mandatory |
Fixed in source; verify live bytecode |
| TARE-8 | Keep admin on value path | Deployment config — timelock required |
| COMP-2 | Gauge router ALLOCATOR_ROLE only |
Implemented |
| FMR-002 | CoilFeeRouter keep deposit path | Fixed FLYWHEEL 2.0 |
| H-2 | CoilMaker spread floor vs hostile solver | maker_margin_bps default 100 |
| CDP deploy | add_collateral threshold assert |
Verify on deployed engine bytecode |
| M-1/M-2 | CoilMaker harvest cap / depeg exit | Params at deploy |
Run StressSim Scenario 3 (CDP) and Scenario 5 (solver drain) as regression proofs.
Launch envelope (auditor should bound-check)¶
Parameters in config/mainnet-params.toml:
- Coil
fee_bps≤ 100 (1%) keep_bps + gauge_bps≤ 5000 (50%)emission_bps≤ 3000 (30% to CoilMaker; ≥70% to sTARE)- PegKeeper
debt_ceilingsized to pool depth max_swap_inon CoilFeeRouter and CoilMaker set before harvest enabled
Deliverables requested from auditor¶
- Report covering all in-scope contracts + seams above
- Severity-rated findings with exploit paths
- Confirmation of invariant scope (engine vs Keep)
- Sign-off or explicit blockers before mainnet deploy
- Optional: Rust solver (
Coil-DEX/solver/) review for settlement math parity
Pre-audit checklist (protocol team)¶
- [ ] Fresh mainnet deploy from audited commit (no stale Sepolia bytecode)
- [ ]
deploy_verifierGO on mainnet manifest (pre-launch script) - [ ] Timelock/multisig owns all
value_pathadmin roles - [ ]
nightly_fuzzgreen on audit commit - [ ] StressSim worst-case report archived in
reviews/ - [ ] Keeper fleet documented and tested on Sepolia (keepers README)
See also Audit status and Trust model.