{"assessments":[],"deployments":[{"attestationHash":"9ed47630c53320690a8b2daad02cc16906cd8566ead1c3ecde89a54d510792bd","chainId":1,"contracts":[],"id":"82c202bf-9378-4855-9b8c-5df9c4d5956f","manifestHash":"f99960467952a91363a8b1c2d26821d1d05efaa4acef4a10926932e6b29b3551","status":"parked"}],"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":"911c808a-6fc8-4c42-b6bf-ed778018daec","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"97f44a7801d4e5dd9e453074eef7876a42ed09e371a41c221ec457aeba725f8b","dependsOn":["manifest"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":"448fb21282fea70eaf50a5ba009444ed6b6444f1dc75300b0e23a2f96b8945ce","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"}],"objective":"Launch the Swarmlings repository on Ethereum mainnet as a univ4_hook launch paired with IMD, exactly as launch.json describes: token Swarmlings (LING) with constructor (), hook SwarmlingsHook with constructor ($poolManager, $token) at an address whose low 14 bits are all set (0x3FFF, all hook flags), pool IMD / LING at fee 12500, tick spacing 60. Do not change the contracts' behaviour; adapt only what the launcher needs. Access: the token and the NFT contract have no owner and cannot change; owner() is a marketplace label with no power. The hook is a router whose fee slices and modules can be changed only by SwarmlingsCouncil, already deployed at 0x4d0b3507D80f678d9e658Fd5482Ca6a96636A032 and owned by the dev wallet 0x92cEf4823119f3332A85A39023eEbA01a06890c4, at once with a logged memo, within limits fixed in code: total hook fee at most 5%, the holders' 1.25% fixed, no module can block a sell or a liquidity removal. At launch there are no slices and no modules. Anyone may call SwarmlingsHook.distribute(), Swarmlings.syncEth(), syncToken(), addRewards() and a sink's poke(); claim(), claimEth() and claimToken() pay only the caller's own rewards; claimDev() pays only the fixed DEV wallet. Numbers: 300,000 LING per NFT, 3,333 NFTs max, 1.25% hook fee in IMD to holders on every LING / IMD pool using the hook, a 60-second launch snipe tax on buys falling from 40% to 0 (to holders), 5% creator fee on NFT sales (half to holders in ETH, half to DEV), rewards that arrive on one UTC day are paid out the next day per second held, poolBps 9000, auto-skip above 800 NFTs minted in one transfer. This job only launches the contracts; the site is built afterwards in a continuation that reads the live addresses.","parentJobId":null,"planHash":"fe64888148a6a644aac4d9c664092a423077f81747c36917777b4b33d7761af7","previousHash":"6503f801399175f08af61c90d4e0ebbeb3aa5ba8b88b6baee441beaebe373ba6","projectId":"911c808a-6fc8-4c42-b6bf-ed778018daec","publication":{"commit":"a3593f9ca38bc8948f16e3b2cd63aec15d5ba6be","deliveredAt":"2026-10-16T09:16:14.052Z","repoUrl":"https://github.com/identity-md-launches/launch-1954-launch-swarmlings-repository-ethereum"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"18068d9bd54bc13da7d356b1479afd8a835e7f047c2d8b18ca96b591ca1984b5","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"b392a380df6060c68d6ffd198723860d0382dffc503f1a429dc8706c33d9ec4f","device":"82692ab5f7f7e54e","findings":[],"hash":"448fb21282fea70eaf50a5ba009444ed6b6444f1dc75300b0e23a2f96b8945ce","nodeId":"c06cbf2b-c29f-4703-bc2d-7d3b3391fbf0","outcome":"completed","summary":"`launch.json` is written and verified. Only that file changed.\n\n**What the manifest declares**\n\n- `\"kind\": \"univ4_hook\"` as the first field.\n- Hook `SwarmlingsHook` with constructor args `[\"$poolManager\", \"$token\"]`, matching `constructor(IPoolManager manager, address token)` at `src/SwarmlingsHook.sol:155`.\n- All 14 permissions, matching `getHookPermissions()` at `src/SwarmlingsHook.sol:196`, which sets every flag including beforeInitialize and afterInitialize. Both callbacks are restricted to the PoolManager and return their selectors.\n- Token `Swarmlings`, name \"Swarmlings\", symbol \"LING\", 18 decimals, taken from the pure name and symbol functions in `src/Swarmlings.sol`.\n- Pool: pairedCurrency is the IMD address, fee 12500, tickSpacing 60, initialPrice 2^96, exactly as the launch facts give them. afterInitialize binds the first IMD / LING pool at fee 12500 as the launch pool and never rejects a pool.\n\n**Notes** describe the access model and numbers from the brief, each checked against the source: the 300,000 LING per NFT and 3,333 cap, the 800-NFT auto-skip, the holders' fixed 1.25% fee and the 5% total cap enforced by the Council at the fixed address, the 60-second snipe tax from 40% to 0, the 5% creator fee split, next-day per-second payouts, and which functions anyone may call versus caller-only claims. Notes are 3562 characters, under the 4000 cap.\n\n**Checks run**\n\n- `forge build` succeeds.\n- `forge test` with the verifier's fuzz seed: 239 tests passed, 0 failed, including the invariant suite and `test/Manifest.t.sol`, which reads launch.json and asserts the pairing, fee, tick spacing, contract names, constructor args and permission count.\n\nNo value had to be guessed. The hook takes no owner or factory argument, so no placeholder beyond `$poolManager` and `$token` was needed.","treeHash":"489011e1534cbad410ac29dd2f74e6508872cf0c","usage":{"cachedInputTokens":339181,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":5614,"runtime":"claude","turns":8,"wallClockMs":129658}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3b260b68e9ad6a37","findings":[{"citation":"resolved","description":"afterInitialize binds launchPool to the first IMD / LING pool at fee 12500 whatever its tick spacing. Before the hook has code, PoolManager.initialize reverts (beforeInitialize returns no data, Hooks.callHook raises InvalidHookResponse), so nothing can bind first as long as the IMD factory deploys the hook and initializes the pool in one transaction, which is what the launch does. The audit report records this as accepted (A-4 / G-8); no change is requested. The adapter should only keep the deployment atomic.","line":287,"path":"src/SwarmlingsHook.sol","reproduction":"State: hook deployed at its 0x3FFF address in transaction 1, pool not yet initialized. Input: any account calls PoolManager.initialize(PoolKey(IMD, LING, 12500, tickSpacing 1, hook), anyPrice) in transaction 2 before the factory. Actual: launchPoolSet becomes true for the attacker's pool; the factory's spacing-60 pool is still charged the 1.25% holder fee (_isCharged) but modules and sink services (_launchKey) point at the attacker's pool. Expected / what happens in the real launch: deployment and initialize are in one transaction, so the factory's pool binds.","severity":"info","snippet":"        if (!launchPoolSet && key.fee == LAUNCH_LP_FEE) {","title":"Launch-pool binding relies on the factory initializing the pool in the same transaction that deploys the hook (accepted A-4/G-8)"},{"citation":"resolved","description":"launcher is msg.sender of the hook constructor (line 163). The exemption from the JIT penalty applies to positions whose PoolManager caller is that address. If the factory deploys the hook through a separate deployer contract but adds and collects liquidity from the factory address itself, the two differ. The effect is bounded: only reward-currency fees collected within JIT_BLOCKS (10 blocks) of the position's last addition are redirected to holders, pro rata; principal is untouched and nothing reverts. The launch flow described in the notes (the factory deploys the hook itself and is the PoolManager caller) satisfies the exemption, as test/Launcher.t.sol exercises.","line":461,"path":"src/SwarmlingsHook.sol","reproduction":"State: hook created by contract D (launcher = D); position opened at block N by contract F != D in the launch pool with trades following. Input: F calls modifyLiquidity(liquidityDelta 0) at block N+1 to collect fees of 1,000 IMD. Actual: _jitPenalty computes 1000 * (10 - 1) / 10 = 900 IMD to holders, F receives 100 IMD. Expected for the launcher: 1,000 IMD to F. With F == D (the documented flow) F receives 1,000 IMD.","severity":"info","snippet":"        if (owner == launcher) return BalanceDeltaLibrary.ZERO_DELTA;","title":"JIT exemption keys on the hook's deployer; a factory that holds its position from a different address than the one that ran CREATE2 would be penalized on collects inside the 10-block window"},{"citation":"resolved","description":"Token with mirror ~4.3M and hook ~4.6M of creation gas (per launch.json and docs/OPERATIONS.md), plus pool initialize and the full-range seed. The requested economics (poolBps 9000, nothing to the requester) leave 100,000,000 LING to the policy's remainder. If that remainder is transferred to an EOA inside the launch transaction, 333 Swarmlings are minted there (333 < MAX_MINT_PER_TRANSFER = 800, so auto-skip does not trigger), about 12.1k gas each, roughly 4.0M more. The whole still fits under 16,777,216 (about 13.5M), but the adapter should keep any extra EOA allocation in mind; a recipient that is a contract skips NFTs by default.","line":430,"path":"src/Swarmlings.sol","reproduction":"Input: in the launch transaction the factory transfers 100,000,000e18 LING to an EOA with no prior balance. Actual: _transfer computes mint = 333, have = 0, 333 <= 800 so no auto-skip; DN404 mints 333 NFTs, about 4.0M gas (test/GasCap.t.sol: 800 NFTs ~9.7M). Total launch gas about 4.3M + 4.6M + 4.0M + ~0.6M (initialize, seed, transfers) = ~13.5M, under the 16,777,216 cap. Expected: the launch transaction must stay under the cap; it does under this accounting.","severity":"info","snippet":"            if (mint > have + MAX_MINT_PER_TRANSFER) {","title":"Launch transaction gas under the EIP-7825 16,777,216 cap: creation ~8.9M plus up to ~4M if the policy's 10% remainder is paid to an EOA"},{"citation":"resolved","description":"By design (documented in the comment above the line) the hook refuses a swap whose fee was charged in beforeSwap on an amount the pool did not fully swap. Routers that pass MIN_SQRT_PRICE+1 / MAX_SQRT_PRICE-1 are unaffected; a trader who passes a tight sqrtPriceLimitX96 gets a revert instead of a partial fill. Exact-out buys and exact-in sells (fee taken in afterSwap on the gross amount) fill partially as usual. No change requested; noted so the site and integrators pass wide limits on exact-in buys.","line":361,"path":"src/SwarmlingsHook.sol","reproduction":"State: launch pool at tick T. Input: exact-in buy of 1,000 IMD (amountSpecified = -1000e18) with sqrtPriceLimitX96 one tick past the current price. Fee = 12.5 IMD charged in beforeSwap; the pool swaps only until the limit, so rewardDelta = -(600e18) != -1000e18 + 12.5e18. Actual: revert PartialFill(). Expected by a trader used to Uniswap semantics: a partial fill of 600 IMD. With the router default limit the swap fills fully and no revert occurs.","severity":"info","snippet":"            if (rewardDelta != params.amountSpecified + int256(fee)) revert PartialFill();","title":"Swaps that specify the IMD side (exact-in buys, exact-out sells) revert with PartialFill when a price limit stops them early"},{"citation":"resolved","description":"The auto-skip guard compares the NFTs the receiver would hold after the transfer with what it holds now. A wallet in skip mode whose balance already covers more than 800 NFTs (have = 0, mint > 800) is switched back to skipNFT on every incoming transfer, including a 1 wei self-transfer after setSkipNFT(false), because DN404 mints all missing NFTs at once. The holder must first move LING out until the balance covers at most 800 units, or split across wallets. This is the intended gas protection under EIP-7825 and is documented in README and OPERATIONS; noted for the site's holder guidance, not a code change.","line":430,"path":"src/Swarmlings.sol","reproduction":"State: Alice holds 300,000,000e18 LING (1,000 units) with skipNFT = true after a large buy. Input: Alice calls setSkipNFT(false) then transfer(alice, 1). Actual: _transfer sees mint = 1000, have = 0, 1000 > 800, sets skipNFT back to true, emits AutoSkipNFT(alice, 1000); zero NFTs minted. Expected by the holder: up to 800 NFTs. Remedy within the design: transfer 60,000,000e18 LING to a second wallet (200 units), then self-transfer: mint = 800, allowed.","severity":"info","snippet":"            if (mint > have + MAX_MINT_PER_TRANSFER) {","title":"A wallet auto-switched to skipNFT while holding more than 800 units cannot re-enable Swarmlings by any single incoming transfer"},{"citation":"resolved","description":"Read over a public mainnet RPC: code 22,990 bytes, decimals 18, name Identity.md, symbol IMD, owner 0x047f606fd5b2baa5f5c6c4ab8958e45cb6b054b7, dispatcher contains OFT selectors (send, quoteSend, peers, setPeer, lzReceive) and no pause, blacklist or fee-on-transfer selectors. transfer(address,uint256) returns bool, which _payToken and the hook's PoolManager.take path handle; _syncToken is balance-based so a future change in IMD transfer behaviour would not strand accounting. This is a trust assumption the audit's CROPS section already records (IMD's owner controls bridge peers), not a defect.","line":40,"path":"src/Swarmlings.sol","reproduction":"eth_call decimals() on 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7 returns 0x12; name() returns Identity.md; selector set extracted from eth_getCode contains bb0b6a53 (peers), c7c7f5b3 (send), 13137d65 (lzReceive), a9059cbb (transfer) and lacks 5c975abb (paused), 8456cb59 (pause). test/fork/Validator.t.sol::test_fork_realImdRewards passes on a fork of block 0x18fd7d0: IMD taken to the token is streamed and claimed by a holder.","severity":"info","snippet":"    address public constant IMD = 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7;","title":"External dependency record: IMD is a LayerZero OFT ERC-20 whose owner controls bridge peers; standard transfer semantics confirmed on mainnet"}],"hash":"97f44a7801d4e5dd9e453074eef7876a42ed09e371a41c221ec457aeba725f8b","nodeId":"0d68923b-6aa5-400e-ab3a-4159d154858d","outcome":"completed","summary":"The review is complete and the findings file is validated: all six snippets match the tree, all 53 entry points have coverage rows, and `src/` contains no DELEGATECALL, CALLCODE, SELFDESTRUCT, initializer or post-construction mint.\n\n**Verdict: nothing stops or breaks this launch.** All six findings in `.imd-findings.json` are informational.\n\n**What I read and verified**\n- Read in full: `Swarmlings.sol`, `SwarmlingsHook.sol`, `SwarmlingsMirror.sol`, `SwarmlingsCouncil.sol`, `IHive.sol`, and the HiveSink, AutoLiquidity, BuybackBurn, TreasurySink and TwapOracle modules. Also the vendored DN404 storage edits and v4-core's liquidity-callback routing.\n- Not read line by line: MaxBuy and VolatilityFee (not deployed at launch), the renderer, and upstream DN404 beyond the edited structs. IMD's launch factory bytecode is not in the tree and could not be reached.\n- The full local suite passes (239 tests). The mainnet fork suite also passes against a public RPC, covering the real OpenSea validator and real IMD rewards.\n- Over mainnet RPC: IMD is a LayerZero OFT ERC-20 with 18 decimals and no pause, blacklist or fee selectors. The Council has code at its constant address with the dev wallet as owner. The renderer, validator and PoolManager all have code. DEV is an EOA.\n- launch.json is schema-clean: two constructor args in order, 14 permissions matching `getHookPermissions`, fee 12500, tick spacing 60, lowercase IMD, decimal sqrtPriceX96, notes under the 4,000-character cap.\n\n**Informational notes for the adapter**\n- Launch-pool binding depends on the hook deployment and pool initialize being one transaction, as the launch does. This is the accepted audit item A-4, no change requested.\n- The JIT exemption keys on the hook's deployer. If the factory held its position from a different address, collects within 10 blocks of the add would lose part of the reward fees. The documented flow satisfies the exemption.\n- Launch transaction gas stays under the 16,777,216 cap even if the policy's 10% remainder goes to an EOA and mints 333 Swarmlings, at roughly 13.5M total.\n- Exact-in buys and exact-out sells revert with PartialFill when a tight price limit stops them early. Router defaults are unaffected. Documented design.\n- A wallet auto-switched to skipNFT above 800 units cannot re-enable NFTs with any single incoming transfer. Documented design, relevant for holder guidance on the site.\n- IMD's owner controls bridge peers, a trust assumption the prior audit already records.\n\nNo files other than `.imd-findings.json` were changed, and nothing was written under `test/scratch/` since no finding warranted a proof.","treeHash":null,"usage":{"cachedInputTokens":1183932,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":50710,"runtime":"claude","turns":26,"wallClockMs":761699}}],"verification":[{"checks":[{"durationMs":11247,"exitCode":0,"name":"build","output":"Compiling 109 files with Solc 0.8.26\nSolc 0.8.26 finished in 11.12s\nCompiler run successful with warnings:\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/SwarmlingsHook.sol:237:51:\n    |\n237 |     function currentSwap() external view returns (bool buy, uint256 bps, uint256 fee) {\n    |                                                   ^^^^^^^^\nNote: The other declaration is here:\n   --> src/SwarmlingsHook.sol:702:5:\n    |\n702 |     function buy(uint256 budget, uint160 sqrtPriceLimitX96)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/SwarmlingsHook.sol:315:9:\n    |\n315 |         bool buy = _isBuy(params);\n    |         ^^^^^^^^\nNote: The other declaration is here:\n   --> src/SwarmlingsHook.sol:702:5:\n    |\n702 |     function buy(uint256 budget, uint160 sqrtPriceLimitX96)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/SwarmlingsHook.sol:353:9:\n    |\n353 |         bool buy = _isBuy(params);\n    |         ^^^^^^^^\nNote: The other declaration is here:\n   --> src/SwarmlingsHook.sol:702:5:\n    |\n702 |     function buy(uint256 budget, uint160 sqrtPriceLimitX96)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/SwarmlingsHook.sol:515:21:\n    |\n515 |     function _quote(bool buy, uint256 depth) private returns (uint256 bps) {\n    |                     ^^^^^^^^\nNote: The other declaration is here:\n   --> src/SwarmlingsHook.sol:702:5:\n    |\n702 |     function buy(uint256 budget, uint160 sqrtPriceLimitX96)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/SwarmlingsHook.sol:639:49:\n    |\n639 |     function _collect(uint256 fee, uint256 bps, bool buy) private {\n    |                                                 ^^^^^^^^\nNote: The other declaration is here:\n   --> src/SwarmlingsHook.sol:702:5:\n    |\n702 |     function buy(uint256 budget, uint160 sqrtPriceLimitX96)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:282:30:\n    |\n282 |     function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick)\n    |                              ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:282:68:\n    |\n282 |     function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick)\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:282:90:\n    |\n282 |     function afterInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96, int24 tick)\n    |                                                                                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:307:9:\n    |\n307 |         address sender,\n    |         ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:310:9:\n    |\n310 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:336:9:\n    |\n336 |         address sender,\n    |         ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:340:9:\n    |\n340 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:387:9:\n    |\n387 |         address sender,\n    |         ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:389:9:\n    |\n389 |         ModifyLiquidityParams calldata params,\n    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:390:9:\n    |\n390 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:404:9:\n    |\n404 |         BalanceDelta delta,\n    |         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:406:9:\n    |\n406 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:422:9:\n    |\n422 |         address sender,\n    |         ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:424:9:\n    |\n424 |         ModifyLiquidityParams calldata params,\n    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:425:9:\n    |\n425 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:439:9:\n    |\n439 |         BalanceDelta delta,\n    |         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:441:9:\n    |\n441 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:484:9:\n    |\n484 |         address sender,\n    |         ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:486:9:\n    |\n486 |         uint256 amount0,\n    |         ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:487:9:\n    |\n487 |         uint256 amount1,\n    |         ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:488:9:\n    |\n488 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:497:9:\n    |\n497 |         address sender,\n    |         ^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:499:9:\n    |\n499 |         uint256 amount0,\n    |         ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:500:9:\n    |\n500 |         uint256 amount1,\n    |         ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/SwarmlingsHook.sol:501:9:\n    |\n501 |         bytes calldata hookData\n    |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/fork/Validator.t.sol:58:5:\n   |\n58 |     function test_fork_marketplaceView() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":2496,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/fork/Validator.t.sol:ValidatorForkTest\n[PASS] test_fork_marketplaceView() (gas: 2305)\n[PASS] test_fork_ownersMoveTheirOwnNfts() (gas: 2305)\n[PASS] test_fork_realImdRewards() (gas: 2371)\n[PASS] test_fork_unauthorizedOperatorsAreStopped() (gas: 2306)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 300.33µs (187.90µs CPU time)\n\nRan 1 test for test/Manifest.t.sol:ManifestTest\n[PASS] test_launchJsonPairsWithImdAtTheLaunchTier() (gas: 31067)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 439.00µs (283.56µs CPU time)\n\nRan 1 test for test/SwarmlingsHook.t.sol:TokenOnlySeedTest\n[PASS] test_firstBuysWorkWithAnEmptyManager() (gas: 3863709)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.21ms (1.88ms CPU time)\n\nRan 3 tests for test/Launcher.t.sol:LingFirstLauncherTest\n[PASS] test_dealWritesLingBalanceAndSupply() (gas: 567615)\n[PASS] test_launcherCollectsItsWholeFeeInsideTheJitWindow() (gas: 906095)\n[PASS] test_launcherIsTheDeployer() (gas: 5671)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 5.04ms (1.54ms CPU time)\n\nRan 3 tests for test/Launcher.t.sol:ImdFirstLauncherTest\n[PASS] test_dealWritesLingBalanceAndSupply() (gas: 567615)\n[PASS] test_launcherCollectsItsWholeFeeInsideTheJitWindow() (gas: 906436)\n[PASS] test_launcherIsTheDeployer() (gas: 5671)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 5.29ms (1.07ms CPU time)\n\nRan 1 test for test/GasCap.t.sol:GasCapTest\n[PASS] test_gasWorstCases() (gas: 28574142)\nLogs:\n  n 800\n  buy exact-out minting n    9750848\n  transfer moving n NFTs     5976267\n  sell burning n NFTs        4031202\n  plain transfer minting n   9550855\n  EIP-7825 cap               16777216\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 14.91ms (11.28ms CPU time)\n\nRan 3 tests for test/Launcher.t.sol:NativeLauncherTest\n[PASS] test_dealWritesLingBalanceAndSupply() (gas: 567615)\n[PASS] test_launcherCollectsItsWholeFeeInsideTheJitWindow() (gas: 2539264)\n[PASS] test_launcherIsTheDeployer() (gas: 5671)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 18.83ms (1.46ms CPU time)\n\nRan 22 tests for test/SwarmlingsHook.t.sol:NativeHookTest\n[PASS] testFuzz_feeModes(uint256,uint8) (runs: 256, μ: 6456873, ~: 6756913)\n[PASS] test_buyExactIn() (gas: 2108546)\n[PASS] test_buyExactOut() (gas: 440234)\n[PASS] test_callbacksOnlyFromManager() (gas: 120630)\n[PASS] test_distributeNeedsMinimum() (gas: 560639)\n[PASS] test_distributeStreamsEverythingToHolders() (gas: 2792100)\n[PASS] test_everyLingRewardPoolPaysTheHolderFee() (gas: 746077)\n[PASS] test_feesWithNoHoldersWaitForTheFirstNft() (gas: 1296231)\n[PASS] test_flashBorrowedNftsEarnNothing() (gas: 14823767)\n[PASS] test_holdersClaim() (gas: 13374551)\n[PASS] test_jitPenaltyOnlyWithinTheWindow() (gas: 2590041)\n[PASS] test_launchPoolCannotBeHijacked() (gas: 421271)\n[PASS] test_onlyTheFirstLaunchPairPays() (gas: 90038)\n[PASS] test_partialFillRevertsWhenFeeWasTakenUpFront() (gas: 199485)\n[PASS] test_permissionsAndLaunchPool() (gas: 79798)\n[PASS] test_poolAndRoutersNeverHoldNfts() (gas: 1710598)\n[PASS] test_rewardsFollowTimeHeld() (gas: 9785413)\n[PASS] test_sellExactIn() (gas: 532948)\n[PASS] test_sellExactOut() (gas: 705517)\n[PASS] test_skippedHandOverGivesALateBuyerNoBackPay() (gas: 2418)\n[PASS] test_unsolicitedUnlockCallbackReverts() (gas: 35278)\n[PASS] test_whaleBuyMintsManyNfts() (gas: 1552643)\nLogs:\n  gas, exact-out buy minting 100 NFTs: 1529056\n\nSuite result: ok. 22 passed; 0 failed; 0 skipped; finished in 128.06ms (153.42ms CPU time)\n\nRan 22 tests for test/SwarmlingsHook.t.sol:ImdFirstHookTest\n[PASS] testFuzz_feeModes(uint256,uint8) (runs: 256, μ: 5330347, ~: 4362527)\n[PASS] test_buyExactIn() (gas: 383646)\n[PASS] test_buyExactOut() (gas: 471931)\n[PASS] test_callbacksOnlyFromManager() (gas: 121110)\n[PASS] test_distributeNeedsMinimum() (gas: 1859492)\n[PASS] test_distributeStreamsEverythingToHolders() (gas: 1130345)\n[PASS] test_everyLingRewardPoolPaysTheHolderFee() (gas: 858567)\n[PASS] test_feesWithNoHoldersWaitForTheFirstNft() (gas: 1405667)\n[PASS] test_flashBorrowedNftsEarnNothing() (gas: 9023813)\n[PASS] test_holdersClaim() (gas: 3800772)\n[PASS] test_jitPenaltyOnlyWithinTheWindow() (gas: 898055)\n[PASS] test_launchPoolCannotBeHijacked() (gas: 442083)\n[PASS] test_onlyTheFirstLaunchPairPays() (gas: 90390)\n[PASS] test_partialFillRevertsWhenFeeWasTakenUpFront() (gas: 201096)\n[PASS] test_permissionsAndLaunchPool() (gas: 79808)\n[PASS] test_poolAndRoutersNeverHoldNfts() (gas: 7903055)\n[PASS] test_rewardsFollowTimeHeld() (gas: 1581766)\n[PASS] test_sellExactIn() (gas: 598521)\n[PASS] test_sellExactOut() (gas: 810319)\n[PASS] test_skippedHandOverGivesALateBuyerNoBackPay() (gas: 7901511)\n[PASS] test_unsolicitedUnlockCallbackReverts() (gas: 35278)\n[PASS] test_whaleBuyMintsManyNfts() (gas: 1574712)\nLogs:\n  gas, exact-out buy minting 100 NFTs: 1551125\n\nSuite result: ok. 22 passed; 0 failed; 0 skipped; finished in 135.95ms (156.61ms CPU time)\n\nRan 22 tests for test/SwarmlingsHook.t.sol:LingFirstHookTest\n[PASS] testFuzz_feeModes(uint256,uint8) (runs: 256, μ: 5320375, ~: 4363342)\n[PASS] test_buyExactIn() (gas: 383283)\n[PASS] test_buyExactOut() (gas: 472746)\n[PASS] test_callbacksOnlyFromManager() (gas: 121110)\n[PASS] test_distributeNeedsMinimum() (gas: 1859196)\n[PASS] test_distributeStreamsEverythingToHolders() (gas: 1130799)\n[PASS] test_everyLingRewardPoolPaysTheHolderFee() (gas: 855719)\n[PASS] test_feesWithNoHoldersWaitForTheFirstNft() (gas: 1405830)\n[PASS] test_flashBorrowedNftsEarnNothing() (gas: 9004500)\n[PASS] test_holdersClaim() (gas: 3801329)\n[PASS] test_jitPenaltyOnlyWithinTheWindow() (gas: 897746)\n[PASS] test_launchPoolCannotBeHijacked() (gas: 442149)\n[PASS] test_onlyTheFirstLaunchPairPays() (gas: 90324)\n[PASS] test_partialFillRevertsWhenFeeWasTakenUpFront() (gas: 200713)\n[PASS] test_permissionsAndLaunchPool() (gas: 79808)\n[PASS] test_poolAndRoutersNeverHoldNfts() (gas: 7903002)\n[PASS] test_rewardsFollowTimeHeld() (gas: 1582162)\n[PASS] test_sellExactIn() (gas: 598827)\n[PASS] test_sellExactOut() (gas: 809213)\n[PASS] test_skippedHandOverGivesALateBuyerNoBackPay() (gas: 7882583)\n[PASS] test_unsolicitedUnlockCallbackReverts() (gas: 35278)\n[PASS] test_whaleBuyMintsManyNfts() (gas: 1575529)\nLogs:\n  gas, exact-out buy minting 100 NFTs: 1551942\n\nSuite result: ok. 22 passed; 0 failed; 0 skipped; finished in 139.90ms (159.78ms CPU time)\n\nRan 32 tests for test/Hive.t.sol:ImdFirstHiveTest\n[PASS] testFuzz_feeSplitsAcrossModes(uint256,uint8) (runs: 256, μ: 5618117, ~: 4665535)\n[PASS] test_audit_badQuotersNeverBlockSells() (gas: 3198835)\n[PASS] test_audit_dirtySinkNeverBlocksSwaps() (gas: 2712876)\n[PASS] test_audit_dueSinkDoesNotMakeLowGasSwapsRevert() (gas: 1529302)\n[PASS] test_audit_failingSinkDoesNotStarveTheNext() (gas: 909989)\n[PASS] test_audit_jitTopUpIsPenalizedToo() (gas: 5363087)\n[PASS] test_audit_nestedSwapKeepsTheOuterFee() (gas: 1597186)\n[PASS] test_audit_returnDataBombIsNotPaidByTraders() (gas: 6745519)\n[PASS] test_audit_sinkCannotBeTheHook() (gas: 74210)\n[PASS] test_audit_twapHasNoLag() (gas: 8886919)\n[PASS] test_autoLiquidityBuildsAPermanentPosition() (gas: 6923848)\n[PASS] test_buybackBurnsSupply() (gas: 2402917)\n[PASS] test_buybackLeavesTheRestWhenTheBandIsHit() (gas: 2345226)\n[PASS] test_councilExecutesAtOnce() (gas: 216141)\n[PASS] test_councilLivesAtTheConstant() (gas: 54278)\n[PASS] test_frozenCouncil() (gas: 98654)\n[PASS] test_guardsRevertBuysNeverSells() (gas: 2053852)\n[PASS] test_journal() (gas: 63399)\n[PASS] test_lowGasSkipsObserversInsteadOfReverting() (gas: 436128)\n[PASS] test_maxBuyGuard() (gas: 2681238)\n[PASS] test_moduleValidationAndEmergencyDisable() (gas: 4021587)\n[PASS] test_observersNeverBlock() (gas: 2361353)\n[PASS] test_onlyTheCouncilConfigures() (gas: 88312)\n[PASS] test_ownerCanHandTheCouncilOn() (gas: 105133)\n[PASS] test_quotedExtraGoesToHoldersAndIsCapped() (gas: 1563200)\n[PASS] test_servicesOnlyForSinks() (gas: 756526)\n[PASS] test_sliceValidation() (gas: 515839)\n[PASS] test_snipeTaxDecaysOverTheFirstMinute() (gas: 18462551)\n[PASS] test_snipeTaxNeverHitsSells() (gas: 586751)\n[PASS] test_snipeTaxSitsOutsideTheCouncilCap() (gas: 7523534)\n[PASS] test_treasurySinkForwardsToTheRecipient() (gas: 1459829)\n[PASS] test_twapAndVolatilityFee() (gas: 13178895)\nSuite result: ok. 32 passed; 0 failed; 0 skipped; finished in 141.78ms (185.65ms CPU time)\n\nRan 33 tests for test/Swarmlings.t.sol:SwarmlingsMainnetTest\n[PASS] testFuzz_rewardsNeverExceedWhatArrived(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 256, μ: 1588772, ~: 1574442)\n[PASS] test_claimCannotBeReentered() (gas: 832708)\n[PASS] test_claimCannotReenterSyncToken() (gas: 1536249)\n[PASS] test_claimCountsUnsyncedCreatorFees() (gas: 525771)\n[PASS] test_claimOneAssetAtATime() (gas: 720542)\n[PASS] test_constructor() (gas: 98955)\n[PASS] test_contractsSkipUnlessTheyOptIn() (gas: 750233)\n[PASS] test_creatorFeeSplitsHalfToDev() (gas: 610194)\n[PASS] test_delegatedWalletsGetNftsLikeAnyWallet() (gas: 588508)\n[PASS] test_eachDayPaysWhatArrivedTheDayBefore() (gas: 691552)\n[PASS] test_holdingForAMomentEarnsAMomentsShare() (gas: 904188)\n[PASS] test_hugeBuySwitchesToSkipInsteadOfRunningOutOfGas() (gas: 19661275)\n[PASS] test_keepPutsFavouritesFirst() (gas: 630495)\n[PASS] test_keepRejectsOthersAndDuplicates() (gas: 537199)\n[PASS] test_mainnetEarnsBothCurrencies() (gas: 1142012)\n[PASS] test_nextMintIdsFollowTheCycle() (gas: 10855297)\n[PASS] test_nftSaleKeepsEarningsWithSeller() (gas: 985588)\n[PASS] test_quietDaysKeepTheQueueIntact() (gas: 582185)\n[PASS] test_rewardWithNoNftsWaitsForTheFirstOne() (gas: 519445)\n[PASS] test_rewardsStreamOverADay() (gas: 1201868)\n[PASS] test_royaltyInfo() (gas: 43821)\n[PASS] test_selfTransferProtectsAFavourite() (gas: 636145)\n[PASS] test_sellingBelowAUnitBurnsTheNewestAndKeepsEarnings() (gas: 699692)\n[PASS] test_swapFeesNeverGoToDev() (gas: 405973)\n[PASS] test_swarmShareMintsNoNftUntilTopUp() (gas: 391064)\n[PASS] test_tokenURIComesFromRenderer() (gas: 494629)\n[PASS] test_tokenURIPlaceholderWithoutRenderer() (gas: 288251)\n[PASS] test_tokenURISurvivesARevertingRenderer() (gas: 425735)\n[PASS] test_transfersMoveExactAmounts(uint256) (runs: 256, μ: 592896, ~: 207307)\n[PASS] test_unitBoundaries() (gas: 707550)\n[PASS] test_unsolicitedImdGoesToHoldersToo() (gas: 547211)\n[PASS] test_validatorGatesOperatorTransfersOnly() (gas: 1167114)\n[PASS] test_validatorIsFixed() (gas: 8525)\nSuite result: ok. 33 passed; 0 failed; 0 skipped; finished in 150.71ms (219.47ms CPU time)\n\nRan 32 tests for test/Hive.t.sol:NativeHiveTest\n[PASS] testFuzz_feeSplitsAcrossModes(uint256,uint8) (runs: 256, μ: 6660388, ~: 6969218)\n[PASS] test_audit_badQuotersNeverBlockSells() (gas: 1764031)\n[PASS] test_audit_dirtySinkNeverBlocksSwaps() (gas: 1397683)\n[PASS] test_audit_dueSinkDoesNotMakeLowGasSwapsRevert() (gas: 3167787)\n[PASS] test_audit_failingSinkDoesNotStarveTheNext() (gas: 2557069)\n[PASS] test_audit_jitTopUpIsPenalizedToo() (gas: 6928781)\n[PASS] test_audit_nestedSwapKeepsTheOuterFee() (gas: 1377791)\n[PASS] test_audit_returnDataBombIsNotPaidByTraders() (gas: 6701497)\n[PASS] test_audit_sinkCannotBeTheHook() (gas: 74210)\n[PASS] test_audit_twapHasNoLag() (gas: 8793337)\n[PASS] test_autoLiquidityBuildsAPermanentPosition() (gas: 5780748)\n[PASS] test_buybackBurnsSupply() (gas: 1095010)\n[PASS] test_buybackLeavesTheRestWhenTheBandIsHit() (gas: 18729399)\n[PASS] test_councilExecutesAtOnce() (gas: 216117)\n[PASS] test_councilLivesAtTheConstant() (gas: 54278)\n[PASS] test_frozenCouncil() (gas: 98642)\n[PASS] test_guardsRevertBuysNeverSells() (gas: 1953280)\n[PASS] test_journal() (gas: 63399)\n[PASS] test_lowGasSkipsObserversInsteadOfReverting() (gas: 435876)\n[PASS] test_maxBuyGuard() (gas: 2572494)\n[PASS] test_moduleValidationAndEmergencyDisable() (gas: 1574401)\n[PASS] test_observersNeverBlock() (gas: 1062488)\n[PASS] test_onlyTheCouncilConfigures() (gas: 88288)\n[PASS] test_ownerCanHandTheCouncilOn() (gas: 105133)\n[PASS] test_quotedExtraGoesToHoldersAndIsCapped() (gas: 5865778)\n[PASS] test_servicesOnlyForSinks() (gas: 2453768)\n[PASS] test_sliceValidation() (gas: 515803)\n[PASS] test_snipeTaxDecaysOverTheFirstMinute() (gas: 5123809)\n[PASS] test_snipeTaxNeverHitsSells() (gas: 523678)\n[PASS] test_snipeTaxSitsOutsideTheCouncilCap() (gas: 1775238)\n[PASS] test_treasurySinkForwardsToTheRecipient() (gas: 4567099)\n[PASS] test_twapAndVolatilityFee() (gas: 11287657)\nSuite result: ok. 32 passed; 0 failed; 0 skipped; finished in 156.20ms (200.70ms CPU time)\n\nRan 32 tests for test/Hive.t.sol:LingFirstHiveTest\n[PASS] testFuzz_feeSplitsAcrossModes(uint256,uint8) (runs: 256, μ: 5482892, ~: 4666350)\n[PASS] test_audit_badQuotersNeverBlockSells() (gas: 3199151)\n[PASS] test_audit_dirtySinkNeverBlocksSwaps() (gas: 2712884)\n[PASS] test_audit_dueSinkDoesNotMakeLowGasSwapsRevert() (gas: 1530016)\n[PASS] test_audit_failingSinkDoesNotStarveTheNext() (gas: 909626)\n[PASS] test_audit_jitTopUpIsPenalizedToo() (gas: 5362802)\n[PASS] test_audit_nestedSwapKeepsTheOuterFee() (gas: 1577536)\n[PASS] test_audit_returnDataBombIsNotPaidByTraders() (gas: 6745825)\n[PASS] test_audit_sinkCannotBeTheHook() (gas: 74210)\n[PASS] test_audit_twapHasNoLag() (gas: 8885518)\n[PASS] test_autoLiquidityBuildsAPermanentPosition() (gas: 6922291)\n[PASS] test_buybackBurnsSupply() (gas: 2401805)\n[PASS] test_buybackLeavesTheRestWhenTheBandIsHit() (gas: 2349538)\n[PASS] test_councilExecutesAtOnce() (gas: 216141)\n[PASS] test_councilLivesAtTheConstant() (gas: 54278)\n[PASS] test_frozenCouncil() (gas: 98654)\n[PASS] test_guardsRevertBuysNeverSells() (gas: 2053491)\n[PASS] test_journal() (gas: 63399)\n[PASS] test_lowGasSkipsObserversInsteadOfReverting() (gas: 436127)\n[PASS] test_maxBuyGuard() (gas: 2684872)\n[PASS] test_moduleValidationAndEmergencyDisable() (gas: 4020995)\n[PASS] test_observersNeverBlock() (gas: 2361057)\n[PASS] test_onlyTheCouncilConfigures() (gas: 88312)\n[PASS] test_ownerCanHandTheCouncilOn() (gas: 105133)\n[PASS] test_quotedExtraGoesToHoldersAndIsCapped() (gas: 1562241)\n[PASS] test_servicesOnlyForSinks() (gas: 756161)\n[PASS] test_sliceValidation() (gas: 515839)\n[PASS] test_snipeTaxDecaysOverTheFirstMinute() (gas: 18462411)\n[PASS] test_snipeTaxNeverHitsSells() (gas: 587057)\n[PASS] test_snipeTaxSitsOutsideTheCouncilCap() (gas: 7523236)\n[PASS] test_treasurySinkForwardsToTheRecipient() (gas: 1459983)\n[PASS] test_twapAndVolatilityFee() (gas: 13174320)\nSuite result: ok. 32 passed; 0 failed; 0 skipped; finished in 156.41ms (183.16ms CPU time)\n\nRan 30 tests for test/Swarmlings.t.sol:SwarmlingsTest\n[PASS] testFuzz_rewardsNeverExceedWhatArrived(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 256, μ: 1520504, ~: 1506184)\n[PASS] test_claimCannotBeReentered() (gas: 769562)\n[PASS] test_claimCountsUnsyncedCreatorFees() (gas: 467127)\n[PASS] test_claimOneAssetAtATime() (gas: 636496)\n[PASS] test_constructor() (gas: 93547)\n[PASS] test_contractsSkipUnlessTheyOptIn() (gas: 699766)\n[PASS] test_creatorFeeSplitsHalfToDev() (gas: 568874)\n[PASS] test_delegatedWalletsGetNftsLikeAnyWallet() (gas: 523636)\n[PASS] test_eachDayPaysWhatArrivedTheDayBefore() (gas: 655516)\n[PASS] test_holdingForAMomentEarnsAMomentsShare() (gas: 831416)\n[PASS] test_hugeBuySwitchesToSkipInsteadOfRunningOutOfGas() (gas: 19567493)\n[PASS] test_keepPutsFavouritesFirst() (gas: 580049)\n[PASS] test_keepRejectsOthersAndDuplicates() (gas: 486754)\n[PASS] test_nextMintIdsFollowTheCycle() (gas: 10790448)\n[PASS] test_nftSaleKeepsEarningsWithSeller() (gas: 934003)\n[PASS] test_quietDaysKeepTheQueueIntact() (gas: 546037)\n[PASS] test_rewardWithNoNftsWaitsForTheFirstOne() (gas: 483319)\n[PASS] test_rewardsStreamOverADay() (gas: 1128490)\n[PASS] test_royaltyInfo() (gas: 43821)\n[PASS] test_selfTransferProtectsAFavourite() (gas: 556892)\n[PASS] test_sellingBelowAUnitBurnsTheNewestAndKeepsEarnings() (gas: 646425)\n[PASS] test_swapFeesNeverGoToDev() (gas: 367260)\n[PASS] test_swarmShareMintsNoNftUntilTopUp() (gas: 340597)\n[PASS] test_tokenURIComesFromRenderer() (gas: 458545)\n[PASS] test_tokenURIPlaceholderWithoutRenderer() (gas: 252145)\n[PASS] test_tokenURISurvivesARevertingRenderer() (gas: 389629)\n[PASS] test_transfersMoveExactAmounts(uint256) (runs: 256, μ: 528551, ~: 171267)\n[PASS] test_unitBoundaries() (gas: 628273)\n[PASS] test_validatorGatesOperatorTransfersOnly() (gas: 1087792)\n[PASS] test_validatorIsFixed() (gas: 8547)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 157.30ms (236.79ms CPU time)\n\nRan 2 tests for test/Invariant.t.sol:InvariantTest\n[PASS]\nInvariantTest invariants:\n[PASS] invariant_claimsAreCounted\n[PASS] invariant_hookLedger\n[PASS] invariant_nftsMatchBalances\n[PASS] invariant_rewardsAreSolvent\n InvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------+------------+-------+---------+----------╮\n| Contract | Selector   | Calls | Reverts | Discards |\n+====================================================+\n| Handler  | buy        | 783   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | claim      | 812   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | creatorFee | 786   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | devClaim   | 826   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | distribute | 834   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | donate     | 880   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | sell       | 844   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | sendLing   | 799   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | sendNft    | 846   | 0       | 0        |\n|----------+------------+-------+---------+----------|\n| Handler  | wait       | 782   | 0       | 0        |\n╰----------+------------+-------+---------+----------╯\n\n[PASS] test_handlerTradesForReal() (gas: 34290342)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.39s (2.41s CPU time)\n\nRan 16 test suites in 2.39s (3.60s CPU time): 243 tests passed, 0 failed, 0 skipped (243 total tests)\n","passed":true},{"durationMs":83,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"AutoLiquidity.collect()\",\"AutoLiquidity.poke()\",\"BuybackBurn.poke()\",\"Swarmlings.addRewards()\",\"Swarmlings.approve(address,uint256)\",\"Swarmlings.burn(uint256)\",\"Swarmlings.claim()\",\"Swarmlings.claimDev()\",\"Swarmlings.claimEth()\",\"Swarmlings.claimToken()\",\"Swarmlings.fallback()\",\"Swarmlings.keep(uint256[])\",\"Swarmlings.receive()\",\"Swarmlings.setSkipNFT(bool)\",\"Swarmlings.syncEth()\",\"Swarmlings.syncToken()\",\"Swarmlings.transfer(address,uint256)\",\"Swarmlings.transferFrom(address,address,uint256)\",\"SwarmlingsCouncil.execute(address,bytes,string)\",\"SwarmlingsCouncil.post(string)\",\"SwarmlingsCouncil.setOwner(address)\",\"SwarmlingsHook.addLiquidity(int24,int24,uint128)\",\"SwarmlingsHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"SwarmlingsHook.afterDonate(address,(address,address,uint24,int24,address),uint256,uint256,bytes)\",\"SwarmlingsHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SwarmlingsHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"SwarmlingsHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SwarmlingsHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"SwarmlingsHook.beforeDonate(address,(address,address,uint24,int24,address),uint256,uint256,bytes)\",\"SwarmlingsHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"SwarmlingsHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"SwarmlingsHook.buy(uint256,uint160)\",\"SwarmlingsHook.collectFees(int24,int24)\",\"SwarmlingsHook.disableModule(address)\",\"SwarmlingsHook.distribute()\",\"SwarmlingsHook.receive()\",\"SwarmlingsHook.setCouncil(address)\",\"SwarmlingsHook.setModules((address,uint16,bool)[])\",\"SwarmlingsHook.setSlices((address,uint16,bool)[])\",\"SwarmlingsHook.take(address,address,uint256)\",\"SwarmlingsHook.unlockCallback(bytes)\",\"SwarmlingsMirror.approve(address,uint256)\",\"SwarmlingsMirror.fallback()\",\"SwarmlingsMirror.pullOwner()\",\"SwarmlingsMirror.receive()\",\"SwarmlingsMirror.safeTransferFrom(address,address,uint256)\",\"SwarmlingsMirror.safeTransferFrom(address,address,uint256,bytes)\",\"SwarmlingsMirror.setApprovalForAll(address,bool)\",\"SwarmlingsMirror.transferFrom(address,address,uint256)\",\"TreasurySink.poke()\",\"TwapOracle.onBeforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"TwapOracle.record()\"],\"files\":{\".gitignore\":8,\"LICENSE\":21,\"README.md\":156,\"docs/DEPENDENCIES.md\":26,\"docs/HIVE.md\":133,\"docs/OPERATIONS.md\":99,\"docs/SECURITY.md\":122,\"docs/abi/AutoLiquidity.json\":276,\"docs/abi/BuybackBurn.json\":224,\"docs/abi/MaxBuy.json\":204,\"docs/abi/Swarmlings.json\":964,\"docs/abi/SwarmlingsCouncil.json\":137,\"docs/abi/SwarmlingsHook.json\":2072,\"docs/abi/SwarmlingsMirror.json\":607,\"docs/abi/SwarmlingsRenderer.json\":152,\"docs/abi/TreasurySink.json\":223,\"docs/abi/TwapOracle.json\":259,\"docs/abi/VolatilityFee.json\":228,\"docs/audit/2026-10-10/AUDIT-REPORT.md\":57,\"docs/audit/2026-10-10/CROPS.md\":152,\"docs/audit/2026-10-10/findings-access-control.md\":201,\"docs/audit/2026-10-10/findings-defi-amm.md\":91,\"docs/audit/2026-10-10/findings-dos.md\":93,\"docs/audit/2026-10-10/findings-erc20.md\":63,\"docs/audit/2026-10-10/findings-erc721.md\":143,\"docs/audit/2026-10-10/findings-flashloans.md\":112,\"docs/audit/2026-10-10/findings-general.md\":204,\"docs/audit/2026-10-10/findings-precision-math.md\":111,\"docs/audit/2026-10-10/poc/AccessControlAudit.t.sol\":283,\"docs/audit/2026-10-10/poc/AmmAudit.t.sol\":470,\"docs/audit/2026-10-10/poc/Dos.t.sol\":638,\"docs/audit/2026-10-10/poc/ERC20Audit.t.sol\":640,\"docs/audit/2026-10-10/poc/Erc721Audit.t.sol\":490,\"docs/audit/2026-10-10/poc/Erc721AuditFork.t.sol\":186,\"docs/audit/2026-10-10/poc/FlashAtomic.t.sol\":297,\"docs/audit/2026-10-10/poc/FlashJit.t.sol\":88,\"docs/audit/2026-10-10/poc/FlashOracle.t.sol\":120,\"docs/audit/2026-10-10/poc/FlashSinks.t.sol\":256,\"docs/audit/2026-10-10/poc/FlashSkip.t.sol\":32,\"docs/audit/2026-10-10/poc/GeneralAudit.t.sol\":176,\"docs/audit/2026-10-10/poc/PrecisionMath.t.sol\":204,\"docs/audit/2026-10-10/poc/RendererCode.sol\":4,\"docs/audit/2026-10-10/poc/RendererGas.t.sol\":30,\"foundry.toml\":23,\"launch.json\":39,\"remappings.txt\":4,\"renderer/README.md\":17,\"renderer/foundry.toml\":16,\"renderer/lib/solady/LICENSE.txt\":21,\"renderer/lib/solady/src/utils/Base64.sol\":171,\"renderer/lib/solady/src/utils/DynamicBufferLib.sol\":1318,\"renderer/lib/solady/src/utils/LibBytes.sol\":882,\"renderer/lib/solady/src/utils/LibString.sol\":979,\"renderer/script/Deploy.s.sol\":32,\"renderer/src/SwarmlingsData.sol\":35,\"renderer/src/SwarmlingsRenderer.sol\":566,\"renderer/test/Renderer.t.sol\":86,\"renderer/test/data/expected-riso2.bin\":467,\"renderer/test/data/logo.svg\":1,\"renderer/test/data/riso2-1.svg\":1,\"renderer/test/data/riso2-1697.svg\":1,\"renderer/test/data/riso2-32.svg\":1,\"script/Day1Modules.s.sol\":72,\"script/DeployCouncil.s.sol\":30,\"src/Swarmlings.sol\":482,\"src/SwarmlingsCouncil.sol\":54,\"src/SwarmlingsHook.sol\":941,\"src/SwarmlingsMirror.sol\":147,\"src/interfaces/IHive.sol\":151,\"src/modules/AutoLiquidity.sol\":71,\"src/modules/BuybackBurn.sol\":47,\"src/modules/HiveSink.sol\":64,\"src/modules/MaxBuy.sol\":54,\"src/modules/TreasurySink.sol\":34,\"src/modules/TwapOracle.sol\":122,\"src/modules/VolatilityFee.sol\":72,\"test/GasCap.t.sol\":38,\"test/Hive.t.sol\":847,\"test/Invariant.t.sol\":248,\"test/Launcher.t.sol\":81,\"test/Manifest.t.sol\":33,\"test/Swarmlings.t.sol\":626,\"test/SwarmlingsHook.t.sol\":463,\"test/fork/Validator.t.sol\":78,\"test/utils/SwarmlingsBase.sol\":204},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"448fb21282fea70eaf50a5ba009444ed6b6444f1dc75300b0e23a2f96b8945ce","verifiedTreeHash":"489011e1534cbad410ac29dd2f74e6508872cf0c","verifierVersion":"0.1.0+d952fceb"}]}