{"workflow":null,"planning":null,"id":"f936eafb-0bfb-4584-95be-9113b9d451ad","state":"completed","template":"audit","objective":"Audit the vault: src/CDPVault.sol, src/ParameterizedVault.sol, src/ImdUSD.sol and src/TransientReentrancyGuard.sol, in full, plus the deployment and the runbook's launch window, at the pinned commit, for a mainnet launch. Read whatever else in src/ these depend on, but report on this scope. Fifteen audit rounds and their fixes are in (docs/AUDIT-*.md; the chain is web/content/docs/reference/audit-history.md). The newest, docs/AUDIT-FINAL-SWEEP-2-2026-10-09.md, found one high: a pool held down through the feed's median window paid a redeemer the whole one-step fall in extra IMD. Its fix is this commit's newest mechanism: the price a redemption is PAID at is paced. The same commit clamps the paced debt against the pre-existing principal a transaction cancelled, seeds the paced supply no higher than the fee-base floor, reads the price and NHI once per entry point, and replaces the reentrancy guard with a transient-storage one: git diff a3aa9e4 c90e8d9 -- src. Read the vault in full, as it will deploy. A finding of an earlier round counts only if its fix regressed or left a gap. Items ACCEPTED, their reasons stated where they live, are findings only if the reason is wrong or the bound does not hold: the dip and the stale-term read (the paced figures' NatSpec), the paced payout price's lag after an honest fall (cash), the fee-base floor and its seed, the work ceiling as an aggregate once the wage is on. Rank severity by what a finding lets someone take or block with the constants as committed (LINE $1M, wage 0, mat 170, the rise 2 points of par an hour, the follow 10%, the payout price's fall 5%, PACE_INTERVAL 1 hour, fee floor 100,000, FEED_MAX_DEVIATION_BPS 2000).\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. THE PACED PAYOUT PRICE (cash, _pacedPrice, PAYOUT_PRICE_FALL_BPS_PER_HOUR, payoutPrice). cash pays IMD at max(attested price, paced price), the paced price falling at most PAYOUT_PRICE_FALL_BPS_PER_HOUR per hour of elapsed time (at most PACE_INTERVAL per pacing, on the backing's clock, written only at a fresh, agreed price) and rising at once; eligibility, health, RedemptionWorsensRatio and the collateral term stay at the attested price. With the feeds as committed (a one-step fall of FEED_MAX_DEVIATION_BPS from a fresh anchor, twice that after two silent hours, both feeds reading the one pool, the 13-sample two-hour median): the cheapest profitable push of the pool in either direction against redemptions, in money and hours, now; whether a RISE of the attested price (paid at once) or a sequence of falls and rises across pacings pays a redeemer more than the honest IMD; whether the mixed route's conversion of the reserve's IMD back into cancelled debt at the paid price can be made inconsistent with the candidate's share; and the cost to honest redeemers after a real fall, as a figure, against what cash's comment states.\n2. THE CANCELLATION-AWARE CLAMP (_clampPacedDebt, CANCELLED_PRE_SLOT, PACED_DEBT_AT_START_SLOT, MINTED_BY_SLOT keyed per position by XOR, _tallyPrincipalRetired, _debtForPacing, the WIPED tally). Every ordering of draw, wipe, cash, bite and cover by one or several positions, in one transaction or across block boundaries: can zero-second debt count for the work ceiling sooner than the follow rate, can a transaction cancelling its own fresh draw move the paced debt, can the XOR-keyed slot collide with any fixed transient slot or another owner's, and can the netting of a position's own minted principal be used to cancel seasoned debt while reporting none?\n3. THE PRICE READ ONCE. Every entry point reads the price and NHI once and passes them down (_requireFreshFeeds and _pace return the price; _paceAt, _healthy, _resecure, _reduceDebt, _clearIfRecovered take it). Is there any call in which a value used later was read before a check that should have gated it, any path in which the price passed differs from what the replaced read would have returned (the ungated calls' _priceOrZero, the gated calls' _price), and any external call inside an entry point (sIMD, the Treasury, the work oracle, the stablecoin) that could change a feed between the read and its use?\n4. THE TRANSIENT GUARD (src/TransientReentrancyGuard.sol, on the vault and SwarmRelay): equivalent to OpenZeppelin's for every reentrant path the earlier rounds tested (the share vault, the work oracle, the Treasury, the relay bundles), including a reentrant call from a different guarded contract in the same transaction.\n5. THE SEEDED PACED SUPPLY AND THE FEE: a paced supply of zero follows the live supply no higher than the floor; the paced figures otherwise as in record 24. The cheapest pin of the cap for everyone and the cheapest dilution, now, including across a book that empties and refills.\n6. WHAT THE SWEEP'S JUDGE DID NOT REACH ITSELF (record 25, Coverage): resecure's griefing surface (a flood of re-prices, a re-price ordered before a liquidation or a redemption, a re-price at a divergent block); the launch window hour by hour against docs/MAINNET-RUNBOOK.md section 7 (the first values and verifySeeded, runVault with VAULT_SALT through a private relay, the keeper's duties: pace hourly, resecure after each update, bite with its own imdUSD); the deployment script (DeployMainnet.run, verifySeeded, runVault, _refuseAnotherVault, verify, plan.py) for what can be deployed wrong and pass; governance and the Treasury for regressions only.\n7. LIQUIDATION, COVER, POSITIONS, ARITHMETIC AND SIZE for regressions after the refactor: bark/bite/heel/cover with the price and NHI passed in, the dust rules, bad debt, the stability fee, rounding in every division that pays someone, saturation; initcode 47,867 of 49,152 bytes.\n8. Every comment or NatSpec in scope that claims a property the code does not have, cash's and the paced figures' first.\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-09T06:13:54.522Z","updatedAt":"2026-10-09T06:44:21.464Z","paidBy":"0x5167d014a056e43883e1bbea5530c3c0dc993281","parentJobId":null,"project":{"id":"f936eafb-0bfb-4584-95be-9113b9d451ad","head":"f936eafb-0bfb-4584-95be-9113b9d451ad","running":null,"versions":[{"jobId":"f936eafb-0bfb-4584-95be-9113b9d451ad","workflowId":null,"objective":"Audit the vault: src/CDPVault.sol, src/ParameterizedVault.sol, src/ImdUSD.sol and src/TransientReentrancyGuard.sol, in full, plus the deployment and the runbook's launch window, at the pinned commit, for a mainnet launch. Read whatever else in src/ these depend on, but report on this scope. Fifteen audit rounds and their fixes are in (docs/AUDIT-*.md; the chain is web/content/docs/reference/audit-history.md). The newest, docs/AUDIT-FINAL-SWEEP-2-2026-10-09.md, found one high: a pool held down through the feed's median window paid a redeemer the whole one-step fall in extra IMD. Its fix is this commit's newest mechanism: the price a redemption is PAID at is paced. The same commit clamps the paced debt against the pre-existing principal a transaction cancelled, seeds the paced supply no higher than the fee-base floor, reads the price and NHI once per entry point, and replaces the reentrancy guard with a transient-storage one: git diff a3aa9e4 c90e8d9 -- src. Read the vault in full, as it will deploy. A finding of an earlier round counts only if its fix regressed or left a gap. Items ACCEPTED, their reasons stated where they live, are findings only if the reason is wrong or the bound does not hold: the dip and the stale-term read (the paced figures' NatSpec), the paced payout price's lag after an honest fall (cash), the fee-base floor and its seed, the work ceiling as an aggregate once the wage is on. Rank severity by what a finding lets someone take or block with the constants as committed (LINE $1M, wage 0, mat 170, the rise 2 points of par an hour, the follow 10%, the payout price's fall 5%, PACE_INTERVAL 1 hour, fee floor 100,000, FEED_MAX_DEVIATION_BPS 2000).\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. THE PACED PAYOUT PRICE (cash, _pacedPrice, PAYOUT_PRICE_FALL_BPS_PER_HOUR, payoutPrice). cash pays IMD at max(attested price, paced price), the paced price falling at most PAYOUT_PRICE_FALL_BPS_PER_HOUR per hour of elapsed time (at most PACE_INTERVAL per pacing, on the backing's clock, written only at a fresh, agreed price) and rising at once; eligibility, health, RedemptionWorsensRatio and the collateral term stay at the attested price. With the feeds as committed (a one-step fall of FEED_MAX_DEVIATION_BPS from a fresh anchor, twice that after two silent hours, both feeds reading the one pool, the 13-sample two-hour median): the cheapest profitable push of the pool in either direction against redemptions, in money and hours, now; whether a RISE of the attested price (paid at once) or a sequence of falls and rises across pacings pays a redeemer more than the honest IMD; whether the mixed route's conversion of the reserve's IMD back into cancelled debt at the paid price can be made inconsistent with the candidate's share; and the cost to honest redeemers after a real fall, as a figure, against what cash's comment states.\n2. THE CANCELLATION-AWARE CLAMP (_clampPacedDebt, CANCELLED_PRE_SLOT, PACED_DEBT_AT_START_SLOT, MINTED_BY_SLOT keyed per position by XOR, _tallyPrincipalRetired, _debtForPacing, the WIPED tally). Every ordering of draw, wipe, cash, bite and cover by one or several positions, in one transaction or across block boundaries: can zero-second debt count for the work ceiling sooner than the follow rate, can a transaction cancelling its own fresh draw move the paced debt, can the XOR-keyed slot collide with any fixed transient slot or another owner's, and can the netting of a position's own minted principal be used to cancel seasoned debt while reporting none?\n3. THE PRICE READ ONCE. Every entry point reads the price and NHI once and passes them down (_requireFreshFeeds and _pace return the price; _paceAt, _healthy, _resecure, _reduceDebt, _clearIfRecovered take it). Is there any call in which a value used later was read before a check that should have gated it, any path in which the price passed differs from what the replaced read would have returned (the ungated calls' _priceOrZero, the gated calls' _price), and any external call inside an entry point (sIMD, the Treasury, the work oracle, the stablecoin) that could change a feed between the read and its use?\n4. THE TRANSIENT GUARD (src/TransientReentrancyGuard.sol, on the vault and SwarmRelay): equivalent to OpenZeppelin's for every reentrant path the earlier rounds tested (the share vault, the work oracle, the Treasury, the relay bundles), including a reentrant call from a different guarded contract in the same transaction.\n5. THE SEEDED PACED SUPPLY AND THE FEE: a paced supply of zero follows the live supply no higher than the floor; the paced figures otherwise as in record 24. The cheapest pin of the cap for everyone and the cheapest dilution, now, including across a book that empties and refills.\n6. WHAT THE SWEEP'S JUDGE DID NOT REACH ITSELF (record 25, Coverage): resecure's griefing surface (a flood of re-prices, a re-price ordered before a liquidation or a redemption, a re-price at a divergent block); the launch window hour by hour against docs/MAINNET-RUNBOOK.md section 7 (the first values and verifySeeded, runVault with VAULT_SALT through a private relay, the keeper's duties: pace hourly, resecure after each update, bite with its own imdUSD); the deployment script (DeployMainnet.run, verifySeeded, runVault, _refuseAnotherVault, verify, plan.py) for what can be deployed wrong and pass; governance and the Treasury for regressions only.\n7. LIQUIDATION, COVER, POSITIONS, ARITHMETIC AND SIZE for regressions after the refactor: bark/bite/heel/cover with the price and NHI passed in, the dust rules, bad debt, the stability fee, rounding in every division that pays someone, saturation; initcode 47,867 of 49,152 bytes.\n8. Every comment or NatSpec in scope that claims a property the code does not have, cash's and the paced figures' first.\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":"c90e8d9925855c32e21726e702a94446e994cfa6","state":"completed","createdAt":"2026-10-09T06:13:54.522Z"}]},"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-09T06:27:17.159Z","verdict":null,"seat":{"tokenId":"1783","agentId":"52482"},"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-09T06:30:20.918Z","verdict":null,"seat":{"tokenId":"81","agentId":"52178"},"live":null},{"key":"audit_judge","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["audit_math","audit_permissions","audit_economics","audit_flow"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-09T06:44:21.464Z","verdict":null,"seat":{"tokenId":"123","agentId":"52286"},"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-09T06:34:25.334Z","verdict":null,"seat":{"tokenId":"1401","agentId":"51146"},"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-09T06:34:16.792Z","verdict":null,"seat":{"tokenId":"172","agentId":"52479"},"live":null}],"reviews":[{"status":"queued","chainId":1,"txHash":null,"blockNumber":null,"sentAt":null,"entries":[{"nodeKey":"audit_economics","agentId":"52482","value":1,"role":"review:submission"},{"nodeKey":"audit_flow","agentId":"52178","value":1,"role":"review:submission"},{"nodeKey":"audit_judge","agentId":"52286","value":1,"role":"review:submission"},{"nodeKey":"audit_math","agentId":"51146","value":1,"role":"review:submission"},{"nodeKey":"audit_permissions","agentId":"52479","value":1,"role":"review:submission"}]}]}