{"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":"9c8dba79-d85e-442b-b655-733a7cd7ce08","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"waiting"},{"acceptedSubmissionHash":"7bebe44e7d8e7c27ccc74e12580e9d4a028a6994edf1128d365de317c7b0b369","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b72293c3366fff3f0b93151bca72cc6cbd189dad31d1ccd1d34dd483f2165a36","skillId":"audit-imported-code","subagents":4,"tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"b72293c3366fff3f0b93151bca72cc6cbd189dad31d1ccd1d34dd483f2165a36","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","subagents":4,"tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["audit_imported_code"],"execution":{"mustProduce":["src/LaunchToken.sol"],"network":false,"profile":"foundry","requires":[],"skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","state":"failed"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"waiting"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"forkChains":[8453],"network":false,"profile":"foundry","requires":[],"skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","state":"waiting"}],"objective":"Launch The Firm company with the notSTOCK token and its LP desk on Base: one evm_project launch on chain 8453, pair IMD. SPEC.md at commit 78e24ba794c7bd647263768f30654e57348e53cc is binding; build exactly it, every number and address fixed: fail, don't change. Adapt only what the launch rules or a reproduced finding require, each in ADAPTATION.md. Never change rates, recipients, limits or splits; never add an owner power, pause, upgrade or minting. Every contract and rule in SPEC.md is mandatory; no accepted- or known-limitation exception.\n\nProject wallet (fixed): 0x3c587Eff6c96eAcF7E3dcC2CFf6416161386E48C. Dev wallet (fixed, operator): 0x8Ad18E99F4C8d8406f9Ba8899CF308000518A981. IMD on Base: 0xFF0C532FDB8Cd566Ae169C1CB157ff2Bdc83E105 (on-chain name Fren Pet). Dead: 0x000000000000000000000000000000000000dEaD. (fail, don't change)\n\nToken (SPEC 3): the launch's fixed token, name notSTOCK, symbol NOTSTOCK, 18 decimals, supply 1,000,000,000, no owner, mint, fee, pause or upgrade. economics poolBps 3000: 30% pool, 10% swarm, 60% to remainderTo = the project wallet, which then transfers exactly 600,000,000 NOTSTOCK to GenesisSplitter. Pool notSTOCK/IMD, fee 12500, the policy's 2,500 IMD opening cap. (fail, don't change)\n\nContracts beside the token in deploy order, one launch transaction under 16,777,216 gas, at most 8 contracts with modules, no linked libraries or delegatecall (SPEC 2):\n\n1. LpDesk($token, operator = dev wallet, project wallet); constructor creates Burner with new. Anyone may later call deployModule(kind, code) once per kind: CREATE2 of LpGovernor, PriceGuard (VenueV3, DeskSwap if used), code hash fixed in LpDesk. Runtime under 24,576 bytes; FirmVault 10,240, GenesisSplitter 2,048, Burner 1,024. No function, for any caller, moves a held asset to a wallet but the project wallet or swaps outside positions and buyback(); assets leave only as SPEC 2 lists. Per token, kept apart: free balance, top-up basket, buyback basket. (fail, don't change)\n   Bootstrap: 604,800 seconds from registerNotStock, the operator opens positions directly; later every open needs a passed, unvetoed proposal. Operator alone, no vote, any time: close a position (withdrawn amounts to free balance, fees split as below), shift a range, re-split the single side, move balance between own positions, collect fees, stake/withdraw a position in its venue's staking (gauge, MasterChefV3). (fail, don't change)\n   Fees and staking rewards collected: NOTSTOCK 100% to Burner; every other token 25% buyback (IMD to FirmVault's buyback bucket, others to that asset's buyback basket), 25% project wallet, 25% top-up basket, 25% free. Operator alone: increaseLiquidity(id, amount, sqrtPriceX96, minLiquidity) adds the asset from its top-up basket to that open position, no NOTSTOCK; buyback(id, amount, minOut) swaps the asset (not IMD) from its buyback basket in that position's pool, all NOTSTOCK out to dead. Each basket is spent only by its function. (fail, don't change)\n   Open amount above free balance reverts. Open and increaseLiquidity revert if the pool's price is over 0.5% off the given sqrtPriceX96; with no pool, open creates it at that price; an OpenPosition fixes it at creation, execute() reverts if the pool moved more. Minimums of at least 99.5%: at that price, amount0Min/amount1Min on open and liquidity on increaseLiquidity; of the in-call quote, per-asset outs on shift and close and minOut on buyback. (fail, don't change)\n   Burn: operator alone, any time, burn(amount) sends free NOTSTOCK only to dead; above free balance reverts. Burner (SPEC 2c): anyone may send it NOTSTOCK or call burn(), moving all its NOTSTOCK to dead; nothing else. (fail, don't change)\n   PriceGuard (SPEC 2b): asset list fixed in code, extended only by an executed AddAsset(asset address only). The six venues fixed in code at SPEC 2b addresses (V4, three V3, two CL); more only by an executed AddVenue (SPEC 2b checks); none removed. All rules hold on every venue. Open prices and ranges are set by hand. notSTOCK/IMD reference for the FirmVault buyback only: median of poke() checkpoints, no Chainlink. registerNotStock, once by anyone, checks the factory record of this launch as SPEC 2b and stores the pool fee recipient as FirmVault if its lpDesk() is this LpDesk. (fail, don't change)\n   LpGovernor (SPEC 2a): stake()/unstake() NOTSTOCK at will, weight checkpointed at proposal creation. A staker with at least 0.1% of staked NOTSTOCK, or the operator, proposes OpenPosition, AddAsset, AddVenue, AddBridge or BridgeOut, one per kind at a time (failed, vetoed or expired ones do not count); BridgeOut sends free NOTSTOCK via the record's LayerZero OFT adapter (token() = NOTSTOCK) only to its dstLpDesk. 3-day vote; passes with 3% of staked supply voted and more for than against, else fails permanently; then a 2-day operator veto() (cancel only); unvetoed, anyone may execute() it once through LpDesk in the next 3 days, else it expires. Views list all of it. (fail, don't change)\n   Operator may hand its role to a new address; no power beyond this section. (fail, don't change)\n\n2. FirmVault(project wallet, $contract:LpDesk). Receives the notSTOCK/IMD pool's 1% launching-side trading fee once the project wallet (payer) calls the factory's setRequester(launchNumber, FirmVault) after launch; if that is impossible, fail. Fees arrive by plain transfer and stay until anyone calls distribute(token), splitting the whole undistributed balance: IMD exactly 25% buyback bucket, 25% project wallet, 25% LpDesk's IMD top-up basket, 25% LpDesk's free IMD; NOTSTOCK 100% to Burner; buckets and baskets untouched. IMD credited by LpDesk goes 100% to buyback. The buyback bucket is spent only by a permissionless swap of IMD for notSTOCK in its IMD pool only: PriceGuard's reference, minimum output at least 99.5% of it, one slice at most 0.1% of the pool's executable notSTOCK reserves, notSTOCK sent to dead; below 25 IMD equivalent it only accrues. Funds go nowhere else. (fail, don't change)\n\n3. GenesisSplitter($contract:LpDesk, dev wallet). Permissionless split(), once it holds notSTOCK, sends exactly 50/60 of its balance to LpDesk and 10/60 to the dev wallet; a second call moves nothing. It gets its 60% from the project wallet's transfer after launch. (fail, don't change)\n\nNothing external is called at deploy. No rule relies on a transfer callback or a factory, pool or venue calling us; splits run in explicit calls. Do not vendor Uniswap BitMath/TickMath assembly shifts (slither incorrect-shift): call deployed contracts or write it without them; pass the swarm's static analysis with no exception.\n\nConstructor arguments: only fixed addresses, $token, $contract: of this launch or fixed numbers.\n\nTests, all green on a Base fork before and after this launch (forge test and forge test --fork-url):\n- LpDesk: every SPEC section 6 rule: bootstrap end, close to free balance only, fee 25/25/25/25, NOTSTOCK to Burner, top-up, buyback, burn, BridgeOut, each of the six venues, staking, open price and 0.5% check, AddAsset, AddVenue, sizes, deployModule.\n- LpGovernor: checkpoint weight, threshold, quorum and majority, veto window, execute() once, expiry, as SPEC 6.\n- FirmVault: a plain IMD transfer then distribute() splits exactly 25/25/25/25, no dust; a repeat moves nothing; buckets and baskets untouched; funds leave only via SPEC 5; a buyback executes only when guards pass.\n- GenesisSplitter: 50/60 and 10/60 once.\n- Full rehearsal of the launch through the live factory on a Base fork, gas under 16,777,216, then each deployModule, the 600,000,000 transfer, setRequester, registerNotStock and split(): LpDesk 500,000,000, dev wallet 100,000,000, GenesisSplitter 0.\n\nDeliver: launch contracts verified on Base, DeployModules script; README with the addresses and the rules above; ADAPTATION.md even if empty.","parentJobId":null,"planHash":"d8915f7e63e1bc6c2108d20b759918b0252a481a5f7864607c9931406888802e","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"9c8dba79-d85e-442b-b655-733a7cd7ce08","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-3184-launch-firm-company-notstock"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51886","feedbackHash":"2597dd29f90e56164bda83c65f877c49dd0e9998562a878d2e63a9bfab4eff52","nodeKey":"audit_imported_code","submissionHash":"7bebe44e7d8e7c27ccc74e12580e9d4a028a6994edf1128d365de317c7b0b369","tag1":"review:submission","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"2e6105f406fec35db749fd1378e9d66f14060fd5a2d613a2750b7b76e83d6629","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"194b47a372650d59","findings":[],"hash":"2d010f4553f43a7f001880322083183210e56278e54f869eaf53059e4be196d5","nodeId":"aa720e05-9774-403c-950c-417c1f8d58da","outcome":"failed","summary":"needs input: SPEC 2b and 6 require successful staking of this launch's new NOTSTOCK PancakeSwap v3 positions in the fixed MasterChefV3 at 0xC6A2Db661D5a5690172d8eB0a7DEA2d3008665A3. Reproduced on a Base fork at block 55711985: opening NOTSTOCK/WETH at the enabled 2500 fee succeeds, but v3PoolAddressPid(pool) is 0 and depositing its NFT reverts InvalidNFT(). The verified MasterChefV3 implementation permits adding pools only through add(uint256,address,bool), restricted to its owner. That owner is Safe 0xf2Bb8d4f27028b8B8340B4e2C64Baa101C9Af46B, with threshold 3 of 7; neither the fixed project nor dev wallet is a signer. The brief supplies no authorized external pool-registration process. A successful staking test obtained by impersonating that Safe would not establish that the real launch can stake. With fixed staking addresses, no new owner power, and no accepted limitation permitted, the mandatory staking success requires an explicit external owner-authorized registration step. — Can you arrange f","treeHash":null,"usage":{"cachedInputTokens":19437952,"cost":{"source":"estimated","usdMicros":5752844},"inputTokens":195647,"model":"gpt-6.1-sol","outputTokens":147396,"runtime":"codex","turns":13,"wallClockMs":3496135}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"dd3018ab6b18e7bc","findings":[{"citation":"resolved","description":"At commit 78e24ba the only Solidity source is src/FirmAddresses.sol, a library of constants. The SPEC 3 token (name notSTOCK, symbol NOTSTOCK, 18 decimals, 1,000,000,000 supply minted to msg.sender, no owner/mint/pause/upgrade) is not implemented. The launch floor (.imd/reads/protected/evm_project/Token.protected.t.sol and Project.protected.t.sol) needs IMD_TOKEN_CREATION_CODE from a LaunchToken artifact, and the launch reference states a project launch cannot deploy without src/LaunchToken.sol. Nothing in the tree can be launched, so every SPEC 3 and SPEC 4 number (30% pool, 10% swarm, 60% remainder to the project wallet) is unenforced.","line":3,"path":"README.md","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\n\ninterface IMetaToken {\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function decimals() external view returns (uint8);\n    function totalSupply() external view returns (uint256);\n    function balanceOf(address) external view returns (uint256);\n}\n\n/// @notice Fails on commit 78e24ba: the tree has no `LaunchToken` artifact, so vm.getCode reverts.\n/// Passes once src/LaunchToken.sol exists and mints the SPEC 3 token to its deployer.\ncontract LaunchTokenMissingTest is Test {\n    function test_launchTokenExistsAndMintsSpecSupplyToDeployer() public {\n        bytes memory code = vm.getCode(\"LaunchToken\");\n        assertGt(code.length, 0, \"LaunchToken has no creation code\");\n        address deployed;\n        assembly (\"memory-safe\") {\n            deployed := create(0, add(code, 0x20), mload(code))\n        }\n        assertTrue(deployed != address(0), \"LaunchToken constructor reverted\");\n        IMetaToken token = IMetaToken(deployed);\n        assertEq(token.name(), \"notSTOCK\", \"name\");\n        assertEq(token.symbol(), \"NOTSTOCK\", \"symbol\");\n        assertEq(uint256(token.decimals()), 18, \"decimals\");\n        assertEq(token.totalSupply(), 1_000_000_000e18, \"supply\");\n        assertEq(token.balanceOf(address(this)), 1_000_000_000e18, \"supply not minted to the deployer\");\n    }\n}","reproduction":"State: checkout 78e24ba. Run `forge build` then `forge inspect LaunchToken bytecode` (or vm.getCode(\"LaunchToken\") in a test). Expected: creation code of a fixed-supply ERC-20 named notSTOCK/NOTSTOCK with 10^27 units minted to its deployer. Actual: `forge build` compiles only FirmAddresses.sol and vm.getCode reverts with `no matching artifact found` (see proof test, which fails on this tree with exactly that error).","severity":"high","snippet":"Token notSTOCK, symbol NOTSTOCK, on Base (chain 8453), paired with IMD. 18 decimals, 1 000 000 000 NOTSTOCK, minted once at launch. The binding rules are in SPEC.md; the cash model is in FINMODEL.md.","title":"Launch token src/LaunchToken.sol is absent: the evm_project launch has no token to deploy"},{"citation":"resolved","description":"README and SPEC describe LpDesk (constructor creates Burner; deployModule for LpGovernor and PriceGuard), FirmVault and GenesisSplitter with fixed constructor arguments, size limits (LpDesk < 24,576 runtime and < 49,152 initcode, FirmVault < 10,240, GenesisSplitter < 2,048, Burner < 1,024) and a no-external-call-at-deploy rule. None of these contracts is in src/. There is therefore no code enforcing any SPEC 2, 2a, 2b, 2c or 5 rule: the 25/25/25/25 fee split, the 50/60 and 10/60 genesis split, the 0.1%/3% governance thresholds, the 7-day bootstrap, the 0.5% price check or the 99.5% minimums. The adapter must write them from SPEC.md; the review could audit only the address constants.","line":14,"path":"README.md","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\n\n/// @notice Fails on commit 78e24ba: none of the SPEC 2 contracts (LpDesk with Burner, FirmVault,\n/// GenesisSplitter) nor the modules (LpGovernor, PriceGuard) has an artifact, so the first vm.getCode\n/// reverts. Passes once they exist, deploy on an empty chain with only fixed arguments (SPEC 2:\n/// nothing external is called at deploy) and respect the SPEC 2 size limits.\ncontract LaunchContractsMissingTest is Test {\n    address constant DEV_WALLET = 0x8Ad18E99F4C8d8406f9Ba8899CF308000518A981;\n    address constant PROJECT_WALLET = 0x3c587Eff6c96eAcF7E3dcC2CFf6416161386E48C;\n\n    function _create(bytes memory initcode) internal returns (address a) {\n        assembly (\"memory-safe\") {\n            a := create(0, add(initcode, 0x20), mload(initcode))\n        }\n    }\n\n    function test_spec2ContractsExistDeployWithoutExternalCallsAndFitSizeLimits() public {\n        address token = _create(vm.getCode(\"LaunchToken\"));\n        assertTrue(token != address(0), \"LaunchToken constructor reverted\");\n\n        bytes memory lpDeskCode = vm.getCode(\"LpDesk\");\n        assertLt(lpDeskCode.length + 96, 49_152, \"LpDesk initcode over 49152\");\n        address lpDesk = _create(abi.encodePacked(lpDeskCode, abi.encode(token, DEV_WALLET, PROJECT_WALLET)));\n        assertTrue(lpDesk != address(0), \"LpDesk constructor reverted on an empty chain\");\n        assertLt(lpDesk.code.length, 24_576, \"LpDesk runtime over 24576\");\n\n        (bool ok, bytes memory ret) = lpDesk.staticcall(abi.encodeWithSignature(\"burner()\"));\n        assertTrue(ok && ret.length == 32, \"LpDesk.burner() view missing\");\n        address burner = abi.decode(ret, (address));\n        assertGt(burner.code.length, 0, \"Burner not created by LpDesk constructor\");\n        assertLt(burner.code.length, 1_024, \"Burner runtime over 1024\");\n\n        address vault = _create(abi.encodePacked(vm.getCode(\"FirmVault\"), abi.encode(PROJECT_WALLET, lpDesk)));\n        assertTrue(vault != address(0), \"FirmVault constructor reverted\");\n        assertLt(vault.code.length, 10_240, \"FirmVault runtime over 10240\");\n\n        address splitter = _create(abi.encodePacked(vm.getCode(\"GenesisSplitter\"), abi.encode(lpDesk, DEV_WALLET)));\n        assertTrue(splitter != address(0), \"GenesisSplitter constructor reverted\");\n        assertLt(splitter.code.length, 2_048, \"GenesisSplitter runtime over 2048\");\n\n        assertGt(vm.getCode(\"LpGovernor\").length, 0, \"LpGovernor missing\");\n        assertGt(vm.getCode(\"PriceGuard\").length, 0, \"PriceGuard missing\");\n    }\n}","reproduction":"State: checkout 78e24ba. `ls src/` shows only FirmAddresses.sol; `forge build` produces a single artifact. The proof test calls vm.getCode(\"LpDesk\"), \"FirmVault\", \"GenesisSplitter\", \"LpGovernor\", \"PriceGuard\" and then deploys LpDesk(token, 0x8Ad18E99F4C8d8406f9Ba8899CF308000518A981, 0x3c587Eff6c96eAcF7E3dcC2CFf6416161386E48C), FirmVault(project wallet, LpDesk) and GenesisSplitter(LpDesk, dev wallet) on an empty chain and checks the SPEC 2 size limits and the burner() view. Expected: all five artifacts exist, constructors succeed with only fixed arguments, sizes are within limits. Actual: the first vm.getCode reverts with `no matching artifact found`.","severity":"high","snippet":"- One launch on Base: the notSTOCK token, its NOTSTOCK/IMD pool and, beside the token, LpDesk (its constructor creates Burner), FirmVault and GenesisSplitter. LpDesk's modules LpGovernor and PriceGuard are deployed after the launch by deployModule, callable by anyone, once per module, with the code hash fixed in LpDesk.","title":"SPEC 2 contracts (LpDesk with Burner, FirmVault, GenesisSplitter, LpGovernor, PriceGuard) do not exist in the tree"},{"citation":"resolved","description":"SPEC 6 mandates a Foundry suite on a Base mainnet fork covering FirmVault distribute() 25/25/25/25 with no dust, LpDesk bootstrap/close/fees/top-up/buyback/burn/bridge, each of the six venues and staking, LpGovernor thresholds and windows, bytecode limits, GenesisSplitter 50/60 and 10/60, and a full launch rehearsal under 16,777,216 gas. The configured test directory `test` does not exist and the configured library directory `lib` does not exist, so forge-std is unavailable and even a trivial test importing forge-std/Test.sol fails to compile. Every edge SPEC 6 lists is untested.","line":3,"path":"foundry.toml","reproduction":"State: checkout 78e24ba. Run `forge test`. Actual output: `Warning: No tests found in project! Forge looks for functions that start with `test`` Create any file test/X.t.sol importing \"forge-std/Test.sol\" and run `forge test`: compilation fails with `Source \"forge-std/Test.sol\" not found` because lib/ is absent. Expected: the SPEC 6 suite green with `forge test` and `forge test --fork-url <Base RPC>`.","severity":"medium","snippet":"test = \"test\"\nlibs = [\"lib\"]","title":"No test suite and no forge-std: none of the SPEC 6 Base-fork tests exist and no test can compile"},{"citation":"resolved","description":"The venue-list preamble says each of the six fixed venues answers factory() and WETH9(). On Base the Uniswap v4 PositionManager 0x7C5f5A4bBd8fD63184577525326123B519429bDc answers WETH9() = 0x4200000000000000000000000000000000000006 and poolManager() = 0x498581fF718922c3f8e6A244956aF099B2652b2b but has no factory(): the call reverts. An adapter that implements line 58 literally (one factory()/WETH9() probe on all six venues, e.g. in PriceGuard or in the SPEC 6 venue test) will revert on the V4 venue. The AddVenue rule on line 66 already distinguishes V4 (poolManager() only); the V4 entry must follow that rule, not line 58. All other probed addresses answer as SPEC 2b states (verified at Base block 55693395: every V3/CL manager returns its listed factory and Base WETH; MasterChefV3 returns CAKE 0x3055913c90Fcc1A6CE9a358911721eEb942013A1 and the PancakeSwap manager; the Aerodrome factories enable tick spacing 100 with fees 500 and 10000; IMD reads name and symbol \"Fren Pet\" with 18 decimals; the nine B20 stock tokens read 8 decimals with the listed tickers).","line":58,"path":"SPEC.md","reproduction":"State: Base mainnet, block 55693395. `cast call 0x7C5f5A4bBd8fD63184577525326123B519429bDc 'factory()(address)' --rpc-url https://base-rpc.publicnode.com -b 55693395`. Expected per line 58: an address. Actual: `execution reverted`. The same call on 0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1 returns 0x33128a8fC17869897dcE68Ed026d694621f6FDfD as listed.","severity":"low","snippet":"- Venue list at deploy (Base 8453, each with code on chain, its factory() and WETH9() 0x4200000000000000000000000000000000000006 answering): (fail, don't change)","title":"SPEC 2b claims factory() answers on every listed venue, but the Uniswap v4 PositionManager reverts on factory()"},{"citation":"resolved","description":"SPEC 2c says Burner(address(this)) takes the NOTSTOCK token from LpDesk's views and SPEC 2 says LpDesk's constructor creates Burner with new. During LpDesk's constructor its address has no runtime code, so a Solidity external call from Burner's constructor to LpDesk.token() reverts (extcodesize check), which reverts LpDesk's constructor and the whole launch transaction, parking the launch. Burner must store msg.sender and read the token lazily in burn(). Guidance for the adapter, not a defect in existing code.","line":82,"path":"SPEC.md","reproduction":"Scratch test (run on this tree): a DeskEager contract whose constructor does `new BurnerEager(address(this))` where BurnerEager's constructor calls IDesk(msg.sender).token(). Expected by a literal reading of SPEC 2c: deploys. Actual: `new DeskEager(0x1234)` reverts (test_burnerReadingLpDeskViewInConstructorRevertsTheLaunch passes with vm.expectRevert). The lazy variant, storing the desk and reading token() inside burn(), deploys and returns the token.","severity":"info","snippet":"- Burner(address(this)) takes the NOTSTOCK token from LpDesk's views. Any address may send it NOTSTOCK by a plain transfer. burn(), callable by any address, transfers Burner's whole NOTSTOCK balance to the dead address 0x000000000000000000000000000000000000dEaD and reverts on a zero balance. Burner has no owner, no setter and no other function; any other token sent to it stays there. (fail, don't change)","title":"Burner must not read LpDesk's token view in its constructor: LpDesk has no code while it creates Burner"},{"citation":"resolved","description":"The project wallet must pay for the launch, then send 600,000,000 NOTSTOCK to GenesisSplitter and call setRequester(launchNumber, FirmVault); the dev wallet is the LpDesk operator who must open positions during the 7-day bootstrap. Both are externally owned addresses that have never transacted on Base and hold no ETH at the probed block. Key custody for both cannot be verified from the repository; if the project wallet key is not held, the two post-launch transactions SPEC 3 requires can never happen and registerNotStock never succeeds, which blocks FirmVault.distribute and GenesisSplitter.split forever.","line":8,"path":"src/FirmAddresses.sol","reproduction":"State: Base mainnet, block 55693395. `cast nonce 0x3c587Eff6c96eAcF7E3dcC2CFf6416161386E48C --rpc-url https://base-rpc.publicnode.com -B 55693395` returns 0 and `cast balance` returns 0; the same for 0x8Ad18E99F4C8d8406f9Ba8899CF308000518A981. Expected before launch: the paying wallet funded and controlled by the requester.","severity":"info","snippet":"    address internal constant DEV_WALLET = 0x8Ad18E99F4C8d8406f9Ba8899CF308000518A981;\n    address internal constant PROJECT_WALLET = 0x3c587Eff6c96eAcF7E3dcC2CFf6416161386E48C;","title":"Project wallet and dev wallet are unused addresses on Base with zero balance and zero nonce"}],"hash":"7bebe44e7d8e7c27ccc74e12580e9d4a028a6994edf1128d365de317c7b0b369","nodeId":"dfb00451-56d2-4965-b6af-7cc42bca786d","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds six findings, two with proof tests.\n\n**What was read.** The tree at 78e24ba contains one Solidity source, `src/FirmAddresses.sol`, which is a library of 31 fixed Base addresses. SPEC.md, README.md, FINMODEL.md, foundry.toml and the three protected evm_project floor tests were read in full. There is no LaunchToken, LpDesk, Burner, FirmVault, GenesisSplitter, LpGovernor, PriceGuard, no script and no test directory. Nothing beyond the constants could be audited for access control, fund flow, arithmetic or reentrancy because no state-changing function exists yet.\n\n**What could not be reached.** The live launch factory and its `setRequester` / `positionOf` record. No factory address is in the tree, so SPEC 3's fee-recipient handover and SPEC 2b's `registerNotStock` record check remain unverified.\n\n**Findings written:**\n\n- **High, with proof:** `src/LaunchToken.sol` is absent. The launch floor needs its creation code and refuses the build without it. The proof test fails now with `no matching artifact found` and passes once a notSTOCK/NOTSTOCK token mints 10^27 units to its deployer.\n- **High, with proof:** none of the SPEC 2 contracts exists. The proof test fails now and, once fixed, deploys LpDesk, FirmVault and GenesisSplitter on an empty chain with only fixed arguments and asserts the SPEC 2 runtime and initcode limits plus the `burner()` view.\n- **Medium:** no tests and no `lib/`. Bare `forge test` reports no tests, and any test importing forge-std fails to compile. Every SPEC 6 edge is untested.\n- **Low:** SPEC 2b line 58 says every listed venue answers `factory()`, but the Uniswap v4 PositionManager reverts on it. The V4 entry must follow the line 66 `poolManager()` rule.\n- **Info:** Burner must read the token lazily. A scratch test shows a Burner that calls back into LpDesk's view during LpDesk's constructor reverts the whole launch transaction.\n- **Info:** the project wallet and dev wallet have zero nonce and zero balance on Base. Key custody for the paying wallet cannot be verified from the tree.\n\n**Verified clean.** At Base block 55693395 all other addresses answer as SPEC 2b states: every V3 and CL manager returns its listed factory and Base WETH, the V4 manager returns the PoolManager, MasterChefV3 returns CAKE and the PancakeSwap manager, both Aerodrome factories enable tick spacing 100, IMD reads \"Fren Pet\" with 18 decimals, and the nine B20 stock tokens read 8 decimals with the listed tickers. Solidity's checksum enforcement also confirms every literal compiles.\n\nProof tests live under `test/scratch/` and run with forge-std remapped from outside the repository, so nothing in `lib/` or the config was touched. Build artifacts were removed.","treeHash":null,"usage":{"cachedInputTokens":767545,"cost":{"source":"runtime","usdMicros":3271193},"inputTokens":322,"model":"claude-fable-5-1","outputTokens":25493,"runtime":"claude","turns":17,"wallClockMs":415525}},{"artifacts":[],"attempt":2,"bundleHash":null,"device":"eedfe508061c8582","findings":[],"hash":"987284d3183f9f3947bf484b5d5715a578760f5b253ac8d58d3de84a3eecc41f","nodeId":"aa720e05-9774-403c-950c-417c1f8d58da","outcome":"failed","summary":"needs input: An owner-authorized PancakeSwap pool-registration arrangement is still missing. Independently reproduced on a Base fork at block 55712738, without altering or impersonating the external protocol owner: a newly deployed fixed-supply notSTOCK/NOTSTOCK token opens a WETH position with positive liquidity through the fixed PancakeSwap V3 position manager at fee 2500. The new pool's v3PoolAddressPid is 0; safeTransferFrom of its NFT to the fixed MasterChefV3 0xC6A2Db661D5a5690172d8eB0a7DEA2d3008665A3 reverts InvalidNFT(), leaving the NFT with its holder. Calls to add(uint256,address,bool) from both fixed project and dev wallets revert Ownable: caller is not the owner. MasterChefV3.owner() is Safe 0xf2Bb8d4f27028b8B8340B4e2C64Baa101C9Af46B, threshold 3 of 7; neither fixed wallet is a signer. SPEC sections 2b and 6 require successful staking of this launch's own NOTSTOCK positions, and the assignment forbids treating this as an accepted limitation or changing the staking address. An owner-sett","treeHash":null,"usage":{"cachedInputTokens":821632,"cost":{"source":"estimated","usdMicros":2248912},"inputTokens":101623,"model":"gpt-6-astra","outputTokens":8221,"runtime":"codex","turns":5,"wallClockMs":230678}}],"verification":[]}