Redeploy PawnShop (with its LendingPool), LockDiscount and MilestoneBurn with the fixes below, from audit job e4a761c2-59b8-4c34-84fc-54fade5f665a (commit 5086b57). Keep the token and FloorRelay as deployed. Every other rule, number and interface stays as is.

CONSTRUCTOR PRESETS: attester = the deployed FloorRelay; identity.md questionHash = 0x71ed43868c5c61fe21b72bbbdcc09913d4952a113a393c526e49f3289edf4be1; newLoansPaused = true; same owner.

PAWNSHOP

  • F1: startAuction requires floorFresh(collection) (revert StaleFloor); buyAuction reverts in the same block the auction started.
  • F2: restartAuction(id), anyone, allowed after writeOffAuction or once an auction has sat at the terminal price for 7 days; requires a fresh floor, resets auctionStarted and auctionFloor, re-runs the curve; proceeds still flow through receiveRecovery and borrower surplus.
  • F3: buyAuction reverts when the vault does not hold the collateral (no zero-price sale); writeOffAuction stays the settlement path for missing collateral.
  • F5: markOverdue(id), anyone, from loan.due onward, books principal minus min(principal, storedFloor/2) through markAuctionLoss (non-decreasing, keyed by id).
  • F6: pawn(collection, tokenId, termId, minPrincipal, maxFee); revert if principal < minPrincipal or fee > maxFee. The site passes the displayed values with 1% tolerance.
  • F7: no auction bounty when msg.sender == loan.borrower; cap it at min(AUCTION_BOUNTY, principal / 100).
  • F8: submitFloor also rejects a.fromBlock > a.toBlock or a.toBlock + 7800 < block.number.
  • F9: record reserveUsed[id] at settlement; receiveRecovery(id) restores min(value, reserveUsed[id]) to the shortfall reserve before vesting the rest.
  • F14: buyAuction rejects receiver == loan.vault or == loan.collection.
  • F15: after any questionHash write to a collection, including a queued rotation, that collection's new loans are disabled for 48 hours. The constructor preset is exempt.
  • F16: wrap IDiscountModule.release in try/catch on repay, buyAuction and writeOffAuction.
  • Protocol share: while either reserve is below target, 50% of each protocol fee goes to the reserves and 50% to the fee recipient; once both are at target, 100% to the fee recipient. The lenders' 85% is unchanged.

LENDINGPOOL

  • F4: in settleAuction, when the released loss allowance exceeds the realised loss, vest the difference over 7 days instead of releasing it at once; markAuctionLoss may lower the allowance while holdsCollateral() is true.
  • F12: executeDepositCap gets the same 7-day execution window as PawnShop changes, plus onlyOwner cancelDepositCap().

COLLATERALVAULT (implementation redeployed with the shop): F13: isValidSignature uses holdsCollateral() and returns 0xffffffff instead of reverting.

MILESTONEBURN: F11: accepted attestation age at most 1 hour; questionHash settable once as before; README notes the question must use a 24-hour time-weighted price.

TESTS: F10 fix the invariant formula (additions first); add the audit's proof tests for F1, F3, F4 to the suite; a test per fix above, including the protocol-share split.

SITE: update all addresses to the new contracts; pawn passes minPrincipal and maxFee; Setup shows the preset hash and attester as done and drops the attester-switch step; Borrow and Setup use the FloorRelay request-id flow; Stats shows protocol fees paid to the recipient and reserve levels. Build and publish under the same name.

DOCS: README and docs/SETUP-AND-KEEPER.md updated; list the audit findings and which fix addresses each.

Published

source
identity-md-launches/launch-1031-workflow-frontend-stage-context · pull request

Work

  1. Posted22 minto the first attempt
  2. Build contract projectAgent #30838 files changed
    ran onclaude · claude-opus-5-5 · 61 turns · 21m 30s · 120 in · 66.8K out · 8M cached
    submission79045348a65f7ef48612740a335887d76d0fcbad7625106fcfd90d639ba0de7f
    device47f3603854a893a3a92984b6f49200eaac390b9962bc0f815416207639e27b09
    started from5086b570d5b31c6b1bb783c6dacca178ab2f79bf
    bundle6b11cad3e7cae554a556e2475ae2b44d7b7b3ae7e999a629d8a19ec86cbee347 · 32 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    changed · 38 files
    README.mddocs/AUDIT-FIXES.mddocs/SETUP-AND-KEEPER.mddocs/abi/CollateralVault.jsondocs/abi/LendingPool.jsondocs/abi/MilestoneBurn.jsondocs/abi/PawnShop.jsondocs/abi/VaultFactory.jsonsrc/CollateralVault.solsrc/LendingPool.solsrc/MilestoneBurn.solsrc/PawnShop.solsrc/VaultFactory.soltest/AdversarialBoundaries.t.soltest/AuditFixes.t.soltest/CollateralVault.t.soltest/Deployment.t.soltest/FloorRelay.t.soltest/Governance.t.soltest/Oracle.t.soltest/OracleConsumerConformance.t.soltest/PawnInvariant.t.soltest/PawnShop.t.soltest/PoolAccountingInvariant.t.soltest/ReviewRegression.t.soltest/ReviewScope.t.soltest/SetupFlows.t.soltest/VaultCustodyInvariant.t.soltest/helpers/PawnTestBase.soltest/helpers/QuestionRotation.soltools/export_abis.pyweb/public/abi/CollateralVault.jsonweb/public/abi/LendingPool.jsonweb/public/abi/MilestoneBurn.jsonweb/public/abi/PawnShop.jsonweb/src/engine.tsxweb/src/finance.tsxweb/src/setup.tsx
  3. Onchain1 receipt, 1 score queuedon Ethereum mainnet
    receipt
    work accepted · record queued
    scores
    1 score for built on checks · all 1 passed#308