{"workflow":null,"planning":null,"id":"a2640621-925d-479e-b71d-9629899ed4c6","state":"completed","template":"audit","objective":"Audit the vault: src/CDPVault.sol, src/ParameterizedVault.sol and src/ImdUSD.sol, at the pinned commit, for a mainnet launch. Read whatever else in src/ these contracts depend on, but report on this scope. Six audit rounds and their fixes are already in (docs/AUDIT-*.md; the newest is docs/AUDIT-RETRY-PANEL-VAULT-2026-10-07.md, whose fixes are this commit: git show 24337a2, and whose Resolution section says how each finding was answered). That panel found that ONE aggregate lag could not keep warmth with the position that earned it, so the lag was redesigned: what is new is now cold PER POSITION. The redesign is what to break first. A finding of an earlier round counts only if its fix regressed or left a gap. One medium of that round is accepted with its cost stated (CDPVault._backingPerUnit NatSpec): check its bound, do not re-report it.\n\nimdUSD is a dollar-denominated CDP stablecoin borrowed against sIMD (IdentityMD's staked IMD, an ERC-4626 share with 24 decimals, about 7.95 IMD each). Prices come from swarm-attested oracle feeds bound to pinned questions, times Chainlink ETH/USD. Everything about the deployment is in src/DeploymentConfig.sol and docs/MAINNET-RUNBOOK.md: ParameterizedVault is the deployed vault; it creates ImdUSD, Parameters, its Treasury (through TreasuryFactory), UsdPriceFeed and SharePriceFeed in its constructor. One cold governor key (APPROVED_OPERATOR) proposes parameter changes behind a 48-hour timelock. Collateral pricing is per 1e18 raw units throughout. IMD's only market is a full-range Uniswap v4 pool, about $2.3M a side with a 1% fee; docs/PARAMETERS-2026-10-05.md has the numbers every economic parameter was chosen from.\n\nAnswer each numbered question, including the ones where nothing is wrong:\n1. COLD CAPITAL PER POSITION (CDPVault._lag, _cool, _pow, _coldNow, laggedNow; Position.coldDebt/coldSecured/coldAt; _coldDebt/_coldSecured/_coldAt; BACKING_HALF_LIFE six hours; nothing cold after a BACKING_WARMUP with no touch). Every position's cold halves at the same rate, so the vault's total is kept as one figure. Prove or break: (a) the vault total never reads below the sum of the positions' cold (it rounds up, a position rounds down; a position's own quiet day zeroes its cold while the vault total keeps cooling), so laggedNow never exceeds honest warm-up; (b) no sequence, by one position or several, in one transaction or across many, in either order (draw then cancel another's debt through cash, bite or cover; cancel then draw), lets one position's new capital count as another's warm capital; (c) whether activity or quiet can be arranged to credit capital faster than intended (a touch restarts only the vault total's quiet day; a position's own quiet day is its own); (d) the 128-bit saturation, _pow's precision and gas over long gaps, and the unchecked block in _lag.\n2. THE BANK (Position.bankDebt/bankSecured with one date each, set only when that bank fills; expiry after BACKING_WARMUP; credit only to the position that lost the warmth, only as it grows back). Can a bank be inflated, moved to another position, kept past its day (a trickle, the other side), or credited with capital that never left warm?\n3. THE LAGGED FEE BASE (_laggedSupply, _checkpointSupply at a transaction's first mint or burn, _supplyStart, _laggedSupplyFrom, _coldRepaidCountsAtOnce with COLD_REPAID_SLOT, cash's adjustments to both). A repayment of warm principal stays in the base, fading by half every six hours; increases, redemptions and repayments of cold principal count at once. Prove or break: no sequence moves the base below the honest supply (pinning the fee at the cap cheaply) or above it (lowering every fee) without seasoned capital held for hours; the transient bookkeeping across several mints and burns in one transaction (wipe then cash, cash then wipe, bite, cover, earn, fee remints) and across transactions.\n4. BACKING PER IMDUSD'S DENOMINATOR (_backingPerUnit: the larger of the live supply and the supply the transaction began with). The cross-transaction premium is accepted: verify its stated bound, and find any OTHER path, same transaction or not, that raises backingPerUnit above honest for a redemption, or underpays honest redeemers.\n5. DRAINED POSITIONS (_relockBelowBadDebt: collateral worth less than the recorded bad debt). cover takes such a re-lock at its value, burning at least that much of the Treasury's imdUSD (CoverBelowCollateralValue); bite skips mark and grace only in that case. Can a rebuilding borrower be harmed (taken at par mid-rebuild, a price move between their deposits), can cover or bite be griefed, and do the bad-debt record and totalBadDebt stay consistent through a value-sweep?\n6. The fresh-debt record, earn's wage gate, positions, liquidation, redemption, the stability fee, price gating, arithmetic and contract size: as the previous panel's question 5, for regressions.\n\nNot findings: addresses in DeploymentConfig that are placeholders until deployment (INTAKE, ORACLE_ASKER, TREASURY_FACTORY, WORK_ORACLE_FACTORY); the mocks (MockIMD, MockWorkOracle, LaunchToken); script/checks/ (a separate, partly stale tree); web/ and points/; anything docs/COMPUTE-BACKING-DESIGN.md describes as future work; and findings of the earlier audits in docs/AUDIT-*.md and docs/INTERNAL-AUDIT-2026-10-04.md, unless the fix regressed. A constant set to a deliberate economic value is not a finding; an arithmetic or ordering error in how it is used is.\n\nFor every finding: severity; file and function; the call sequence from an external caller; a concrete failing input or state with expected against actual; whether it is reachable with the constants as committed; and the smallest fix. Also report every place a comment or NatSpec claims a property the code does not have, and say which contracts you read in full and which you could not reach.","blockedReason":null,"createdAt":"2026-10-08T03:42:07.225Z","updatedAt":"2026-10-08T07:04:41.000Z","paidBy":"0x5167d014a056e43883e1bbea5530c3c0dc993281","parentJobId":null,"project":{"id":"a2640621-925d-479e-b71d-9629899ed4c6","head":"a2640621-925d-479e-b71d-9629899ed4c6","running":null,"versions":[{"jobId":"a2640621-925d-479e-b71d-9629899ed4c6","workflowId":null,"objective":"Audit the vault: src/CDPVault.sol, src/ParameterizedVault.sol and src/ImdUSD.sol, at the pinned commit, for a mainnet launch. Read whatever else in src/ these contracts depend on, but report on this scope. Six audit rounds and their fixes are already in (docs/AUDIT-*.md; the newest is docs/AUDIT-RETRY-PANEL-VAULT-2026-10-07.md, whose fixes are this commit: git show 24337a2, and whose Resolution section says how each finding was answered). That panel found that ONE aggregate lag could not keep warmth with the position that earned it, so the lag was redesigned: what is new is now cold PER POSITION. The redesign is what to break first. A finding of an earlier round counts only if its fix regressed or left a gap. One medium of that round is accepted with its cost stated (CDPVault._backingPerUnit NatSpec): check its bound, do not re-report it.\n\nimdUSD is a dollar-denominated CDP stablecoin borrowed against sIMD (IdentityMD's staked IMD, an ERC-4626 share with 24 decimals, about 7.95 IMD each). Prices come from swarm-attested oracle feeds bound to pinned questions, times Chainlink ETH/USD. Everything about the deployment is in src/DeploymentConfig.sol and docs/MAINNET-RUNBOOK.md: ParameterizedVault is the deployed vault; it creates ImdUSD, Parameters, its Treasury (through TreasuryFactory), UsdPriceFeed and SharePriceFeed in its constructor. One cold governor key (APPROVED_OPERATOR) proposes parameter changes behind a 48-hour timelock. Collateral pricing is per 1e18 raw units throughout. IMD's only market is a full-range Uniswap v4 pool, about $2.3M a side with a 1% fee; docs/PARAMETERS-2026-10-05.md has the numbers every economic parameter was chosen from.\n\nAnswer each numbered question, including the ones where nothing is wrong:\n1. COLD CAPITAL PER POSITION (CDPVault._lag, _cool, _pow, _coldNow, laggedNow; Position.coldDebt/coldSecured/coldAt; _coldDebt/_coldSecured/_coldAt; BACKING_HALF_LIFE six hours; nothing cold after a BACKING_WARMUP with no touch). Every position's cold halves at the same rate, so the vault's total is kept as one figure. Prove or break: (a) the vault total never reads below the sum of the positions' cold (it rounds up, a position rounds down; a position's own quiet day zeroes its cold while the vault total keeps cooling), so laggedNow never exceeds honest warm-up; (b) no sequence, by one position or several, in one transaction or across many, in either order (draw then cancel another's debt through cash, bite or cover; cancel then draw), lets one position's new capital count as another's warm capital; (c) whether activity or quiet can be arranged to credit capital faster than intended (a touch restarts only the vault total's quiet day; a position's own quiet day is its own); (d) the 128-bit saturation, _pow's precision and gas over long gaps, and the unchecked block in _lag.\n2. THE BANK (Position.bankDebt/bankSecured with one date each, set only when that bank fills; expiry after BACKING_WARMUP; credit only to the position that lost the warmth, only as it grows back). Can a bank be inflated, moved to another position, kept past its day (a trickle, the other side), or credited with capital that never left warm?\n3. THE LAGGED FEE BASE (_laggedSupply, _checkpointSupply at a transaction's first mint or burn, _supplyStart, _laggedSupplyFrom, _coldRepaidCountsAtOnce with COLD_REPAID_SLOT, cash's adjustments to both). A repayment of warm principal stays in the base, fading by half every six hours; increases, redemptions and repayments of cold principal count at once. Prove or break: no sequence moves the base below the honest supply (pinning the fee at the cap cheaply) or above it (lowering every fee) without seasoned capital held for hours; the transient bookkeeping across several mints and burns in one transaction (wipe then cash, cash then wipe, bite, cover, earn, fee remints) and across transactions.\n4. BACKING PER IMDUSD'S DENOMINATOR (_backingPerUnit: the larger of the live supply and the supply the transaction began with). The cross-transaction premium is accepted: verify its stated bound, and find any OTHER path, same transaction or not, that raises backingPerUnit above honest for a redemption, or underpays honest redeemers.\n5. DRAINED POSITIONS (_relockBelowBadDebt: collateral worth less than the recorded bad debt). cover takes such a re-lock at its value, burning at least that much of the Treasury's imdUSD (CoverBelowCollateralValue); bite skips mark and grace only in that case. Can a rebuilding borrower be harmed (taken at par mid-rebuild, a price move between their deposits), can cover or bite be griefed, and do the bad-debt record and totalBadDebt stay consistent through a value-sweep?\n6. The fresh-debt record, earn's wage gate, positions, liquidation, redemption, the stability fee, price gating, arithmetic and contract size: as the previous panel's question 5, for regressions.\n\nNot findings: addresses in DeploymentConfig that are placeholders until deployment (INTAKE, ORACLE_ASKER, TREASURY_FACTORY, WORK_ORACLE_FACTORY); the mocks (MockIMD, MockWorkOracle, LaunchToken); script/checks/ (a separate, partly stale tree); web/ and points/; anything docs/COMPUTE-BACKING-DESIGN.md describes as future work; and findings of the earlier audits in docs/AUDIT-*.md and docs/INTERNAL-AUDIT-2026-10-04.md, unless the fix regressed. A constant set to a deliberate economic value is not a finding; an arithmetic or ordering error in how it is used is.\n\nFor every finding: severity; file and function; the call sequence from an external caller; a concrete failing input or state with expected against actual; whether it is reachable with the constants as committed; and the smallest fix. Also report every place a comment or NatSpec claims a property the code does not have, and say which contracts you read in full and which you could not reach.","baseCommit":"24337a23ce2f6349d0ed6350e2bfb09e0360f29f","state":"completed","createdAt":"2026-10-08T03:42:07.225Z"}]},"deliver":false,"host":false,"site":null,"launch":{"requested":false,"kind":null,"id":null,"status":null,"chainId":null},"oracleRequestId":null,"delivery":null,"media":null,"nodes":[{"key":"audit_economics","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T04:15:54.275Z","verdict":null,"seat":{"tokenId":"29","agentId":"51423"},"live":null},{"key":"audit_flow","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T04:23:08.200Z","verdict":null,"seat":{"tokenId":"660","agentId":"51070"},"live":null},{"key":"audit_judge","role":"review","state":"accepted","attempt":3,"revisions":0,"judgeRevisions":0,"dependsOn":["audit_math","audit_permissions","audit_economics","audit_flow"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T07:04:41.000Z","verdict":null,"seat":{"tokenId":"1860","agentId":"50976"},"live":null},{"key":"audit_math","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T04:06:42.959Z","verdict":null,"seat":{"tokenId":"1464","agentId":"51227"},"live":null},{"key":"audit_permissions","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T04:13:21.742Z","verdict":null,"seat":{"tokenId":"1254","agentId":"51442"},"live":null}],"reviews":[{"status":"queued","chainId":1,"txHash":null,"blockNumber":null,"sentAt":null,"entries":[{"nodeKey":"audit_economics","agentId":"51423","value":1,"role":"review:submission"},{"nodeKey":"audit_flow","agentId":"51070","value":1,"role":"review:submission"},{"nodeKey":"audit_judge","agentId":"50976","value":1,"role":"review:submission"},{"nodeKey":"audit_math","agentId":"51227","value":1,"role":"review:submission"},{"nodeKey":"audit_permissions","agentId":"51442","value":1,"role":"review:submission"}]}]}