{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"17b4f2ef-e83c-41e4-8765-cdbf11196fd3","kind":"skill:build-contract-project","nodes":[{"acceptedSubmissionHash":"e3fc9ace74ce3f01d440dcf011deb9e8321a61421b05414918b14954d5655631","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"}],"objective":"First address the findings in audit job 0baee611-180e-4e5d-9c3a-a23ba1245fbb against foundation commit 42119ec0a1425064b6cb7bd5a5015fd4f665d736. Fix the incomplete chain-rejection test, correct and verify the vendored-file checksum evidence, and make the salt-mining page reliable under typical eth_call gas limits. Resolve the mismatch between the documented mainnet restriction and the hook constructor without permanently blocking the Store’s intended future mainnet support. Explicitly decide and document whether the swap limit caps only amountSpecified or both sides of the swap; test the chosen behavior. Preserve the existing passing tests. Then implement the IMD request integration described below. Do not deploy or submit a paid onchain request.\n\nThen\nExtend this Hooks Store foundation, preserving its existing HookSpec, hook, factory and passing tests. Build and locally test the no-backend IMD integration: a wallet-approved Intake v2 job.open request for standalone-hook code with explicit build, tests and adversarial-review steps; request-ID tracking; authenticated, one-time result/failure handling; and a documented way for a static website to show genuine job and review status.\n\nDo not rely on browser access to api.imd.fun from an arbitrary website origin. Demonstrate the Intake event/callback and result-readback path locally, with failure and replay tests. Document what still requires a live Ethereum or Robinhood Chain pilot. Do not submit a paid request or deploy to a public chain. If a static website cannot reliably determine whether review passed, report that blocker—do not invent an “audited” status.","parentJobId":"28e81139-f2a5-4a5a-a239-b6c315b58e01","planHash":"75617c88b76ad1ff2f44b81dae93eee44117b4cae156181c496e0644cf7aac85","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"28e81139-f2a5-4a5a-a239-b6c315b58e01","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1811-build-technical-foundation-hooks"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52130","feedbackHash":"2477e1d6f7beb3dd05b9fd2e1472f155a94e3f0c863a2e3b3812fb63f2d8b421","nodeKey":"build_contract_project","submissionHash":"e3fc9ace74ce3f01d440dcf011deb9e8321a61421b05414918b14954d5655631","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"787cc259fbf665c010a032dad20f1543888a0d6e2b7c8fdb6119dc2139c282b1","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"a3c298f572397d467bc54614b3f924a561b999fd9c47204b67fe044826021dc1","device":"1c29c7c6e4cf57eb","findings":[],"hash":"e3fc9ace74ce3f01d440dcf011deb9e8321a61421b05414918b14954d5655631","nodeId":"a7dfecda-1ddb-4ed5-97c6-3a30a29f982d","outcome":"completed","summary":"All the audit follow-ups and the IMD integration are in place. `forge build`, `forge test` and `forge fmt --check` pass. That is 80 tests (the original 39 unchanged), run with both the pinned seed and the verifier's seed. Nothing was deployed and no paid request was submitted. The Python SDK tests fail here with \"local transaction failed\", and they fail the same way on the untouched foundation commit, so the cause is this environment rather than these changes; I couldn't run them.\n\n**Audit fixes**\n- **Chain-rejection test:** the old test is kept. A new one (`test/AuditFixes.t.sol`) checks Ethereum, Base and Robinhood mainnets, plus random unknown chains, on every release path: factory constructor, `deploy`, both scripts and the shared deployment code. A deploy with a correctly matched spec still gets refused, so only the chain policy can be what stops it. The allowed testnet IDs deploy and verify end to end in local simulation.\n- **Checksum evidence:** `lib/SHA256SUMS` holds the upstream hashes. I re-downloaded all 80 upstream files and they match those hashes. But 18 files actually in `lib/` differ from upstream. Each difference is exactly what `forge fmt` produces from the upstream file, and the bytecode compiled from either version is identical. `lib/` is protected, so I left it and put the corrected evidence in `docs/checksums/`. `script/verify-vendored.sh` checks it offline. `docs/DEPENDENCIES.md` corrects the earlier \"copied unchanged\" claim.\n- **Salt mining:** the audit finding is real. A full 131,072-candidate page costs about 46M gas, above common `eth_call` caps. A page now stops early when gas runs low and returns the nonce to resume from. With too little gas for even one candidate it reverts `InsufficientGas`. A search capped at 10M gas per call finds the same salt as an uncapped one. The Python SDK accepts these shorter pages.\n- **Mainnet restriction:** the restriction belongs to this factory release, not to the hook. The hook constructor only requires the spec's chain to match the chain it runs on. A later reviewed factory release can allow mainnet without changing the hook, its bytecode or the spec, so nothing is permanently blocked. A test shows a hook deployed directly on chain 1 is not recognised by the Store's factory.\n- **Swap limit:** I decided it caps only `amountSpecified`, not both sides. Capping both would break existing passing tests and change the hook's bytecode. A test shows an exact-output swap at the limit paying more than the limit in input. The reasons are in the README.\n\n**IMD integration** (`src/imd/HookJobRequester.sol`, details in `docs/IMD_INTEGRATION.md`)\n- **Opening a job:** the creator's wallet approves IMD to the contract and calls `openJob`, which places an Intake v2 `requestWithFailure` `job.open`. The owner's body template must name `forge build`, `forge test` and `adversarial review`. The creator's text is validated and quoted as untrusted data.\n- **Tracking and callbacks:** jobs are tracked by the Intake's request ID. Result and failure callbacks are accepted only from the Intake, only for this contract's own open jobs, and only once. Each job and each review request has a deadline after which its requester can expire it.\n- **Review status:** \"passed\" can only come from an IdentityMD oracle answer signed for this contract, with minimum panel size and agreement. It is checked against the protocol's test vector. Nothing ever shows \"audited\".\n- **Status page:** `site/index.html` reads job status straight from the chain over JSON-RPC, with no backend and no call to api.imd.fun.\n- **Tests:** all of this is tested against a mock Intake, including replay, wrong sender, forged, tampered, expired or weak-panel answers, deadlines and the 200,000-gas callback limit.\n\n**Blocker and what needs a live pilot**\n- **Review status:** without the oracle step, a static site cannot tell whether review passed. The job completion from the Intake is unsigned and carries no verdict.\n- **`job.open` details","treeHash":"d0aff6584bda427680534a5e2dcd472673301404","usage":{"cachedInputTokens":5949330,"inputTokens":92,"model":"claude-opus-5-5","outputTokens":85989,"runtime":"claude","turns":55,"wallClockMs":900841}}],"verification":[{"checks":[{"durationMs":3855,"exitCode":0,"name":"build","output":"Compiling 104 files with Solc 0.8.26\nSolc 0.8.26 finished in 3.74s\nCompiler run successful!\n","passed":true},{"durationMs":540,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_acceptsAFreshSignatureFromTheVectorKeyAsDelivered() (gas: 1765722)\n[PASS] test_callbackSelectorsAreCanonical() (gas: 3943)\n[PASS] test_digestMatchesTheProtocol() (gas: 13912)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 7.54ms (3.97ms CPU time)\n\nRan 26 tests for test/HookJobRequester.t.sol:HookJobRequesterTest\n[PASS] testAnswerSignedForAnotherConsumerRefused() (gas: 1713928)\n[PASS] testBodyIsExactTemplateWithStepsSpecAndQuotedBrief() (gas: 906801)\n[PASS] testBriefValidation() (gas: 1825659)\n[PASS] testCallbackWithUnexpectedAbiFailsSafeAndJobCanExpire() (gas: 1104689)\n[PASS] testCallbacksFitTheIntakeStipend() (gas: 1767623)\n[PASS] testConstructorRefusesZeroAddresses() (gas: 10404)\n[PASS] testForgedExpiredWeakOrMistypedAnswersRefused() (gas: 2074224)\n[PASS] testFuzzPrintableAsciiBriefAcceptedUnlessReserved(bytes32,uint8) (runs: 256, μ: 523237, ~: 827755)\nLogs:\n  Bound result 7\n\n[PASS] testJobFailureClosesJobOnceAndIsNotAVerdict() (gas: 1103289)\n[PASS] testOpenJobPaysOncePullsExactPriceAndTracksRequestId() (gas: 1112689)\n[PASS] testOwnerSettersAreOwnerOnlyAndValidated() (gas: 498606)\n[PASS] testResultAcceptedOnceFromIntakeOnly() (gas: 1071747)\n[PASS] testReusedRequestIdRefused() (gas: 1183210)\n[PASS] testReviewExpiryByRequesterOnly() (gas: 1823459)\n[PASS] testReviewFailureLeavesNoVerdictAndAllowsRetry() (gas: 2629867)\n[PASS] testReviewNotPassedIsStoredNotReverted() (gas: 1795088)\n[PASS] testReviewOnlyForDeliveredOrExpiredJobsByRequester() (gas: 1921803)\n[PASS] testReviewPassedOnlyFromSignedOracleAnswer() (gas: 2020518)\n[PASS] testSameAttestationCannotSettleASecondAsk() (gas: 4131813)\n[PASS] testSignerRotationTakesEffect() (gas: 1864354)\n[PASS] testStaticSiteReadContract() (gas: 956320)\n[PASS] testSweepRecoversStrayTokens() (gas: 125812)\n[PASS] testUnconfiguredRequesterRefusesUntilOwnerSetsTemplates() (gas: 1518344)\n[PASS] testUnknownRequestIdRefused() (gas: 130101)\n[PASS] testUnpricedActionAndVersion1IntakeRefusedWithoutPayment() (gas: 459707)\n[PASS] testWalletMustApproveAndPay() (gas: 356155)\nSuite result: ok. 26 passed; 0 failed; 0 skipped; finished in 36.07ms (40.25ms CPU time)\n\nRan 15 tests for test/HookIntegration.t.sol:HookIntegrationTest\n[PASS] testAllDirectionsAndExactModesAcceptLimit() (gas: 650218)\n[PASS] testDuplicatePoolInitializationFails() (gas: 41653)\n[PASS] testDynamicFeePoolRejectedAtomically() (gas: 97839)\n[PASS] testFuzzHookDataHasNoAuthority(bytes) (runs: 256, μ: 210226, ~: 210022)\n[PASS] testFuzzRealSwapsSettleAndConserve(uint128,bool,bool,bool) (runs: 256, μ: 281019, ~: 278533)\nLogs:\n  Bound result 3600\n\n[PASS] testFuzzSignedBoundaryAndNeutralReturn(int256,bytes) (runs: 256, μ: 30892, ~: 29822)\n[PASS] testFuzzUnauthorizedCallbacks(address) (runs: 256, μ: 94964, ~: 95102)\n[PASS] testIntMinIntMaxAndZeroFailClearly() (gas: 88270)\n[PASS] testLimitCapsOnlySpecifiedSideNotUnspecifiedSide() (gas: 427039)\n[PASS] testLiquidityWithdrawalRemainsAvailableAfterRejectedSwap() (gas: 184825)\n[PASS] testOverLimitRevertsThroughManagerInAllModes() (gas: 253819)\n[PASS] testSettlementFailureRollsBackCounterAndPoolState() (gas: 388376)\n[PASS] testTwoNewPoolsReuseOneDeployedHook() (gas: 624953)\n[PASS] testUnusedCallbacksAlwaysRevert() (gas: 209241)\n[PASS] testWrongHookAndUnknownPoolRejected() (gas: 124522)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 36.08ms (77.86ms CPU time)\n\nRan 11 tests for test/AuditFixes.t.sol:AuditFixesTest\n[PASS] testAllowedTestnetsDeployAndVerifyEndToEnd() (gas: 7765983)\n[PASS] testBaseMainnetRejectedOnEveryReleasePath() (gas: 9450397)\n[PASS] testEthereumMainnetRejectedOnEveryReleasePath() (gas: 9450443)\n[PASS] testFullPageCompletesOrResumesUnderTypicalCallGasCap() (gas: 4696895)\n[PASS] testFuzzUnknownChainsRejectedOnEveryReleasePath(uint64) (runs: 256, μ: 9453605, ~: 9453605)\n[PASS] testHookConstructorStillBindsSpecToActualChain() (gas: 19895)\n[PASS] testHookTemplateStaysChainAgnosticForFutureMainnetRelease() (gas: 1388790)\n[PASS] testMaxPageGasWithinBudgetWhenUncapped() (gas: 2338692)\n[PASS] testRobinhoodMainnetRejectedOnEveryReleasePath() (gas: 9450442)\n[PASS] testTooLittleGasForOneCandidateRevertsClearly() (gas: 17619788)\n[PASS] testTruncatedPageReportsFirstUncheckedNonce() (gas: 1946363)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 416.76ms (584.52ms CPU time)\n\nRan 25 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] testAllNamedMainnetsAndUnknownChainsRejected() (gas: 4440)\n[PASS] testAnyoneMayDeployIdenticalPlanWithoutTakingOwnership() (gas: 3340102)\n[PASS] testChangedConstructorSettingsInvalidateCachedPlan() (gas: 2452880)\n[PASS] testChangingManagerChangesCommitments() (gas: 4456007)\n[PASS] testDuplicateDeploymentRejectedAndMinerSkipsOccupiedAddress() (gas: 3409894)\n[PASS] testFuzzOnlyExactPermissionMaskAccepted(uint160) (runs: 256, μ: 30093, ~: 30225)\n[PASS] testFuzzPredictionMatchesIndependentCreate2Formula(address,bytes32,bytes32) (runs: 256, μ: 3933, ~: 3933)\n[PASS] testFuzzSpecLimitCommitsToExactConstructor(uint128,bytes32) (runs: 256, μ: 44323, ~: 44323)\n[PASS] testInvalidSearchRanges() (gas: 100769)\n[PASS] testInvalidSpecFieldsRejected() (gas: 161488)\n[PASS] testManagerCodeChangeFailsClosed() (gas: 2410875)\n[PASS] testManagerMustHaveExpectedCode() (gas: 68520)\n[PASS] testPredictionDeploymentPermissionsSettingsAndBytecodeAgree() (gas: 3496937)\n[PASS] testPrefundedPredictedAddressStillDeploys() (gas: 3331370)\n[PASS] testScriptUsesSamePlanAndDeploymentAsStore() (gas: 7192658)\n[PASS] testScriptsRejectMissingBroadcaster() (gas: 7147621)\n[PASS] testSearchExhaustionAndResume() (gas: 6291072)\n[PASS] testStaleOrForgedScriptPlansRejected() (gas: 6271704)\n[PASS] testTestnetPolicyIdsOnlyLocalSimulation() (gas: 7542)\n[PASS] testVerificationDetectsCorruptedConstructorStorage() (gas: 3314813)\n[PASS] testVerificationDetectsCorruptedRuntime() (gas: 3308499)\n[PASS] testVerifyUndeployedOrWrongAddressRejected() (gas: 2430633)\n[PASS] testWrongChainRejected() (gas: 29640)\n[PASS] testWrongExpectedAddressAndHashRejected() (gas: 2458895)\n[PASS] testWrongSaltRejectedByFactoryAndConstructor() (gas: 98469)\nSuite result: ok. 25 passed; 0 failed; 0 skipped; finished in 416.76ms (266.79ms CPU time)\n\nRan 5 test suites in 417.44ms (913.20ms CPU time): 80 tests passed, 0 failed, 0 skipped (80 total tests)\n","passed":true},{"durationMs":66,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"BoundedSwapHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"BoundedSwapHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"HookJobRequester.expireJob(bytes32)\",\"HookJobRequester.expireReview(bytes32)\",\"HookJobRequester.onJobFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"HookJobRequester.onJobResult(bytes32,bytes)\",\"HookJobRequester.onReviewFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"HookJobRequester.onReviewResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"HookJobRequester.openJob(bytes32,bytes)\",\"HookJobRequester.requestReview(bytes32)\",\"HookJobRequester.setAsset(address)\",\"HookJobRequester.setIntake(address)\",\"HookJobRequester.setJobTemplate(bytes32,bytes,bytes,bytes)\",\"HookJobRequester.setOracleSigner(address)\",\"HookJobRequester.setReviewTemplate(bytes32,bytes,bytes,uint16,uint16)\",\"HookJobRequester.setTimeouts(uint64,uint64)\",\"HookJobRequester.sweep(address,address,uint256)\",\"HookJobRequester.transferOwnership(address)\",\"HooksStoreFactory.deploy((uint32,bytes32,uint256,address,bytes32,uint160,uint128),bytes32,address,bytes32)\"],\"files\":{\".gitignore\":6,\"LICENSE\":24,\"README.md\":76,\"dependencies.lock.json\":20,\"docs/CHAINS.md\":18,\"docs/DEPENDENCIES.md\":22,\"docs/DEPLOYMENT.md\":54,\"docs/HOOK_SPEC.md\":63,\"docs/IMD_INTEGRATION.md\":71,\"docs/STORE_API.md\":64,\"docs/THREAT_MODEL.md\":49,\"docs/VERIFICATION.md\":58,\"docs/build-fingerprints.json\":28,\"docs/checksums/FORMAT_ONLY.txt\":24,\"docs/checksums/UPSTREAM.sha256\":96,\"docs/checksums/VENDORED.sha256\":96,\"foundry.toml\":22,\"remappings.txt\":3,\"schemas/hook-spec.v1.schema.json\":17,\"script/DeployHook.s.sol\":38,\"script/DeployStore.s.sol\":19,\"script/verify-vendored.sh\":15,\"sdk/hooks_store.py\":306,\"site/index.html\":99,\"src/BoundedSwapHook.sol\":97,\"src/DisabledCallbacks.sol\":63,\"src/HookSpec.sol\":61,\"src/HooksStoreFactory.sol\":114,\"src/deployment/DeploymentPolicy.sol\":21,\"src/deployment/HookDeployment.sol\":44,\"src/deployment/HookMiner.sol\":63,\"src/imd/HookJobRequester.sol\":496,\"src/imd/IIntake.sol\":27,\"src/imd/OracleAttestation.sol\":221,\"src/interfaces/IHooksStore.sol\":36,\"src/vendor/openzeppelin/LICENSE\":22,\"src/vendor/openzeppelin/interfaces/IERC1271.sol\":17,\"src/vendor/openzeppelin/interfaces/IERC5267.sol\":28,\"src/vendor/openzeppelin/interfaces/IERC7913.sol\":18,\"src/vendor/openzeppelin/utils/Bytes.sol\":247,\"src/vendor/openzeppelin/utils/Panic.sol\":57,\"src/vendor/openzeppelin/utils/ShortStrings.sol\":122,\"src/vendor/openzeppelin/utils/StorageSlot.sol\":143,\"src/vendor/openzeppelin/utils/Strings.sol\":515,\"src/vendor/openzeppelin/utils/cryptography/ECDSA.sol\":285,\"src/vendor/openzeppelin/utils/cryptography/EIP712.sol\":160,\"src/vendor/openzeppelin/utils/cryptography/MessageHashUtils.sol\":100,\"src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol\":162,\"src/vendor/openzeppelin/utils/math/Math.sol\":758,\"src/vendor/openzeppelin/utils/math/SafeCast.sol\":1162,\"src/vendor/openzeppelin/utils/math/SignedMath.sol\":68,\"test/AuditFixes.t.sol\":192,\"test/Deployment.t.sol\":329,\"test/HookIntegration.t.sol\":294,\"test/HookJobRequester.t.sol\":618,\"test/OracleConformance.t.sol\":103,\"test/helpers/Fixture.sol\":46,\"test/helpers/ImdTemplates.sol\":15,\"test/helpers/MockIntake.sol\":111,\"test/helpers/PoolRouter.sol\":76,\"test/helpers/TestToken.sol\":13,\"test/test_store_sdk.py\":193},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":3376,"exitCode":0,"name":"slither","output":"[high/medium] incorrect-exp at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) has bitwise-xor operator ^ instead of the exponentiation operator **: \n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:315: Math.invMod(uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#315-363) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/vendor/openzeppelin/utils/math/Math.sol:204: Math.mulDiv(uint256,uint256,uint256) (src/vendor/openzeppelin/utils/math/Math.sol#204-275) performs a multiplication on the result of a division:\n[medium/medium] reentrancy-no-eth at src/imd/HookJobRequester.sol:243: Reentrancy in HookJobRequester.requestReview(bytes32) (src/imd/HookJobRequester.sol#243-273):\n[medium/medium] uninitialized-local at src/imd/HookJobRequester.sol:447: HookJobRequester._validateBrief(bytes).cp (src/imd/HookJobRequester.sol#447) is a local variable never initialized\n[medium/medium] uninitialized-local at src/imd/HookJobRequester.sol:446: HookJobRequester._validateBrief(bytes).len (src/imd/HookJobRequester.sol#446) is a local variable never initialized\n[medium/medium] unused-return at src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol:44: SignatureChecker.isValidSignatureNowCalldata(address,bytes32,bytes) (src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol#44-55) ignores return value by (recovered,err,None) = ECDSA.tryRecoverCalldata(hash,signature) (src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol#50)\n[medium/medium] unused-return at src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol:32: SignatureChecker.isValidSignatureNow(address,bytes32,bytes) (src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol#32-39) ignores return value by (recovered,err,None) = ECDSA.tryRecover(hash,signature) (src/vendor/openzeppelin/utils/cryptography/SignatureChecker.sol#34)\n[low/medium] reentrancy-benign at src/imd/HookJobRequester.sol:166: Reentrancy in HookJobRequester.openJob(bytes32,bytes) (src/imd/HookJobRequester.sol#166-192):\n[low/medium] reentrancy-benign at src/imd/HookJobRequester.sol:243: Reentrancy in HookJobRequester.requestReview(bytes32) (src/imd/HookJobRequester.sol#243-273):\n[low/medium] timestamp at src/imd/HookJobRequester.sol:311: HookJobRequester.expireReview(bytes32) (src/imd/HookJobRequester.sol#311-321) uses timestamp for comparisons\n[low/medium] timestamp at src/imd/OracleAttestation.sol:157: OracleAttestationConsumer._verifyAttestation(OracleAttestation.Attestation,bytes) (src/imd/OracleAttestation.sol#157-165) uses timestamp for comparisons\n[low/medium] timestamp at src/imd/HookJobRequester.sol:228: HookJobRequester.expireJob(bytes32) (src/imd/HookJobRequester.sol#228-236) uses timestamp for comparisons","passed":true},{"durationMs":703,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/vendor/openzeppelin/utils/cryptography/MessageHashUtils.sol:63: `abi.encodePacked()` Hash Collision (2 places)\n[high] incorrect-caret-operator at src/vendor/openzeppelin/utils/math/Math.sol:257: Incorrect use of caret operator\n[high] incorrect-shift-order at src/deployment/HookMiner.sol:27: Incorrect Assembly Shift Parameter Order\n[high] reentrancy-state-change at src/imd/HookJobRequester.sol:172: Reentrancy: State change after external call (2 places)\n[high] reused-contract-name at src/vendor/openzeppelin/utils/math/SafeCast.sol:19: Contract Name Reused in Different Files\n[high] unsafe-casting at src/vendor/openzeppelin/utils/Strings.sol:432: Unsafe Casting of integers\n[low] centralization-risk at src/imd/HookJobRequester.sol:21: Centralization Risk (8 places)\n[low] ecrecover at src/vendor/openzeppelin/utils/cryptography/ECDSA.sol:191: `ecrecover` Signature Malleability\n[low] internal-function-used-once at src/HookSpec.sol:35: Internal Function Used Only Once (33 places)\n[low] large-numeric-literal at src/deployment/HookMiner.sol:9: Large Numeric Literal\n[low] literal-instead-of-constant at src/imd/HookJobRequester.sol:430: Literal Instead of Constant (209 places)\n[low] push-zero-opcode at src/vendor/openzeppelin/interfaces/IERC1271.sol:4: PUSH0 Opcode (15 places)\n[low] require-revert-in-loop at src/deployment/HookMiner.sol:51: Loop Contains `require`/`revert` (3 places)\n[low] state-no-address-check at src/BoundedSwapHook.sol:43: Address State Variable Set Without Checks\n[low] state-variable-could-be-immutable at src/BoundedSwapHook.sol:21: State Variable Could Be Immutable (5 places)\n[low] uninitialized-local-variable at src/imd/HookJobRequester.sol:476: Uninitialized Local Variable\n[low] unspecific-solidity-pragma at src/vendor/openzeppelin/interfaces/IERC1271.sol:4: Unspecific Solidity Pragma (4 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"e3fc9ace74ce3f01d440dcf011deb9e8321a61421b05414918b14954d5655631","verifiedTreeHash":"d0aff6584bda427680534a5e2dcd472673301404","verifierVersion":"0.1.0+63e0a393"}]}