C-11MediumRemediated
Raising the redemption floor during a live settlement could permanently freeze the queue — a residual on the previous round's fix
The previous round stopped a settlement committing while it could never reach the economic floor. It did not stop the floor moving underneath a settlement that had already legitimately committed. Because the liquidity budget is captured once and can only shrink, raising the floor mid-settlement made both guards permanently unsatisfiable — the same dead end reached through a governance setter rather than a chunk boundary. The previous round's own regression test could not catch it, because it sets the floor before settling. Fixed by capturing the floor alongside the budget when a settlement opens, so a live settlement is judged against the parameters it opened under and a change takes effect on the next one. Proven reachable against the unfixed code before the fix was written.
C-07MediumOpen
A reserve-level write-down has no cascade absorber, and the backing assertion then blocks ordinary operation
One reserve primitive lowers backing without a paired token burn and without asserting the backing invariant — the exception to the pairing rule the design documents state. Because the protocol operates at zero headroom, any resulting shortfall then blocks minting, redemption, yield recognition and servicing until governance acts, and the loss cascade has no path to absorb a loss that occurred at the reserve layer rather than in the loan book. The primitive currently has no callers. One part of the original filing was withdrawn: relaxing the backing assertion to permit delta-neutral redemption was already considered and rejected in an ADR, because it inverts the loss cascade.
C-19MediumOpen
CONTESTED: the yield cap leaves a healthy vault at the exact top of the accepted skim band
Published as contested because it turns on the precise reading of an accepted trade-off rather than on disputed code. The entry guard closes only when the withheld stream is strictly greater than a set multiple of vault assets, and the cap introduced two rounds ago sets the stream to exactly that multiple — so entry stays open at the boundary rather than inside it, and a depositor arriving at that instant shares in yield already earned by incumbents. The band itself is an accepted residual from an earlier round; what is new is that a healthy vault now sits at its very top by construction rather than transiently. This is a calibration question for economic review, not a coding error.
C-01LowRemediated
The storage-layout check the upgradeability ADR asserts did not exist, and the per-slot test added last round covered one namespace of sixteen
Found independently by five reviewers, each arriving from a different contract. The previous round's response to a storage-layout risk pinned exactly one struct, leaving fifteen namespaces in the prior posture — and the verification command the contracts' own comments prescribe reports nothing for this storage pattern, because these contracts declare no ordinary state. Fixed by a check that compares the field order and types of every namespaced and array-element struct against a committed baseline, wired into the pipeline: inserts, reorders, retypes and deletions fail; extending a namespaced root at its tail passes; any growth of an array-element struct fails, because those are laid out contiguously. The ADR now describes the check that exists.
C-02LowOpen
Pausing the attestation oracle transitively halts the loss cascade while leaving both exits open at an unimpaired price
Loss realization, payment recording and past-due curing each require a freshly minted attestation, and the submission path is pausable. A guardian pause therefore suspends loss recognition — which the design documents describe as never pausable — while redemption and the queue continue pricing against a book that cannot be marked down. The asymmetry is the finding: not that the pause exists, but that it stops the marking without stopping the exiting.
C-03LowOpen
The token pause halts every inflow but leaves the redemption path draining the reserve
Burns deliberately bypass the pause so the loss cascade cannot be frozen — a fix from an earlier round. The consequence is that a token pause stops minting, staking and yield routing while the direct redemption path, which is a burn plus a transfer out of reserves, stays fully open. The compensating symmetry the governing documents rely on no longer holds, and neither contract consults the other's pause state.
C-05LowOpen
The outflow cap restarts the vesting clock on every qualifying settlement, deferring yield already earned
A residual on the previous round's fix. The cap does not merely clamp the retained amount, it re-stretches it over a fresh full vesting window; and because the inflow cap leaves no slack at the boundary, an ordinary settlement re-triggers it. Permissionless settlement can therefore defer recognition of yield that has already been realized. The deferral is conservative in direction and the retained amount is non-increasing, but it does not converge as quickly as assumed when the fix was written.
C-06LowOpen
The outflow cap runs after assets leave, so equal-ranking exits in one settlement can be priced differently
The same fix places its re-cap after the withdrawal completes, and the settlement loop re-reads the vault price on every fill. A later fill in the same settlement is therefore priced against a value the previous fill's own re-cap stepped up. The strict-FIFO head — the position that waited longest — is priced worst. Display-neutral and small in ordinary conditions, but it breaks the pari-passu expectation within a single settlement.
C-09LowOpen
Documentary mint-gate attestations are existence-only and can be satisfied in advance for facilities that do not exist yet
The submission path accepts any facility identifier, never checks that the facility exists, and imposes no payload requirement on the documentary kinds. The mint gate then asks only whether an attestation of that kind exists at the identifier about to be minted. The binding that does hold is the separate terms attestation, which is unconditional — so the residual is that the documentary facts are proved to exist rather than proved to be about the facility in question.
C-10LowOpen
A non-renewable facility that outlives its maturity can never be amended again, and its full balance stays permanently markable
Found by the facility-lifetime lens, and visible only if a facility is kept alive past its maturity. Only two functions can move a schedule forward: one cannot push past maturity, and the other rejects any amendment that would extend a non-renewable facility. Once maturity has passed, every admissible amendment necessarily exceeds it, so the workout has no on-chain path to reschedule, while the outstanding balance remains permissionlessly assertable into the senior impairment mark.
C-13LowRemediated
The impairment-source setter accepts any address with no interface probe, on a read path that deliberately does not swallow failure
The setter performs no code or interface check, and the read path deliberately refuses to catch failure — individually correct, since silently substituting zero impairment would be worse. Together they mean one governance mis-wire freezes every senior exit price until a second timelocked proposal lands. Same shape as an already-published finding about a sibling setter. CLOSED by the ADR-0031 work: `sUSDfr.setImpairmentSource` now runs `_validateImpairmentSource`, a bounded two-selector ABI-shape probe that also enforces the ordering invariant between the two impairment views, and `clearUnreadableImpairmentSource` provides the paired recovery. Verified in Round 14.
C-14LowOpen
Latent: re-pointing the vault at a new redemption queue would strand every position held by the old one
Queued shares are held in the queue's own custody, and the vault admits only the currently configured queue as a caller. Pointing the vault at a replacement therefore leaves the old queue holding shares it can no longer redeem, with no cancel and no rescue path for the positions inside it. Unreachable today; reachable on an ordinary queue migration.
C-16LowOpen
Latent: a class activated without its attestation mask would originate and fund with the documentary checks skipped entirely
The mint gate reads the required-attestation mask and iterates it without requiring it to be non-empty, so a class whose mask was never set reads zero and the loop body never runs — on both the origination and the funding gate. The unconditional terms attestation still applies, so the economic binding survives; the documentary requirements would not. Reachable through a routine governance sequencing mistake rather than an attack.
C-17LowOpen
The headline collateral ratio divides a numerator containing idle reserves by loan principal alone
A frontend-to-contract reconciliation defect. The numerator mixes loan collateral with idle reserves — which back the portion of supply that is not on loan — while the denominator is deployed principal only, so the displayed coverage of the loan book rises without bound as the book shrinks. A correctly-based coverage figure is already computed nearby and discarded.
C-18LowOpen
A receipt-wait timeout discards the transaction hash and re-arms a one-click duplicate of a non-cancellable action
The error state carries no transaction hash, unlike the pending and success states. On a receipt timeout — set well below the underlying library's own default — the transition destroys the only reference the user had to a transaction that may still land, and re-enables the button. For a queue request, which cannot be cancelled or withdrawn, that invites a duplicate irreversible entry.
C-20LowOpen
Origination events emit only a commitment hash, so maturity and the off-chain reference appear in no event
The engineering rules require the on-chain register to be reconstructable purely from events. The origination and amendment events carry a 32-byte terms commitment rather than the terms themselves, so the maturity date and the off-chain document reference are not recoverable from the log — while the comment directly above the event, and an earlier published review, both state that the full terms are emitted.
C-21LowOpen
The origination fee is read from mutable governance storage at funding time and is not part of the attested terms
The fee is applied from live governance storage when funds are disbursed, and the borrower receives principal less that fee while the facility is booked at full principal. The signed terms bundle — which an earlier round extended specifically so the economic terms are quorum-bound — does not include it. So the cash actually disbursed is the one parameter the binding does not cover.
C-22LowOpen
The funding gate re-checks only the time-sensitive class parameters, so tightening the draw ceiling or tenor cap does not bind an already-originated facility
Origination enforces the class loan-to-value ceiling and maximum tenor; the funding gate reloads the same class parameters and re-checks activity, maturity, the payment date, attestations, the terms binding and mark freshness — but never re-reads those two. A facility originated under looser limits can therefore still be funded after governance tightens them.
C-23LowOpen
The directional assessment binding was applied to the backstop only, so a trivial curator top-up still voids a live recovery assessment
An earlier remediation made global backstop capacity a directional comparison — an increase tolerated, a decrease failing closed — precisely so that a permissionless contribution could not void a depositor-favourable assessment. Per-class curator capacity was deliberately left on the exact-match side, so the same class of nuisance survives through a different pool.
C-24LowOpen
Curator first-loss is shown as one blended percentage although absorption is strictly per-class and non-fungible
The dashboard reads each class pool individually, sums them, and divides by the whole book. On chain a loss draws only against its own class pool and cannot reach another. The blended figure therefore overstates subordination for any class whose pool is thin relative to its exposure.
C-25LowOpen
The transparency dashboard re-reads the entire event history on every poll, and blanks its panels while it does
The same class of defect fixed on a sibling panel two rounds ago, still present here across five event streams: no cursor, a full re-read from the deployment block every minute, both panels reset to a loading state first, and no cancellation of a superseded sweep. Request volume grows linearly with chain age.
C-26LowOpen
The error-decoding drift guard never checks contracts against the interface, so a newly added custom error renders as raw hexadecimal
The guard verifies that published copy matches the interface and that the interface matches the contracts, but not that the contracts are fully represented in the interface. One error added to the vault is already missing, and it is raised on the application's own staking path — where its own documentation says it exists precisely so the revert carries a specific, readable reason.
C-27LowOpen
Latent: the testnet address table is hand-maintained with no binding to the deployment manifest
For production every address is bound to the manifest by several independent checks. For the testnet and local profiles the verification returns before the manifest is opened, and the address table is a hand-maintained duplicate that partial environment overrides can silently mix across two deployments. Reachable on the next redeploy rather than today.
C-04InformationalOpen
A workout recovery on a defaulted facility can be booked entirely as interest, leaving the impaired principal fully marked
Distribution admits defaulted facilities and routes the interest leg through the identical path a performing loan uses, while every piece of recovery bookkeeping sits behind a non-zero principal condition. Nothing requires a post-default receipt to be booked as principal. The discretion belongs to a trusted role and overlaps an already-accepted finding about servicer discretion; recorded because the direction of the error disadvantages the junior layers.
C-12InformationalOpen
The timelock delay is shorter than the only available exit, so the promised exit window does not exist in practice
Two ADRs and the access-control matrix state that the timelock gives holders time to exit before a change takes effect. The only senior exit is queue-gated at three weeks and the staked-token exit at three weeks, against a two-day minimum delay. The protection is real as visibility and unreal as an exit window; the documents should say which one they mean.
C-28InformationalOpen
The compliance check exempts every burn before consulting the sender's sanctions status
Burns return permitted without checking the sender, so that the loss cascade and settlement can never be blocked — a sound reason. The exemption is nonetheless unconditional on the sender rather than scoped to the cascade, so any future user-callable burn path would inherit it. Latent, and a property of the token rather than of the cascade.
C-30InformationalOpen
The per-event backstop coverage cap is never exercised at a fractional value by any test
The mock backstop's cap setter has no callers anywhere, so every campaign built on that mock runs with the cap effectively unlimited and the mock's capacity degenerates to its raw balance. The cap is a real production control; the suite has never exercised it at a binding value. A test-fidelity gap rather than a contract defect, and adjacent to a test-strength item already open from an earlier round.
Historical snapshot — superseded. This narrative predates ADR-0031 and the
later impairment-source liveness remediation. Statements below about missing CI,
coverage, formal, fork, or render evidence describe that earlier point in time and
are not the current assurance status.
What changed about how this round was run
The previous full audit ended with a specific criticism of itself: its weakness was not effort
but shape. The defects it missed were the ones that require a single entity to be walked
through many sequential operations across a module boundary — each function correct in
isolation, the fault living only in their composition. Seventeen of eighteen reviewers missed
one such defect entirely.
So this round kept the nine module surfaces, each still reviewed twice by independent agents
with opposing briefs, and added four lenses that follow one entity through its whole life
rather than reviewing by module: a single facility from origination through a dozen sequential
repayments to maturity and through the parallel default path; a single senior position from
deposit through several rate epochs and a loss to settlement and claim; junior capital across
repeated losses and recoveries; and a lens for scale and unbounded growth.
Every candidate then faced two adversarial refuters, and a critic was asked — among other
things — to judge whether those new lenses had actually done what they were added for.
Whether that worked: two of four
Worth reporting honestly, because it decides how the next round should be run.
The facility and senior-position lenses worked. Each traced a real sequence, and each
produced findings no module review did: a post-maturity amendment freeze visible only if you
keep a facility alive past its maturity, and two defects in a recent fix that exist only across
successive operations. The facility lens also named its own limit — that no test in the tree
warps past maturity on a live facility — which is what a genuine lifetime review looks like.
The junior-capital and scale lenses collapsed back into module review. Their coverage
statements read as file lists and static surveys. The scale lens conceded the point directly:
it ran nothing, so every growth figure it gave was an arithmetic estimate rather than a
measurement. Both were competent second passes over ground already covered, wearing a label
they did not earn.
The result
No Critical and no High finding. Nothing found here reaches a loss of funds, an unauthorized
mint, a backing break, a cascade inversion or a compliance bypass.
Eighty-four raw candidates consolidated to thirty. Two were then dropped outright by the
critic, and the reason matters more than the count:
- one would have recommended undoing an earlier fix. It described as an exploit the exact
behaviour a named regression test asserts as that fix working, and its load-bearing claim —
that no test composes those two calls adversarially — was simply false;
- the other named a root cause that is causally inert, so its proposed remedy would have
changed nothing.
A third had its headline struck: relaxing the backing assertion, which it proposed, was already
considered and rejected in an ADR on the grounds that it inverts the loss cascade.
Twenty-seven findings remain: three Medium, twenty Low, four Informational. About half are
documentation drift — an ADR asserting a check that did not exist, an invariants document
describing a pause envelope the code changed, a matrix listing functions that are gone.
The clearest new defect was in the previous round's own fix
Two rounds ago a guard was added to stop a settlement committing while it could never reach the
redemption floor. It did not stop the floor moving underneath a settlement that had already
legitimately committed. Because the liquidity budget is captured once and can only shrink,
raising the floor mid-settlement made the guard permanently unsatisfiable — the same dead end,
reached through a governance setter instead of a chunk boundary.
The reason it survived is the instructive part: the regression test written for the original
fix sets the floor before settling, and no stateful-fuzzing handler carries a governance
selector. The test bound the path its author was thinking about and missed the one beside it.
It is fixed — the floor is now captured alongside the budget, so a live settlement is judged
against the parameters it opened under — and it was reproduced against the unfixed code before
the fix was written.
The finding five reviewers found independently
The previous round responded to a storage-layout risk by pinning one contract's fields to their
exact slots. Five reviewers in this round, each arriving from a different contract, pointed out
the same thing: that covered one namespace of sixteen, the upgradeability ADR asserted a
pipeline check that did not exist, and the verification command the contracts' own comments
prescribe reports nothing at all for this storage pattern, because these contracts declare no
ordinary state.
That is a fair criticism of closing an instance and calling it the class. It is now closed
properly: a check compares the field order and types of every namespaced and array-element
struct against a committed baseline and runs in the pipeline. Inserts, reorders, retypes and
deletions fail. Extending a namespaced root at its tail passes, because that is safe. Any
growth of an array-element struct fails, because those are laid out contiguously and growing
one shifts every later element on a live proxy. The ADR now describes the check that exists.
One finding published as contested
The vault's entry guard closes only when the withheld yield stream is strictly greater than a
set multiple of vault assets, and a cap introduced two rounds ago sets the stream to exactly
that multiple. So a healthy vault now sits at the very top of an accepted trade-off band by
construction, rather than passing through it transiently.
Whether that matters is a calibration question for economic review, not a coding error, and the
reviewers split on it. It is published as contested rather than resolved, because presenting a
genuine disagreement as a settled finding would be the more misleading choice.
What this round establishes, and what it does not
It establishes that nine rounds of increasingly specialised reading now return documentation
drift and remediation-completeness gaps rather than defects. That is a meaningful result about
the contracts — but it is also the signal that source review has converged.
It does not establish that the contracts behave correctly, because nothing was executed
during the review: every figure in every finding is hand-derived. The only measurements are
the suites run alongside it, which themselves run one stateful campaign against an unbounded
mock and skip the environment-gated fork tests in the pipeline. It does not establish frontend
behaviour, because there is still no render harness. And it does not touch the economic
calibration — the coverage cap level, the first-loss target, the vesting ratio whose acceptance
rationale one finding here shows a later change falsified — which remains a human decision.
The honest read is that the remaining risk has moved out of reading and into execution, the
deferred economic review, and the independent external audit. Another reading round is unlikely
to earn its keep.
This remains an internal review and closes none of the production-assurance gates.