- Scope
- contracts/src as deployed, 49 files, 18,244 lines, driven against the LIVE Ethereum mainnet addresses rather than against source or a testnet. solc 0.8.30 (runs 100), Slither 0.11.6. The first review of this protocol conducted against a live mainnet deployment.
- Method
- Fork-reproduced and adversarially cross-examined. A harness binds to the live mainnet addresses and drives the deployed contracts from genesis through mint, deposit, origination, funding, default and settlement, so every code finding is a passing Foundry test against PRODUCTION BYTECODE rather than a source argument. Four independent reviewers read all 23 contracts in full under four distinct adversarial lenses, economic sequencing, cross-contract invariants, accounting and state machines, and authority and voting. Every surviving candidate was re-examined by a skeptic instructed to refute it. The engagement lead independently traced every value-moving path. EXPLICITLY NOT RUN, per the report: coverage-guided fuzzing, symbolic execution or formal proof, model qualification benchmarking, and live-fire governance rehearsal beyond the fork. AI-assisted, and explicitly NOT a maximum-assurance audit.
- Reviewed baseline
- f1f1f47, freeze tag mainnet-v1-production-freeze-2026-08-16, deployed to Ethereum mainnet at block 25,768,251
DV-01MediumForest Road: LowOpen
A fixed-gas recovery probe misreads a healthy impairment source as broken, and the fix drops the senior mark to par
Reproduced against live bytecode. The vault prices every senior exit at totalAssets minus pendingSeniorImpairment, read through a walk over every live default event that nothing bounds. The emergency recovery lever gates on a FIXED 200,000-gas probe and treats an out-of-gas result as proof the source is broken, while ordinary reads of the same source are uncapped. Past roughly 46 declared defaults the probe fails on a perfectly healthy source, so a good-faith operator diagnostic reports it broken, clearUnreadableImpairmentSource fires: the conservative mark leaves exit pricing entirely, and the high-water mark ratchets IRREVERSIBLY. In the reproduction a genuine $2.3M impairment vanishes and the exit price jumps from 17,700,100e18 to par at 20,000,100e18. NOT ATTACKER-REACHABLE, but reachable by ordinary operation plus a good-faith governance action, which is why it is not rated lower. The measurement is against warm storage; the production probe runs against cold storage and is strictly more expensive, so the real threshold is LOWER than 46. This falsifies the premise of the earlier FEE-09 acceptance, which rested on the true mark being unreadable at that moment. Recommendation: bound the ledger walk or restore an O(1) aggregate, and make the recovery probe scale with gasleft() the way the install gate already does, so 'unreadable' means actually unreadable rather than merely heavy. At minimum, never let the clear fire while an uncapped read of the same source succeeds in the same transaction. MATERIAL TO ANY INTEGRATOR RECORDING A HIGH-WATER EXCHANGE RATE: the discontinuity is upward, so a watermark can be set at a phantom level the true rate never returns to.
Forest Road assessment: Low
Measured on mainnet 2026-08-28: the DefaultManager has emitted ZERO DefaultDeclared events since deployment at block 25768251, so the CommitmentLedger walk the probe must outrun is empty. Corrovera measured the 200,000-gas crossing at 46 declared defaults against WARM storage and noted the production cold-storage figure is strictly lower. Nothing is near it, and the whole mechanism needs a good-faith operator to then call clearUnreadableImpairmentSource on a source the diagnostic has mislabelled. The finding is correct and unfixed; it is simply out of reach at this book size.
Restores to Medium when: Re-measure the probe against live cold-storage cost BEFORE the live declared-default count reaches 20, and restore Medium at that point unless the measurement clears it. Twenty rather than forty-six because the project's own W7_PerEventLadder test already shows 32 events exceeding a 400,000-gas stipend under an active assessment, which is double the recovery probe's budget, so the real cliff is well below the warm figure.
DV-02MediumForest Road: LowOpen
A shared, never-cleared incident-id namespace strands the reserve-loss arm and blocks custody-loss absorption
Reproduced against live bytecode; finder and refuter agree. The modern arm/ratify/finalize path and the legacy open/close incident pair mint incident ids from the SAME function, and the used-marker is write-once and cleared nowhere in src. Two privileged-reachable consequences follow. Mis-closing an arm-bound incident orphans the arm, the close checks only id identity, carries no arm-awareness and, despite the interface declaring a deficit error and the NatSpec promising one, no deficit guard, after which finalize reverts NoActiveIncident and ratify reverts IncidentAlreadyUsed, so the arm can never be cancelled. And opening plus closing a small legacy nonce PROSPECTIVELY BURNS the id that a future arm will compute. Because ratifyAndOpen is the sole production write-down path and the arm machine is single-threaded: a genuine custody loss can then no longer be absorbed through the cascade at all: the reproduction prints 'the only on-chain custody-loss absorption path is stranded'. The refuter confirmed recapitalize cannot cure it. The only escapes are an out-of-band USDC donation, which shifts the loss onto the donor rather than the intended waterfall, or a UUPS upgrade. A DEFECT INTRODUCED BY THE C-01 REMEDIATION: the arm/incident state machine postdates the entire register and no existing entry touches it. Recommendation: separate the legacy nonce namespace from the arm namespace, add the documented deficit guard, and make the close refuse an arm-bound incident, or, since the path is deprecated, remove the legacy pair from the deployed surface entirely.
Forest Road assessment: Low
Measured on mainnet 2026-08-28 over the full history from block 25768251: the ReserveManager has emitted ZERO ReserveLossIncidentOpened, ZERO ReserveLossIncidentClosed, ZERO ReserveLossArmed and ZERO ReserveLossArmCancelled events. Neither trigger has ever fired. Both require a privileged caller to use the DEPRECATED legacy incident pair, which production operation has no reason to touch because ratifyAndOpen is the live write-down path, and no outside party can reach either. The stranded state also remains recoverable through a UUPS upgrade under a functioning governor.
Restores to Medium when: Restore Medium if openReserveLossIncident or closeReserveLossIncident is ever called on mainnet, or if the deprecated pair is still present on the deployed surface after the next ReserveManager upgrade. This downgrade rests on an operational rule rather than on code, so it holds only while the rule does.
DV-03MediumRemediated
Origination and funding require no first-loss capital, and both cascade layers are empty at launch
Reproduced against live bytecode. The protocol advertises a three-layer loss cascade, curator first-loss, then the sGROVE backstop, then senior principal, but the first two layers are ENFORCED AT NEITHER ORIGINATION NOR FUNDING. The curator required-first-loss and headroom figures bound only a curator's own withdrawal and are referenced nowhere in the claim bridge or the waterfall's fund path; nothing in origination or funding reads curator capital at all. Live state confirms both layers are empty today: all five curator pool balances are zero, sGROVE coverage capacity is zero, and impairment backstop capacity is zero, while the anchor curator is approved on all five classes with nothing posted. In the reproduction a $2M class-2 facility originates and funds with the cascade empty, and a declared default drives the FULL principal onto seniors, pending senior impairment of 2,000,000e18 entirely unabsorbed, redemption assets falling from 10,000,100e18 to 8,000,100e18. THIS UNSETTLES AN ACCEPTED FINDING: register entry F-01 was accepted on the premise that the curator's first-loss capital is consumed before any senior loss. That capital does not exist in the deployed state and will not until the anchor curator posts. Recommendation: make first-loss and backstop funding a hard capped-launch acceptance gate before the first origination and before any user deposit path opens, or gate the fund path on posted balance meeting required first loss. THE SINGLE MOST IMPORTANT FINDING FOR ANY PARTY ROUTING CAPITAL INTO THE SENIOR TRANCHE. REMEDIATED 2026-08-28, layer one only: the curator first-loss layer is FUNDED ON CHAIN. poolBalance(2) reads 100000000000000000000 against a requiredFirstLoss(2) of the same, posted by the anchor curator Safe 0x02C76084…9066 and attributed to it, so the stake is withdrawable only under that Safe's 2-of-4 threshold rather than by any single key -- noting that the deployment-audit finding carried forward on this register, four Safes sharing one 2-of-4 owner set, applies to this Safe too, so the protection is only as strong as that owner set. FirstLossPosted at block 25853905, tx 0x7942c5fe4edde8c3f0e65aa4e760a56ad8b6807967e20841a03f0af291538415, amount and shares both 100e18, round 0. Supply and backing were unchanged at 502e18 across the operation and the backing invariant held throughout; the capital was transferred from an existing Forest Road holding rather than newly minted, which satisfies the requirement without adding new capital and is stated here so the record is not read as more than it is. Rehearsed against pinned mainnet state before broadcast (contracts/test/fork/DV03FirstLossRehearsal.t.sol). STILL OPEN, AND THE REASON THIS IS NOT FULLY CLOSED: the sGROVE backstop, cascade layer TWO, REMAINS EMPTY, coverageCapacity and impairmentBackstopCapacity are both zero. A loss larger than 100e18 on class 2 still reaches senior principal with only one layer in front of it, and origination and funding still consult NEITHER layer, so nothing prevents a future facility outgrowing the posted first loss. FOREST ROAD POSITION: this one was FIXED rather than re-rated, because the remedy was operational and needed no contract change, and because unlike DV-01 and DV-02 its precondition was not a remote state but the live one. It is deliberately given no lowered Forest Road severity for that reason.
DV-04LowOpen
The points-hook gas-floor hardening reached only two of five fail-open hooks
Reproduced against live bytecode. The F-18-02 hardening put an enforceable absolute gas floor on the USDfr and sUSDfr transfer hooks, but the terminal curator-stake hook is still caller-gas-starvable and emits NO failure telemetry. A curator can therefore withdraw first-loss capital while the points ledger keeps accruing on capital that is no longer posted, and nothing observable records that the transition was dropped. Repairable through the points module's reconcile path once noticed; the defect is that nothing announces it needs noticing.
DV-05LowOpen
A precautionary reserve-loss arm freezes the senior redemption queue, and its cancel gate is global solvency rather than custody health
Reproduced against live bytecode. A guardian's precautionary arm freezes senior exits, and the gate that would cancel the arm tests global solvency rather than the custody health the arm was raised about. DE-ESCALATED FROM THE REVIEWER'S MEDIUM: the refuter proved the wedge state coincides with states that freeze exits anyway, so the arm adds no incremental harm. Recorded rather than dismissed because the cancel gate testing the wrong quantity is real, and would matter if the coincidence ever stopped holding.
DV-06LowOpen
The cascade's order-conservatism guard is provably vacuous
Verified from source. The min(forward, reverse) guard that is supposed to preserve order-conservatism in the loss cascade is provably vacuous, forward equals reverse for every book, yet an O(N) release shift and a redundant walk are paid to preserve it, and the NatSpec documents a margin that does not exist. No incorrect accounting results; the cost and the false documentation are the finding.
DV-07LowOpen
Queue settlement sizes yield recognition against the liquidity budget rather than the actual outflow
Verified from source. Settlement recognises yield against the treasury liquidity budget rather than the settlement's actual outflow, transferring a sliver of unvested yield from holders who stay to holders who leave. INERT AT THE LAUNCH CONFIGURATION, where the yield vesting period is zero and there is no unvested stream to transfer; live only if governance enables vesting. Recorded so that enabling vesting is understood to activate it.
DV-08LowOpen
The RC-01 anti-latch guard documents an invariant that is false
Verified from source. The guard's NatSpec states that distributed plus budget is pinned to the opening snapshot; the H-04 live-cap clamp breaks that. The code is safe only because it re-evaluates per chunk. The hazard is prospective and specific: a future reviewer who trusts the comment and hoists the check out of the loop reinstates the RC-01 dead-end. A false comment on a load-bearing guard, rather than a live defect.
This is the first review conducted against a live Ethereum mainnet deployment rather than
against source or a testnet. It supersedes the same-day deployment audit, which examined bytecode,
roles, parameters and disclosure but declared two gaps explicitly: no fork reproduction, so no
finding could reach confirmed, and no independent adversarial cross-examination. This engagement
closes both.
It remains an AI-assisted audit, not a maximum-assurance audit, and must not be represented as
one.
What changed relative to the deployment audit
A harness binds to the live mainnet addresses and drives the deployed contracts from genesis through
mint → deposit → originate → fund → default → settlement. Every code finding below is a passing
test against production bytecode, not a source argument.
Four independent reviewers read all 23 contracts in full under four distinct adversarial lenses, economic sequencing, cross-contract invariants, accounting and state machines, and authority and
voting. Every surviving candidate was then re-examined by a skeptic instructed to refute it. One
finding was refuted outright: one was de-escalated from Medium to Low, and one previously accepted
High-severity register entry was corrected downward.
What is still absent, and what that costs
No coverage-guided fuzzing. No symbolic execution or formal proof. No model qualification benchmark.
No live-fire governance rehearsal beyond the fork. A clean result is evidence that these methods at
this depth found nothing; it is not proof of security.
The honest headline
The deployed code is unusually hardened, sixteen prior review rounds, a large in-house fork and
attack corpus, and a Slither surface that reduces entirely to the project's own triaged baseline.
The engineering findings are not fund-theft-by-anyone. The three Mediums are two
privileged-operator liveness traps and one launch-sequencing gap. The sharpest exposure remains who
holds the keys and what has been disclosed, unchanged from the deployment audit. No user funds are
at risk at the current seed state.
The finding that most affects an integrator
DV-03 is the one to read first if you are considering routing capital here. The protocol
advertises a three-layer loss cascade, curator first-loss, then the sGROVE backstop, then senior
principal. Origination and funding consult neither junior layer, and both are empty on chain
today. A declared default therefore drives the full principal onto the senior NAV with nothing in
front of it.
The recommendation is to make first-loss and backstop funding a hard capped-launch acceptance gate,
before the first origination and before any user deposit path opens.
The finding that most affects a rate oracle
DV-01 produces an upward discontinuity in the exit price. A good-faith operator action, taken
on the protocol's own diagnostic, can drop a real senior impairment mark out of exit pricing
entirely and irreversibly ratchet the high-water mark. In the reproduction a genuine $2.3M mark
vanishes and the exit price jumps to par.
Any consumer that records a high-water exchange rate should understand this before integrating.
Carried forward from the deployment audit, still valid
Four Safes sharing one 2-of-4 owner set. Queued governance being unstoppable and undisclosed, now
fork-proven. A degenerate 2-of-2 attester quorum with unfunded keys. Three unmanifested contracts in
the trusted base. A red entrypoint-guard test on the working tree.