{"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":"1199a044-1d25-4b47-ae2a-addf0b8ae2de","kind":"impl_tests_review","nodes":[{"acceptedSubmissionHash":"6c5d782f550525e29ef84b481b02f38c3e490135c4708c19c0b9092540145177","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d37537abb20af46832b24602788d7895021ecaac20c6934313dc4f8aba4ad047","skillId":"implement-contract","tools":[]},"key":"impl","kind":"code","role":"implement","skillHash":"d37537abb20af46832b24602788d7895021ecaac20c6934313dc4f8aba4ad047","skillId":"implement-contract","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["impl","tests"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":null,"dependsOn":["impl","tests","manifest"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","tools":[]},"key":"review","kind":"code","role":"review","skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","state":"waiting"},{"acceptedSubmissionHash":"6eb8064ba5f01db32d75e0a6388c3d8d2bf4ed5e8c40d55c88fec71db326a4fd","dependsOn":["impl"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Token name: Work\nToken symbol: WORK\n\nRobinhood Chain 4663. Builders address B = 0xc9EAFE33A510a3a3d95A94c4f85AdaF6a3EA12a0 (EOA). Owner = requester wallet. Contracts: WorkHook (Uniswap v4 hook on the WORK/IMD pool) and WorkersNFT. IMD on this chain = 0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127. All owner changes are bounded and emit events; every parameter has a view.\n\n1) WorkHook: takes its fee in the swap callbacks (beforeSwap/afterSwap) on every buy and sell, default 0.75% (2% total with the launch's 1.25%), owner may set 0 to 8.75% max. While the NFT mint runs, hook fees go 100% to B. After the mint ends (sold out or endMint): stakerShareBps (default 10000, owner may set 9000-10000, so B gets at most 10%) goes to WorkersNFT for stakers, the rest to B; if nothing is staked, all to B.\n\n2) WorkersNFT (ERC-721, max 3,333). Owner levers (UNICRED lesson): setCap(newCap) lowers the cap to any value >= minted, never raises; endMint() stops minting forever (cap = minted) and starts the post-mint phase; pause()/unpause() halts minting and WORK earning in an emergency; each pause auto-expires after 24 h, and a new pause needs at least 24 h unpaused since the last one ended.\n- Mint by proof of work: keccak256(abi.encode(DOMAIN, chainid, this, keccak256(abi.encode(anchorHash, prevWork)), msg.sender, nonce)) < target; anchorHash = blockhash at most 250 blocks old; one mint per block; retarget every 8 mints toward 10 s; target doubles after 300 s idle; 9 epochs of 370 (+3), min difficulty +1 bit per epoch; owner may move the floor +-2 bits.\n- Paid in IMD (transferFrom, permit if supported, no ETH): price per epoch [0.25,0.5,0.75,1.25,1.75,2.5,3.25,4,5] IMD, never above 5; owner may scale prices 0.5x-1x.\n- Token id = pool[hash % remaining] (swap-and-pop, no reveal, no reserved ids, no team mint).\n- Overclocked if the hash beats target by >= 4 extra bits: tokenURI = baseURI + \"oc/\" + id + \".json\", else baseURI + id + \".json\". Initial baseURI = ipfs://bafybeibmkvtnptsqztdvsm5sh3avormdnfyarbxpgdlcj6bmg37qchhqve/ (owner may update it).\n- Everyone mints on equal terms: no allowlist, no free mints, no difficulty discounts.\n\n3) Money (automatic, in IMD):\n- Each mint: 65% stakers, 25% buyback balance, 10% to B.\n- Marketplaces: activated (earning) workers stay in the holder's wallet and transfer/list normally (activation and unclaimed WORK move with the token); never block transfers of unstaked workers. Staked workers are held by the contract, so they cannot be listed while staked (no fake floor); unstaking returns them. Stake and unstake are real ERC-721 transfers that emit Transfer, so marketplaces update ownership on their own. Implement ERC-4906 (supportsInterface 0x49064906): emit BatchMetadataUpdate when baseURI changes and MetadataUpdate when a token's metadata changes.\n- Staking: escrow the NFT for 7/14/30 days = weight 1x/2x/4x, no early exit; stakers claim mint IMD and hook rewards pro-rata by weight; mint share with no stakers goes to buyback.\n- buyback(): anyone, max 100 IMD per call, once per 60 s, swaps IMD to WORK in the WORK/IMD pool and burns it.\n- WORK supply: 10% swarm, 70% pool, 20% to B (5% B's own, then B deposits 100M as the mining pool and 50M as the burn pool).\n\n4) After the mint ends:\n- activate(tokenId): one time, fee to B, default 0.15 IMD, owner may set 0-0.5 IMD; stays with the token on transfer.\n- Workers keep working passively (no hashing, no device online): activated, unburned workers earn WORK from the mining pool every second. 8 eras from mint end: era k (0..7) lasts 7*2^k days and emits 12.5M WORK, split equally among all activated workers (reward-per-worker accumulator, updated on activate, burn and claim). claimWork(tokenIds) pays the holder or staker; unclaimed WORK stays with the token on transfer. WORK scheduled while paused or while no worker is activated is never lost: carry it (emissionCarry) and release it to activated workers at the next unpaused update. After all eras end, releaseMiningRemainder() (owner, not while paused) sends what is left in the mining pool to B.\n- Burn: any holder may burn an unstaked worker for burnPool / workers minted (fixed at mint end, ~15,000 WORK); burned workers stop mining.\n\nSafety: sweep(token) to B for anything sent by mistake (incl. WETH, ETH) but never staker IMD, the buyback balance, the mining pool or the burn pool. ERC-2981 royalty 5% to B, max 10%. Not upgradeable. No minting outside proof of work, no owner path to user funds.\n\nBuild rules (a previous attempt failed deployment on these): no deployed contract may have linked libraries (forge linkReferences must be empty), so every library function is internal; ship foundry.toml with optimizer = true, via_ir = true, bytecode_hash = \"none\"; WorkersNFT and WorkHook runtime < 24,576 bytes; tests read time with vm.getBlockTimestamp()/vm.getBlockNumber() so they pass under via_ir. src/ contains only WorkersNFT.sol and WorkHook.sol; any test token lives in test/ (the launch token is IMD's, never deploy a second one). Deploy wiring: WorkersNFT takes the launch token address; WorkHook is deployed at the required flag address; the hook must be bound to WorkersNFT before pool initialization (e.g. WorkersNFT.bindHook() called by the hook in beforeInitialize, allowed only when tx.origin is the account that deployed WorkersNFT; the owner can also bind with setHook). Pool fee and tickSpacing must match the launch policy.\n\nTests: Foundry incl. fuzz on work checks, retargets, id picking, splits, staking escrow, hook split, activation, passive accrual per era, burn reward, sweep limits; then an adversarial security review.","parentJobId":null,"planHash":"76075e0d7deeab05ca78fcd91f395118c2dbd8f0b3ab81192e0589aead089008","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"1199a044-1d25-4b47-ae2a-addf0b8ae2de","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-920-src-workersnft-sol-src-workhook-sol"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51436","feedbackHash":"6ed3bf78075aaa769221e636d782110844c893b23d544e81c5c40ce5fd6bfa24","nodeKey":"impl","submissionHash":"6c5d782f550525e29ef84b481b02f38c3e490135c4708c19c0b9092540145177","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51091","feedbackHash":"c226ff5e91322d29fed949b81364076799835baaca704c1063564479ca9a04ba","nodeKey":"manifest","submissionHash":"311ba85b76f678d4afc135740670181ef87c062bb2e2a6cad2ef35f40a83b4d2","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51006","feedbackHash":"5616e14a4554bf45b18811e4f06ec29b205ef9940fee2a39101305d96638a95b","nodeKey":"manifest","submissionHash":"2247ef8dece663e168869f14fdb58ca83c8b930152c821cf49b908599875ec71","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51001","feedbackHash":"f97d6af10e03285e8d460e7e24cb842695a969bb2729265f2ff36bfa2617e8af","nodeKey":"tests","submissionHash":"3d84b46310432a1887db969d869e267c24a264895638d20e47474a6a8a8ea885","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51434","feedbackHash":"a0406d361957a63eee4ebcdb18b676ce33c407b08502e0b6ced00d5fae593cfb","nodeKey":"tests","submissionHash":"6eb8064ba5f01db32d75e0a6388c3d8d2bf4ed5e8c40d55c88fec71db326a4fd","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51195","feedbackHash":"28147c51a1d933fdf061f47d9bb14e91d559b12fa8cfbc9cb83ea0fa3c610400","nodeKey":"tests","submissionHash":"5e3b3cb982e3501fd28b657d4347c29343dcceedf54dffd185a8f58f86cdd3ca","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"953e81c07f77e5fe504cb4b3e6d638fb4afda44f1d2f4250033d5ecf7210d2ce","state":"blocked","submissions":[{"artifacts":[],"attempt":2,"bundleHash":"b4077856237ff541c3318bd6d23c2c213bdd49fe6ff70643e02928363c139930","device":"dca8f60f0d611b2d","findings":[],"hash":"2247ef8dece663e168869f14fdb58ca83c8b930152c821cf49b908599875ec71","nodeId":"03e12f65-f643-4db2-9144-e2e3a5a92852","outcome":"completed","summary":"Created [launch.json](/home/imd-worker/.identitymd/work/1199a044-1d25-4b47-ae2a-addf0b8ae2de/03e12f65-f643-4db2-9144-e2e3a5a92852/launch.json).\n\nSupplied schema and permission checks passed. Optimized via-IR build and all 67 tests passed. Only the manifest is submitted.\n\nDeployment remains blocked by WorkersNFT constructor wiring; notes document that mismatch and unconfirmed pool inputs.","treeHash":"30b4aece13121bccea1e146e05c090524565ca8f","usage":{"cachedInputTokens":721152,"inputTokens":60302,"model":"gpt-6-astra","outputTokens":8477,"runtime":"codex","turns":7,"wallClockMs":471912}},{"artifacts":[],"attempt":3,"bundleHash":null,"device":"ef9a9f22916c0ddf","findings":[],"hash":"2425b93ba840f15a0806b641ab25d81b75599557c78a6f69a1bd699d12485601","nodeId":"03e12f65-f643-4db2-9144-e2e3a5a92852","outcome":"failed","summary":"Selected model is at capacity. Please try a different model.","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":"gpt-6-astra","outputTokens":0,"runtime":"codex","turns":1,"wallClockMs":36523}},{"artifacts":[],"attempt":1,"bundleHash":"22db137a131107d14257db1cac2cfedf8743f92ea8562fc820d4757633a0ec29","device":"9704b5b521bdf559","findings":[],"hash":"311ba85b76f678d4afc135740670181ef87c062bb2e2a6cad2ef35f40a83b4d2","nodeId":"03e12f65-f643-4db2-9144-e2e3a5a92852","outcome":"completed","summary":"Created [launch.json](/home/imd/.identitymd/work/1199a044-1d25-4b47-ae2a-addf0b8ae2de/03e12f65-f643-4db2-9144-e2e3a5a92852/launch.json).\n\nSupplied schema checks and permission matching pass. `forge build` succeeds; all 67 tests pass, including via-IR.\n\nOnly the manifest is submitted. Notes document unresolved NFT wiring, missing build configuration, and assumed pool inputs. Full protocol admission remains unverified.","treeHash":"1ca6ef3670280ad83a4b3e96054c6c59d932f2e3","usage":{"cachedInputTokens":600064,"inputTokens":58074,"model":"gpt-6-astra","outputTokens":9044,"runtime":"codex","turns":6,"wallClockMs":292550}},{"artifacts":[],"attempt":1,"bundleHash":"10810552bd16ea5ef580870d18dfdbedc9eb60d7b2bba8d51665cd0e7780d466","device":"6156e0902980b6f9","findings":[{"description":"The accepted checkout contains only the two source files and no foundry.toml. Its default Foundry configuration has optimizer=false, via_ir=false and bytecode_hash=ipfs, contrary to the requested deployable build profile. WorkersNFT therefore has 38,457 bytes of deployed runtime, exceeding the 24,576-byte limit. Default forge build and Foundry behavioral tests can succeed without making this artifact deployable. Using optimizer and via-IR produces a 19,942-byte runtime, so the implementation/build owner should restore the required committed configuration; the tests-only assignment cannot modify configuration.","line":83,"path":"src/WorkersNFT.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {WorkersNFT} from \"src/WorkersNFT.sol\";\n\ninterface SizeProofVm {\n    function getDeployedCode(string calldata artifact) external returns (bytes memory);\n}\n\n// Self-contained, with no test dependency or live chain required.\ncontract DeploymentSizeProof {\n    SizeProofVm private constant vm = SizeProofVm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n    function test_WorkersNFTMeetsDeploymentSizeLimit() public {\n        bytes memory runtime = vm.getDeployedCode(\"src/WorkersNFT.sol:WorkersNFT\");\n        require(runtime.length > 0, \"missing runtime artifact\");\n        require(runtime.length < 24576, \"WorkersNFT runtime exceeds deployment size limit\");\n    }\n}","reproduction":"Save the proof as test/scratch/DeploymentSizeProof.t.sol and run forge test --match-path test/scratch/DeploymentSizeProof.t.sol -vv using the repository defaults. Expected: WorkersNFT runtime < 24,576 bytes. Actual: 38,457 bytes and the assertion fails with WorkersNFT runtime exceeds deployment size limit. This was reproduced locally. forge config --json also shows optimizer=false, via_ir=false, bytecode_hash=ipfs. Running the same proof with --via-ir --optimize produces a 19,942-byte runtime; command-line flags are diagnostic, not a persistent fix for the offline verifier.","severity":"medium","title":"Missing required build configuration leaves WorkersNFT above the deployment size limit"}],"hash":"3d84b46310432a1887db969d869e267c24a264895638d20e47474a6a8a8ea885","nodeId":"809fac4c-75ec-43b0-b65f-8007fb76412a","outcome":"completed","summary":"Added 56 tests covering failure paths, fuzz properties, and two invariant suites totaling 32,768 randomized calls.\n\n`forge build`, `forge test`, and optimized via-IR tests pass.\n\nReported one deployment blocker in `.imd-findings.json`: missing build configuration leaves WorkersNFT at 38,457 bytes, exceeding the deployment limit. Included a reproducing proof. Source and configuration files remain unchanged.\n\nLive-chain fork validation remains outstanding; integration tests use an offline v4 model.","treeHash":"1776f8c8551cc4f30a86986c4a3988f7191063a7","usage":{"cachedInputTokens":1504384,"inputTokens":102186,"model":"gpt-6-astra","outputTokens":36094,"runtime":"codex","turns":6,"wallClockMs":1269741}},{"artifacts":[],"attempt":1,"bundleHash":"2bf86a9bae85d7873db3719dfee189ccaf1f20037721d53f0a4a4be3417d0dbd","device":"e02ee782fe2a91c3","findings":[{"description":"The checkout has no foundry.toml. A default forge build with Solidity 0.8.26 produces a 38,457-byte WorkersNFT runtime, exceeding the 24,576-byte EIP-170 limit and the brief's deployment requirement. Foundry tests can still deploy this contract in their test environment, so passing the functional suite does not establish deployability. The required optimizer=true, via_ir=true, bytecode_hash=none settings are not persisted in the submission. Those settings produce a 19,901-byte WorkersNFT runtime and a 7,969-byte WorkHook runtime, with empty linkReferences for both. Configuration is outside this test revision's write scope; the implementation/build owner must supply it.","line":83,"path":"src/WorkersNFT.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {WorkersNFT} from \"src/WorkersNFT.sol\";\n\ninterface SizeProofVm {\n    function etch(address target, bytes calldata code) external;\n}\n\ncontract SizeProofToken {\n    function decimals() external pure returns (uint8) {\n        return 18;\n    }\n}\n\n// No external test dependency is needed in this checkout.\ncontract DeploymentSizeProof {\n    event log_named_uint(string key, uint256 value);\n\n    function test_WorkersNFTRuntimeFitsDeploymentLimit() public {\n        SizeProofVm vm = SizeProofVm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n        SizeProofToken token = new SizeProofToken();\n        vm.etch(0x5F7Bb59365ce557C26dbcAa4EE9d39A4b95B7127, address(token).code);\n        WorkersNFT nft = new WorkersNFT(address(token), address(this));\n        emit log_named_uint(\"WorkersNFT runtime bytes\", address(nft).code.length);\n        require(address(nft).code.length < 24576, \"WorkersNFT exceeds deployment runtime limit\");\n    }\n}","reproduction":"Save the proof as test/scratch/DeploymentSizeProof.t.sol. Run forge test --out /tmp/imd-size-proof-out --cache-path /tmp/imd-size-proof-cache --match-path test/scratch/DeploymentSizeProof.t.sol -vv with default settings. Expected: WorkersNFT runtime is below 24,576 bytes. Actual: the logged size is 38,457 bytes and test_WorkersNFTRuntimeFitsDeploymentLimit fails with 'WorkersNFT exceeds deployment runtime limit'. Confirmed locally. For comparison, the identical proof passes and logs 19,901 bytes with FOUNDRY_OPTIMIZER=true FOUNDRY_VIA_IR=true FOUNDRY_BYTECODE_HASH=none forge test --out /tmp/imd-size-proof-ir-out --cache-path /tmp/imd-size-proof-ir-cache --match-path test/scratch/DeploymentSizeProof.t.sol -vv. These environment settings demonstrate the fix but are not delivered build configuration.","severity":"medium","title":"Default build exceeds the WorkersNFT deployment size limit because required compiler configuration is absent"}],"hash":"5e3b3cb982e3501fd28b657d4347c29343dcceedf54dffd185a8f58f86cdd3ca","nodeId":"809fac4c-75ec-43b0-b65f-8007fb76412a","outcome":"completed","summary":"Added six adversarial tests and strengthened both invariant suites. `forge build` succeeds; all 62 tests pass under default and optimized via-IR settings.\n\nReported one deployment blocker in [.imd-findings.json](/home/seat/.identitymd/work/1199a044-1d25-4b47-ae2a-addf0b8ae2de/809fac4c-75ec-43b0-b65f-8007fb76412a/.imd-findings.json): missing compiler configuration leaves WorkersNFT above the runtime size limit. Included a verified reproducer; configuration remains untouched.\n\nLive-chain integration remains unverified; tests use the offline protocol model.","treeHash":"a61f9ee9fc475ea561fa8912cd8f0a7b3853403c","usage":{"cachedInputTokens":1010432,"inputTokens":74848,"model":"gpt-6-astra","outputTokens":10424,"runtime":"codex","turns":6,"wallClockMs":474732}},{"artifacts":[],"attempt":1,"bundleHash":"b57fcad769de8fc8180669daf219695574ad6b1f1a8f4f93bbd6018bb8920536","device":"563355f47e653bac","findings":[],"hash":"6c5d782f550525e29ef84b481b02f38c3e490135c4708c19c0b9092540145177","nodeId":"5b98ecb2-bcbe-4917-92f6-44406ecb2348","outcome":"completed","summary":"Implemented both allowed contracts.\n\n- `forge build` passes offline.\n- All 70 scratch tests pass, including fuzzing and real Uniswap v4 integration.\n- Manual adversarial review completed.\n- Optimized runtime: WorkersNFT **19,901 bytes**; WorkHook **7,969 bytes**. No linked libraries.\n\nConfiguration remains untouched. Deployment needs `optimizer=true`, `via_ir=true`, and `bytecode_hash=\"none\"`, supplied through build flags during verification. WorkHook requires address flags `0x30cc`.","treeHash":"1f4d3ff04a51338680f76592ce18dc3d467d7f08","usage":{"cachedInputTokens":1607936,"inputTokens":122388,"model":"gpt-6-astra","outputTokens":37610,"runtime":"codex","turns":8,"wallClockMs":1447315}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"df98a348cb33e978","findings":[],"hash":"6d11c78bcfa772561efe8161a7bdd9fa1b805c166f4844789e446892cc4d4bdc","nodeId":"5b98ecb2-bcbe-4917-92f6-44406ecb2348","outcome":"no_change","summary":"Recorded the finding as `disputed` in [.imd-responses.json](/home/imd1/.identitymd/work/1199a044-1d25-4b47-ae2a-addf0b8ae2de/5b98ecb2-bcbe-4917-92f6-44406ecb2348/.imd-responses.json).\n\n- Default build succeeds; size proof fails at **38,457 bytes**.\n- With the required compiler settings, the proof passes at **19,901 bytes**. Both contracts have empty library links.\n\nContracts remain unchanged. The missing configuration remains unresolved because your overriding rules prohibit configuration changes; the build owner must persist the required settings before deployment.","treeHash":null,"usage":{"cachedInputTokens":366080,"inputTokens":75597,"model":"gpt-6-astra","outputTokens":3380,"runtime":"codex","turns":4,"wallClockMs":147777}},{"artifacts":[],"attempt":1,"bundleHash":"7f083a2068c93152fe8f3f57b443ad155990998deceecd7b5caadcf3b4e3c917","device":"87f02002d6a2b915","findings":[{"description":"The supplied checkout has no foundry.toml. Consequently the default build does not enable the required optimizer or via_ir and retains the IPFS bytecode hash. WorkersNFT's default deployed bytecode is 38,457 bytes, exceeding the 24,576-byte runtime limit. The passing unit tests do not establish deployability. With optimizer and via_ir enabled the runtime is 19,942 bytes. The required configuration must be supplied by a contributor authorized to edit configuration; it is outside this test revision's permitted paths.","line":83,"path":"src/WorkersNFT.sol","reproduction":"On this checkout run `forge config --json`: optimizer=false, via_ir=false, bytecode_hash=ipfs. Run `forge build --sizes --out test/scratch/out --cache-path test/scratch/cache`: WorkersNFT runtime is 38,457 bytes and the command exits 1 for exceeding EIP-170. Expected: the default committed build enables optimizer=true, via_ir=true, bytecode_hash=none and produces WorkersNFT runtime below 24,576 bytes. Actual: the configuration file is absent and the default artifact is too large. For comparison, `forge build --optimize --via-ir --sizes --out test/scratch/out-ir --cache-path test/scratch/cache-ir` produces a 19,942-byte WorkersNFT runtime. Both contracts have empty linkReferences.","severity":"medium","title":"Missing Foundry configuration makes the default WorkersNFT artifact undeployable"}],"hash":"6eb8064ba5f01db32d75e0a6388c3d8d2bf4ed5e8c40d55c88fec71db326a4fd","nodeId":"809fac4c-75ec-43b0-b65f-8007fb76412a","outcome":"completed","summary":"Added five targeted regression tests, preserving the existing suite. Builds and all 67 tests pass in default and optimized via-IR modes, including stateful invariants.\n\nReported the missing configuration in `.imd-findings.json`: default WorkersNFT runtime is 38,457 bytes, exceeding the deployment limit.\n\nLive Robinhood fork verification remains outstanding.","treeHash":"f9f54b49b61661ecde9982bc30046e8a7908ee2f","usage":{"cachedInputTokens":1254400,"inputTokens":79891,"model":"gpt-6-astra","outputTokens":10932,"runtime":"codex","turns":6,"wallClockMs":478101}},{"artifacts":[],"attempt":2,"bundleHash":null,"device":"b7f1fc143076cedc","findings":[],"hash":"7d39ed146bb1da085f11cbf9c2034f8d17905379fe3806009a9cfb722c0993a7","nodeId":"03e12f65-f643-4db2-9144-e2e3a5a92852","outcome":"failed","summary":"Selected model is at capacity. Please try a different model.","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":"gpt-6-astra","outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":10638}},{"artifacts":[],"attempt":3,"bundleHash":null,"device":"0b129ef2f81deead","findings":[],"hash":"ac134020101e8b621ebb106f6dbde3c15ad25ba9f20d7810284cf28924d53506","nodeId":"03e12f65-f643-4db2-9144-e2e3a5a92852","outcome":"failed","summary":"the task produced no changes; the agent's last message was: Blocked: the current contracts cannot be represented by the supplied manifest schema.\n\n- `WorkersNFT` requires two constructor arguments, but the schema forbids `token.constructorArgs`. Declaring it would repeat the previous rejection.\n- `WorkHook` requires a deployed `WorkersNFT` address, which was not supplied; `$token` cannot substitute for that NFT.\n\nThis requires an upstream deployment/schema correction outside the permitted scope.\n\n`forge build` succeeded and all 67 tests passed, including optimized via-IR checks. No submitted files changed; I did not create another manifest known to fail admission.","treeHash":null,"usage":{"cachedInputTokens":794752,"inputTokens":61147,"model":"gpt-6-astra","outputTokens":6466,"runtime":"codex","turns":6,"wallClockMs":456850}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"7d4a49a940f788b7","findings":[],"hash":"e4755e1256c80883e603842fb9bf75be3f6ddd6ff6e4a12686df87da8cf5105a","nodeId":"5b98ecb2-bcbe-4917-92f6-44406ecb2348","outcome":"no_change","summary":"Recorded the finding as `disputed` in [.imd-responses.json](/home/bc/.identitymd/work/1199a044-1d25-4b47-ae2a-addf0b8ae2de/5b98ecb2-bcbe-4917-92f6-44406ecb2348/.imd-responses.json): it reproduces, but the requested configuration change is explicitly forbidden.\n\n- `forge build`: passes.\n- Default `forge test`: size proof fails at 38,457 bytes.\n- Requested build settings, applied temporarily: passes at 19,901 bytes.\n\nContracts remain unchanged. Persistent build configuration remains unresolved.","treeHash":null,"usage":{"cachedInputTokens":561280,"inputTokens":82766,"model":"gpt-6-astra","outputTokens":4007,"runtime":"codex","turns":4,"wallClockMs":189723}}],"verification":[{"checks":[{"durationMs":785,"exitCode":0,"name":"build","output":"Compiling 4 files with Solc 0.8.26\nSolc 0.8.26 finished in 666.26ms\nCompiler run successful!\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkHook.sol:138:13\n    │\n138 │         if (tx.origin != workers.deploymentOrigin() && tx.origin != workers.owner()) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkersNFT.sol:429:13\n    │\n429 │         if (tx.origin != deploymentOrigin) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/WorkersNFT.sol:67:13\n   │\n67 │         if (IWorkerToken(token).balanceOf(address(this)) != beforeBalance + amount) revert TokenTransferFailed();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[missing-events-arithmetic]: `tickCumulative` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:231:9\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastObservationTime` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:232:9\n    │\n232 │         lastObservationTime = block.timestamp;\n    │         ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastTick` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:233:9\n    │\n233 │         lastTick = int24(uint24(uint256(poolManager.extsload(_poolSlot)) >> 160));\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-access-control]: `owner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:343:9\n    │\n343 │         owner = msg.sender;\n    │         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `pendingOwner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:344:9\n    │\n344 │         pendingOwner = address(0);\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `totalWeight` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:581:9\n    │\n581 │         totalWeight += weight;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_owners` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:299:9\n    │\n299 │         _owners[id] = to;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_buybackAmount` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:771:9\n    │\n771 │         _buybackAmount = 0; // Only one callback can consume this authorization.\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/WorkersNFT.sol:201:17\n    │\n201 │     constructor(address launchToken, address initialOwner) {\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:166:22\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:166:30\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:172:16\n    │\n172 │         return uint256(amount < 0 ? -amount : amount);\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[reentrancy-no-eth]: external call can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:304:36\n    │\n304 │         if (to.code.length != 0 && IWorkerReceiver(to).onERC721Received(msg.sender, from, id, data) != 0x150b7a02) {\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:188:34\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\n    │                                  ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:188:27\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkersNFT.sol:318:15\n    │\n318 │             ++length;\n    │               ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:323:37\n    │\n323 │             text[--length] = bytes1(uint8(48 + number % 10));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' 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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:331:27\n    │\n331 │         return (BUILDERS, salePrice / 10000 * royaltyBps + salePrice % 10000 * royaltyBps / 10000);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:212:56\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:237:13\n    │\n237 │             emit ObservationWritten(block.timestamp, tickCumulative, lastTick);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:199:57\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:199:88\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:204:56\n    │\n204 │             int256 expected = params.amountSpecified + int256(charged);\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/WorkHook.sol:212:42\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:212:49\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:221:13\n    │\n221 │         if (stakersPart != 0) {\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/WorkHook.sol:227:9\n    │\n227 │         emit HookFee(fee, stakersPart, buildersPart);\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/WorkHook.sol:234:13\n    │\n234 │         if (block.timestamp >= latestObservation.timestamp + ORACLE_WINDOW) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:231:46\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkHook.sol:244:13\n    │\n244 │         if (block.timestamp < start.timestamp + ORACLE_WINDOW) start = previousObservation;\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/WorkHook.sol:246:13\n    │\n246 │         if (elapsed < ORACLE_WINDOW) revert OracleNotReady();\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/WorkHook.sol:250:27\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:247:65\n    │\n247 │         int256 cumulative = tickCumulative + int256(lastTick) * int256(block.timestamp - lastObservationTime);\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/WorkHook.sol:249:34\n    │\n249 │         int256 result = change / int256(elapsed);\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/WorkHook.sol:250:36\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\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/WorkHook.sol:251:20\n    │\n251 │         meanTick = int24(result);\n    │                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' 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/WorkHook.sol:268:25\n    │\n268 │         uint256 power = uint256(tick < 0 ? -int256(tick) : int256(tick));\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkHook.sol:327:9\n    │\n327 │         emit Swept(token, 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/WorkersNFT.sol:405:16\n    │\n405 │         return block.timestamp < pauseUntil;\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/WorkersNFT.sol:409:39\n    │\n409 │         if (paused() || (hasPaused && block.timestamp < pauseUntil + 1 days)) revert Unavailable();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:473:24\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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/WorkersNFT.sol:473:32\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:480:13\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:480:30\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:482:16\n    │\n482 │         return result > ceiling ? ceiling : result;\n    │                ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `minted` is updated\n    ╭▸ src/WorkersNFT.sol:528:13\n    │\n528 │         try IWorkerToken(IMD).permit(msg.sender, address(this), mintPrice(), deadline, v, r, s) {} catch {}\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:560:9\n    │\n560 │         emit TargetChanged(target);\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/WorkersNFT.sol:300:9\n    │\n300 │         emit Transfer(from, to, 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/WorkersNFT.sol:374:9\n    │\n374 │         emit MintEnded(minted, block.timestamp, burnReward);\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/WorkersNFT.sol:627:9\n    │\n627 │         emit ImdRewardAdded(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/WorkersNFT.sol:571:9\n    │\n571 │         emit Mined(msg.sender, id, hash, overclocked[id], price);\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/WorkersNFT.sol:552:17\n    │\n552 │             if (elapsed < 20) elapsed = 20;\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/WorkersNFT.sol:553:17\n    │\n553 │             if (elapsed > 320) elapsed = 320;\n    │                 ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:580:40\n    │\n580 │         stakes[id] = Stake(msg.sender, uint64(until), weight, accImdPerWeight);\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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:594:45\n    │\n594 │         if (position.account != msg.sender) revert Unauthorized();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:612:13\n    │\n612 │         if (block.timestamp < position.unlockTime) revert Unavailable();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:679:32\n    │\n679 │             uint256 assigned = perWorker * activeWorkers;\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:241:35\n    │\n241 │         if (result == address(0)) revert Invalid();\n    │                                   ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:708:54\n    │\n708 │             if (beneficiaryOf(ids[i]) != msg.sender) revert Unauthorized();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/WorkersNFT.sol:730:58\n    │\n730 │     function releaseMiningRemainder() external onlyOwner nonReentrant whenRunning {\n    │                                                          ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:731:45\n    │\n731 │         if (!mintEnded || miningReleased || block.timestamp < mintEndTime + MINING_DURATION) revert Unavailable();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_buybackMinimum` is updated\n    ╭▸ src/WorkersNFT.sol:757:31\n    │\n757 │         bytes memory result = IWorkHook(hook).poolManager().unlock(\"\");\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:746:38\n    │\n746 │                 || (hasBoughtBack && block.timestamp < lastBuyback + 60)\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/WorkersNFT.sol:762:9\n    │\n762 │         emit Buyback(amount, output);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:778:18\n    │\n778 │                 -int256(amount),\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/WorkersNFT.sol:783:25\n    │\n783 │         int128 delta0 = int128(delta >> 128);\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/WorkersNFT.sol:784:25\n    │\n784 │         int128 delta1 = int128(delta);\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/WorkersNFT.sol:787:23\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:787:56\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:792:47\n    │\n792 │         manager.take(workToken, BURN_ADDRESS, uint256(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/WorkersNFT.sol:793:27\n    │\n793 │         return abi.encode(uint256(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[reentrancy-eth]: uncapped ETH transfer can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:807:26\n    │\n807 │             (bool ok,) = BUILDERS.call{value: amount}(\"\");\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:812:9\n    │\n812 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":6642,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 21 tests for test/WorkHook.t.sol:WorkHookTest\n[PASS] testFuzz_AllFourSwapModesChargeIMDExactlyOnce(uint96,uint16,bool,bool) (runs: 1000, μ: 379022, ~: 388885)\n[PASS] testFuzz_HookSweepOnlySendsToBuilders(uint96,uint96) (runs: 1000, μ: 170850, ~: 171606)\n[PASS] testFuzz_PostMintSplitConservesFeeAndCanBeClaimed(uint96,uint16) (runs: 1000, μ: 1729568, ~: 1744586)\n[PASS] test_BuybackBadOutputWrongInputOrSettlementRollsEverythingBack() (gas: 2675816)\n[PASS] test_BuybackCapsSpendAt100IMDAndCooldownEndsAt60Seconds() (gas: 170037964)\n[PASS] test_BuybackUsesSettlementBurnSinkCooldownAndDoesNotSpendReserves() (gas: 2115811)\n[PASS] test_CallbacksRejectForeignPoolWrongCallerAndUninitializedState() (gas: 425810)\n[PASS] test_Create2FlagsPermissionsPolicyAndBindingBeforeInitialization() (gas: 261686)\n[PASS] test_DefaultBuyAndSellFeeAndZeroFee() (gas: 575682)\n[PASS] test_FailedBuybackBurnTransferRestoresFeesRewardsAndSettlement() (gas: 2180702)\n[PASS] test_FailedInitializationCannotLeaveHookBoundOrOracleStarted() (gas: 487623)\n[PASS] test_FeeBoundsEventsAndOwnershipFollowsNFT() (gas: 405026)\n[PASS] test_FeesAndBuybackForOppositeCurrencyOrdering() (gas: 79380632)\n[PASS] test_InitializationRequiresManagerAuthorizedOriginAndCorrectPool() (gas: 363711)\n[PASS] test_OracleWaitsFullWindowAndQuoteIncludesBothFeesAndSlippage() (gas: 251227)\n[PASS] test_OracleWeightsPriorTickAndRoundsNegativeMeanDown() (gas: 893652)\n[PASS] test_PartialSpecifiedIMDFillRevertsAtomicallyAndWorkSpecifiedUsesActualIMD() (gas: 617898)\n[PASS] test_PostMintPartialFillRollsBackStakerNotificationAndBuildersPayment() (gas: 1629676)\n[PASS] test_PostMintWithoutStakeAndAfterLastUnstakeRoutesEverythingToBuilders() (gas: 1442772)\n[PASS] test_TaxedHookRewardCannotCreateUnbackedStakerLiability() (gas: 1259695)\n[PASS] test_ZeroIntMinimumAndOversizedAmountsRejectWithoutFees() (gas: 296020)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 2.17s (4.23s CPU time)\n\nRan 44 tests for test/WorkersNFT.t.sol:WorkersNFTTest\n[PASS] testFuzz_BurnRewardStaysFixedAndCannotBeClaimedTwice(uint8,uint8) (runs: 1000, μ: 2346442, ~: 1982694)\n[PASS] testFuzz_EightEraAccrual(uint8,uint32) (runs: 1000, μ: 889361, ~: 890219)\n[PASS] testFuzz_EpochFloorsAndIdleTargetRemainBounded(uint16,uint8,uint16) (runs: 1000, μ: 8851538, ~: 8853386)\n[PASS] testFuzz_FrequentClaimsRetainFractionalIMDCredit(uint8,uint8) (runs: 1000, μ: 3526429, ~: 3045232)\n[PASS] testFuzz_MintPicksUnreservedIdAndConservesPayment(uint256,uint16) (runs: 1000, μ: 1177464, ~: 933069)\n[PASS] testFuzz_MintSplitsAndWeightedClaims(uint16,uint8) (runs: 1000, μ: 2315443, ~: 2315471)\n[PASS] testFuzz_PricesUseIMDDecimalsAndBoundedScale(uint256,uint8) (runs: 1000, μ: 60690, ~: 60699)\n[PASS] testFuzz_RetargetEveryEightAndIdleRecovery(uint16) (runs: 1000, μ: 6779391, ~: 6777746)\n[PASS] testFuzz_RoyaltyCannotOverflow(uint256,uint16) (runs: 1000, μ: 43721, ~: 43731)\n[PASS] testFuzz_SweepCannotTouchReserves(uint96,uint96,uint96) (runs: 1000, μ: 1681210, ~: 1681892)\n[PASS] testFuzz_WorkHashBindsChainContractMinerNonceAndPreviousWork(uint256,address) (runs: 1000, μ: 50971, ~: 50971)\n[PASS] test_ActivatedWorkerTransferCarriesAccruedWorkAndApprovalClears() (gas: 1304474)\n[PASS] test_ActivationDoesNotDilutePastRewardsAndBurnStopsFutureWork() (gas: 1741678)\n[PASS] test_ActivationRequiresPostMintBeneficiaryAndFeeAndEmitsMetadata() (gas: 1514939)\n[PASS] test_AnchorsAreNonzeroPastAndAtMost250BlocksOld() (gas: 51833)\n[PASS] test_AutoExpiredPauseAssignsCarryBeforeNewWorkerJoins() (gas: 1819120)\n[PASS] test_BoundedUpdatesEmitEventsAndOwnershipNeedsAcceptance() (gas: 348116)\n[PASS] test_CapOnlyDecreasesAndSelloutIsPermanent() (gas: 2200627)\n[PASS] test_ConstructorRejectsInvalidOwnerTokenAndDecimals() (gas: 9767636)\n[PASS] test_EmptyAndPausedEmissionIsCarriedThenReleased() (gas: 1385048)\n[PASS] test_EmptyClaimsAndUnauthorizedUnlockDoNotMoveFunds() (gas: 185424)\n[PASS] test_EndMintAndCapAtMintedSnapshotRewards() (gas: 976305)\n[PASS] test_EpochBoundariesIncludeFinalThreeWorkers() (gas: 9674759)\n[PASS] test_FailedActivationPaymentCannotConsumeCarriedMining() (gas: 2040091)\n[PASS] test_FailedBurnPayoutRestoresOwnershipApprovalAndBothReserves() (gas: 1375428)\n[PASS] test_FailedUnstakePayoutPreservesEscrowAndClaimableIMD() (gas: 1649736)\n[PASS] test_FundingOnlyBuildersExactlyOnceAndNoUnfundedMint() (gas: 8842491)\n[PASS] test_HookRewardsRequireBoundHookPostMintWeightAndBacking() (gas: 2454963)\n[PASS] test_IdPoolNeverRepeatsAndCapDoesNotReserveIds() (gas: 68667136)\n[PASS] test_InvalidProofAndOneMintPerBlockRollback() (gas: 995348)\n[PASS] test_MiningReleasePreservesUnclaimedLiabilities() (gas: 1239374)\n[PASS] test_MiningReleaseWithoutActivationReturnsOnlyMiningReserve() (gas: 694227)\n[PASS] test_MixedOwnerClaimBatchesRevertWithoutConsumingEarlierRewards() (gas: 2926678)\n[PASS] test_NoFreeMintOnMissingAllowanceFalseReturnOrTransferTax() (gas: 1823837)\n[PASS] test_NormalAndOverclockedMetadataAndERC4906() (gas: 11820284)\n[PASS] test_OwnerLeversRejectOutsidersAndOutOfRangeInputs() (gas: 539332)\n[PASS] test_PauseExpiresAndCannotBeRenewedBeforeFullDayUnpaused() (gas: 1168072)\n[PASS] test_PermitUnsupportedUsesAllowanceAndSupportedPermitNeedsNoPriorApproval() (gas: 1976461)\n[PASS] test_RejectedMintReceiverRestoresSelloutPaymentAndIdPool() (gas: 2522169)\n[PASS] test_RobinhoodUsesChildChainBlockAndHash() (gas: 5227217)\n[PASS] test_StakeEscrowsAndCannotBeListedBurnedOrExitedEarly() (gas: 1604108)\n[PASS] test_TokenCallbackCannotReenterMint() (gas: 976505)\n[PASS] test_TransfersWorkWhilePausedButRejectUntrackedEscrowAndBadReceivers() (gas: 1209471)\n[PASS] test_ZeroMintCancellationNeverReopens() (gas: 176360)\nSuite result: ok. 44 passed; 0 failed; 0 skipped; finished in 2.17s (21.54s CPU time)\n\nRan 1 test for test/WorkHook.t.sol:WorkHookInvariantTest\n[PASS] invariant_FeesAreFullyBackedAndNeverRedirected() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| HookHandler | advance        | 2146  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | buyback        | 2050  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | claim          | 2049  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | donateAndSweep | 2039  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | endMint        | 2011  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | policy         | 1994  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | stakeOrUnstake | 2089  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | swap           | 2006  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.13s (3.12s CPU time)\n\nRan 1 test for test/WorkersNFT.t.sol:WorkersNFTInvariantTest\n[PASS] invariant_ReservesCustodySupplyAndLiabilities() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| WorkersHandler | activate      | 1091  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | advance       | 1116  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | burn          | 1097  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | changePolicy  | 1030  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | claim         | 1112  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | donate        | 1062  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | finishMint    | 1086  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | hookReward    | 1057  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | mintWorker    | 1109  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | pauseOrResume | 1139  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | release       | 1055  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | stake         | 1141  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | sweep         | 1073  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | transfer      | 1107  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | unstake       | 1109  | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.58s (6.57s CPU time)\n\nRan 4 test suites in 6.58s (14.06s CPU time): 67 tests passed, 0 failed, 0 skipped (67 total tests)\n","passed":true},{"durationMs":39,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WorkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"WorkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"WorkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"WorkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"WorkHook.receive()\",\"WorkHook.setFeeBps(uint16)\",\"WorkHook.setStakerShareBps(uint16)\",\"WorkHook.sweep(address)\",\"WorkersNFT.acceptOwnership()\",\"WorkersNFT.activate(uint256)\",\"WorkersNFT.approve(address,uint256)\",\"WorkersNFT.bindHook()\",\"WorkersNFT.burn(uint256)\",\"WorkersNFT.buyback()\",\"WorkersNFT.claimRewards(uint256[])\",\"WorkersNFT.claimWork(uint256[])\",\"WorkersNFT.endMint()\",\"WorkersNFT.fundPools()\",\"WorkersNFT.mint(uint256,uint256)\",\"WorkersNFT.mintWithPermit(uint256,uint256,uint256,uint8,bytes32,bytes32)\",\"WorkersNFT.notifyHookReward(uint256)\",\"WorkersNFT.pause()\",\"WorkersNFT.receive()\",\"WorkersNFT.releaseMiningRemainder()\",\"WorkersNFT.safeTransferFrom(address,address,uint256)\",\"WorkersNFT.safeTransferFrom(address,address,uint256,bytes)\",\"WorkersNFT.setActivationFee(uint256)\",\"WorkersNFT.setApprovalForAll(address,bool)\",\"WorkersNFT.setBaseURI(string)\",\"WorkersNFT.setCap(uint256)\",\"WorkersNFT.setFloorAdjustment(int8)\",\"WorkersNFT.setHook(address)\",\"WorkersNFT.setPriceScaleBps(uint16)\",\"WorkersNFT.setRoyaltyBps(uint16)\",\"WorkersNFT.stake(uint256,uint256)\",\"WorkersNFT.sweep(address)\",\"WorkersNFT.transferFrom(address,address,uint256)\",\"WorkersNFT.transferOwnership(address)\",\"WorkersNFT.unlockCallback(bytes)\",\"WorkersNFT.unpause()\",\"WorkersNFT.unstake(uint256)\",\"WorkersNFT.updateMining()\"],\"files\":{\"launch.json\":28,\"src/WorkHook.sol\":329,\"src/WorkersNFT.sol\":814,\"test/WorkHook.t.sol\":900,\"test/WorkersNFT.t.sol\":1625},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"launch.json: WorkersNFT: expected 2 constructor arguments, got 0","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"2247ef8dece663e168869f14fdb58ca83c8b930152c821cf49b908599875ec71","verifiedTreeHash":"30b4aece13121bccea1e146e05c090524565ca8f","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":792,"exitCode":0,"name":"build","output":"Compiling 4 files with Solc 0.8.26\nSolc 0.8.26 finished in 686.03ms\nCompiler run successful!\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkersNFT.sol:429:13\n    │\n429 │         if (tx.origin != deploymentOrigin) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkHook.sol:138:13\n    │\n138 │         if (tx.origin != workers.deploymentOrigin() && tx.origin != workers.owner()) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/WorkersNFT.sol:67:13\n   │\n67 │         if (IWorkerToken(token).balanceOf(address(this)) != beforeBalance + amount) revert TokenTransferFailed();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[missing-events-arithmetic]: `tickCumulative` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:231:9\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastObservationTime` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:232:9\n    │\n232 │         lastObservationTime = block.timestamp;\n    │         ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastTick` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:233:9\n    │\n233 │         lastTick = int24(uint24(uint256(poolManager.extsload(_poolSlot)) >> 160));\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-access-control]: `owner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:343:9\n    │\n343 │         owner = msg.sender;\n    │         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `pendingOwner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:344:9\n    │\n344 │         pendingOwner = address(0);\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `totalWeight` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:581:9\n    │\n581 │         totalWeight += weight;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_owners` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:299:9\n    │\n299 │         _owners[id] = to;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_buybackAmount` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:771:9\n    │\n771 │         _buybackAmount = 0; // Only one callback can consume this authorization.\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/WorkersNFT.sol:201:17\n    │\n201 │     constructor(address launchToken, address initialOwner) {\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:166:22\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:166:30\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:172:16\n    │\n172 │         return uint256(amount < 0 ? -amount : amount);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:188:34\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\n    │                                  ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:188:27\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:212:56\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:237:13\n    │\n237 │             emit ObservationWritten(block.timestamp, tickCumulative, lastTick);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:199:57\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:199:88\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:204:56\n    │\n204 │             int256 expected = params.amountSpecified + int256(charged);\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/WorkHook.sol:212:42\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:212:49\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:221:13\n    │\n221 │         if (stakersPart != 0) {\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/WorkHook.sol:227:9\n    │\n227 │         emit HookFee(fee, stakersPart, buildersPart);\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/WorkHook.sol:234:13\n    │\n234 │         if (block.timestamp >= latestObservation.timestamp + ORACLE_WINDOW) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:231:46\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\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[reentrancy-no-eth]: external call can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:304:36\n    │\n304 │         if (to.code.length != 0 && IWorkerReceiver(to).onERC721Received(msg.sender, from, id, data) != 0x150b7a02) {\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkHook.sol:244:13\n    │\n244 │         if (block.timestamp < start.timestamp + ORACLE_WINDOW) start = previousObservation;\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/WorkHook.sol:246:13\n    │\n246 │         if (elapsed < ORACLE_WINDOW) revert OracleNotReady();\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/WorkHook.sol:250:27\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:247:65\n    │\n247 │         int256 cumulative = tickCumulative + int256(lastTick) * int256(block.timestamp - lastObservationTime);\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/WorkHook.sol:249:34\n    │\n249 │         int256 result = change / int256(elapsed);\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/WorkHook.sol:250:36\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\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/WorkHook.sol:251:20\n    │\n251 │         meanTick = int24(result);\n    │                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' 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/WorkHook.sol:268:25\n    │\n268 │         uint256 power = uint256(tick < 0 ? -int256(tick) : int256(tick));\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkHook.sol:327:9\n    │\n327 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkersNFT.sol:318:15\n    │\n318 │             ++length;\n    │               ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:323:37\n    │\n323 │             text[--length] = bytes1(uint8(48 + number % 10));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' 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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:331:27\n    │\n331 │         return (BUILDERS, salePrice / 10000 * royaltyBps + salePrice % 10000 * royaltyBps / 10000);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:405:16\n    │\n405 │         return block.timestamp < pauseUntil;\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/WorkersNFT.sol:409:39\n    │\n409 │         if (paused() || (hasPaused && block.timestamp < pauseUntil + 1 days)) revert Unavailable();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:473:24\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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/WorkersNFT.sol:473:32\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:480:13\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:480:30\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:482:16\n    │\n482 │         return result > ceiling ? ceiling : result;\n    │                ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `minted` is updated\n    ╭▸ src/WorkersNFT.sol:528:13\n    │\n528 │         try IWorkerToken(IMD).permit(msg.sender, address(this), mintPrice(), deadline, v, r, s) {} catch {}\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:560:9\n    │\n560 │         emit TargetChanged(target);\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/WorkersNFT.sol:300:9\n    │\n300 │         emit Transfer(from, to, 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/WorkersNFT.sol:374:9\n    │\n374 │         emit MintEnded(minted, block.timestamp, burnReward);\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/WorkersNFT.sol:627:9\n    │\n627 │         emit ImdRewardAdded(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/WorkersNFT.sol:571:9\n    │\n571 │         emit Mined(msg.sender, id, hash, overclocked[id], price);\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/WorkersNFT.sol:552:17\n    │\n552 │             if (elapsed < 20) elapsed = 20;\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/WorkersNFT.sol:553:17\n    │\n553 │             if (elapsed > 320) elapsed = 320;\n    │                 ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:580:40\n    │\n580 │         stakes[id] = Stake(msg.sender, uint64(until), weight, accImdPerWeight);\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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:594:45\n    │\n594 │         if (position.account != msg.sender) revert Unauthorized();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:612:13\n    │\n612 │         if (block.timestamp < position.unlockTime) revert Unavailable();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:679:32\n    │\n679 │             uint256 assigned = perWorker * activeWorkers;\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:241:35\n    │\n241 │         if (result == address(0)) revert Invalid();\n    │                                   ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:708:54\n    │\n708 │             if (beneficiaryOf(ids[i]) != msg.sender) revert Unauthorized();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/WorkersNFT.sol:730:58\n    │\n730 │     function releaseMiningRemainder() external onlyOwner nonReentrant whenRunning {\n    │                                                          ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:731:45\n    │\n731 │         if (!mintEnded || miningReleased || block.timestamp < mintEndTime + MINING_DURATION) revert Unavailable();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_buybackMinimum` is updated\n    ╭▸ src/WorkersNFT.sol:757:31\n    │\n757 │         bytes memory result = IWorkHook(hook).poolManager().unlock(\"\");\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:746:38\n    │\n746 │                 || (hasBoughtBack && block.timestamp < lastBuyback + 60)\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/WorkersNFT.sol:762:9\n    │\n762 │         emit Buyback(amount, output);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:778:18\n    │\n778 │                 -int256(amount),\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/WorkersNFT.sol:783:25\n    │\n783 │         int128 delta0 = int128(delta >> 128);\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/WorkersNFT.sol:784:25\n    │\n784 │         int128 delta1 = int128(delta);\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/WorkersNFT.sol:787:23\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:787:56\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:792:47\n    │\n792 │         manager.take(workToken, BURN_ADDRESS, uint256(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/WorkersNFT.sol:793:27\n    │\n793 │         return abi.encode(uint256(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[reentrancy-eth]: uncapped ETH transfer can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:807:26\n    │\n807 │             (bool ok,) = BUILDERS.call{value: amount}(\"\");\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:812:9\n    │\n812 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":6252,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 21 tests for test/WorkHook.t.sol:WorkHookTest\n[PASS] testFuzz_AllFourSwapModesChargeIMDExactlyOnce(uint96,uint16,bool,bool) (runs: 1000, μ: 379280, ~: 388897)\n[PASS] testFuzz_HookSweepOnlySendsToBuilders(uint96,uint96) (runs: 1000, μ: 170382, ~: 171594)\n[PASS] testFuzz_PostMintSplitConservesFeeAndCanBeClaimed(uint96,uint16) (runs: 1000, μ: 1725894, ~: 1744574)\n[PASS] test_BuybackBadOutputWrongInputOrSettlementRollsEverythingBack() (gas: 2675816)\n[PASS] test_BuybackCapsSpendAt100IMDAndCooldownEndsAt60Seconds() (gas: 170037964)\n[PASS] test_BuybackUsesSettlementBurnSinkCooldownAndDoesNotSpendReserves() (gas: 2115811)\n[PASS] test_CallbacksRejectForeignPoolWrongCallerAndUninitializedState() (gas: 425810)\n[PASS] test_Create2FlagsPermissionsPolicyAndBindingBeforeInitialization() (gas: 261686)\n[PASS] test_DefaultBuyAndSellFeeAndZeroFee() (gas: 575682)\n[PASS] test_FailedBuybackBurnTransferRestoresFeesRewardsAndSettlement() (gas: 2180702)\n[PASS] test_FailedInitializationCannotLeaveHookBoundOrOracleStarted() (gas: 487623)\n[PASS] test_FeeBoundsEventsAndOwnershipFollowsNFT() (gas: 405026)\n[PASS] test_FeesAndBuybackForOppositeCurrencyOrdering() (gas: 79380632)\n[PASS] test_InitializationRequiresManagerAuthorizedOriginAndCorrectPool() (gas: 363711)\n[PASS] test_OracleWaitsFullWindowAndQuoteIncludesBothFeesAndSlippage() (gas: 251227)\n[PASS] test_OracleWeightsPriorTickAndRoundsNegativeMeanDown() (gas: 893652)\n[PASS] test_PartialSpecifiedIMDFillRevertsAtomicallyAndWorkSpecifiedUsesActualIMD() (gas: 617898)\n[PASS] test_PostMintPartialFillRollsBackStakerNotificationAndBuildersPayment() (gas: 1629676)\n[PASS] test_PostMintWithoutStakeAndAfterLastUnstakeRoutesEverythingToBuilders() (gas: 1442772)\n[PASS] test_TaxedHookRewardCannotCreateUnbackedStakerLiability() (gas: 1259695)\n[PASS] test_ZeroIntMinimumAndOversizedAmountsRejectWithoutFees() (gas: 296020)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 2.27s (2.79s CPU time)\n\nRan 44 tests for test/WorkersNFT.t.sol:WorkersNFTTest\n[PASS] testFuzz_BurnRewardStaysFixedAndCannotBeClaimedTwice(uint8,uint8) (runs: 1000, μ: 2400881, ~: 1982694)\n[PASS] testFuzz_EightEraAccrual(uint8,uint32) (runs: 1000, μ: 889074, ~: 889348)\n[PASS] testFuzz_EpochFloorsAndIdleTargetRemainBounded(uint16,uint8,uint16) (runs: 1000, μ: 8851706, ~: 8853449)\n[PASS] testFuzz_FrequentClaimsRetainFractionalIMDCredit(uint8,uint8) (runs: 1000, μ: 3503670, ~: 3085112)\n[PASS] testFuzz_MintPicksUnreservedIdAndConservesPayment(uint256,uint16) (runs: 1000, μ: 1160824, ~: 932895)\n[PASS] testFuzz_MintSplitsAndWeightedClaims(uint16,uint8) (runs: 1000, μ: 2315453, ~: 2315471)\n[PASS] testFuzz_PricesUseIMDDecimalsAndBoundedScale(uint256,uint8) (runs: 1000, μ: 60690, ~: 60699)\n[PASS] testFuzz_RetargetEveryEightAndIdleRecovery(uint16) (runs: 1000, μ: 6778901, ~: 6777746)\n[PASS] testFuzz_RoyaltyCannotOverflow(uint256,uint16) (runs: 1000, μ: 43727, ~: 43731)\n[PASS] testFuzz_SweepCannotTouchReserves(uint96,uint96,uint96) (runs: 1000, μ: 1680818, ~: 1681892)\n[PASS] testFuzz_WorkHashBindsChainContractMinerNonceAndPreviousWork(uint256,address) (runs: 1000, μ: 50971, ~: 50971)\n[PASS] test_ActivatedWorkerTransferCarriesAccruedWorkAndApprovalClears() (gas: 1304474)\n[PASS] test_ActivationDoesNotDilutePastRewardsAndBurnStopsFutureWork() (gas: 1741678)\n[PASS] test_ActivationRequiresPostMintBeneficiaryAndFeeAndEmitsMetadata() (gas: 1514939)\n[PASS] test_AnchorsAreNonzeroPastAndAtMost250BlocksOld() (gas: 51833)\n[PASS] test_AutoExpiredPauseAssignsCarryBeforeNewWorkerJoins() (gas: 1819120)\n[PASS] test_BoundedUpdatesEmitEventsAndOwnershipNeedsAcceptance() (gas: 348116)\n[PASS] test_CapOnlyDecreasesAndSelloutIsPermanent() (gas: 2200627)\n[PASS] test_ConstructorRejectsInvalidOwnerTokenAndDecimals() (gas: 9767636)\n[PASS] test_EmptyAndPausedEmissionIsCarriedThenReleased() (gas: 1385048)\n[PASS] test_EmptyClaimsAndUnauthorizedUnlockDoNotMoveFunds() (gas: 185424)\n[PASS] test_EndMintAndCapAtMintedSnapshotRewards() (gas: 976305)\n[PASS] test_EpochBoundariesIncludeFinalThreeWorkers() (gas: 9674759)\n[PASS] test_FailedActivationPaymentCannotConsumeCarriedMining() (gas: 2040091)\n[PASS] test_FailedBurnPayoutRestoresOwnershipApprovalAndBothReserves() (gas: 1375428)\n[PASS] test_FailedUnstakePayoutPreservesEscrowAndClaimableIMD() (gas: 1649736)\n[PASS] test_FundingOnlyBuildersExactlyOnceAndNoUnfundedMint() (gas: 8842491)\n[PASS] test_HookRewardsRequireBoundHookPostMintWeightAndBacking() (gas: 2454963)\n[PASS] test_IdPoolNeverRepeatsAndCapDoesNotReserveIds() (gas: 68667136)\n[PASS] test_InvalidProofAndOneMintPerBlockRollback() (gas: 995348)\n[PASS] test_MiningReleasePreservesUnclaimedLiabilities() (gas: 1239374)\n[PASS] test_MiningReleaseWithoutActivationReturnsOnlyMiningReserve() (gas: 694227)\n[PASS] test_MixedOwnerClaimBatchesRevertWithoutConsumingEarlierRewards() (gas: 2926678)\n[PASS] test_NoFreeMintOnMissingAllowanceFalseReturnOrTransferTax() (gas: 1823837)\n[PASS] test_NormalAndOverclockedMetadataAndERC4906() (gas: 11820284)\n[PASS] test_OwnerLeversRejectOutsidersAndOutOfRangeInputs() (gas: 539332)\n[PASS] test_PauseExpiresAndCannotBeRenewedBeforeFullDayUnpaused() (gas: 1168072)\n[PASS] test_PermitUnsupportedUsesAllowanceAndSupportedPermitNeedsNoPriorApproval() (gas: 1976461)\n[PASS] test_RejectedMintReceiverRestoresSelloutPaymentAndIdPool() (gas: 2522169)\n[PASS] test_RobinhoodUsesChildChainBlockAndHash() (gas: 5227217)\n[PASS] test_StakeEscrowsAndCannotBeListedBurnedOrExitedEarly() (gas: 1604108)\n[PASS] test_TokenCallbackCannotReenterMint() (gas: 976505)\n[PASS] test_TransfersWorkWhilePausedButRejectUntrackedEscrowAndBadReceivers() (gas: 1209471)\n[PASS] test_ZeroMintCancellationNeverReopens() (gas: 176360)\nSuite result: ok. 44 passed; 0 failed; 0 skipped; finished in 2.40s (20.48s CPU time)\n\nRan 1 test for test/WorkHook.t.sol:WorkHookInvariantTest\n[PASS] invariant_FeesAreFullyBackedAndNeverRedirected() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| HookHandler | advance        | 2141  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | buyback        | 1956  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | claim          | 2084  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | donateAndSweep | 2078  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | endMint        | 2029  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | policy         | 2084  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | stakeOrUnstake | 1974  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | swap           | 2038  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.93s (2.91s CPU time)\n\nRan 1 test for test/WorkersNFT.t.sol:WorkersNFTInvariantTest\n[PASS] invariant_ReservesCustodySupplyAndLiabilities() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| WorkersHandler | activate      | 1150  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | advance       | 1068  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | burn          | 1101  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | changePolicy  | 1053  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | claim         | 1102  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | donate        | 1092  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | finishMint    | 1061  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | hookReward    | 1143  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | mintWorker    | 1115  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | pauseOrResume | 1050  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | release       | 1064  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | stake         | 1101  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | sweep         | 1087  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | transfer      | 1120  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | unstake       | 1077  | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.20s (6.19s CPU time)\n\nRan 4 test suites in 6.20s (13.80s CPU time): 67 tests passed, 0 failed, 0 skipped (67 total tests)\n","passed":true},{"durationMs":30,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WorkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"WorkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"WorkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"WorkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"WorkHook.receive()\",\"WorkHook.setFeeBps(uint16)\",\"WorkHook.setStakerShareBps(uint16)\",\"WorkHook.sweep(address)\",\"WorkersNFT.acceptOwnership()\",\"WorkersNFT.activate(uint256)\",\"WorkersNFT.approve(address,uint256)\",\"WorkersNFT.bindHook()\",\"WorkersNFT.burn(uint256)\",\"WorkersNFT.buyback()\",\"WorkersNFT.claimRewards(uint256[])\",\"WorkersNFT.claimWork(uint256[])\",\"WorkersNFT.endMint()\",\"WorkersNFT.fundPools()\",\"WorkersNFT.mint(uint256,uint256)\",\"WorkersNFT.mintWithPermit(uint256,uint256,uint256,uint8,bytes32,bytes32)\",\"WorkersNFT.notifyHookReward(uint256)\",\"WorkersNFT.pause()\",\"WorkersNFT.receive()\",\"WorkersNFT.releaseMiningRemainder()\",\"WorkersNFT.safeTransferFrom(address,address,uint256)\",\"WorkersNFT.safeTransferFrom(address,address,uint256,bytes)\",\"WorkersNFT.setActivationFee(uint256)\",\"WorkersNFT.setApprovalForAll(address,bool)\",\"WorkersNFT.setBaseURI(string)\",\"WorkersNFT.setCap(uint256)\",\"WorkersNFT.setFloorAdjustment(int8)\",\"WorkersNFT.setHook(address)\",\"WorkersNFT.setPriceScaleBps(uint16)\",\"WorkersNFT.setRoyaltyBps(uint16)\",\"WorkersNFT.stake(uint256,uint256)\",\"WorkersNFT.sweep(address)\",\"WorkersNFT.transferFrom(address,address,uint256)\",\"WorkersNFT.transferOwnership(address)\",\"WorkersNFT.unlockCallback(bytes)\",\"WorkersNFT.unpause()\",\"WorkersNFT.unstake(uint256)\",\"WorkersNFT.updateMining()\"],\"files\":{\"launch.json\":32,\"src/WorkHook.sol\":329,\"src/WorkersNFT.sol\":814,\"test/WorkHook.t.sol\":900,\"test/WorkersNFT.t.sol\":1625},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"launch.json: constructor argument \"$workersNFT\" is neither an address nor an integer, and a launch manifest can express nothing else","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"311ba85b76f678d4afc135740670181ef87c062bb2e2a6cad2ef35f40a83b4d2","verifiedTreeHash":"1ca6ef3670280ad83a4b3e96054c6c59d932f2e3","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":761,"exitCode":0,"name":"build","output":"Compiling 4 files with Solc 0.8.26\nSolc 0.8.26 finished in 629.90ms\nCompiler run successful!\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkHook.sol:138:13\n    │\n138 │         if (tx.origin != workers.deploymentOrigin() && tx.origin != workers.owner()) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkersNFT.sol:429:13\n    │\n429 │         if (tx.origin != deploymentOrigin) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[missing-events-arithmetic]: `tickCumulative` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:231:9\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastObservationTime` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:232:9\n    │\n232 │         lastObservationTime = block.timestamp;\n    │         ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastTick` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:233:9\n    │\n233 │         lastTick = int24(uint24(uint256(poolManager.extsload(_poolSlot)) >> 160));\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/WorkersNFT.sol:67:13\n   │\n67 │         if (IWorkerToken(token).balanceOf(address(this)) != beforeBalance + amount) revert TokenTransferFailed();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[missing-events-access-control]: `owner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:343:9\n    │\n343 │         owner = msg.sender;\n    │         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `pendingOwner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:344:9\n    │\n344 │         pendingOwner = address(0);\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `totalWeight` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:581:9\n    │\n581 │         totalWeight += weight;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_owners` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:299:9\n    │\n299 │         _owners[id] = to;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_buybackAmount` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:771:9\n    │\n771 │         _buybackAmount = 0; // Only one callback can consume this authorization.\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/WorkersNFT.sol:201:17\n    │\n201 │     constructor(address launchToken, address initialOwner) {\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:166:22\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:166:30\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:172:16\n    │\n172 │         return uint256(amount < 0 ? -amount : amount);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:188:34\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\n    │                                  ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:188:27\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:212:56\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:237:13\n    │\n237 │             emit ObservationWritten(block.timestamp, tickCumulative, lastTick);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:199:57\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:199:88\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:204:56\n    │\n204 │             int256 expected = params.amountSpecified + int256(charged);\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/WorkHook.sol:212:42\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:212:49\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:221:13\n    │\n221 │         if (stakersPart != 0) {\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/WorkHook.sol:227:9\n    │\n227 │         emit HookFee(fee, stakersPart, buildersPart);\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/WorkHook.sol:234:13\n    │\n234 │         if (block.timestamp >= latestObservation.timestamp + ORACLE_WINDOW) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:231:46\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkHook.sol:244:13\n    │\n244 │         if (block.timestamp < start.timestamp + ORACLE_WINDOW) start = previousObservation;\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/WorkHook.sol:246:13\n    │\n246 │         if (elapsed < ORACLE_WINDOW) revert OracleNotReady();\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/WorkHook.sol:250:27\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:247:65\n    │\n247 │         int256 cumulative = tickCumulative + int256(lastTick) * int256(block.timestamp - lastObservationTime);\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/WorkHook.sol:249:34\n    │\n249 │         int256 result = change / int256(elapsed);\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/WorkHook.sol:250:36\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\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/WorkHook.sol:251:20\n    │\n251 │         meanTick = int24(result);\n    │                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' 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/WorkHook.sol:268:25\n    │\n268 │         uint256 power = uint256(tick < 0 ? -int256(tick) : int256(tick));\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkHook.sol:327:9\n    │\n327 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:304:36\n    │\n304 │         if (to.code.length != 0 && IWorkerReceiver(to).onERC721Received(msg.sender, from, id, data) != 0x150b7a02) {\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkersNFT.sol:318:15\n    │\n318 │             ++length;\n    │               ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:323:37\n    │\n323 │             text[--length] = bytes1(uint8(48 + number % 10));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' 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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:331:27\n    │\n331 │         return (BUILDERS, salePrice / 10000 * royaltyBps + salePrice % 10000 * royaltyBps / 10000);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:405:16\n    │\n405 │         return block.timestamp < pauseUntil;\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/WorkersNFT.sol:409:39\n    │\n409 │         if (paused() || (hasPaused && block.timestamp < pauseUntil + 1 days)) revert Unavailable();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:473:24\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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/WorkersNFT.sol:473:32\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:480:13\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:480:30\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:482:16\n    │\n482 │         return result > ceiling ? ceiling : result;\n    │                ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `minted` is updated\n    ╭▸ src/WorkersNFT.sol:528:13\n    │\n528 │         try IWorkerToken(IMD).permit(msg.sender, address(this), mintPrice(), deadline, v, r, s) {} catch {}\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:560:9\n    │\n560 │         emit TargetChanged(target);\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/WorkersNFT.sol:300:9\n    │\n300 │         emit Transfer(from, to, 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/WorkersNFT.sol:374:9\n    │\n374 │         emit MintEnded(minted, block.timestamp, burnReward);\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/WorkersNFT.sol:627:9\n    │\n627 │         emit ImdRewardAdded(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/WorkersNFT.sol:571:9\n    │\n571 │         emit Mined(msg.sender, id, hash, overclocked[id], price);\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/WorkersNFT.sol:552:17\n    │\n552 │             if (elapsed < 20) elapsed = 20;\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/WorkersNFT.sol:553:17\n    │\n553 │             if (elapsed > 320) elapsed = 320;\n    │                 ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:580:40\n    │\n580 │         stakes[id] = Stake(msg.sender, uint64(until), weight, accImdPerWeight);\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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:594:45\n    │\n594 │         if (position.account != msg.sender) revert Unauthorized();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:612:13\n    │\n612 │         if (block.timestamp < position.unlockTime) revert Unavailable();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:679:32\n    │\n679 │             uint256 assigned = perWorker * activeWorkers;\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:241:35\n    │\n241 │         if (result == address(0)) revert Invalid();\n    │                                   ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:708:54\n    │\n708 │             if (beneficiaryOf(ids[i]) != msg.sender) revert Unauthorized();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/WorkersNFT.sol:730:58\n    │\n730 │     function releaseMiningRemainder() external onlyOwner nonReentrant whenRunning {\n    │                                                          ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:731:45\n    │\n731 │         if (!mintEnded || miningReleased || block.timestamp < mintEndTime + MINING_DURATION) revert Unavailable();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_buybackMinimum` is updated\n    ╭▸ src/WorkersNFT.sol:757:31\n    │\n757 │         bytes memory result = IWorkHook(hook).poolManager().unlock(\"\");\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:746:38\n    │\n746 │                 || (hasBoughtBack && block.timestamp < lastBuyback + 60)\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/WorkersNFT.sol:762:9\n    │\n762 │         emit Buyback(amount, output);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:778:18\n    │\n778 │                 -int256(amount),\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/WorkersNFT.sol:783:25\n    │\n783 │         int128 delta0 = int128(delta >> 128);\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/WorkersNFT.sol:784:25\n    │\n784 │         int128 delta1 = int128(delta);\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/WorkersNFT.sol:787:23\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:787:56\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:792:47\n    │\n792 │         manager.take(workToken, BURN_ADDRESS, uint256(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/WorkersNFT.sol:793:27\n    │\n793 │         return abi.encode(uint256(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[reentrancy-eth]: uncapped ETH transfer can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:807:26\n    │\n807 │             (bool ok,) = BUILDERS.call{value: amount}(\"\");\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:812:9\n    │\n812 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":6522,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 17 tests for test/WorkHook.t.sol:WorkHookTest\n[PASS] testFuzz_AllFourSwapModesChargeIMDExactlyOnce(uint96,uint16,bool,bool) (runs: 1000, μ: 378749, ~: 388889)\n[PASS] testFuzz_HookSweepOnlySendsToBuilders(uint96,uint96) (runs: 1000, μ: 170538, ~: 171594)\n[PASS] testFuzz_PostMintSplitConservesFeeAndCanBeClaimed(uint96,uint16) (runs: 1000, μ: 1728961, ~: 1744540)\n[PASS] test_BuybackBadOutputWrongInputOrSettlementRollsEverythingBack() (gas: 2675838)\n[PASS] test_BuybackCapsSpendAt100IMDAndCooldownEndsAt60Seconds() (gas: 170037964)\n[PASS] test_BuybackUsesSettlementBurnSinkCooldownAndDoesNotSpendReserves() (gas: 2115789)\n[PASS] test_CallbacksRejectForeignPoolWrongCallerAndUninitializedState() (gas: 425832)\n[PASS] test_Create2FlagsPermissionsPolicyAndBindingBeforeInitialization() (gas: 261708)\n[PASS] test_DefaultBuyAndSellFeeAndZeroFee() (gas: 575682)\n[PASS] test_FeeBoundsEventsAndOwnershipFollowsNFT() (gas: 404938)\n[PASS] test_FeesAndBuybackForOppositeCurrencyOrdering() (gas: 79380632)\n[PASS] test_InitializationRequiresManagerAuthorizedOriginAndCorrectPool() (gas: 363689)\n[PASS] test_OracleWaitsFullWindowAndQuoteIncludesBothFeesAndSlippage() (gas: 251227)\n[PASS] test_OracleWeightsPriorTickAndRoundsNegativeMeanDown() (gas: 893652)\n[PASS] test_PartialSpecifiedIMDFillRevertsAtomicallyAndWorkSpecifiedUsesActualIMD() (gas: 617898)\n[PASS] test_PostMintWithoutStakeAndAfterLastUnstakeRoutesEverythingToBuilders() (gas: 1442772)\n[PASS] test_ZeroIntMinimumAndOversizedAmountsRejectWithoutFees() (gas: 295931)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 2.30s (4.76s CPU time)\n\nRan 37 tests for test/WorkersNFT.t.sol:WorkersNFTTest\n[PASS] testFuzz_BurnRewardStaysFixedAndCannotBeClaimedTwice(uint8,uint8) (runs: 1000, μ: 2411147, ~: 1982606)\n[PASS] testFuzz_EightEraAccrual(uint8,uint32) (runs: 1000, μ: 888660, ~: 889415)\n[PASS] testFuzz_EpochFloorsAndIdleTargetRemainBounded(uint16,uint8,uint16) (runs: 1000, μ: 8851209, ~: 8853342)\n[PASS] testFuzz_MintPicksUnreservedIdAndConservesPayment(uint256,uint16) (runs: 1000, μ: 1164617, ~: 932699)\n[PASS] testFuzz_MintSplitsAndWeightedClaims(uint16,uint8) (runs: 1000, μ: 2315418, ~: 2315449)\n[PASS] testFuzz_PricesUseIMDDecimalsAndBoundedScale(uint256,uint8) (runs: 1000, μ: 60671, ~: 60677)\n[PASS] testFuzz_RetargetEveryEightAndIdleRecovery(uint16) (runs: 1000, μ: 6778614, ~: 6777768)\n[PASS] testFuzz_RoyaltyCannotOverflow(uint256,uint16) (runs: 1000, μ: 43685, ~: 43687)\n[PASS] testFuzz_SweepCannotTouchReserves(uint96,uint96,uint96) (runs: 1000, μ: 1680816, ~: 1681836)\n[PASS] testFuzz_WorkHashBindsChainContractMinerNonceAndPreviousWork(uint256,address) (runs: 1000, μ: 50927, ~: 50927)\n[PASS] test_ActivatedWorkerTransferCarriesAccruedWorkAndApprovalClears() (gas: 1304474)\n[PASS] test_ActivationDoesNotDilutePastRewardsAndBurnStopsFutureWork() (gas: 1741656)\n[PASS] test_ActivationRequiresPostMintBeneficiaryAndFeeAndEmitsMetadata() (gas: 1514939)\n[PASS] test_AnchorsAreNonzeroPastAndAtMost250BlocksOld() (gas: 51921)\n[PASS] test_BoundedUpdatesEmitEventsAndOwnershipNeedsAcceptance() (gas: 348138)\n[PASS] test_CapOnlyDecreasesAndSelloutIsPermanent() (gas: 2200605)\n[PASS] test_ConstructorRejectsInvalidOwnerTokenAndDecimals() (gas: 9767636)\n[PASS] test_EmptyAndPausedEmissionIsCarriedThenReleased() (gas: 1385048)\n[PASS] test_EmptyClaimsAndUnauthorizedUnlockDoNotMoveFunds() (gas: 185380)\n[PASS] test_EndMintAndCapAtMintedSnapshotRewards() (gas: 976305)\n[PASS] test_EpochBoundariesIncludeFinalThreeWorkers() (gas: 9674824)\n[PASS] test_FundingOnlyBuildersExactlyOnceAndNoUnfundedMint() (gas: 8842491)\n[PASS] test_HookRewardsRequireBoundHookPostMintWeightAndBacking() (gas: 2454929)\n[PASS] test_IdPoolNeverRepeatsAndCapDoesNotReserveIds() (gas: 68667114)\n[PASS] test_InvalidProofAndOneMintPerBlockRollback() (gas: 995370)\n[PASS] test_MiningReleasePreservesUnclaimedLiabilities() (gas: 1239285)\n[PASS] test_MiningReleaseWithoutActivationReturnsOnlyMiningReserve() (gas: 694183)\n[PASS] test_NoFreeMintOnMissingAllowanceFalseReturnOrTransferTax() (gas: 1823859)\n[PASS] test_NormalAndOverclockedMetadataAndERC4906() (gas: 11820284)\n[PASS] test_OwnerLeversRejectOutsidersAndOutOfRangeInputs() (gas: 539310)\n[PASS] test_PauseExpiresAndCannotBeRenewedBeforeFullDayUnpaused() (gas: 1168028)\n[PASS] test_PermitUnsupportedUsesAllowanceAndSupportedPermitNeedsNoPriorApproval() (gas: 1976439)\n[PASS] test_RobinhoodUsesChildChainBlockAndHash() (gas: 5227217)\n[PASS] test_StakeEscrowsAndCannotBeListedBurnedOrExitedEarly() (gas: 1604064)\n[PASS] test_TokenCallbackCannotReenterMint() (gas: 976483)\n[PASS] test_TransfersWorkWhilePausedButRejectUntrackedEscrowAndBadReceivers() (gas: 1209471)\n[PASS] test_ZeroMintCancellationNeverReopens() (gas: 176382)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 2.33s (18.42s CPU time)\n\nRan 1 test for test/WorkHook.t.sol:WorkHookInvariantTest\n[PASS] invariant_FeesAreFullyBackedAndNeverRedirected() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| HookHandler | advance        | 2350  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | claim          | 2344  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | donateAndSweep | 2292  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | endMint        | 2334  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | policy         | 2352  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | stakeOrUnstake | 2383  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | swap           | 2329  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.66s (2.65s CPU time)\n\nRan 1 test for test/WorkersNFT.t.sol:WorkersNFTInvariantTest\n[PASS] invariant_ReservesCustodySupplyAndLiabilities() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| WorkersHandler | activate      | 1101  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | advance       | 1053  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | burn          | 1089  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | changePolicy  | 1139  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | claim         | 1126  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | donate        | 1094  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | finishMint    | 1056  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | hookReward    | 1092  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | mintWorker    | 1126  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | pauseOrResume | 1082  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | release       | 1080  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | stake         | 1046  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | sweep         | 1120  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | transfer      | 1074  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | unstake       | 1106  | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.46s (6.45s CPU time)\n\nRan 4 test suites in 6.46s (13.75s CPU time): 56 tests passed, 0 failed, 0 skipped (56 total tests)\n","passed":true},{"durationMs":61,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WorkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"WorkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"WorkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"WorkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"WorkHook.receive()\",\"WorkHook.setFeeBps(uint16)\",\"WorkHook.setStakerShareBps(uint16)\",\"WorkHook.sweep(address)\",\"WorkersNFT.acceptOwnership()\",\"WorkersNFT.activate(uint256)\",\"WorkersNFT.approve(address,uint256)\",\"WorkersNFT.bindHook()\",\"WorkersNFT.burn(uint256)\",\"WorkersNFT.buyback()\",\"WorkersNFT.claimRewards(uint256[])\",\"WorkersNFT.claimWork(uint256[])\",\"WorkersNFT.endMint()\",\"WorkersNFT.fundPools()\",\"WorkersNFT.mint(uint256,uint256)\",\"WorkersNFT.mintWithPermit(uint256,uint256,uint256,uint8,bytes32,bytes32)\",\"WorkersNFT.notifyHookReward(uint256)\",\"WorkersNFT.pause()\",\"WorkersNFT.receive()\",\"WorkersNFT.releaseMiningRemainder()\",\"WorkersNFT.safeTransferFrom(address,address,uint256)\",\"WorkersNFT.safeTransferFrom(address,address,uint256,bytes)\",\"WorkersNFT.setActivationFee(uint256)\",\"WorkersNFT.setApprovalForAll(address,bool)\",\"WorkersNFT.setBaseURI(string)\",\"WorkersNFT.setCap(uint256)\",\"WorkersNFT.setFloorAdjustment(int8)\",\"WorkersNFT.setHook(address)\",\"WorkersNFT.setPriceScaleBps(uint16)\",\"WorkersNFT.setRoyaltyBps(uint16)\",\"WorkersNFT.stake(uint256,uint256)\",\"WorkersNFT.sweep(address)\",\"WorkersNFT.transferFrom(address,address,uint256)\",\"WorkersNFT.transferOwnership(address)\",\"WorkersNFT.unlockCallback(bytes)\",\"WorkersNFT.unpause()\",\"WorkersNFT.unstake(uint256)\",\"WorkersNFT.updateMining()\"],\"files\":{\"src/WorkHook.sol\":329,\"src/WorkersNFT.sol\":814,\"test/WorkHook.t.sol\":755,\"test/WorkersNFT.t.sol\":1370},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3d84b46310432a1887db969d869e267c24a264895638d20e47474a6a8a8ea885","verifiedTreeHash":"1776f8c8551cc4f30a86986c4a3988f7191063a7","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":721,"exitCode":0,"name":"build","output":"Compiling 4 files with Solc 0.8.26\nSolc 0.8.26 finished in 609.56ms\nCompiler run successful!\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkHook.sol:138:13\n    │\n138 │         if (tx.origin != workers.deploymentOrigin() && tx.origin != workers.owner()) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkersNFT.sol:429:13\n    │\n429 │         if (tx.origin != deploymentOrigin) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/WorkersNFT.sol:67:13\n   │\n67 │         if (IWorkerToken(token).balanceOf(address(this)) != beforeBalance + amount) revert TokenTransferFailed();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[missing-events-arithmetic]: `tickCumulative` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:231:9\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastObservationTime` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:232:9\n    │\n232 │         lastObservationTime = block.timestamp;\n    │         ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastTick` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:233:9\n    │\n233 │         lastTick = int24(uint24(uint256(poolManager.extsload(_poolSlot)) >> 160));\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-access-control]: `owner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:343:9\n    │\n343 │         owner = msg.sender;\n    │         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `pendingOwner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:344:9\n    │\n344 │         pendingOwner = address(0);\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `totalWeight` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:581:9\n    │\n581 │         totalWeight += weight;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_owners` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:299:9\n    │\n299 │         _owners[id] = to;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_buybackAmount` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:771:9\n    │\n771 │         _buybackAmount = 0; // Only one callback can consume this authorization.\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/WorkersNFT.sol:201:17\n    │\n201 │     constructor(address launchToken, address initialOwner) {\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:166:22\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:166:30\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:172:16\n    │\n172 │         return uint256(amount < 0 ? -amount : amount);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:188:34\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\n    │                                  ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:188:27\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\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[reentrancy-no-eth]: external call can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:304:36\n    │\n304 │         if (to.code.length != 0 && IWorkerReceiver(to).onERC721Received(msg.sender, from, id, data) != 0x150b7a02) {\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkersNFT.sol:318:15\n    │\n318 │             ++length;\n    │               ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:323:37\n    │\n323 │             text[--length] = bytes1(uint8(48 + number % 10));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' 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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:331:27\n    │\n331 │         return (BUILDERS, salePrice / 10000 * royaltyBps + salePrice % 10000 * royaltyBps / 10000);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:212:56\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:237:13\n    │\n237 │             emit ObservationWritten(block.timestamp, tickCumulative, lastTick);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:199:57\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:199:88\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:204:56\n    │\n204 │             int256 expected = params.amountSpecified + int256(charged);\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/WorkHook.sol:212:42\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:212:49\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:221:13\n    │\n221 │         if (stakersPart != 0) {\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/WorkHook.sol:227:9\n    │\n227 │         emit HookFee(fee, stakersPart, buildersPart);\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/WorkHook.sol:234:13\n    │\n234 │         if (block.timestamp >= latestObservation.timestamp + ORACLE_WINDOW) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:231:46\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkHook.sol:244:13\n    │\n244 │         if (block.timestamp < start.timestamp + ORACLE_WINDOW) start = previousObservation;\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/WorkHook.sol:246:13\n    │\n246 │         if (elapsed < ORACLE_WINDOW) revert OracleNotReady();\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/WorkHook.sol:250:27\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:247:65\n    │\n247 │         int256 cumulative = tickCumulative + int256(lastTick) * int256(block.timestamp - lastObservationTime);\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/WorkHook.sol:249:34\n    │\n249 │         int256 result = change / int256(elapsed);\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/WorkHook.sol:250:36\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\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/WorkHook.sol:251:20\n    │\n251 │         meanTick = int24(result);\n    │                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' 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/WorkHook.sol:268:25\n    │\n268 │         uint256 power = uint256(tick < 0 ? -int256(tick) : int256(tick));\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkHook.sol:327:9\n    │\n327 │         emit Swept(token, 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/WorkersNFT.sol:405:16\n    │\n405 │         return block.timestamp < pauseUntil;\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/WorkersNFT.sol:409:39\n    │\n409 │         if (paused() || (hasPaused && block.timestamp < pauseUntil + 1 days)) revert Unavailable();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:473:24\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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/WorkersNFT.sol:473:32\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:480:13\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:480:30\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:482:16\n    │\n482 │         return result > ceiling ? ceiling : result;\n    │                ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `minted` is updated\n    ╭▸ src/WorkersNFT.sol:528:13\n    │\n528 │         try IWorkerToken(IMD).permit(msg.sender, address(this), mintPrice(), deadline, v, r, s) {} catch {}\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:560:9\n    │\n560 │         emit TargetChanged(target);\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/WorkersNFT.sol:300:9\n    │\n300 │         emit Transfer(from, to, 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/WorkersNFT.sol:374:9\n    │\n374 │         emit MintEnded(minted, block.timestamp, burnReward);\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/WorkersNFT.sol:627:9\n    │\n627 │         emit ImdRewardAdded(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/WorkersNFT.sol:571:9\n    │\n571 │         emit Mined(msg.sender, id, hash, overclocked[id], price);\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/WorkersNFT.sol:552:17\n    │\n552 │             if (elapsed < 20) elapsed = 20;\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/WorkersNFT.sol:553:17\n    │\n553 │             if (elapsed > 320) elapsed = 320;\n    │                 ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:580:40\n    │\n580 │         stakes[id] = Stake(msg.sender, uint64(until), weight, accImdPerWeight);\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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:594:45\n    │\n594 │         if (position.account != msg.sender) revert Unauthorized();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:612:13\n    │\n612 │         if (block.timestamp < position.unlockTime) revert Unavailable();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:679:32\n    │\n679 │             uint256 assigned = perWorker * activeWorkers;\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:241:35\n    │\n241 │         if (result == address(0)) revert Invalid();\n    │                                   ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:708:54\n    │\n708 │             if (beneficiaryOf(ids[i]) != msg.sender) revert Unauthorized();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/WorkersNFT.sol:730:58\n    │\n730 │     function releaseMiningRemainder() external onlyOwner nonReentrant whenRunning {\n    │                                                          ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:731:45\n    │\n731 │         if (!mintEnded || miningReleased || block.timestamp < mintEndTime + MINING_DURATION) revert Unavailable();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_buybackMinimum` is updated\n    ╭▸ src/WorkersNFT.sol:757:31\n    │\n757 │         bytes memory result = IWorkHook(hook).poolManager().unlock(\"\");\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:746:38\n    │\n746 │                 || (hasBoughtBack && block.timestamp < lastBuyback + 60)\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/WorkersNFT.sol:762:9\n    │\n762 │         emit Buyback(amount, output);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:778:18\n    │\n778 │                 -int256(amount),\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/WorkersNFT.sol:783:25\n    │\n783 │         int128 delta0 = int128(delta >> 128);\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/WorkersNFT.sol:784:25\n    │\n784 │         int128 delta1 = int128(delta);\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/WorkersNFT.sol:787:23\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:787:56\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:792:47\n    │\n792 │         manager.take(workToken, BURN_ADDRESS, uint256(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/WorkersNFT.sol:793:27\n    │\n793 │         return abi.encode(uint256(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[reentrancy-eth]: uncapped ETH transfer can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:807:26\n    │\n807 │             (bool ok,) = BUILDERS.call{value: amount}(\"\");\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:812:9\n    │\n812 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":6865,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 19 tests for test/WorkHook.t.sol:WorkHookTest\n[PASS] testFuzz_AllFourSwapModesChargeIMDExactlyOnce(uint96,uint16,bool,bool) (runs: 1000, μ: 379544, ~: 388885)\n[PASS] testFuzz_HookSweepOnlySendsToBuilders(uint96,uint96) (runs: 1000, μ: 170349, ~: 171606)\n[PASS] testFuzz_PostMintSplitConservesFeeAndCanBeClaimed(uint96,uint16) (runs: 1000, μ: 1726263, ~: 1744564)\n[PASS] test_BuybackBadOutputWrongInputOrSettlementRollsEverythingBack() (gas: 2675816)\n[PASS] test_BuybackCapsSpendAt100IMDAndCooldownEndsAt60Seconds() (gas: 170037986)\n[PASS] test_BuybackUsesSettlementBurnSinkCooldownAndDoesNotSpendReserves() (gas: 2115789)\n[PASS] test_CallbacksRejectForeignPoolWrongCallerAndUninitializedState() (gas: 425810)\n[PASS] test_Create2FlagsPermissionsPolicyAndBindingBeforeInitialization() (gas: 261686)\n[PASS] test_DefaultBuyAndSellFeeAndZeroFee() (gas: 575682)\n[PASS] test_FeeBoundsEventsAndOwnershipFollowsNFT() (gas: 405026)\n[PASS] test_FeesAndBuybackForOppositeCurrencyOrdering() (gas: 79380654)\n[PASS] test_InitializationRequiresManagerAuthorizedOriginAndCorrectPool() (gas: 363689)\n[PASS] test_OracleWaitsFullWindowAndQuoteIncludesBothFeesAndSlippage() (gas: 251227)\n[PASS] test_OracleWeightsPriorTickAndRoundsNegativeMeanDown() (gas: 893652)\n[PASS] test_PartialSpecifiedIMDFillRevertsAtomicallyAndWorkSpecifiedUsesActualIMD() (gas: 617898)\n[PASS] test_PostMintPartialFillRollsBackStakerNotificationAndBuildersPayment() (gas: 1629698)\n[PASS] test_PostMintWithoutStakeAndAfterLastUnstakeRoutesEverythingToBuilders() (gas: 1442794)\n[PASS] test_TaxedHookRewardCannotCreateUnbackedStakerLiability() (gas: 1259585)\n[PASS] test_ZeroIntMinimumAndOversizedAmountsRejectWithoutFees() (gas: 296020)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 1.31s (1.88s CPU time)\n\nRan 41 tests for test/WorkersNFT.t.sol:WorkersNFTTest\n[PASS] testFuzz_BurnRewardStaysFixedAndCannotBeClaimedTwice(uint8,uint8) (runs: 1000, μ: 2337241, ~: 1982694)\n[PASS] testFuzz_EightEraAccrual(uint8,uint32) (runs: 1000, μ: 888400, ~: 889415)\n[PASS] testFuzz_EpochFloorsAndIdleTargetRemainBounded(uint16,uint8,uint16) (runs: 1000, μ: 8851658, ~: 8853354)\n[PASS] testFuzz_FrequentClaimsRetainFractionalIMDCredit(uint8,uint8) (runs: 1000, μ: 3444323, ~: 2871481)\n[PASS] testFuzz_MintPicksUnreservedIdAndConservesPayment(uint256,uint16) (runs: 1000, μ: 1163531, ~: 932699)\n[PASS] testFuzz_MintSplitsAndWeightedClaims(uint16,uint8) (runs: 1000, μ: 2315426, ~: 2315449)\n[PASS] testFuzz_PricesUseIMDDecimalsAndBoundedScale(uint256,uint8) (runs: 1000, μ: 60674, ~: 60677)\n[PASS] testFuzz_RetargetEveryEightAndIdleRecovery(uint16) (runs: 1000, μ: 6778905, ~: 6777746)\n[PASS] testFuzz_RoyaltyCannotOverflow(uint256,uint16) (runs: 1000, μ: 43690, ~: 43687)\n[PASS] testFuzz_SweepCannotTouchReserves(uint96,uint96,uint96) (runs: 1000, μ: 1681050, ~: 1681848)\n[PASS] testFuzz_WorkHashBindsChainContractMinerNonceAndPreviousWork(uint256,address) (runs: 1000, μ: 50927, ~: 50927)\n[PASS] test_ActivatedWorkerTransferCarriesAccruedWorkAndApprovalClears() (gas: 1304474)\n[PASS] test_ActivationDoesNotDilutePastRewardsAndBurnStopsFutureWork() (gas: 1741678)\n[PASS] test_ActivationRequiresPostMintBeneficiaryAndFeeAndEmitsMetadata() (gas: 1514939)\n[PASS] test_AnchorsAreNonzeroPastAndAtMost250BlocksOld() (gas: 51921)\n[PASS] test_BoundedUpdatesEmitEventsAndOwnershipNeedsAcceptance() (gas: 348138)\n[PASS] test_CapOnlyDecreasesAndSelloutIsPermanent() (gas: 2200583)\n[PASS] test_ConstructorRejectsInvalidOwnerTokenAndDecimals() (gas: 9767636)\n[PASS] test_EmptyAndPausedEmissionIsCarriedThenReleased() (gas: 1385048)\n[PASS] test_EmptyClaimsAndUnauthorizedUnlockDoNotMoveFunds() (gas: 185380)\n[PASS] test_EndMintAndCapAtMintedSnapshotRewards() (gas: 976305)\n[PASS] test_EpochBoundariesIncludeFinalThreeWorkers() (gas: 9674846)\n[PASS] test_FailedBurnPayoutRestoresOwnershipApprovalAndBothReserves() (gas: 1375318)\n[PASS] test_FailedUnstakePayoutPreservesEscrowAndClaimableIMD() (gas: 1649736)\n[PASS] test_FundingOnlyBuildersExactlyOnceAndNoUnfundedMint() (gas: 8842491)\n[PASS] test_HookRewardsRequireBoundHookPostMintWeightAndBacking() (gas: 2454963)\n[PASS] test_IdPoolNeverRepeatsAndCapDoesNotReserveIds() (gas: 68667114)\n[PASS] test_InvalidProofAndOneMintPerBlockRollback() (gas: 995348)\n[PASS] test_MiningReleasePreservesUnclaimedLiabilities() (gas: 1239374)\n[PASS] test_MiningReleaseWithoutActivationReturnsOnlyMiningReserve() (gas: 694183)\n[PASS] test_MixedOwnerClaimBatchesRevertWithoutConsumingEarlierRewards() (gas: 2926634)\n[PASS] test_NoFreeMintOnMissingAllowanceFalseReturnOrTransferTax() (gas: 1823837)\n[PASS] test_NormalAndOverclockedMetadataAndERC4906() (gas: 11820284)\n[PASS] test_OwnerLeversRejectOutsidersAndOutOfRangeInputs() (gas: 539310)\n[PASS] test_PauseExpiresAndCannotBeRenewedBeforeFullDayUnpaused() (gas: 1168028)\n[PASS] test_PermitUnsupportedUsesAllowanceAndSupportedPermitNeedsNoPriorApproval() (gas: 1976439)\n[PASS] test_RobinhoodUsesChildChainBlockAndHash() (gas: 5227217)\n[PASS] test_StakeEscrowsAndCannotBeListedBurnedOrExitedEarly() (gas: 1604064)\n[PASS] test_TokenCallbackCannotReenterMint() (gas: 976572)\n[PASS] test_TransfersWorkWhilePausedButRejectUntrackedEscrowAndBadReceivers() (gas: 1209471)\n[PASS] test_ZeroMintCancellationNeverReopens() (gas: 176360)\nSuite result: ok. 41 passed; 0 failed; 0 skipped; finished in 2.29s (17.99s CPU time)\n\nRan 1 test for test/WorkHook.t.sol:WorkHookInvariantTest\n[PASS] invariant_FeesAreFullyBackedAndNeverRedirected() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| HookHandler | advance        | 2046  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | buyback        | 2098  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | claim          | 1988  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | donateAndSweep | 2028  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | endMint        | 2038  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | policy         | 2014  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | stakeOrUnstake | 2117  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | swap           | 2055  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.20s (3.18s CPU time)\n\nRan 1 test for test/WorkersNFT.t.sol:WorkersNFTInvariantTest\n[PASS] invariant_ReservesCustodySupplyAndLiabilities() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| WorkersHandler | activate      | 1044  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | advance       | 1116  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | burn          | 1115  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | changePolicy  | 1118  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | claim         | 1063  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | donate        | 1022  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | finishMint    | 1098  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | hookReward    | 1112  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | mintWorker    | 1108  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | pauseOrResume | 1076  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | release       | 1107  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | stake         | 1076  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | sweep         | 1070  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | transfer      | 1184  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | unstake       | 1075  | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.81s (6.80s CPU time)\n\nRan 4 test suites in 6.81s (13.60s CPU time): 62 tests passed, 0 failed, 0 skipped (62 total tests)\n","passed":true},{"durationMs":34,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WorkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"WorkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"WorkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"WorkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"WorkHook.receive()\",\"WorkHook.setFeeBps(uint16)\",\"WorkHook.setStakerShareBps(uint16)\",\"WorkHook.sweep(address)\",\"WorkersNFT.acceptOwnership()\",\"WorkersNFT.activate(uint256)\",\"WorkersNFT.approve(address,uint256)\",\"WorkersNFT.bindHook()\",\"WorkersNFT.burn(uint256)\",\"WorkersNFT.buyback()\",\"WorkersNFT.claimRewards(uint256[])\",\"WorkersNFT.claimWork(uint256[])\",\"WorkersNFT.endMint()\",\"WorkersNFT.fundPools()\",\"WorkersNFT.mint(uint256,uint256)\",\"WorkersNFT.mintWithPermit(uint256,uint256,uint256,uint8,bytes32,bytes32)\",\"WorkersNFT.notifyHookReward(uint256)\",\"WorkersNFT.pause()\",\"WorkersNFT.receive()\",\"WorkersNFT.releaseMiningRemainder()\",\"WorkersNFT.safeTransferFrom(address,address,uint256)\",\"WorkersNFT.safeTransferFrom(address,address,uint256,bytes)\",\"WorkersNFT.setActivationFee(uint256)\",\"WorkersNFT.setApprovalForAll(address,bool)\",\"WorkersNFT.setBaseURI(string)\",\"WorkersNFT.setCap(uint256)\",\"WorkersNFT.setFloorAdjustment(int8)\",\"WorkersNFT.setHook(address)\",\"WorkersNFT.setPriceScaleBps(uint16)\",\"WorkersNFT.setRoyaltyBps(uint16)\",\"WorkersNFT.stake(uint256,uint256)\",\"WorkersNFT.sweep(address)\",\"WorkersNFT.transferFrom(address,address,uint256)\",\"WorkersNFT.transferOwnership(address)\",\"WorkersNFT.unlockCallback(bytes)\",\"WorkersNFT.unpause()\",\"WorkersNFT.unstake(uint256)\",\"WorkersNFT.updateMining()\"],\"files\":{\"src/WorkHook.sol\":329,\"src/WorkersNFT.sol\":814,\"test/WorkHook.t.sol\":839,\"test/WorkersNFT.t.sol\":1499},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"5e3b3cb982e3501fd28b657d4347c29343dcceedf54dffd185a8f58f86cdd3ca","verifiedTreeHash":"a61f9ee9fc475ea561fa8912cd8f0a7b3853403c","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":347,"exitCode":0,"name":"build","output":"Compiling 2 files with Solc 0.8.26\nSolc 0.8.26 finished in 184.26ms\nCompiler run successful!\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkHook.sol:138:13\n    │\n138 │         if (tx.origin != workers.deploymentOrigin() && tx.origin != workers.owner()) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkersNFT.sol:429:13\n    │\n429 │         if (tx.origin != deploymentOrigin) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/WorkersNFT.sol:67:13\n   │\n67 │         if (IWorkerToken(token).balanceOf(address(this)) != beforeBalance + amount) revert TokenTransferFailed();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[missing-events-arithmetic]: `tickCumulative` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:231:9\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastObservationTime` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:232:9\n    │\n232 │         lastObservationTime = block.timestamp;\n    │         ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastTick` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:233:9\n    │\n233 │         lastTick = int24(uint24(uint256(poolManager.extsload(_poolSlot)) >> 160));\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-access-control]: `owner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:343:9\n    │\n343 │         owner = msg.sender;\n    │         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `pendingOwner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:344:9\n    │\n344 │         pendingOwner = address(0);\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `totalWeight` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:581:9\n    │\n581 │         totalWeight += weight;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_owners` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:299:9\n    │\n299 │         _owners[id] = to;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_buybackAmount` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:771:9\n    │\n771 │         _buybackAmount = 0; // Only one callback can consume this authorization.\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/WorkersNFT.sol:201:17\n    │\n201 │     constructor(address launchToken, address initialOwner) {\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:166:22\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:166:30\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:172:16\n    │\n172 │         return uint256(amount < 0 ? -amount : amount);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:188:34\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\n    │                                  ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:188:27\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:212:56\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:237:13\n    │\n237 │             emit ObservationWritten(block.timestamp, tickCumulative, lastTick);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:199:57\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:199:88\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:204:56\n    │\n204 │             int256 expected = params.amountSpecified + int256(charged);\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/WorkHook.sol:212:42\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:212:49\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:221:13\n    │\n221 │         if (stakersPart != 0) {\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/WorkHook.sol:227:9\n    │\n227 │         emit HookFee(fee, stakersPart, buildersPart);\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/WorkHook.sol:234:13\n    │\n234 │         if (block.timestamp >= latestObservation.timestamp + ORACLE_WINDOW) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:231:46\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkHook.sol:244:13\n    │\n244 │         if (block.timestamp < start.timestamp + ORACLE_WINDOW) start = previousObservation;\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/WorkHook.sol:246:13\n    │\n246 │         if (elapsed < ORACLE_WINDOW) revert OracleNotReady();\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/WorkHook.sol:250:27\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:247:65\n    │\n247 │         int256 cumulative = tickCumulative + int256(lastTick) * int256(block.timestamp - lastObservationTime);\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/WorkHook.sol:249:34\n    │\n249 │         int256 result = change / int256(elapsed);\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/WorkHook.sol:250:36\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\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/WorkHook.sol:251:20\n    │\n251 │         meanTick = int24(result);\n    │                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' 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/WorkHook.sol:268:25\n    │\n268 │         uint256 power = uint256(tick < 0 ? -int256(tick) : int256(tick));\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkHook.sol:327:9\n    │\n327 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:304:36\n    │\n304 │         if (to.code.length != 0 && IWorkerReceiver(to).onERC721Received(msg.sender, from, id, data) != 0x150b7a02) {\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkersNFT.sol:318:15\n    │\n318 │             ++length;\n    │               ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:323:37\n    │\n323 │             text[--length] = bytes1(uint8(48 + number % 10));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' 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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:331:27\n    │\n331 │         return (BUILDERS, salePrice / 10000 * royaltyBps + salePrice % 10000 * royaltyBps / 10000);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:405:16\n    │\n405 │         return block.timestamp < pauseUntil;\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/WorkersNFT.sol:409:39\n    │\n409 │         if (paused() || (hasPaused && block.timestamp < pauseUntil + 1 days)) revert Unavailable();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:473:24\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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/WorkersNFT.sol:473:32\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:480:13\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:480:30\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:482:16\n    │\n482 │         return result > ceiling ? ceiling : result;\n    │                ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `minted` is updated\n    ╭▸ src/WorkersNFT.sol:528:13\n    │\n528 │         try IWorkerToken(IMD).permit(msg.sender, address(this), mintPrice(), deadline, v, r, s) {} catch {}\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:560:9\n    │\n560 │         emit TargetChanged(target);\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/WorkersNFT.sol:300:9\n    │\n300 │         emit Transfer(from, to, 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/WorkersNFT.sol:374:9\n    │\n374 │         emit MintEnded(minted, block.timestamp, burnReward);\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/WorkersNFT.sol:627:9\n    │\n627 │         emit ImdRewardAdded(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/WorkersNFT.sol:571:9\n    │\n571 │         emit Mined(msg.sender, id, hash, overclocked[id], price);\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/WorkersNFT.sol:552:17\n    │\n552 │             if (elapsed < 20) elapsed = 20;\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/WorkersNFT.sol:553:17\n    │\n553 │             if (elapsed > 320) elapsed = 320;\n    │                 ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:580:40\n    │\n580 │         stakes[id] = Stake(msg.sender, uint64(until), weight, accImdPerWeight);\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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:594:45\n    │\n594 │         if (position.account != msg.sender) revert Unauthorized();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:612:13\n    │\n612 │         if (block.timestamp < position.unlockTime) revert Unavailable();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:679:32\n    │\n679 │             uint256 assigned = perWorker * activeWorkers;\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:241:35\n    │\n241 │         if (result == address(0)) revert Invalid();\n    │                                   ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:708:54\n    │\n708 │             if (beneficiaryOf(ids[i]) != msg.sender) revert Unauthorized();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/WorkersNFT.sol:730:58\n    │\n730 │     function releaseMiningRemainder() external onlyOwner nonReentrant whenRunning {\n    │                                                          ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:731:45\n    │\n731 │         if (!mintEnded || miningReleased || block.timestamp < mintEndTime + MINING_DURATION) revert Unavailable();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_buybackMinimum` is updated\n    ╭▸ src/WorkersNFT.sol:757:31\n    │\n757 │         bytes memory result = IWorkHook(hook).poolManager().unlock(\"\");\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:746:38\n    │\n746 │                 || (hasBoughtBack && block.timestamp < lastBuyback + 60)\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/WorkersNFT.sol:762:9\n    │\n762 │         emit Buyback(amount, output);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:778:18\n    │\n778 │                 -int256(amount),\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/WorkersNFT.sol:783:25\n    │\n783 │         int128 delta0 = int128(delta >> 128);\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/WorkersNFT.sol:784:25\n    │\n784 │         int128 delta1 = int128(delta);\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/WorkersNFT.sol:787:23\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:787:56\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:792:47\n    │\n792 │         manager.take(workToken, BURN_ADDRESS, uint256(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/WorkersNFT.sol:793:27\n    │\n793 │         return abi.encode(uint256(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[reentrancy-eth]: uncapped ETH transfer can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:807:26\n    │\n807 │             (bool ok,) = BUILDERS.call{value: amount}(\"\");\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:812:9\n    │\n812 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":57,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\nWarning: No tests found in project! Forge looks for functions that start with `test`\n","passed":true},{"durationMs":26,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WorkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"WorkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"WorkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"WorkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"WorkHook.receive()\",\"WorkHook.setFeeBps(uint16)\",\"WorkHook.setStakerShareBps(uint16)\",\"WorkHook.sweep(address)\",\"WorkersNFT.acceptOwnership()\",\"WorkersNFT.activate(uint256)\",\"WorkersNFT.approve(address,uint256)\",\"WorkersNFT.bindHook()\",\"WorkersNFT.burn(uint256)\",\"WorkersNFT.buyback()\",\"WorkersNFT.claimRewards(uint256[])\",\"WorkersNFT.claimWork(uint256[])\",\"WorkersNFT.endMint()\",\"WorkersNFT.fundPools()\",\"WorkersNFT.mint(uint256,uint256)\",\"WorkersNFT.mintWithPermit(uint256,uint256,uint256,uint8,bytes32,bytes32)\",\"WorkersNFT.notifyHookReward(uint256)\",\"WorkersNFT.pause()\",\"WorkersNFT.receive()\",\"WorkersNFT.releaseMiningRemainder()\",\"WorkersNFT.safeTransferFrom(address,address,uint256)\",\"WorkersNFT.safeTransferFrom(address,address,uint256,bytes)\",\"WorkersNFT.setActivationFee(uint256)\",\"WorkersNFT.setApprovalForAll(address,bool)\",\"WorkersNFT.setBaseURI(string)\",\"WorkersNFT.setCap(uint256)\",\"WorkersNFT.setFloorAdjustment(int8)\",\"WorkersNFT.setHook(address)\",\"WorkersNFT.setPriceScaleBps(uint16)\",\"WorkersNFT.setRoyaltyBps(uint16)\",\"WorkersNFT.stake(uint256,uint256)\",\"WorkersNFT.sweep(address)\",\"WorkersNFT.transferFrom(address,address,uint256)\",\"WorkersNFT.transferOwnership(address)\",\"WorkersNFT.unlockCallback(bytes)\",\"WorkersNFT.unpause()\",\"WorkersNFT.unstake(uint256)\",\"WorkersNFT.updateMining()\"],\"files\":{\"src/WorkHook.sol\":329,\"src/WorkersNFT.sol\":814},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":275,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":462,"exitCode":0,"name":"aderyn","output":"[high] incorrect-caret-operator at src/WorkHook.sol:305: Incorrect use of caret operator\n[high] reentrancy-state-change at src/WorkHook.sol:77: Reentrancy: State change after external call (10 places)\n[high] tx-origin-used-for-auth at src/WorkHook.sol:138: Use of `tx.origin` for authentication (2 places)\n[high] unchecked-send at src/WorkHook.sol:325: Unchecked `bool success` value for ETH send (10 places)\n[high] unsafe-casting at src/WorkHook.sol:251: Unsafe Casting of integers (2 places)\n[low] centralization-risk at src/WorkHook.sol:118: Centralization Risk (14 places)\n[low] costly-loop at src/WorkersNFT.sol:602: Costly operations inside loop (2 places)\n[low] division-before-multiplication at src/WorkersNFT.sol:331: Incorrect Order of Division and Multiplication\n[low] large-numeric-literal at src/WorkHook.sol:32: Large Numeric Literal (17 places)\n[low] literal-instead-of-constant at src/WorkHook.sol:125: Literal Instead of Constant (55 places)\n[low] missing-inheritance at src/WorkHook.sol:9: Missing Inheritance\n[low] non-reentrant-not-first at src/WorkersNFT.sol:730: `nonReentrant` is Not the First Modifier\n[low] require-revert-in-loop at src/WorkersNFT.sol:602: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/WorkersNFT.sol:765: State Change Without Event\n[low] unchecked-return at src/WorkersNFT.sol:254: Unchecked Return (3 places)\n[low] uninitialized-local-variable at src/WorkersNFT.sol:602: Uninitialized Local Variable (3 places)\n[low] unsafe-erc20-operation at src/WorkersNFT.sol:59: Unsafe ERC20 Operation\n[low] unused-public-function at src/WorkersNFT.sol:272: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6c5d782f550525e29ef84b481b02f38c3e490135c4708c19c0b9092540145177","verifiedTreeHash":"1f4d3ff04a51338680f76592ce18dc3d467d7f08","verifierVersion":"0.1.0+be003835"},{"checks":[{"durationMs":754,"exitCode":0,"name":"build","output":"Compiling 4 files with Solc 0.8.26\nSolc 0.8.26 finished in 647.68ms\nCompiler run successful!\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkHook.sol:138:13\n    │\n138 │         if (tx.origin != workers.deploymentOrigin() && tx.origin != workers.owner()) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[tx-origin]: `tx.origin` is used for authorization\n    ╭▸ src/WorkersNFT.sol:429:13\n    │\n429 │         if (tx.origin != deploymentOrigin) revert Unauthorized();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/tx-origin\n\nwarning[missing-events-arithmetic]: `tickCumulative` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:231:9\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastObservationTime` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:232:9\n    │\n232 │         lastObservationTime = block.timestamp;\n    │         ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastTick` is changed without an event but is used in arithmetic\n    ╭▸ src/WorkHook.sol:233:9\n    │\n233 │         lastTick = int24(uint24(uint256(poolManager.extsload(_poolSlot)) >> 160));\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/WorkersNFT.sol:67:13\n   │\n67 │         if (IWorkerToken(token).balanceOf(address(this)) != beforeBalance + amount) revert TokenTransferFailed();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[missing-events-access-control]: `owner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:343:9\n    │\n343 │         owner = msg.sender;\n    │         ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `pendingOwner` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:344:9\n    │\n344 │         pendingOwner = address(0);\n    │         ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `totalWeight` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:581:9\n    │\n581 │         totalWeight += weight;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_owners` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:299:9\n    │\n299 │         _owners[id] = to;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `_buybackAmount` is changed without an event but is used for access control\n    ╭▸ src/WorkersNFT.sol:771:9\n    │\n771 │         _buybackAmount = 0; // Only one callback can consume this authorization.\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n    ╭▸ src/WorkersNFT.sol:201:17\n    │\n201 │     constructor(address launchToken, address initialOwner) {\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:166:22\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:166:30\n    │\n166 │         if (amount > uint256(uint128(type(int128).max)) / 2) revert Invalid();\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/WorkHook.sol:172:16\n    │\n172 │         return uint256(amount < 0 ? -amount : amount);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:188:34\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\n    │                                  ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:188:27\n    │\n188 │         beforeSwapDelta = int256(fee << 128);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:212:56\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:237:13\n    │\n237 │             emit ObservationWritten(block.timestamp, tickCumulative, lastTick);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:199:57\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:199:88\n    │\n199 │         int256 imdDelta = key.currency0 == imd ? int256(int128(delta >> 128)) : int256(int128(delta));\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/WorkHook.sol:204:56\n    │\n204 │             int256 expected = params.amountSpecified + int256(charged);\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/WorkHook.sol:212:42\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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/WorkHook.sol:212:49\n    │\n212 │         return (this.afterSwap.selector, int128(int256(fee)));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkHook.sol:221:13\n    │\n221 │         if (stakersPart != 0) {\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/WorkHook.sol:227:9\n    │\n227 │         emit HookFee(fee, stakersPart, buildersPart);\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/WorkHook.sol:234:13\n    │\n234 │         if (block.timestamp >= latestObservation.timestamp + ORACLE_WINDOW) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:231:46\n    │\n231 │         tickCumulative += int256(lastTick) * int256(block.timestamp - lastObservationTime);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkHook.sol:244:13\n    │\n244 │         if (block.timestamp < start.timestamp + ORACLE_WINDOW) start = previousObservation;\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/WorkHook.sol:246:13\n    │\n246 │         if (elapsed < ORACLE_WINDOW) revert OracleNotReady();\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/WorkHook.sol:250:27\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkHook.sol:247:65\n    │\n247 │         int256 cumulative = tickCumulative + int256(lastTick) * int256(block.timestamp - lastObservationTime);\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/WorkHook.sol:249:34\n    │\n249 │         int256 result = change / int256(elapsed);\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/WorkHook.sol:250:36\n    │\n250 │         if (change < 0 && change % int256(elapsed) != 0) --result;\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/WorkHook.sol:251:20\n    │\n251 │         meanTick = int24(result);\n    │                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' 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/WorkHook.sol:268:25\n    │\n268 │         uint256 power = uint256(tick < 0 ? -int256(tick) : int256(tick));\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkHook.sol:327:9\n    │\n327 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:304:36\n    │\n304 │         if (to.code.length != 0 && IWorkerReceiver(to).onERC721Received(msg.sender, from, id, data) != 0x150b7a02) {\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/WorkersNFT.sol:318:15\n    │\n318 │             ++length;\n    │               ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:323:37\n    │\n323 │             text[--length] = bytes1(uint8(48 + number % 10));\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' 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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:331:27\n    │\n331 │         return (BUILDERS, salePrice / 10000 * royaltyBps + salePrice % 10000 * royaltyBps / 10000);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:405:16\n    │\n405 │         return block.timestamp < pauseUntil;\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/WorkersNFT.sol:409:39\n    │\n409 │         if (paused() || (hasPaused && block.timestamp < pauseUntil + 1 days)) revert Unavailable();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:473:24\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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/WorkersNFT.sol:473:32\n    │\n473 │         uint256 bits = uint256(int256(BASE_DIFFICULTY_BITS + epoch()) + floorAdjustment);\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:480:13\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:480:30\n    │\n480 │         if (shifts >= 256 || target > (ceiling >> shifts)) return ceiling;\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/WorkersNFT.sol:482:16\n    │\n482 │         return result > ceiling ? ceiling : result;\n    │                ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `minted` is updated\n    ╭▸ src/WorkersNFT.sol:528:13\n    │\n528 │         try IWorkerToken(IMD).permit(msg.sender, address(this), mintPrice(), deadline, v, r, s) {} catch {}\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:560:9\n    │\n560 │         emit TargetChanged(target);\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/WorkersNFT.sol:300:9\n    │\n300 │         emit Transfer(from, to, 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/WorkersNFT.sol:374:9\n    │\n374 │         emit MintEnded(minted, block.timestamp, burnReward);\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/WorkersNFT.sol:627:9\n    │\n627 │         emit ImdRewardAdded(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/WorkersNFT.sol:571:9\n    │\n571 │         emit Mined(msg.sender, id, hash, overclocked[id], price);\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/WorkersNFT.sol:552:17\n    │\n552 │             if (elapsed < 20) elapsed = 20;\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/WorkersNFT.sol:553:17\n    │\n553 │             if (elapsed > 320) elapsed = 320;\n    │                 ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:580:40\n    │\n580 │         stakes[id] = Stake(msg.sender, uint64(until), weight, accImdPerWeight);\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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:594:45\n    │\n594 │         if (position.account != msg.sender) revert Unauthorized();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:612:13\n    │\n612 │         if (block.timestamp < position.unlockTime) revert Unavailable();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/WorkersNFT.sol:679:32\n    │\n679 │             uint256 assigned = perWorker * activeWorkers;\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:241:35\n    │\n241 │         if (result == address(0)) revert Invalid();\n    │                                   ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/WorkersNFT.sol:708:54\n    │\n708 │             if (beneficiaryOf(ids[i]) != msg.sender) revert Unauthorized();\n    │                                                      ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/WorkersNFT.sol:730:58\n    │\n730 │     function releaseMiningRemainder() external onlyOwner nonReentrant whenRunning {\n    │                                                          ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:731:45\n    │\n731 │         if (!mintEnded || miningReleased || block.timestamp < mintEndTime + MINING_DURATION) revert Unavailable();\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_buybackMinimum` is updated\n    ╭▸ src/WorkersNFT.sol:757:31\n    │\n757 │         bytes memory result = IWorkHook(hook).poolManager().unlock(\"\");\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/WorkersNFT.sol:746:38\n    │\n746 │                 || (hasBoughtBack && block.timestamp < lastBuyback + 60)\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/WorkersNFT.sol:762:9\n    │\n762 │         emit Buyback(amount, output);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/WorkersNFT.sol:778:18\n    │\n778 │                 -int256(amount),\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/WorkersNFT.sol:783:25\n    │\n783 │         int128 delta0 = int128(delta >> 128);\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/WorkersNFT.sol:784:25\n    │\n784 │         int128 delta1 = int128(delta);\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/WorkersNFT.sol:787:23\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:787:56\n    │\n787 │         if (input != -int256(amount) || output <= 0 || uint256(output) < _buybackMinimum) revert Invalid();\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/WorkersNFT.sol:792:47\n    │\n792 │         manager.take(workToken, BURN_ADDRESS, uint256(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/WorkersNFT.sol:793:27\n    │\n793 │         return abi.encode(uint256(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[reentrancy-eth]: uncapped ETH transfer can be reentered before `_entered` is updated\n    ╭▸ src/WorkersNFT.sol:807:26\n    │\n807 │             (bool ok,) = BUILDERS.call{value: amount}(\"\");\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/WorkersNFT.sol:812:9\n    │\n812 │         emit Swept(token, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":6306,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 21 tests for test/WorkHook.t.sol:WorkHookTest\n[PASS] testFuzz_AllFourSwapModesChargeIMDExactlyOnce(uint96,uint16,bool,bool) (runs: 1000, μ: 378458, ~: 388867)\n[PASS] testFuzz_HookSweepOnlySendsToBuilders(uint96,uint96) (runs: 1000, μ: 170866, ~: 171594)\n[PASS] testFuzz_PostMintSplitConservesFeeAndCanBeClaimed(uint96,uint16) (runs: 1000, μ: 1730339, ~: 1744562)\n[PASS] test_BuybackBadOutputWrongInputOrSettlementRollsEverythingBack() (gas: 2675816)\n[PASS] test_BuybackCapsSpendAt100IMDAndCooldownEndsAt60Seconds() (gas: 170037964)\n[PASS] test_BuybackUsesSettlementBurnSinkCooldownAndDoesNotSpendReserves() (gas: 2115811)\n[PASS] test_CallbacksRejectForeignPoolWrongCallerAndUninitializedState() (gas: 425810)\n[PASS] test_Create2FlagsPermissionsPolicyAndBindingBeforeInitialization() (gas: 261686)\n[PASS] test_DefaultBuyAndSellFeeAndZeroFee() (gas: 575682)\n[PASS] test_FailedBuybackBurnTransferRestoresFeesRewardsAndSettlement() (gas: 2180702)\n[PASS] test_FailedInitializationCannotLeaveHookBoundOrOracleStarted() (gas: 487623)\n[PASS] test_FeeBoundsEventsAndOwnershipFollowsNFT() (gas: 405026)\n[PASS] test_FeesAndBuybackForOppositeCurrencyOrdering() (gas: 79380632)\n[PASS] test_InitializationRequiresManagerAuthorizedOriginAndCorrectPool() (gas: 363711)\n[PASS] test_OracleWaitsFullWindowAndQuoteIncludesBothFeesAndSlippage() (gas: 251227)\n[PASS] test_OracleWeightsPriorTickAndRoundsNegativeMeanDown() (gas: 893652)\n[PASS] test_PartialSpecifiedIMDFillRevertsAtomicallyAndWorkSpecifiedUsesActualIMD() (gas: 617898)\n[PASS] test_PostMintPartialFillRollsBackStakerNotificationAndBuildersPayment() (gas: 1629676)\n[PASS] test_PostMintWithoutStakeAndAfterLastUnstakeRoutesEverythingToBuilders() (gas: 1442772)\n[PASS] test_TaxedHookRewardCannotCreateUnbackedStakerLiability() (gas: 1259695)\n[PASS] test_ZeroIntMinimumAndOversizedAmountsRejectWithoutFees() (gas: 296020)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 2.16s (2.00s CPU time)\n\nRan 44 tests for test/WorkersNFT.t.sol:WorkersNFTTest\n[PASS] testFuzz_BurnRewardStaysFixedAndCannotBeClaimedTwice(uint8,uint8) (runs: 1000, μ: 2412573, ~: 1982694)\n[PASS] testFuzz_EightEraAccrual(uint8,uint32) (runs: 1000, μ: 888712, ~: 890219)\n[PASS] testFuzz_EpochFloorsAndIdleTargetRemainBounded(uint16,uint8,uint16) (runs: 1000, μ: 8851347, ~: 8853398)\n[PASS] testFuzz_FrequentClaimsRetainFractionalIMDCredit(uint8,uint8) (runs: 1000, μ: 3536392, ~: 3028103)\n[PASS] testFuzz_MintPicksUnreservedIdAndConservesPayment(uint256,uint16) (runs: 1000, μ: 1155824, ~: 932895)\n[PASS] testFuzz_MintSplitsAndWeightedClaims(uint16,uint8) (runs: 1000, μ: 2315433, ~: 2315471)\n[PASS] testFuzz_PricesUseIMDDecimalsAndBoundedScale(uint256,uint8) (runs: 1000, μ: 60693, ~: 60699)\n[PASS] testFuzz_RetargetEveryEightAndIdleRecovery(uint16) (runs: 1000, μ: 6778636, ~: 6777746)\n[PASS] testFuzz_RoyaltyCannotOverflow(uint256,uint16) (runs: 1000, μ: 43732, ~: 43731)\n[PASS] testFuzz_SweepCannotTouchReserves(uint96,uint96,uint96) (runs: 1000, μ: 1681017, ~: 1681892)\n[PASS] testFuzz_WorkHashBindsChainContractMinerNonceAndPreviousWork(uint256,address) (runs: 1000, μ: 50971, ~: 50971)\n[PASS] test_ActivatedWorkerTransferCarriesAccruedWorkAndApprovalClears() (gas: 1304474)\n[PASS] test_ActivationDoesNotDilutePastRewardsAndBurnStopsFutureWork() (gas: 1741678)\n[PASS] test_ActivationRequiresPostMintBeneficiaryAndFeeAndEmitsMetadata() (gas: 1514939)\n[PASS] test_AnchorsAreNonzeroPastAndAtMost250BlocksOld() (gas: 51833)\n[PASS] test_AutoExpiredPauseAssignsCarryBeforeNewWorkerJoins() (gas: 1819120)\n[PASS] test_BoundedUpdatesEmitEventsAndOwnershipNeedsAcceptance() (gas: 348116)\n[PASS] test_CapOnlyDecreasesAndSelloutIsPermanent() (gas: 2200627)\n[PASS] test_ConstructorRejectsInvalidOwnerTokenAndDecimals() (gas: 9767636)\n[PASS] test_EmptyAndPausedEmissionIsCarriedThenReleased() (gas: 1385048)\n[PASS] test_EmptyClaimsAndUnauthorizedUnlockDoNotMoveFunds() (gas: 185424)\n[PASS] test_EndMintAndCapAtMintedSnapshotRewards() (gas: 976305)\n[PASS] test_EpochBoundariesIncludeFinalThreeWorkers() (gas: 9674759)\n[PASS] test_FailedActivationPaymentCannotConsumeCarriedMining() (gas: 2040091)\n[PASS] test_FailedBurnPayoutRestoresOwnershipApprovalAndBothReserves() (gas: 1375428)\n[PASS] test_FailedUnstakePayoutPreservesEscrowAndClaimableIMD() (gas: 1649736)\n[PASS] test_FundingOnlyBuildersExactlyOnceAndNoUnfundedMint() (gas: 8842491)\n[PASS] test_HookRewardsRequireBoundHookPostMintWeightAndBacking() (gas: 2454963)\n[PASS] test_IdPoolNeverRepeatsAndCapDoesNotReserveIds() (gas: 68667136)\n[PASS] test_InvalidProofAndOneMintPerBlockRollback() (gas: 995348)\n[PASS] test_MiningReleasePreservesUnclaimedLiabilities() (gas: 1239374)\n[PASS] test_MiningReleaseWithoutActivationReturnsOnlyMiningReserve() (gas: 694227)\n[PASS] test_MixedOwnerClaimBatchesRevertWithoutConsumingEarlierRewards() (gas: 2926678)\n[PASS] test_NoFreeMintOnMissingAllowanceFalseReturnOrTransferTax() (gas: 1823837)\n[PASS] test_NormalAndOverclockedMetadataAndERC4906() (gas: 11820284)\n[PASS] test_OwnerLeversRejectOutsidersAndOutOfRangeInputs() (gas: 539332)\n[PASS] test_PauseExpiresAndCannotBeRenewedBeforeFullDayUnpaused() (gas: 1168072)\n[PASS] test_PermitUnsupportedUsesAllowanceAndSupportedPermitNeedsNoPriorApproval() (gas: 1976461)\n[PASS] test_RejectedMintReceiverRestoresSelloutPaymentAndIdPool() (gas: 2522169)\n[PASS] test_RobinhoodUsesChildChainBlockAndHash() (gas: 5227217)\n[PASS] test_StakeEscrowsAndCannotBeListedBurnedOrExitedEarly() (gas: 1604108)\n[PASS] test_TokenCallbackCannotReenterMint() (gas: 976505)\n[PASS] test_TransfersWorkWhilePausedButRejectUntrackedEscrowAndBadReceivers() (gas: 1209471)\n[PASS] test_ZeroMintCancellationNeverReopens() (gas: 176360)\nSuite result: ok. 44 passed; 0 failed; 0 skipped; finished in 2.17s (18.05s CPU time)\n\nRan 1 test for test/WorkHook.t.sol:WorkHookInvariantTest\n[PASS] invariant_FeesAreFullyBackedAndNeverRedirected() (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------+----------------+-------+---------+----------╮\n| Contract    | Selector       | Calls | Reverts | Discards |\n+===========================================================+\n| HookHandler | advance        | 2080  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | buyback        | 2031  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | claim          | 2057  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | donateAndSweep | 2034  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | endMint        | 1976  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | policy         | 2093  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | stakeOrUnstake | 2021  | 0       | 0        |\n|-------------+----------------+-------+---------+----------|\n| HookHandler | swap           | 2092  | 0       | 0        |\n╰-------------+----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.16s (3.13s CPU time)\n\nRan 1 test for test/WorkersNFT.t.sol:WorkersNFTInvariantTest\n[PASS] invariant_ReservesCustodySupplyAndLiabilities() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| WorkersHandler | activate      | 1100  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | advance       | 1034  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | burn          | 1076  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | changePolicy  | 1140  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | claim         | 1087  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | donate        | 1108  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | finishMint    | 1072  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | hookReward    | 1082  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | mintWorker    | 1077  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | pauseOrResume | 1069  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | release       | 1087  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | stake         | 1166  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | sweep         | 1044  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | transfer      | 1114  | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| WorkersHandler | unstake       | 1128  | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.24s (6.24s CPU time)\n\nRan 4 test suites in 6.25s (13.73s CPU time): 67 tests passed, 0 failed, 0 skipped (67 total tests)\n","passed":true},{"durationMs":32,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"WorkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"WorkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"WorkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"WorkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"WorkHook.receive()\",\"WorkHook.setFeeBps(uint16)\",\"WorkHook.setStakerShareBps(uint16)\",\"WorkHook.sweep(address)\",\"WorkersNFT.acceptOwnership()\",\"WorkersNFT.activate(uint256)\",\"WorkersNFT.approve(address,uint256)\",\"WorkersNFT.bindHook()\",\"WorkersNFT.burn(uint256)\",\"WorkersNFT.buyback()\",\"WorkersNFT.claimRewards(uint256[])\",\"WorkersNFT.claimWork(uint256[])\",\"WorkersNFT.endMint()\",\"WorkersNFT.fundPools()\",\"WorkersNFT.mint(uint256,uint256)\",\"WorkersNFT.mintWithPermit(uint256,uint256,uint256,uint8,bytes32,bytes32)\",\"WorkersNFT.notifyHookReward(uint256)\",\"WorkersNFT.pause()\",\"WorkersNFT.receive()\",\"WorkersNFT.releaseMiningRemainder()\",\"WorkersNFT.safeTransferFrom(address,address,uint256)\",\"WorkersNFT.safeTransferFrom(address,address,uint256,bytes)\",\"WorkersNFT.setActivationFee(uint256)\",\"WorkersNFT.setApprovalForAll(address,bool)\",\"WorkersNFT.setBaseURI(string)\",\"WorkersNFT.setCap(uint256)\",\"WorkersNFT.setFloorAdjustment(int8)\",\"WorkersNFT.setHook(address)\",\"WorkersNFT.setPriceScaleBps(uint16)\",\"WorkersNFT.setRoyaltyBps(uint16)\",\"WorkersNFT.stake(uint256,uint256)\",\"WorkersNFT.sweep(address)\",\"WorkersNFT.transferFrom(address,address,uint256)\",\"WorkersNFT.transferOwnership(address)\",\"WorkersNFT.unlockCallback(bytes)\",\"WorkersNFT.unpause()\",\"WorkersNFT.unstake(uint256)\",\"WorkersNFT.updateMining()\"],\"files\":{\"src/WorkHook.sol\":329,\"src/WorkersNFT.sol\":814,\"test/WorkHook.t.sol\":900,\"test/WorkersNFT.t.sol\":1625},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6eb8064ba5f01db32d75e0a6388c3d8d2bf4ed5e8c40d55c88fec71db326a4fd","verifiedTreeHash":"f9f54b49b61661ecde9982bc30046e8a7908ee2f","verifierVersion":"0.1.0+be003835"}]}