{"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":"1929103c-cbed-4f97-9439-bb0bb3e40edb","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"ef386ded787f31a39ca3c0c85169c52a9552c2f2fa173cb415cad5a20b567b17","dependsOn":["audit_imported_code"],"execution":{"mustProduce":["src/LaunchToken.sol"],"network":false,"profile":"foundry","requires":[],"skillHash":"a2cea02e8b33e91eeb784e0e5eaeb571cd62cd69e768d335d5834e24b3aa46e5","skillId":"adapt-contract-project","tools":[]},"key":"adapt_contract_project","kind":"code","role":"implement","skillHash":"a2cea02e8b33e91eeb784e0e5eaeb571cd62cd69e768d335d5834e24b3aa46e5","skillId":"adapt-contract-project","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_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":["adapt_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":"a79b4f30e36f7f687d33dca9fef6f4e7db76f04a635839a829ad0ac35e5804d6","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_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":["adapt_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":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":null,"dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"working"}],"objective":"Deploy TONOFHACKATHONS ($HACK) from this repository as already built and audited (IMD launch 1032, job e1bcd0e4). It is a univ4_hook launch on Ethereum mainnet, paired with IMD 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, exactly as launch.json and docs/launch-request.json state. The previous run passed build, tests, the audit panel and the judge, and failed only because that request was paired with ETH. Do not redesign or add features. Change code only to fix a real finding from the import audit or panel, keeping the pool paired with IMD and launch.json as is.","parentJobId":null,"planHash":"8fa9166bf3822dbc4800a9ee6f81c26f5f016f6ba09283db9006ce4a16613b8a","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"1929103c-cbed-4f97-9439-bb0bb3e40edb","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1044-deploy-tonofhackathons-hack-repository"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51125","feedbackHash":"38aadcfaa474bcfda976c2985cf2d24b20a9bd918977648e9f378c30ddeee1f9","nodeKey":"adapt_contract_project","submissionHash":"ef386ded787f31a39ca3c0c85169c52a9552c2f2fa173cb415cad5a20b567b17","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52021","feedbackHash":"be27c404a99ea829f6eb88c2723f21203a93985422e30321a923119aff4bd9b8","nodeKey":"audit_imported_code","submissionHash":"a79b4f30e36f7f687d33dca9fef6f4e7db76f04a635839a829ad0ac35e5804d6","tag1":"review:submission","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"fc34f72db1388a3aec82a9bcdafa58b3a2c4836aeb28cda019c3e247d8d5a5ac","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"229c8cb0d9067fbe","findings":[{"citation":"resolved","description":"The constructor has no separate paying-wallet argument: the second constructor argument is used both as `owner` (setQuestionHash once, setEntryFee, setWinnerBps, setPanelFloors, pauseEntries, signer/domain rotation, deny list) and as `payingWallet`, the address `_eligible` permanently excludes from registering or winning. launch.json passes `$owner` for that slot and the launch references say `$owner` resolves from the launch policy, not from the request. The policy snapshot committed in this repository (docs/policy-snapshot.json, policy 34) names `owners.hookAdmin = 0xcecc29b037f5064fcdf45a5c318f132ef76aa551` (an EOA on mainnet as of this review; the same address is also the policy's token/treasury/lpPosition owner), while the README and the code comment assume `$owner` is the wallet that paid for the launch. If those differ: (1) the real paying wallet can register and win prizes, voiding the documented exclusion; (2) every owner power sits with 0xcecc..., and in particular `setQuestionHash` must be called once by that address before any `submitResult` can succeed, so if 0xcecc... is not operated by the requester the machine cannot settle any round and every pot rolls forever (there is no withdrawal path). This could not be verified from the repository: the resolution of `$owner` happens in the launch service. Suggested handling: confirm what `$owner` resolves to for this launch before deployment; if it is not the paying wallet, either have the service resolve it to the paying wallet or accept and document that the exclusion does not apply and that 0xcecc... must perform the question pin. A code-level fix (a distinct `payingWallet_` constructor argument) would change the constructor ABI and launch.json, which this task keeps as is, so it is not recommended here.","line":161,"path":"src/HackathonMachine.sol","reproduction":"State: deploy HackathonMachine with owner_ = 0xcecc29b037f5064fcdf45a5c318f132ef76aa551 (the policy hookAdmin) while the wallet that paid for the launch is W != 0xcecc.... Calls: (a) anyone calls register(\"Payer project\", \"https://github.com/payer/repo\", \"\", W, address(0)) -> succeeds and entries[id].payout == W, and a later attestation naming that id settles with lastWonRound[W] set and a stream paying W; expected per README: Ineligible because the paying wallet is excluded. (b) W calls setQuestionHash(h) -> reverts Unauthorized; only 0xcecc... can pin, and until it does submitResult reverts InvalidResult (questionHash == 0). Verified locally with a scratch test deploying the hook with owner_ = 0xcecc... and registering payout W.","severity":"low","snippet":"        payingWallet = owner_; // This launch names no separate owner: $owner resolves to the paying wallet.","title":"payingWallet is taken from $owner; if $owner resolves to the policy hookAdmin the paying wallet is not excluded and owner powers (including the one-shot questionHash pin) belong to another address"},{"citation":"resolved","description":"`_recycle` moves `total - claimed` of a denied winner's stream back into the open pot. `claimed` only grows when someone calls `claim`, so the amount recycled includes IMD that had already vested but was not yet claimed. Because `queueDeny` is owner-only and delayed 48 hours with a public event, and because `claim` is permissionless (anyone can push vested funds to the winner during the delay), this is an intentional owner power rather than a permission bypass, and it is described in the README. It is recorded here because it is the one place where IMD that the contract's own vesting schedule already attributes to a winner can be redirected. A design-preserving softening, if the requester wants it, is to pay `vested - claimed` to the payout inside `_recycle` before recycling only the unvested remainder; that keeps the deny list and its delay unchanged. No change is required for correctness.","line":563,"path":"src/HackathonMachine.sol","reproduction":"State: a 792 IMD stream for payout P starts at t0 (pot 1000 IMD, no token). The owner calls queueDeny(P) at t0 + 7 days; isDenied(P) becomes true at t0 + 9 days. Nobody calls claim(id) before that. At t0 + 9 days, vested = 792 * 9 / 28 = 254.57 IMD and claimed = 0. Call: claim(id) (anyone) -> returns 0, emits StreamRecycled(id, 792e18), openPot += 792e18, streamLiability -= 792e18; P receives nothing, including the 254.57 IMD already vested. If P had claimed at t0 + 7 days it would have received 198 IMD and 594 IMD would be recycled instead.","severity":"info","snippet":"        uint256 unpaid = s.total - s.claimed;","title":"Deny list recycles vested-but-unclaimed prize IMD, not only unvested amounts (intentional per README; documented as a trust assumption)"},{"citation":"resolved","description":"`_isPair` accepts IMD on either side of the key. launch.json's initialPrice 125270724187523965593206900 (sqrtPriceX96) encodes 1e9 HACK = 2,500 IMD only when HACK is currency0, i.e. when the CREATE2-derived HACK address is numerically below 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7. With the opposite ordering the same number prices 1 HACK at about 400,000 IMD, and the hook cannot tell. The launch reference states the deployer derives the effective opening price from the policy's 2,500 IMD cap for the actual pair, in which case this is moot, but that derivation could not be verified from the repository. No code change is recommended: enforcing an ordering in `beforeInitialize` would make the launch transaction revert whenever the mined token address sorts above IMD. The deployer should confirm the predicted token address, the resulting currency order and the opening price before broadcasting (test/Revision.t.sol:254 shows the hook accepting the inverted key at the manifest price).","line":198,"path":"src/HackathonMachine.sol","reproduction":"State: HACK deployed at an address > 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, so key = (currency0 = IMD, currency1 = HACK, 12500, 60, hook). Call: factory -> PoolManager.initialize(key, 125270724187523965593206900). Result: beforeInitialize returns its selector, initialized = true, the pool opens at price(HACK per IMD) = 2.5e-6, i.e. 1 HACK = 400,000 IMD instead of 1e9 HACK = 2,500 IMD. Expected: either the price for that ordering (sqrtPriceX96 = floor(2^96 * sqrt(400000)) = 50108289675009586237282760313921) or a revert.","severity":"info","snippet":"            initialized || sender != factory || address(key.hooks) != address(this) || !_isPair(key, launchToken)","title":"beforeInitialize accepts either currency ordering, so an opening price derived for HACK-as-currency0 would be silently inverted if the deployed HACK address sorts above IMD and the manifest price is u"},{"citation":"resolved","description":"Every fixture passes the same `owner` address as both the owner and the excluded paying wallet, so the suite cannot observe the finding above. The purchase tests cover empty, partial, false-returning and reentering prize tokens and hookless pools, but no test puts a hook with beforeSwap/afterSwap flags on the entrant's pool, and none exhausts the 500,000 gas purchase budget. These edges were checked during this review with a scratch suite (not kept): a hook that re-enters claim/fundRound/redeemFeeClaims, swaps on the launch pool, calls PoolManager.take(IMD, attacker, 50 IMD) or loops forever, and a token whose transfer burns about 1M gas. All attempts were refused by the reentrancy guard or ended in the documented stream fallback with accounting intact (stream totals 693.8316 IMD when the purchase still succeeded, 792.9504 IMD when it fell back, for a 1001.2 IMD pot). Adding those cases to the kept suite would stop them from regressing silently.","line":57,"path":"test/MachineFixture.sol","reproduction":"Edge 1: deploy with owner_ = A and register payout = B where B paid for the launch; the kept suite has no such case. Edge 2: PoolKey(prize, IMD, 3000, 60, hook with flags 0x00c0) whose beforeSwap calls PoolManager.take(IMD, attacker, 50e18) during submitResult; expected and observed: BuySkipped, stream += 10% allocation, attacker balance unchanged. Edge 3: prize token whose transfer loops 1,000,000 iterations; expected and observed: BuySkipped and stream of 792 IMD for a 1000 IMD pot.","severity":"info","snippet":"                IPoolManager(address(manager)), owner, address(this), address(hack), address(imd), vm.addr(SIGNER_KEY)","title":"Test suite never exercises owner != paying wallet, a hostile hook on the entrant's purchase pool, or a gas-exhausting prize token"},{"citation":"resolved","description":"Read in full: src/HackToken.sol, src/HackathonMachine.sol, src/OracleAttestation.sol, src/HookFlags.sol (unused by production code), every file under test/, launch.json, docs/*, and the vendored v4-core paths the hook depends on (PoolManager, Hooks, Pool.swap, BeforeSwapDelta, TransientStateLibrary, StateLibrary, Lock, CurrencyReserves, ERC6909Claims, SafeCast). Reached over the network (public RPC, read-only): the IMD token at 0xd34a99bc...e263b7 is a 22,990-byte non-proxy LayerZero OFT ERC20 (name Identity.md, 18 decimals, about 4.138M supply, no pause/blacklist/fee selectors in its dispatcher), the attester 0x5598aa...2982 and the policy owner 0xcecc...a551 are EOAs, and the PoolManager at 0x000000000004444c5dc75cB358380D2e3dE08A90 contains the transient Lock/CurrencyReserves slot constants the hook reads, so isUnlocked and getSlot0 work against the deployed manager. Not reachable: the launch factory and its initialize path (beforeInitialize requires PoolManager.initialize to be called with msg.sender == $factory; a factory that initializes through periphery would make the launch revert, safely), the resolution of $poolManager/$owner/$factory, and the oracle's canonical questionHash. Compiled artifacts: hook runtime 23,221 bytes, token 1,502 bytes, no DELEGATECALL/CALLCODE/SELFDESTRUCT; full suite passes (90 tests including both invariant campaigns). No minting, proxy, initializer, holder-balance pause or token blacklist exists; pauseEntries only stops new registrations. Privileged powers, all bounded and documented, that holders must trust: the attester key (an EOA; a compromise settles pots to an attacker's entry for up to 7 days because rotation is delayed and there is no emergency stop; the owner can limit loss to the keeper reward, 48 hours of vesting and the 10% purchase by queueing a deny), the owner's ability to stall settlement by raising panel floors or to censor a payout after 48 hours, first-valid-attestation-wins settlement when independently purchased panels disagree, and keeper timing of the winner-token purchase within the entrant's own floor.","line":23,"path":"src/HackathonMachine.sol","reproduction":"Not a defect; see the reachability list in the description. Concrete states checked: 90 kept tests pass; scratch probes (hostile hook modes 1-4, gas-burning token, owner != payer) behave as described in the other entries.","severity":"info","snippet":"contract HackathonMachine is OracleAttestationConsumer, ReentrancyGuard {","title":"Review coverage, external contracts reached, and the privileged powers this launch relies on"}],"hash":"a79b4f30e36f7f687d33dca9fef6f4e7db76f04a635839a829ad0ac35e5804d6","nodeId":"2c471d5f-27e5-4d3e-9bd5-b7b1bb8a742f","outcome":"completed","summary":"The findings file is in place at the repository root (the harness's own exclude rule keeps it out of git, which is expected), and the scratch tests live only under the ignored `test/scratch/`. The review is complete.\n\n## Outcome\n\nNo critical, high or medium defect was found. The `.imd-findings.json` file holds one low finding and four informational entries. The full kept suite passes on the code as it is (90 tests, including both invariant campaigns), the hook runtime is 23,221 bytes, the token 1,502 bytes, and neither contains DELEGATECALL, CALLCODE or SELFDESTRUCT.\n\n**Contracts read in full:** `src/HackToken.sol`, `src/HackathonMachine.sol`, `src/OracleAttestation.sol`, `src/HookFlags.sol` (unused by production code), every test under `test/`, `launch.json`, `docs/*`, and the vendored v4-core paths the hook depends on (PoolManager, Hooks, Pool.swap, BeforeSwapDelta, transient-state and state libraries, Lock, CurrencyReserves, ERC6909Claims, SafeCast).\n\n**Reached over the network (read-only public RPC):** the mainnet IMD token is a non-proxy LayerZero OFT ERC20 with 18 decimals and no pause, blacklist or fee selectors; the attester and the policy owner are EOAs; the deployed PoolManager contains the transient slot constants the hook reads, so its unlock check and `getSlot0` work against mainnet.\n\n**Not reachable:** the launch factory and how it calls `initialize` (the hook requires the factory itself to be `msg.sender`, otherwise the launch reverts safely), the resolution of the `$poolManager`, `$owner` and `$factory` placeholders, and the oracle's canonical question hash.\n\n## Findings\n\n- **Low. `payingWallet` is taken from `$owner`** (`src/HackathonMachine.sol:161`). The repository's own policy snapshot names `hookAdmin = 0xcecc…a551` while the README assumes `$owner` is the paying wallet. If they differ, the paying wallet can register and win, and every owner power sits with `0xcecc…`, including the one-shot question pin without which no round can ever settle. The resolution could not be verified here. No code change is recommended because a separate constructor argument would alter the manifest.\n- **Info. Deny list recycles vested-but-unclaimed prize IMD**, not only unvested amounts. Intentional per the README and delayed 48 hours, so it is recorded as a trust assumption with a design-preserving softening if the requester wants one.\n- **Info. `beforeInitialize` accepts either currency ordering**, so the manifest's opening price is only right when the mined HACK address sorts below IMD. The deployer should confirm the predicted ordering and price; enforcing it on-chain would make the launch revert in the other case.\n- **Info. Untested edges:** owner distinct from paying wallet, a hostile hook on the entrant's purchase pool, and a gas-exhausting prize token. I checked all three with scratch tests. Every hostile attempt was refused by the reentrancy guard or ended in the documented stream fallback with accounting intact.\n- **Info. Coverage and privileged powers** holders must trust: the attester key (an EOA, with a 7-day rotation delay and no emergency stop), the owner's ability to stall settlement through panel floors or censor a payout after 48 hours, first-valid-attestation-wins settlement, and keeper timing of the winner purchase within the entrant's floor.\n\n## What the adapter should do\n\nNothing in the Solidity needs changing for this launch. Before deployment the service should confirm what `$owner` resolves to, and that the factory calls `PoolManager.initialize` directly with the HACK/IMD key at fee 12500 and spacing 60, since the hook refuses anything else.","treeHash":null,"usage":{"cachedInputTokens":5327051,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":98312,"runtime":"claude","turns":53,"wallClockMs":1771076}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"73d25b5e0857cef5","findings":[],"hash":"e2197064438e69c4aa0c65429dcea1fed30aa4e7ceab2f30ebc8bba2acdf84e0","nodeId":"68a0c5d4-e3a6-4b17-9461-b58caafcb2c0","outcome":"failed","summary":"needs input: The brief requires preserving the accepted univ4_hook IMD/HACK launch and also requires an evm_project manifest paired only with native ETH at fee 500, 3000, or 10000. These requirements conflict. The existing launch.json and docs/launch-request.json select univ4_hook and IMD (0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7). HackathonMachine.beforeInitialize requires that IMD/HACK pair, fee 12500, tickSpacing 60, and HackathonMachine itself as the pool hook. The required evm_project format instead supplies an initialization-only guard and does not support the accepted $poolManager and $factory references. No manifest-only change can satisfy both specifications while preserving the accepted implementation. The requester must resolve the launch kind, pairing, and fee conflict. — Which launch specification is authoritative for this assignment: the accepted univ4_hook IMD/HACK launch with fee 12500, or the incompatible evm_project ETH-only requirements?","treeHash":null,"usage":{"cachedInputTokens":909696,"inputTokens":48604,"model":"gpt-6-astra","outputTokens":6550,"runtime":"codex","turns":6,"wallClockMs":374122}},{"artifacts":[],"attempt":1,"bundleHash":"676db28c5a76c53b80d8ced32b671d23834b22937247f14c965ab35cf694328c","device":"42dc54b22317eb81","findings":[],"hash":"ef386ded787f31a39ca3c0c85169c52a9552c2f2fa173cb415cad5a20b567b17","nodeId":"fe312a02-60d9-4a5a-86e4-a4a4d0909933","outcome":"completed","summary":"Added `src/LaunchToken.sol` using the existing `HackToken` implementation; creation and runtime bytecode match exactly. Added regression tests and updated `ADAPTATION.md`.\n\nIMD pairing, `launch.json`, existing contracts, configuration, and dependencies remain unchanged.\n\n`forge build` passed. `forge test`: **102 passed, 0 failed, 0 skipped**.","treeHash":"c859a0c8c3b1e205bc2aa951dadf9dded02bfbeb","usage":{"cachedInputTokens":2653184,"inputTokens":144518,"model":"gpt-6-astra","outputTokens":19987,"runtime":"codex","turns":11,"wallClockMs":1213814}}],"verification":[{"checks":[{"durationMs":83362,"exitCode":0,"name":"build","output":"Compiling 118 files with Solc 0.8.26\nSolc 0.8.26 finished in 83.16s\nCompiler run successful!\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/HackathonMachine.sol:194:9\n    │\n194 │         nonReentrant\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/HackathonMachine.sol:219:73\n    │\n219 │         return (IHooks.beforeSwap.selector, toBeforeSwapDelta(_asInt128(fee), 0), 0);\n    │                                                                         ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/HackathonMachine.sol:210:9\n    │\n210 │         nonReentrant\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/HackathonMachine.sol:225:9\n    │\n225 │         nonReentrant\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:233:56\n    │\n233 │             int256 expected = params.amountSpecified + int256(_specifiedFee(params.amountSpecified));\n    │                                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:237:41\n    │\n237 │         uint256 amount = imdDelta < 0 ? uint256(-int256(imdDelta)) : uint256(int256(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:237:70\n    │\n237 │         uint256 amount = imdDelta < 0 ? uint256(-int256(imdDelta)) : uint256(int256(imdDelta));\n    │                                                                      ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:245:26\n    │\n245 │         uint256 amount = uint256(specified < 0 ? -specified : specified);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:246:22\n    │\n246 │         if (amount > uint256(uint128(type(int128).max))) revert InvalidInput();\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:246:30\n    │\n246 │         if (amount > uint256(uint128(type(int128).max))) revert InvalidInput();\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:266:9\n    │\n266 │         emit FeeCollected(accountingRound, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HackathonMachine.sol:270:16\n    │\n270 │         return block.timestamp < MONDAY_EPOCH ? 0 : uint64((block.timestamp - MONDAY_EPOCH) / WEEK);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:270:53\n    │\n270 │         return block.timestamp < MONDAY_EPOCH ? 0 : uint64((block.timestamp - MONDAY_EPOCH) / WEEK);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/HackathonMachine.sol:459:33\n    │\n459 │         streamed += buyAmount - bought;\n    │                                 ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:456:17\n    │\n456 │                 emit BuySkipped(id);\n    │                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:462:9\n    │\n462 │         emit ResultSettled(round, id, a.requestId, msg.sender, reward, streamed, bought, carried);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:460:40\n    │\n460 │         streams[id] = Stream(e.payout, uint64(block.timestamp), denyGeneration[e.payout], streamed, 0);\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:497:13\n    │\n497 │             emit ClaimsRedeemed(amount);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:525:13\n    │\n525 │             emit FeeCollected(accountingRound, ownFee);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:532:9\n    │\n532 │         emit TokenBought(id, spend, uint256(uint128(output)));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:518:66\n    │\n518 │             poolManager.swap(key, SwapParams(zeroForOne, -int256(uint256(uint128(_asInt128(spend)))), limit), \"\");\n    │                                                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:518:74\n    │\n518 │             poolManager.swap(key, SwapParams(zeroForOne, -int256(uint256(uint128(_asInt128(spend)))), limit), \"\");\n    │                                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:521:31\n    │\n521 │         if (int256(input) != -int256(spend) || output <= 0 || uint256(uint128(output)) < minimum) revert Slippage();\n    │                               ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:521:63\n    │\n521 │         if (int256(input) != -int256(spend) || output <= 0 || uint256(uint128(output)) < minimum) revert Slippage();\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:521:71\n    │\n521 │         if (int256(input) != -int256(spend) || output <= 0 || uint256(uint128(output)) < minimum) revert Slippage();\n    │                                                                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:531:60\n    │\n531 │         poolManager.take(Currency.wrap(e.token), e.payout, uint256(uint128(output)));\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:531:68\n    │\n531 │         poolManager.take(Currency.wrap(e.token), e.payout, uint256(uint128(output)));\n    │                                                                    ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:532:37\n    │\n532 │         emit TokenBought(id, spend, uint256(uint128(output)));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:532:45\n    │\n532 │         emit TokenBought(id, spend, uint256(uint128(output)));\n    │                                             ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HackathonMachine.sol:543:26\n    │\n543 │         uint256 vested = elapsed >= STREAM_DURATION ? s.total : FullMath.mulDiv(s.total, elapsed, STREAM_DURATION);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/HackathonMachine.sol:548:9\n    │\n548 │         emit Claimed(id, s.payout, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:577:22\n    │\n577 │         if (amount > uint256(uint128(type(int128).max))) revert InvalidInput();\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:577:30\n    │\n577 │         if (amount > uint256(uint128(type(int128).max))) revert InvalidInput();\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:578:16\n    │\n578 │         return int128(uint128(amount));\n    │                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:578:23\n    │\n578 │         return int128(uint128(amount));\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:620:25\n    │\n620 │         signerReadyAt = uint64(block.timestamp + ORACLE_DELAY);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HackathonMachine.sol:632:13\n    │\n632 │         if (block.timestamp < signerReadyAt) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:642:26\n    │\n642 │         versionReadyAt = uint64(block.timestamp + ORACLE_DELAY);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HackathonMachine.sol:654:13\n    │\n654 │         if (block.timestamp < versionReadyAt) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/HackathonMachine.sol:693:39\n    │\n693 │         return denyAt[payout] != 0 && block.timestamp >= denyAt[payout];\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/HackathonMachine.sol:698:26\n    │\n698 │         denyAt[payout] = uint64(block.timestamp + DENY_DELAY);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.revertToState`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AdversarialMachine.t.sol:254:20\n    │\n254 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.revertToState`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AdversarialMachine.t.sol:254:20\n    │\n254 │         assertTrue(vm.revertToState(snapshot));\n    │                    ────────────────────────── `vm.revertToState` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AdversarialMachine.t.sol:302:13\n    │\n302 │             vm.warp(start + 28 days);\n    │             ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AdversarialMachine.t.sol:302:13\n    │\n302 │             vm.warp(start + 28 days);\n    │             ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AdversarialMachine.t.sol:341:9\n    │\n341 │         vm.warp(vm.getBlockTimestamp() + 7 days);\n    │         ──────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AdversarialMachine.t.sol:341:9\n    │\n341 │         vm.warp(vm.getBlockTimestamp() + 7 days);\n    │         ──────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Attestation.t.sol:87:26\n   │\n87 │         uint256 queued = block.timestamp;\n   │                          ━━━━━━━━━━━━━━━\n   ‡\n90 │         vm.warp(queued + elapsed);\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Attestation.t.sol:114:9\n    │\n114 │         vm.warp(block.timestamp + 7 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Attestation.t.sol:114:9\n    │\n114 │         vm.warp(block.timestamp + 7 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Attestation.t.sol:114:17\n    │\n114 │         vm.warp(block.timestamp + 7 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Attestation.t.sol:120:17\n    │\n120 │         vm.warp(block.timestamp + 6 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Attestation.t.sol:135:9\n    │\n135 │         vm.warp(block.timestamp + 7 days - 1);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Attestation.t.sol:135:9\n    │\n135 │         vm.warp(block.timestamp + 7 days - 1);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Attestation.t.sol:135:17\n    │\n135 │         vm.warp(block.timestamp + 7 days - 1);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Attestation.t.sol:141:17\n    │\n141 │         vm.warp(block.timestamp + 1);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Attestation.t.sol:163:17\n    │\n163 │         vm.warp(block.timestamp + 7 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n 98 │         vm.warp(machine.roundClose(machine.currentRound()) + 1 hours);\n    │         ───────────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    ‡\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n 98 │         vm.warp(machine.roundClose(machine.currentRound()) + 1 hours);\n    │         ───────────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    ‡\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Machine.t.sol:231:17\n    │\n231 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:116:30\n    │\n116 │             issuedAt: uint64(block.timestamp),\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Revision.t.sol:22:9\n    │\n 22 │         vm.warp(block.timestamp + 1);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/MachineFixture.sol:117:31\n    │\n117 │             expiresAt: uint64(block.timestamp + 6 days)\n    │                               ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Revision.t.sol:22:9\n    │\n 22 │         vm.warp(block.timestamp + 1);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Revision.t.sol:22:17\n   │\n22 │         vm.warp(block.timestamp + 1);\n   │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":5063,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/Token.t.sol:TokenTest\n[PASS] test_fixedSupplyMetadataAndTransfer() (gas: 234376)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 494.91µs (365.77µs CPU time)\n\nRan 2 tests for test/LaunchToken.t.sol:LaunchTokenTest\n[PASS] test_factoryReceivesFixedSupplyAndTransfersExactAmount() (gas: 305379)\n[PASS] test_runtimeMatchesExistingManifestToken() (gas: 6854)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 496.66µs (629.70µs CPU time)\n\nRan 1 test for test/LaunchPurchase.t.sol:LaunchPurchaseTest\n[PASS] test_winnerTokenPurchaseExecutesForOrdinaryPot() (gas: 1005203)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.03ms (576.24µs CPU time)\n\nRan 4 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_acceptsExactProtocolSignature() (gas: 23346)\n[PASS] test_digestMatchesTheProtocol() (gas: 16335)\n[PASS] test_freshVectorKeySignatureSettlesBytes32Entry() (gas: 649612)\n[PASS] test_submitSelectorUsesAllFifteenCanonicalFields() (gas: 3450)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 4.17ms (1.57ms CPU time)\n\nRan 7 tests for test/Attestation.t.sol:AttestationTest\n[PASS] testFuzz_queuedSignerHasNoEffectBeforeSevenDays(uint32) (runs: 256, μ: 192134, ~: 192058)\nLogs:\n  Bound result 63\n\n[PASS] test_domainVersionChangesOnlyAfterSevenDaysAndCanCancel() (gas: 609940)\n[PASS] test_forgedTamperedWrongDomainAndExpiredFail() (gas: 732263)\n[PASS] test_oldKeyAndOldDomainCannotSettleAfterRotation() (gas: 972422)\n[PASS] test_signedButWrongQuestionTypePanelChainTimeOrEntryFail() (gas: 1655446)\n[PASS] test_signerCancellationRequeueAndSignatures() (gas: 779858)\n[PASS] test_unsetQuestionFailsAndCanOnlyBePinnedOnce() (gas: 660674)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 18.56ms (22.05ms CPU time)\n\nRan 9 tests for test/ImportedAudit.t.sol:ImportedAuditTest\n[PASS] test_effectiveDenyRecyclesVestedButUnclaimedAmounts() (gas: 958675)\n[PASS] test_gasExhaustingPrizeTokenFallsBack() (gas: 2519808)\n[PASS] test_gasExhaustingPurchaseHookFallsBack() (gas: 2932290)\n[PASS] test_ownerArgumentAloneControlsExclusionAndQuestionPin() (gas: 1387525)\n[PASS] test_purchaseHookCannotReenterAfterSwap() (gas: 2640446)\n[PASS] test_purchaseHookCannotReenterBeforeSwap() (gas: 2640324)\n[PASS] test_purchaseHookCannotStealIMDAfterSwap() (gas: 2660816)\n[PASS] test_purchaseHookCannotStealIMDBeforeSwap() (gas: 2660666)\n[PASS] test_purchaseHookCannotSwapOnLaunchPool() (gas: 3041569)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 80.28ms (16.75ms CPU time)\n\nRan 1 test for test/FactoryDeployment.t.sol:FactoryDeploymentTest\n[PASS] test_factoryExecutesUnchangedConstructorsAndPreservesSupply() (gas: 35883630)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 85.88ms (84.61ms CPU time)\n\nRan 8 tests for test/Hook.t.sol:HookTest\n[PASS] testFuzz_fourSwapModesCollectOnlyIMD(bool,bool,uint96) (runs: 256, μ: 909571, ~: 911504)\nLogs:\n  Bound result 999278315616700823565\n\n[PASS] test_everyCallbackAuthenticatesManager() (gas: 176764)\n[PASS] test_freshManagerWithOnlyHackLiquidityCanBuy() (gas: 827775)\n[PASS] test_initializationAndPermissions() (gas: 145175)\n[PASS] test_onlyFactoryCanInitializeOnlyLaunchPair() (gas: 240465)\n[PASS] test_partialSellChargesExecutedOutput() (gas: 755864)\n[PASS] test_partialSpecifiedIMDSwapRevertsWithoutTakingFee() (gas: 869287)\n[PASS] test_unknownPoolAndForgedHookDataCannotStealApprovals() (gas: 743490)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 90.70ms (92.09ms CPU time)\n\nRan 7 tests for test/PrizeBuyAdversarial.t.sol:PrizeBuyAdversarialTest\n[PASS] test_emptyPoolFallsBackWithoutSpendingAnyIMD() (gas: 1308935)\n[PASS] test_impossibleOutputFloorRollsBackTheSwapAndItsTransfers() (gas: 1360854)\n[PASS] test_invalidBuyConfigurationsCannotReplaceTheEntrantsCommitment() (gas: 976661)\n[PASS] test_liquidityRemovedAfterConfigurationStillAllowsSettlement() (gas: 1646714)\n[PASS] test_partialBuyRevertsAllPoolEffectsBeforeFallingBack() (gas: 2239172)\n[PASS] test_prizeTokenCallbackCannotReenterOrClaimDuringSettlement() (gas: 2385453)\n[PASS] test_successfulExternalPoolBuySpendsOwnFundsAndPaysOnlyWinner() (gas: 1429129)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 95.07ms (8.58ms CPU time)\n\nRan 21 tests for test/Machine.t.sol:MachineTest\n[PASS] testFuzz_rewardMinimumAndAllocationConserve(uint96,uint16) (runs: 256, μ: 798774, ~: 798769)\nLogs:\n  Bound result 8007\n  Bound result 1263648860\n\n[PASS] test_adminCapsAndNoWithdrawal() (gas: 258967)\n[PASS] test_buyTokenAndFixedRecipient() (gas: 1484307)\n[PASS] test_denyDelayClaimsAndUnpaidRecycling() (gas: 1036957)\n[PASS] test_donationsDoNotIncreaseInternalPot() (gas: 90339)\n[PASS] test_entrySponsorAndWeekBoundary() (gas: 913913)\n[PASS] test_entryValidationAndCallerOnlyTransfers() (gas: 806766)\n[PASS] test_falseReturnAndReentrancyCannotChangeAccounting() (gas: 1431299)\n[PASS] test_falseReturnWinnerTokenFallsBackToStream() (gas: 2187588)\n[PASS] test_manySkippedWeeksRollWithoutLoops() (gas: 741620)\n[PASS] test_missingPoolConfigurationAddsBuyToStream() (gas: 751384)\n[PASS] test_pauseBlocksOnlyEntries() (gas: 879225)\n[PASS] test_pendingDenyCanBeCancelledAndDeniedWinnerCannotSettle() (gas: 544858)\n[PASS] test_poolConfigCannotBeChangedAfterCloseOrByOthers() (gas: 819153)\n[PASS] test_removingActiveDenyDoesNotRestoreUnpaidStream() (gas: 814109)\n[PASS] test_rolloverWholeAndStaleRoundCannotSettle() (gas: 1099730)\n[PASS] test_roundAndRequestCannotSettleTwice() (gas: 936927)\n[PASS] test_settlementStreamingKeeperAndCarry() (gas: 1292447)\n[PASS] test_slippageFailureAddsBuyToStream() (gas: 1417370)\n[PASS] test_smallPotRewardIsOnePercentBelowFive() (gas: 677898)\n[PASS] test_winnerCooldownFourRoundsAndEarlyEntryCannotBypass() (gas: 1444013)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 95.23ms (75.32ms CPU time)\n\nRan 8 tests for test/Hook.t.sol:ReverseOrderHookTest\n[PASS] testFuzz_fourSwapModesCollectOnlyIMD(bool,bool,uint96) (runs: 256, μ: 908560, ~: 906951)\nLogs:\n  Bound result 999000000002563714305\n\n[PASS] test_everyCallbackAuthenticatesManager() (gas: 176080)\n[PASS] test_freshManagerWithOnlyHackLiquidityCanBuy() (gas: 838781)\n[PASS] test_initializationAndPermissions() (gas: 144893)\n[PASS] test_onlyFactoryCanInitializeOnlyLaunchPair() (gas: 239445)\n[PASS] test_partialSellChargesExecutedOutput() (gas: 749961)\n[PASS] test_partialSpecifiedIMDSwapRevertsWithoutTakingFee() (gas: 868512)\n[PASS] test_unknownPoolAndForgedHookDataCannotStealApprovals() (gas: 748091)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 98.16ms (98.94ms CPU time)\n\nRan 12 tests for test/Revision.t.sol:RevisionTest\n[PASS] test_anyValidAttestationSettlesFirstComeFirstServed() (gas: 994388)\n[PASS] test_cappedRegistrationRejectsFeeIncreaseAndAcceptsBudget() (gas: 471880)\n[PASS] test_denyEffectiveBetweenCloseAndSubmitRollsRound() (gas: 627826)\n[PASS] test_invertedOrderingAcceptedAtManifestPrice() (gas: 483091)\n[PASS] test_nonOwnerCannotRaceSignerExecution() (gas: 817365)\n[PASS] test_nonOwnerCannotRaceVersionExecution() (gas: 762863)\n[PASS] test_onlyPayoutCanUpdateBeforeCloseAndMustReconfigureBuy() (gas: 1196996)\n[PASS] test_payoutCanRepairFrontRunRegistration() (gas: 833994)\n[PASS] test_submitInsideUnlockRevertsWithoutConsumingResult() (gas: 1575529)\n[PASS] test_submitterSandwichWithinFloor() (gas: 1707241)\nLogs:\n  HACK to winner after front-running buy: 49791227766071856375\n\n[PASS] test_updatedEntryUsesRegistrationValidation() (gas: 580438)\n[PASS] test_wrongPinnedHashCannotBeCorrected() (gas: 493709)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 98.49ms (9.00ms CPU time)\n\nRan 14 tests for test/AdversarialMachine.t.sol:AdversarialMachineTest\n[PASS] testFuzz_claimCadenceCannotCreateOrLosePrize(uint96,uint32,uint32) (runs: 1000, μ: 1113687, ~: 1116436)\nLogs:\n  Bound result 8051\n  Bound result 2\n  Bound result 240\n\n[PASS] testFuzz_everySignedFieldIsAuthenticated(uint8) (runs: 1000, μ: 952170, ~: 956275)\nLogs:\n  Bound result 8\n\n[PASS] test_adminRejectsInvalidOracleAndDenyConfiguration() (gas: 276028)\n[PASS] test_denyRevokesOnlyOldStreamsAndCannotReviveThemAfterRemoval() (gas: 1769859)\n[PASS] test_everyOwnerOperationRefusesAnUnrelatedCaller() (gas: 378583)\n[PASS] test_expiryBoundaryAndFutureTimestampTolerance() (gas: 1010864)\n[PASS] test_failedEntryAndSponsorTransfersRollBackRoundAdvance() (gas: 944897)\n[PASS] test_failedFeeRedemptionPreservesClaimsAndCanBeRetried() (gas: 1109172)\n[PASS] test_failedKeeperPaymentDoesNotConsumeRequestOrSettleRound() (gas: 1200246)\n[PASS] test_invalidEntriesAndZeroFundingLeaveNoGhostState() (gas: 292892)\n[PASS] test_keeperRewardEdgesConserveEvenWhenTheMinimumConsumesThePot() (gas: 5135727)\n[PASS] test_maximumMetadataIsMeasuredInBytesAndEntryPullsOnlyFromCaller() (gas: 668381)\n[PASS] test_signatureCannotCrossConsumersEvenWithIdenticalEntriesAndQuestion() (gas: 1267296)\n[PASS] test_signedInvalidBlockWindowAndOversizePanelAreRejectedAtomically() (gas: 1060332)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 98.62ms (201.15ms CPU time)\n\nRan 1 test for test/Invariant.t.sol:MachineInvariantTest\n[PASS]\nMachineInvariantTest invariants:\n[PASS] invariant_assetsEqualPotsAndUnpaidStreams\n[PASS] invariant_eachRoundSettlesAtMostOnceAndToItsWinner\n[PASS] invariant_forgedOrStaleAttestationsNeverSettle\n[PASS] invariant_onlyWinnersPoolsKeepersAndCarryReceivePot\n[PASS] invariant_queuedSignerHasNoEffectUntilExecutionAfterDelay\n MachineInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+--------------------------+-------+---------+----------╮\n| Contract       | Selector                 | Calls | Reverts | Discards |\n+========================================================================+\n| MachineHandler | advance                  | 804   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | claim                    | 796   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | executeSigner            | 844   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | fund                     | 772   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | queueSigner              | 873   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | redeem                   | 859   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | register                 | 754   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | rejectInvalidAttestation | 788   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | settle                   | 836   | 0       | 0        |\n|----------------+--------------------------+-------+---------+----------|\n| MachineHandler | trade                    | 866   | 0       | 0        |\n╰----------------+--------------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 9000000000001030954\n  Bound result 9000000001517015002\n  Bound result 123456\n  Bound result 3201303218\n  Bound result 237\n  Bound result 9000000000000015063\n  Bound result 5790\n  Bound result 48\n  Bound result 16384\n  Bound result 658618\n  Bound result 9000000000000001526\n  Bound result 9000000000000019774\n  Bound result 1363486403\n  Bound result 9000000000000020872\n  Bound result 514264337593543950333\n  Bound result 8887421013046764604\n  Bound result 12305\n  Bound result 1022583892\n  Bound result 103872\n  Bound result 10923\n  Bound result 24576\n  Bound result 8000\n  Bound result 12500\n  Bound result 420\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.36s (1.36s CPU time)\n\nRan 3 tests for test/TokenProperties.t.sol:TokenPropertiesTest\n[PASS] invariant_fixedSupplyBalancesAndAllowancesFollowERC20Operations() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------+--------------+-------+---------+----------╮\n| Contract             | Selector     | Calls | Reverts | Discards |\n+==================================================================+\n| TokenTransferHandler | approve      | 4091  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| TokenTransferHandler | overdraft    | 4095  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| TokenTransferHandler | transfer     | 4072  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| TokenTransferHandler | transferFrom | 4126  | 0       | 0        |\n╰----------------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 328\n  Bound result 202\n  Bound result 2002\n  Bound result 0\n  Bound result 0\n  Bound result 190968\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 758\n  Bound result 493\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 7254\n  Bound result 1405\n  Bound result 26\n  Bound result 47891\n  Bound result 0\n  Bound result 2249\n  Bound result 1533\n  Bound result 314\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 5166\n  Bound result 228\n  Bound result 1059\n  Bound result 1080\n  Bound result 52990\n  Bound result 4300\n  Bound result 6358\n  Bound result 0\n  Bound result 8356\n  Bound result 5073\n  Bound result 453\n  Bound result 999999999999999999999848498\n  Bound result 4857\n  Bound result 0\n\n[PASS] test_transferFailureRestoresTheAllowanceItWouldHaveSpent() (gas: 135850)\n[PASS] test_zeroTransferSelfTransferAndInfiniteApproval() (gas: 240814)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 2.21s (2.21s CPU time)\n\nRan 3 tests for test/CustodyInvariant.t.sol:CustodyInvariantTest\n[PASS]\nCustodyInvariantTest invariants:\n[PASS] invariant_domainVersionChangesOnlyOnAnExecutedMatureQueue\n[PASS] invariant_eachSettlementAndStreamRetainsItsOriginalRecipientAndLiability\n[PASS] invariant_internalAccountingExcludesUnsolicitedDonationsAndMatchesRealAssets\n[PASS] invariant_receivedFundsEqualAllRemainingObligationsAndActualPermittedOutflows\n CustodyInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| CustodyHandler | advance       | 1552  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | claim         | 1559  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | configure     | 1568  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | deny          | 1575  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | donate        | 1527  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | fund          | 1630  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | recycle       | 1593  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | redeem        | 1631  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | registerEntry | 1607  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | rejectResult  | 1536  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | rotateVersion | 1493  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | settle        | 1596  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| CustodyHandler | trade         | 1613  | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\nLogs:\n  Bound result 990000000000000000000\n  Bound result 604800\n  Bound result 604800\n  Bound result 17\n  Bound result 8791\n  Bound result 44\n  Bound result 19644939068787388474\n  Bound result 8097\n  Bound result 100\n  Bound result 17914\n  Bound result 2167\n  Bound result 113549766\n  Bound result 1075469243\n  Bound result 1359\n  Bound result 1103294676404703240\n  Bound result 13080\n  Bound result 3169\n  Bound result 7695\n  Bound result 20093\n  Bound result 12244\n  Bound result 14076\n  Bound result 5946\n  Bound result 5276\n  Bound result 2034284841709\n  Bound result 100\n  Bound result 22766\n\n[PASS] test_handlerExercisesDenyPauseDonationsAndVersionExecution() (gas: 1617267)\nLogs:\n  Bound result 990000000000000000000\n  Bound result 604800\n  Bound result 604800\n  Bound result 100000000000000000000\n  Bound result 490\n  Bound result 172800\n  Bound result 604800\n\n[PASS] test_handlerVersionRequeueCancellationAndExactDelay() (gas: 1187492)\nLogs:\n  Bound result 990000000000000000000\n  Bound result 604800\n  Bound result 604800\n  Bound result 518400\n  Bound result 86400\n  Bound result 604800\n  Bound result 604799\n  Bound result 1\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 4.97s (4.97s CPU time)\n\nRan 16 test suites in 4.97s (9.31s CPU time): 102 tests passed, 0 failed, 0 skipped (102 total tests)\n","passed":true},{"durationMs":68,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"HackToken.approve(address,uint256)\",\"HackToken.transfer(address,uint256)\",\"HackToken.transferFrom(address,address,uint256)\",\"HackathonMachine.advanceRound()\",\"HackathonMachine.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"HackathonMachine.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"HackathonMachine.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"HackathonMachine.buyWinnerToken(uint256,uint256)\",\"HackathonMachine.cancelDomainVersion()\",\"HackathonMachine.cancelSigner()\",\"HackathonMachine.claim(uint256)\",\"HackathonMachine.configureBuy(uint256,(address,address,uint24,int24,address),uint256)\",\"HackathonMachine.executeDomainVersion()\",\"HackathonMachine.executeSigner()\",\"HackathonMachine.fundRound(uint256)\",\"HackathonMachine.pauseEntries(bool)\",\"HackathonMachine.queueDeny(address)\",\"HackathonMachine.queueDomainVersion(string)\",\"HackathonMachine.queueSigner(address)\",\"HackathonMachine.recycleDeniedStream(uint256)\",\"HackathonMachine.redeemFeeClaims()\",\"HackathonMachine.register(string,string,string,address,address)\",\"HackathonMachine.registerWithMaxFee(string,string,string,address,address,uint256)\",\"HackathonMachine.removeDeny(address)\",\"HackathonMachine.setEntryFee(uint256)\",\"HackathonMachine.setPanelFloors(uint16,uint16)\",\"HackathonMachine.setQuestionHash(bytes32)\",\"HackathonMachine.setWinnerBps(uint16)\",\"HackathonMachine.submitResult((bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"HackathonMachine.unlockCallback(bytes)\",\"HackathonMachine.updateEntry(uint256,string,string,string,address)\",\"LaunchToken.approve(address,uint256)\",\"LaunchToken.transfer(address,uint256)\",\"LaunchToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":7,\"ADAPTATION.md\":131,\"LICENSE\":25,\"README.md\":130,\"docs/dependencies.json\":26,\"docs/heartbeat.json\":35,\"docs/launch-request.json\":8,\"docs/policy-snapshot.json\":44,\"docs/schedule.json\":10,\"docs/security-review.md\":38,\"foundry.toml\":21,\"launch.json\":34,\"remappings.txt\":4,\"src/HackToken.sol\":11,\"src/HackathonMachine.sol\":709,\"src/HookFlags.sol\":28,\"src/LaunchToken.sol\":10,\"src/OracleAttestation.sol\":221,\"test/AdversarialMachine.t.sol\":368,\"test/Attestation.t.sol\":182,\"test/CustodyInvariant.t.sol\":471,\"test/FactoryDeployment.t.sol\":82,\"test/Hook.t.sol\":179,\"test/ImportedAudit.t.sol\":315,\"test/Invariant.t.sol\":264,\"test/LaunchPurchase.t.sol\":115,\"test/LaunchToken.t.sol\":38,\"test/Machine.t.sol\":373,\"test/MachineFixture.sol\":138,\"test/OracleConformance.t.sol\":120,\"test/PrizeBuyAdversarial.t.sol\":196,\"test/Revision.t.sol\":270,\"test/TESTING.md\":37,\"test/Token.t.sol\":31,\"test/TokenProperties.t.sol\":147,\"test/mocks/MockERC20.sol\":46,\"tools/render_heartbeat.py\":42,\"tools/validate.py\":61},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":6425,"exitCode":0,"name":"slither","output":"[medium/high] incorrect-equality at src/HackathonMachine.sol:281: HackathonMachine.potForRound(uint64) (src/HackathonMachine.sol#281-290) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/HackathonMachine.sol:416: HackathonMachine.submitResult(OracleAttestation.Attestation,bytes) (src/HackathonMachine.sol#416-463) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/HackathonMachine.sol:281: HackathonMachine.potForRound(uint64) (src/HackathonMachine.sol#281-290) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/HackathonMachine.sol:391: HackathonMachine._eligible(address,uint64) (src/HackathonMachine.sol#391-395) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/HackathonMachine.sol:281: HackathonMachine.potForRound(uint64) (src/HackathonMachine.sol#281-290) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/HackathonMachine.sol:570: HackathonMachine._pay(address,uint256) (src/HackathonMachine.sol#570-574) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/HackathonMachine.sol:281: HackathonMachine.potForRound(uint64) (src/HackathonMachine.sol#281-290) uses a dangerous strict equality:\n[medium/medium] uninitialized-local at src/HackathonMachine.sol:214: HackathonMachine.beforeSwap(address,PoolKey,SwapParams,bytes).fee (src/HackathonMachine.sol#214) is a local variable never initialized\n[medium/medium] uninitialized-local at src/HackathonMachine.sol:449: HackathonMachine.submitResult(OracleAttestation.Attestation,bytes).bought (src/HackathonMachine.sol#449) is a local variable never initialized\n[medium/medium] unused-return at src/HackathonMachine.sol:399: HackathonMachine.configureBuy(uint256,PoolKey,uint256) (src/HackathonMachine.sol#399-410) ignores return value by (price,None,None,None) = poolManager.getSlot0(key.toId()) (src/HackathonMachine.sol#406)\n[low/medium] reentrancy-benign at src/HackathonMachine.sol:506: Reentrancy in HackathonMachine._buy(uint256,uint256) (src/HackathonMachine.sol#506-533):\n[low/medium] reentrancy-benign at src/HackathonMachine.sol:416: Reentrancy in HackathonMachine.submitResult(OracleAttestation.Attestation,bytes) (src/HackathonMachine.sol#416-463):\n[low/medium] reentrancy-benign at src/HackathonMachine.sol:416: Reentrancy in HackathonMachine.submitResult(OracleAttestation.Attestation,bytes) (src/HackathonMachine.sol#416-463):\n[low/medium] reentrancy-events at src/HackathonMachine.sol:486: Reentrancy in HackathonMachine.unlockCallback(bytes) (src/HackathonMachine.sol#486-504):\n[low/medium] reentrancy-events at src/HackathonMachine.sol:506: Reentrancy in HackathonMachine._buy(uint256,uint256) (src/HackathonMachine.sol#506-533):\n[low/medium] reentrancy-events at src/HackathonMachine.sol:506: Reentrancy in HackathonMachine._buy(uint256,uint256) (src/HackathonMachine.sol#506-533):\n[low/medium] timestamp at src/HackathonMachine.sol:269: HackathonMachine.currentRound() (src/HackathonMachine.sol#269-271) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:328: HackathonMachine._register(string,string,string,address,address,uint256) (src/HackathonMachine.sol#328-350) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:570: HackathonMachine._pay(address,uint256) (src/HackathonMachine.sol#570-574) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:354: HackathonMachine.updateEntry(uint256,string,string,string,address) (src/HackathonMachine.sol#354-368) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:535: HackathonMachine.claim(uint256) (src/HackathonMachine.sol#535-549) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:692: HackathonMachine.isDenied(address) (src/HackathonMachine.sol#692-694) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:557: HackathonMachine._streamDenied(HackathonMachine.Stream) (src/HackathonMachine.sol#557-559) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:630: HackathonMachine.executeSigner() (src/HackathonMachine.sol#630-637) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:296: HackathonMachine._syncRounds() (src/HackathonMachine.sol#296-304) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:281: HackathonMachine.potForRound(uint64) (src/HackathonMachine.sol#281-290) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:551: HackathonMachine.recycleDeniedStream(uint256) (src/HackathonMachine.sol#551-555) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:399: HackathonMachine.configureBuy(uint256,PoolKey,uint256) (src/HackathonMachine.sol#399-410) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:652: HackathonMachine.executeDomainVersion() (src/HackathonMachine.sol#652-660) uses timestamp for comparisons\n[low/medium] timestamp at src/OracleAttestation.sol:157: OracleAttestationConsumer._verifyAttestation(OracleAttestation.Attestation,bytes) (src/OracleAttestation.sol#157-165) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:391: HackathonMachine._eligible(address,uint64) (src/HackathonMachine.sol#391-395) uses timestamp for comparisons\n[low/medium] timestamp at src/HackathonMachine.sol:416: HackathonMachine.submitResult(OracleAttestation.Attestation,bytes) (src/HackathonMachine.sol#416-463) uses timestamp for comparisons","passed":true},{"durationMs":694,"exitCode":0,"name":"aderyn","output":"[high] reentrancy-state-change at src/HackathonMachine.sol:453: Reentrancy: State change after external call\n[low] centralization-risk at src/HackathonMachine.sol:587: Centralization Risk (13 places)\n[low] internal-function-used-once at src/HookFlags.sol:21: Internal Function Used Only Once (2 places)\n[low] large-numeric-literal at src/HackToken.sol:9: Large Numeric Literal (8 places)\n[low] literal-instead-of-constant at src/HackathonMachine.sol:238: Literal Instead of Constant (23 places)\n[low] local-variable-shadowing at src/HackathonMachine.sol:86: Local Variable Shadows State Variable\n[low] non-reentrant-not-first at src/HackathonMachine.sol:194: `nonReentrant` is Not the First Modifier (3 places)\n[low] state-change-without-event at src/HackathonMachine.sol:466: State Change Without Event (2 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"ef386ded787f31a39ca3c0c85169c52a9552c2f2fa173cb415cad5a20b567b17","verifiedTreeHash":"c859a0c8c3b1e205bc2aa951dadf9dded02bfbeb","verifierVersion":"0.1.0+ad90ce4c"}]}