{"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":"fc4df0ca-3145-4542-a711-3f8dbd56fa47","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"working"},{"acceptedSubmissionHash":"24e8c6cf0168ff2e3fde5b8db7f65c2f7681acbb21ccb5a40d321908e6452d91","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"working"}],"objective":"Launch kind univ4_hook on Ethereum mainnet, paired with native ETH; token, hook, treasury and fee router deploy in the launch. No outside services or oracles. Nobody can change the rules after deployment: no owner, setters, minting, upgrades or pause. No website.\nFACTORIES: LaunchFactory 0x12C63b581d07093F6126bc02263c58f7EadaA96F (hooks, Medici's own) and ProjectFactory 0xfF03410d0Fe5fa8f7F59F743de35E333D9857120 share one fee API and pay native ETH: treasury and router need receive(); send ETH with call, never transfer. INTAKE 0xa43e6F75ee006411F79Ac1C84120606C2330DE82 (IMD IntakeV2). IMD/ETH POOL: ETH, IMD, fee 10000, tickSpacing 200, no hook.\n\nTOKEN. Token name: Medici. Token symbol: MEDICI. The standard launch token; poolBps 9000, no team allocation. Burn = send to 0x000000000000000000000000000000000000dEaD; treasury.totalBurned() counts its burns.\n\nHOOK FEE: 2% of every buy and sell in ETH, on settled deltas, exact-in and exact-out: 1.5% to the treasury, 0.5% accrued for TEAM, paid out by claimTeam() (anyone). The treasury's own swaps pay none. First 15 min the buy fee decays 50% to 2%, surplus to the treasury. The hook keeps a TWAP accumulator.\n\nFEE ROUTER: the paying wallet will setRequester(launchNumber, feeRouter) on LaunchFactory. harvest(), anyone: claimFees, withdraw both currencies; ETH to TEAM, MEDICI burned.\n\nROLES: TEAM and KEEPER, stored in the treasury; each can only hand itself over (setTeam, setKeeper).\n\nTREASURY (holds ETH and IMD; anyone may send IMD):\n- 7-day epochs from pool open; currentEpoch() moves on once the previous end (with extension) passes; ended epochs stay status 0 until settle(epoch).\n- price(): ETH per MEDICI (1e18), 24h TWAP, or since open if younger.\n- propose(title, brief): title max 80 bytes; brief (JSON launch.open body, max 12,000 bytes) emitted in Proposed; store keccak256(brief) and the block. Burns MEDICI worth 0.002 ETH x 1.15^n at price() (n = proposals so far this epoch), clamped 1,000-2,000,000; counts as the proposer's vote. Max 20 per epoch, before the original 7-day end.\n- vote(epoch, id, amount): epoch == currentEpoch(); burns amount, recorded per voter.\n- A vote in the last hour extends the end to 10 min after it, max +24h.\n- flag(epoch, id, note): KEEPER; note max 120 bytes, informational.\n- settle(epoch): anyone, after the end. Most burned wins (tie: earlier); runner-up recorded. Winner's burns under 0.01 ETH at the epoch TWAP: no winner (status 4).\n- Bounty escrowed at settle: min(10% of free treasury ETH, 1 ETH, 50% of the winner's burns at the epoch TWAP), paid to the proposer at recordCommission; kept if the transfer fails.\n- commission(epoch, brief): keccak256(brief) == winner's briefHash; KEEPER at once, anyone 24h after the winner was set; one live request per epoch. If IMD < 0.5, first buys exactly 0.5 IMD in the IMD/ETH POOL for at most 0.03 ETH. Then approves exactly 0.5 IMD and calls INTAKE.requestWithFailure(\"launch.open@launch-1\", brief, (this, onResult), onFailure, IMD, 0.5e18).\n- onResult(bytes32 requestId, bytes32 resultHash, string uri) stores them; onFailure(bytes32,uint8,bytes32,uint16,uint16,bytes) promotes the runner-up. Only from INTAKE for the live request, under 200k gas.\n- lapse(epoch): anyone, 14 days after the winner was set with no recorded launch: runner-up wins with a fresh 14 days; after a second lapse the bounty returns. skip(epoch, reason): KEEPER, before commission; runner-up now. A promoted runner-up's quorum and bounty use its own burns.\n- recordCommission(epoch, launchNumber, jobId): KEEPER, after commission; each launch once; positionOf(launchNumber).requester == treasury (either factory); treasury holds at least 5% of the launch token's supply (the pool currency other than ETH/IMD). Stores both, pays the bounty, reserves that balance as the backer share.\n- claimBacker(epoch): the winner's voters claim it pro rata to their burn for 90 days; then burnUnclaimed(epoch), anyone.\n- Buyback: at settle, 40% of the epoch's ETH income (not returned escrow) unlocks evenly over 24h; unspent carries over. buyback(), anyone: all unlocked ETH buys MEDICI here, burned; caller gets 0.5%; min-out from the TWAP.\n- keeperWithdraw(amount): KEEPER, max 0.01 ETH per epoch.\n- harvest(launchNumber), anyone, recorded launches: claimFees, withdraw; launch tokens above the unclaimed reserve burned; IMD kept for launches.\n\nADDRESSES: TEAM 0x01670a5CfAEEaEE388cD38085C4ADf1Bad45a1c2, KEEPER 0x16578E0dfAFa219f2B0f52095D8206b5c02F8250, IMD 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7.\n\nINTERFACE (exact; a page and keeper use it). epoch, id, amount: uint256; launchNumber, blockNumber, times: uint64; title, note, reason, jobId: string; brief: bytes; briefHash: bytes32; proposer, voter, token: address. hook: treasury(), feeRouter(), teamOwed(), claimTeam(). Treasury views:\ntoken(); price(); totalBurned(); currentEpoch(); epochEnd(e); proposeDeadline(e); proposeCost(); proposalCount(e); votesOf(e,id,voter); claimable(e,voter); totalBuybackBurned();\nproposalOf(e,id) -> (proposer, title, briefHash, blockNumber, burned, flag);\nepochResult(e) -> (uint8 status, winnerId, runnerUpId, bounty, launchNumber, deadline, jobId): 0 open, 1 awaiting launch, 2 launched, 3 lapsed, 4 no winner;\nrequestOf(e) -> (bytes32 requestId, openToAllAt), requestId 0 when none is live; backerShare(e) -> (token, amount, claimed, claimUntil); buybackChunk() -> (unlocked eth, tip).\nWrites as named above. Event Proposed(epoch, id, proposer, title, brief), plus one event per action.\n\nRequirements: Foundry fork tests for every rule (junk winners lose money; ETH from both factories; commission via the real INTAKE), plus an independent review.","parentJobId":null,"planHash":"a744839efef703696d9f8616161c3906838a79875de9593fd2d56914a516c6b8","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"fc4df0ca-3145-4542-a711-3f8dbd56fa47","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1775-launch-kind-univ4-hook-ethereum"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51197","feedbackHash":"31e8989d7caa5600e595a7c4f9c9cdbb8749e2790da80fa8c36f297a1733ea81","nodeKey":"build_contract_project","submissionHash":"24e8c6cf0168ff2e3fde5b8db7f65c2f7681acbb21ccb5a40d321908e6452d91","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"1bcea8b8876af2819b6ba9626d4a3948fd74bd22056de8af22497b6305d66c92","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"a2ace7430add8560aa62b86e9983a3ce78307fe4d490881d52b7bd69bef25b2d","device":"f2d7eadae2a3cfdf","findings":[],"hash":"24e8c6cf0168ff2e3fde5b8db7f65c2f7681acbb21ccb5a40d321908e6452d91","nodeId":"a89b3dd6-0086-41a8-b981-08402bf991f7","outcome":"completed","summary":"Implemented the Medici contracts, tests, and deployment documentation.\n\n- Build and formatting checks passed.\n- 54 local checks and 60 mainnet fork tests passed.\n- Independent review completed and findings fixed.\n- Callback URIs are capped at 96 bytes to fit the gas limit.\n\nSee [README](README.md), [validation results](docs/VALIDATION.md), and [review](docs/INDEPENDENT_REVIEW.md). No transactions were broadcast.","treeHash":"d857b815c37ee770ba547d93fe1ea2aeaaf5c182","usage":{"cachedInputTokens":7414528,"inputTokens":428019,"model":"gpt-6-astra","outputTokens":82870,"runtime":"codex","turns":15,"wallClockMs":2272879}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"410d15d57eeec440","findings":[],"hash":"623653e49348e1e9690f3ed38b58d6d580d314bc33ba77335b23925eb28f4b0f","nodeId":"9117c6cf-cc0d-481a-9881-aeb9990ac834","outcome":"failed","summary":"needs input: The actual positive uint64 launchNumber assigned to this Medici launch is missing. MediciHook requires it as its fourth constructor argument and passes it to MediciFeeRouter, which permanently stores it for LaunchFactory.positionOf and claimFees. The supplied guidance provides no launch-number placeholder; repository test fixtures are not deployment values. launch.json cannot be completed without inventing an ID. — What is the actual positive uint64 launchNumber assigned to this Medici launch by the launch coordinator?","treeHash":null,"usage":{"cachedInputTokens":1049600,"inputTokens":65418,"model":"gpt-6-astra","outputTokens":4462,"runtime":"codex","turns":4,"wallClockMs":213321}}],"verification":[{"checks":[{"durationMs":48936,"exitCode":0,"name":"build","output":"Compiling 97 files with Solc 0.8.26\nSolc 0.8.26 finished in 48.81s\nCompiler run successful!\n","passed":true},{"durationMs":371,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/Mainnet.t.sol:MainnetIntegrationTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 572.52µs (0.00ns CPU time)\n\nRan 19 tests for test/Hook.t.sol:HookTest\n[PASS] testFuzz_dustETHSpecifiedFullFill(uint16,bool) (runs: 256, μ: 293800, ~: 323826)\n[PASS] testFuzz_feeConservation(uint96,bool,bool) (runs: 256, μ: 319621, ~: 301417)\n[PASS] testFuzz_partialETHSpecifiedUsesActualDelta(uint32,uint16,bool) (runs: 256, μ: 384088, ~: 381703)\n[PASS] test_decayAndSurplus() (gas: 343778)\n[PASS] test_exactInputBuyChargesETH() (gas: 409101)\n[PASS] test_exactInputSellChargesSettledETH() (gas: 282739)\n[PASS] test_exactOutputBuyChargesSettledETH() (gas: 279807)\n[PASS] test_exactOutputSellChargesSettledETH() (gas: 327092)\n[PASS] test_factoryZeroLiquidityCollectWorks() (gas: 407021)\n[PASS] test_initializationRejectsWrongFactoryAndPoolKey() (gas: 14367026)\n[PASS] test_partialETHSpecifiedBuyChargesOnlySettledDelta() (gas: 337859)\n[PASS] test_partialETHSpecifiedSellChargesOnlySettledDelta() (gas: 337879)\n[PASS] test_partialTokenSpecifiedSellUsesActualETH() (gas: 291054)\n[PASS] test_permissionsInitializationAndGuards() (gas: 156398)\n[PASS] test_previewCannotBeCalledExternally() (gas: 39127)\n[PASS] test_teamRejectDoesNotStopTradingAndCanHandOver() (gas: 616864)\n[PASS] test_tokenOnlyPoolMintsThenRedeemsETHClaims() (gas: 17102992)\n[PASS] test_tokenStandardFixedSupply() (gas: 132548)\n[PASS] test_twapExcludesSameBlockManipulationAndAveragesHistory() (gas: 439161)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 37.60ms (110.45ms CPU time)\n\nRan 27 tests for test/Treasury.t.sol:TreasuryTest\n[PASS] test_anyoneCanCommissionAfter24Hours() (gas: 1073007)\n[PASS] test_backersProRataOnlyWinnerNoDoubleClaimThenBurnUnclaimed() (gas: 2515224)\n[PASS] test_buybackLinearUnlockCarriesBurnsTipAndExemption() (gas: 946662)\n[PASS] test_buybackTWAPSlippageRefusesManipulatedSpot() (gas: 780979)\n[PASS] test_callbacksAuthenticateLiveRequestAndPreventReplay() (gas: 1341348)\n[PASS] test_commissionExactOutputTopupAndMaxCost() (gas: 1541189)\n[PASS] test_commissionHashExclusiveExactApprovalOneAttemptAndCanonicalCallback() (gas: 1310660)\n[PASS] test_commissionTopupRejectsExcessPriceAndUnsolicitedUnlock() (gas: 1266673)\n[PASS] test_extensionCappedAt24HoursAndRolloverIndependentOfSettle() (gas: 15324352)\n[PASS] test_failurePromotesRunnerWithOwnBountyUnder200k() (gas: 1560528)\n[PASS] test_flagInformationalAndBounded() (gas: 652907)\n[PASS] test_harvestBothFactoriesNativeETHAndPreservesBackerReserve() (gas: 2391605)\n[PASS] test_harvestKeepsIMD() (gas: 2297865)\n[PASS] test_junkWinnerFailureNeverRefundsBurnOrPaysBounty() (gas: 1170958)\n[PASS] test_keeperLimitPerEpochAndCannotSpendReserves() (gas: 378214)\n[PASS] test_lapseTwiceFreshDeadlineCancelsLiveRequestAndNoReturnedIncome() (gas: 1646337)\n[PASS] test_maxResultURIUnder200kAndTooLongRefused() (gas: 1294150)\n[PASS] test_promotedRunnerNeedsOwnQuorum() (gas: 1018707)\n[PASS] test_proposalCapsLengthsAndOriginalDeadline() (gas: 4924829)\n[PASS] test_proposalCostHashBlockVoteAndBurn() (gas: 390888)\n[PASS] test_recordRequiresCommissionKeeperRequesterAndFivePercent() (gas: 2274106)\n[PASS] test_rejectedBountyStaysInTreasuryAndJunkWinnerLosesBurns() (gas: 2224662)\n[PASS] test_rolesCanOnlyHandThemselvesOver() (gas: 226666)\n[PASS] test_routerHarvestETHToCurrentTeamAndMEDICIBurned() (gas: 440688)\n[PASS] test_settleMostBurnTieEarlierRunnerAndBountyCaps() (gas: 1163651)\n[PASS] test_underQuorumAndEmptyEpochNoWinner() (gas: 557114)\n[PASS] test_votesOnlyCurrentPositiveValidProposal() (gas: 585912)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 50.93ms (38.32ms CPU time)\n\nRan 7 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] testFuzz_backerConservationAndRounding(uint96,uint96) (runs: 256, μ: 2331368, ~: 2370065)\n[PASS] test_bountyReentrancyCannotClaimDuringRecord() (gas: 2347456)\n[PASS] test_buybackChunksOverlapAndCarryWithoutDoubleCountingIncome() (gas: 578885)\n[PASS] test_callbackMaximumColdSlotsUnder200k() (gas: 1247808)\n[PASS] test_gasBurningBountyCannotBlockRecording() (gas: 2214932)\n[PASS] test_ineligibleLaunchFactoryDoesNotShadowProjectFactory() (gas: 2680158)\n[PASS] test_sameNumberAcrossFactoriesRecordsAndHarvestsBoth() (gas: 4051344)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 55.82ms (49.71ms CPU time)\n\nRan 1 test for test/Invariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_burnCounterMatchesIrrecoverableMEDICI\n[PASS] invariant_reservedETHAlwaysSolvent\n[PASS] invariant_unlockedNeverExceedsReserved\n TreasuryInvariantTest invariants (runs: 64, calls: 3072, reverts: 0)\n\n╭-----------------+----------------+-------+---------+----------╮\n| Contract        | Selector       | Calls | Reverts | Discards |\n+===============================================================+\n| TreasuryHandler | advance        | 485   | 0       | 0        |\n|-----------------+----------------+-------+---------+----------|\n| TreasuryHandler | buyback        | 513   | 0       | 0        |\n|-----------------+----------------+-------+---------+----------|\n| TreasuryHandler | fund           | 496   | 0       | 0        |\n|-----------------+----------------+-------+---------+----------|\n| TreasuryHandler | proposeAndVote | 513   | 0       | 0        |\n|-----------------+----------------+-------+---------+----------|\n| TreasuryHandler | settle         | 510   | 0       | 0        |\n|-----------------+----------------+-------+---------+----------|\n| TreasuryHandler | withdraw       | 555   | 0       | 0        |\n╰-----------------+----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 238.69ms (229.18ms CPU time)\n\nRan 5 test suites in 241.29ms (383.61ms CPU time): 54 tests passed, 0 failed, 1 skipped (55 total tests)\n","passed":true},{"durationMs":103,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MediciFeeRouter.harvest()\",\"MediciFeeRouter.receive()\",\"MediciHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MediciHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MediciHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MediciHook.claimTeam()\",\"MediciHook.previewSwap((address,address,uint24,int24,address),(bool,int256,uint160))\",\"MediciHook.receive()\",\"MediciHook.redeemFees()\",\"MediciHook.unlockCallback(bytes)\",\"MediciToken.approve(address,uint256)\",\"MediciToken.transfer(address,uint256)\",\"MediciToken.transferFrom(address,address,uint256)\",\"MediciTreasury.burnUnclaimed(uint256)\",\"MediciTreasury.buyback()\",\"MediciTreasury.claimBacker(uint256)\",\"MediciTreasury.commission(uint256,bytes)\",\"MediciTreasury.flag(uint256,uint256,string)\",\"MediciTreasury.harvest(uint64)\",\"MediciTreasury.keeperWithdraw(uint256)\",\"MediciTreasury.lapse(uint256)\",\"MediciTreasury.onFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"MediciTreasury.onResult(bytes32,bytes32,string)\",\"MediciTreasury.propose(string,bytes)\",\"MediciTreasury.receive()\",\"MediciTreasury.recordCommission(uint256,uint64,string)\",\"MediciTreasury.setKeeper(address)\",\"MediciTreasury.setTeam(address)\",\"MediciTreasury.settle(uint256)\",\"MediciTreasury.skip(uint256,string)\",\"MediciTreasury.unlockCallback(bytes)\",\"MediciTreasury.vote(uint256,uint256,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":108,\"docs/INDEPENDENT_REVIEW.md\":64,\"docs/TEST_COVERAGE.md\":35,\"docs/VALIDATION.md\":59,\"docs/intake-abi.json\":1070,\"docs/launch-abi.json\":896,\"docs/project-abi.json\":1332,\"foundry.toml\":26,\"remappings.txt\":4,\"src/HookFlags.sol\":31,\"src/MediciFeeRouter.sol\":48,\"src/MediciHook.sol\":285,\"src/MediciToken.sol\":10,\"src/MediciTreasury.sol\":597,\"src/Protocol.sol\":12,\"src/interfaces/IProtocol.sol\":38,\"test/Adversarial.t.sol\":179,\"test/Base.t.sol\":140,\"test/Hook.t.sol\":260,\"test/Invariant.t.sol\":78,\"test/Treasury.t.sol\":560,\"test/fork/FactoryLaunch.sol\":75,\"test/fork/Mainnet.t.sol\":263,\"test/mocks/Mocks.sol\":99,\"test/mocks/PoolActor.sol\":66},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":10968,"exitCode":0,"name":"slither","output":"[high/medium] arbitrary-send-eth at src/MediciTreasury.sol:508: MediciTreasury.buyback() (src/MediciTreasury.sol#508-527) sends eth to arbitrary user\n[high/medium] arbitrary-send-eth at src/MediciFeeRouter.sol:26: MediciFeeRouter.harvest() (src/MediciFeeRouter.sol#26-45) sends eth to arbitrary user\n[high/medium] arbitrary-send-eth at src/MediciHook.sol:202: MediciHook._payTreasury() (src/MediciHook.sol#202-210) sends eth to arbitrary user\n[medium/high] incorrect-equality at src/MediciTreasury.sol:202: MediciTreasury.vote(uint256,uint256,uint256) (src/MediciTreasury.sol#202-206) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MediciHook.sol:247: MediciHook._observe() (src/MediciHook.sol#247-256) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MediciTreasury.sol:281: MediciTreasury.settle(uint256) (src/MediciTreasury.sol#281-305) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/MediciTreasury.sol:562: Reentrancy in MediciTreasury.harvest(uint64) (src/MediciTreasury.sol#562-568):\n[medium/medium] reentrancy-no-eth at src/MediciTreasury.sol:324: Reentrancy in MediciTreasury.commission(uint256,bytes) (src/MediciTreasury.sol#324-351):\n[medium/medium] uninitialized-local at src/MediciTreasury.sol:500: MediciTreasury.buybackChunk().gross (src/MediciTreasury.sol#500) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MediciHook.sol:260: MediciHook.cumulativeAt(uint64).low (src/MediciHook.sol#260) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MediciTreasury.sol:286: MediciTreasury.settle(uint256).best (src/MediciTreasury.sol#286) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MediciTreasury.sol:287: MediciTreasury.settle(uint256).runner (src/MediciTreasury.sol#287) is a local variable never initialized\n[medium/medium] unused-return at src/MediciHook.sol:216: MediciHook._redeem() (src/MediciHook.sol#216-225) ignores return value by poolManager.unlock(abi.encode(amount)) (src/MediciHook.sol#220)\n[medium/medium] unused-return at src/MediciTreasury.sol:570: MediciTreasury._harvest(address,uint64) (src/MediciTreasury.sol#570-577) ignores return value by (key,None,None,None) = ILaunchFees(factory).positionOf(number) (src/MediciTreasury.sol#571)\n[medium/medium] unused-return at src/MediciFeeRouter.sol:26: MediciFeeRouter.harvest() (src/MediciFeeRouter.sol#26-45) ignores return value by (key,None,None,requester) = factory.positionOf(launchNumber) (src/MediciFeeRouter.sol#28)\n[medium/medium] unused-return at src/MediciHook.sol:247: MediciHook._observe() (src/MediciHook.sol#247-256) ignores return value by (None,tick,None,None) = poolManager.getSlot0(key.toId()) (src/MediciHook.sol#248)\n[medium/medium] unused-return at src/MediciTreasury.sol:570: MediciTreasury._harvest(address,uint64) (src/MediciTreasury.sol#570-577) ignores return value by ILaunchFees(factory).claimFees(number) (src/MediciTreasury.sol#572)\n[medium/medium] unused-return at src/MediciTreasury.sol:536: MediciTreasury.unlockCallback(bytes) (src/MediciTreasury.sol#536-551) ignores return value by poolManager.settle{value: spent}() (src/MediciTreasury.sol#548)\n[medium/medium] unused-return at src/MediciTreasury.sol:428: MediciTreasury._positionAt(address,uint64) (src/MediciTreasury.sol#428-437) ignores return value by (key,requester) = ILaunchFees(factory).positionOf(number) (src/MediciTreasury.sol#429-435)\n[medium/medium] unused-return at src/MediciFeeRouter.sol:26: MediciFeeRouter.harvest() (src/MediciFeeRouter.sol#26-45) ignores return value by factory.claimFees(launchNumber) (src/MediciFeeRouter.sol#34)\n[medium/high] write-after-write at src/MediciTreasury.sol:97: MediciTreasury.swapping (src/MediciTreasury.sol#97) is written in both\n[low/medium] reentrancy-benign at src/MediciTreasury.sol:324: Reentrancy in MediciTreasury.commission(uint256,bytes) (src/MediciTreasury.sol#324-351):\n[low/medium] reentrancy-benign at src/MediciTreasury.sol:508: Reentrancy in MediciTreasury.buyback() (src/MediciTreasury.sol#508-527):\n[low/medium] reentrancy-benign at src/MediciTreasury.sol:570: Reentrancy in MediciTreasury._harvest(address,uint64) (src/MediciTreasury.sol#570-577):\n[low/medium] reentrancy-benign at src/MediciHook.sol:235: Reentrancy in MediciHook.claimTeam() (src/MediciHook.sol#235-245):\n[low/medium] reentrancy-benign at src/MediciHook.sol:216: Reentrancy in MediciHook._redeem() (src/MediciHook.sol#216-225):\n[low/medium] reentrancy-benign at src/MediciTreasury.sol:529: Reentrancy in MediciTreasury._swap(PoolKey,int256,uint256,uint256) (src/MediciTreasury.sol#529-534):\n[low/medium] reentrancy-events at src/MediciHook.sol:190: Reentrancy in MediciHook._charge(uint256,uint256,bool) (src/MediciHook.sol#190-200):\n[low/medium] reentrancy-events at src/MediciHook.sol:107: Reentrancy in MediciHook.beforeSwap(address,PoolKey,SwapParams,bytes) (src/MediciHook.sol#107-152):\n[low/medium] reentrancy-events at src/MediciHook.sol:202: Reentrancy in MediciHook._payTreasury() (src/MediciHook.sol#202-210):\n[low/medium] timestamp at src/MediciTreasury.sol:324: MediciTreasury.commission(uint256,bytes) (src/MediciTreasury.sol#324-351) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:353: MediciTreasury._consume(bytes32) (src/MediciTreasury.sol#353-360) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:258: MediciHook.cumulativeAt(uint64) (src/MediciHook.sol#258-269) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:170: MediciTreasury.price() (src/MediciTreasury.sol#170-177) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:202: MediciHook._payTreasury() (src/MediciHook.sol#202-210) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:190: MediciHook._charge(uint256,uint256,bool) (src/MediciHook.sol#190-200) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:281: MediciTreasury.settle(uint256) (src/MediciTreasury.sol#281-305) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:107: MediciHook.beforeSwap(address,PoolKey,SwapParams,bytes) (src/MediciHook.sol#107-152) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:77: MediciHook.beforeInitialize(address,PoolKey,uint160) (src/MediciHook.sol#77-93) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:202: MediciTreasury.vote(uint256,uint256,uint256) (src/MediciTreasury.sol#202-206) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:95: MediciHook.buyFeeBps() (src/MediciHook.sol#95-98) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:152: MediciTreasury.proposeDeadline(uint256) (src/MediciTreasury.sol#152-156) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:158: MediciTreasury.epochEnd(uint256) (src/MediciTreasury.sol#158-161) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:508: MediciTreasury.buyback() (src/MediciTreasury.sol#508-527) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:406: MediciTreasury.skip(uint256,string) (src/MediciTreasury.sol#406-410) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:439: MediciTreasury.recordCommission(uint256,uint64,string) (src/MediciTreasury.sol#439-464) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:400: MediciTreasury.lapse(uint256) (src/MediciTreasury.sol#400-404) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:208: MediciTreasury._vote(uint256,uint256,uint256) (src/MediciTreasury.sol#208-222) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:100: MediciHook._checkPool(PoolKey) (src/MediciHook.sol#100-102) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:161: MediciHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MediciHook.sol#161-188) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:163: MediciTreasury.currentEpoch() (src/MediciTreasury.sol#163-168) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciHook.sol:247: MediciHook._observe() (src/MediciHook.sol#247-256) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:188: MediciTreasury.propose(string,bytes) (src/MediciTreasury.sol#188-200) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:553: MediciTreasury.keeperWithdraw(uint256) (src/MediciTreasury.sol#553-560) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:466: MediciTreasury.claimable(uint256,address) (src/MediciTreasury.sol#466-471) uses timestamp for comparisons\n[low/medium] timestamp at src/MediciTreasury.sol:484: MediciTreasury.burnUnclaimed(uint256) (src/MediciTreasury.sol#484-493) uses timestamp for comparisons","passed":true},{"durationMs":783,"exitCode":0,"name":"aderyn","output":"[high] eth-send-unchecked-address at src/MediciHook.sol:212: ETH transferred without address checks (2 places)\n[high] reentrancy-state-change at src/MediciTreasury.sol:285: Reentrancy: State change after external call (6 places)\n[high] unsafe-casting at src/MediciHook.sol:278: Unsafe Casting of integers\n[low] costly-loop at src/MediciTreasury.sol:514: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:24: Internal Function Used Only Once\n[low] large-numeric-literal at src/MediciHook.sol:127: Large Numeric Literal (12 places)\n[low] literal-instead-of-constant at src/MediciHook.sol:97: Literal Instead of Constant (34 places)\n[low] local-variable-shadowing at src/MediciTreasury.sol:64: Local Variable Shadows State Variable\n[low] non-reentrant-not-first at src/MediciTreasury.sol:406: `nonReentrant` is Not the First Modifier (3 places)\n[low] storage-array-length-not-cached at src/MediciTreasury.sol:501: Storage Array Length not Cached\n[low] unchecked-return at src/MediciFeeRouter.sol:34: Unchecked Return (4 places)\n[low] uninitialized-local-variable at src/MediciTreasury.sol:182: Uninitialized Local Variable","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"24e8c6cf0168ff2e3fde5b8db7f65c2f7681acbb21ccb5a40d321908e6452d91","verifiedTreeHash":"d857b815c37ee770ba547d93fe1ea2aeaaf5c182","verifierVersion":"0.1.0+aca6c688"}]}