{"rewardSnapshot":null,"merkleRoot":null,"claims":null,"id":"df94a04b-ca9c-4c2c-ae5b-f83d6f791b6e","launchNumber":2363,"kind":"evm_contracts","status":"live","chainId":4663,"sourceRepoUrl":"https://github.com/identity-md-launches/launch-2363-simd-vault-robinhood-chain","sourceCommit":"01d4f6c81bca5f7cc8747edc33e8bdd71b934c57","parkedReason":null,"artifactCount":1,"manifestHash":"d1e85e8e0aa27dfbb619f9b18d832898eea69bdc74128aee5d29fcad50c81082","attestationHash":"0dd9fdbb3e26c542d154f43d3c4246677a7e66c01d69c0d0a31b9d7d164e7541","attestation":{"treeHash":"d4a94c12926cfbd3e8d96ba60a48a399e0c42024","verifierVersion":"0.1.0+560ab6a2","verifierKey":"68249df1f422fa72f61ca7f0ddaf9b62043959c5c134498441d5e552a9921782","toolchain":{"solc":"0.8.26","forge":"forge Version: 1.8.3","viaIR":true,"optimizer":true,"evmVersion":"cancun","bytecodeHash":"none","optimizerRuns":200},"contracts":[{"name":"CompensationVault","path":"src/CompensationVault.sol","abiHash":"cd97806b71e1a92da11f9fbf10891a9d06a6267d622242f4a2ba6813e1fc3104","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"68f1707e3d6e8cb3c213e5a9dd01b17feb785fd8b22820ee9a2cb3b1cd516c00","creationCodeHash":"e5c9e3159a3e0df169bcb6fe244c224c1fa097e0622d89bedecc28367b986bae","deployedCodeHash":"176df909399aac95047adb71cf0de6fcf9a04181539a5a4639df4f4cda0b2139","creationCodeBytes":7986,"deployedCodeBytes":7756},{"name":"HolderRewards","path":"src/HolderRewards.sol","abiHash":"20a2deb1231968999b6ca93cb230ca6d58cafb8fc1cafd5de0096ff75037dccd","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"d03f1422da3b72be184fa93e2fcd8c92b539f7d1cece1a9f2c825b2cfd9cc4b6","creationCodeHash":"376ddfed0c4e7b1f8ec70792392b7ef2e317130b0a8dbc1e1e46c71121ae337e","deployedCodeHash":"6965f2da4ec904fb0e30ff95ac778c64e25df15df4f2a682539dcece763927a0","creationCodeBytes":17677,"deployedCodeBytes":16153},{"name":"JobsVault","path":"src/JobsVault.sol","abiHash":"9f304cbed637631160a77bb8ab2bfecc9e5d8473d90de2eda01c2812af2ada3a","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"07fff85d008a39571c738351cd476cf8099ae641445b29ff417b78278808ac92","creationCodeHash":"1f5728ad0cbfb769c082b6355beb390ccc6e01533e8dc541543e489906e623a6","deployedCodeHash":"c5214fe85232c624b0a82f5ce24325399bf8c688cdb2b2a75122ecfe52333d90","creationCodeBytes":2651,"deployedCodeBytes":2422},{"name":"Network","path":"src/Network.sol","abiHash":"518674ab2b227e5f11e9084f615d57663cde47bce1ba168b4c19c7ee22a73d70","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"88cde95ac5b44e01499ad02081b742417dcfe9a7ce71da9b10c6605c643f11d4","creationCodeHash":"796634aa970ab164beb2be298b3ab1452786d411f081573a00c42fddcc896c48","deployedCodeHash":"19735bdf4d52c6f889cfd85f70fad899c9f4372c41ff8aa853bf043831e21b36","creationCodeBytes":44,"deployedCodeBytes":16},{"name":"OracleAttestation","path":"src/oracle/OracleAttestation.sol","abiHash":"518674ab2b227e5f11e9084f615d57663cde47bce1ba168b4c19c7ee22a73d70","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"86b756e43cdc8eda6a73a88b72a3640d953414b1a62d6d2a1afd7f2f30f5333d","creationCodeHash":"796634aa970ab164beb2be298b3ab1452786d411f081573a00c42fddcc896c48","deployedCodeHash":"19735bdf4d52c6f889cfd85f70fad899c9f4372c41ff8aa853bf043831e21b36","creationCodeBytes":44,"deployedCodeBytes":16},{"name":"OracleQuestion","path":"src/oracle/OracleQuestion.sol","abiHash":"c852298924000f858dae8e7b568efe64a88c8bca6a066fb0a1cc862297530a26","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"f5f5e16de378279e240ef78050c335a51c9451e6b2bc67b1fee9780011560404","creationCodeHash":"796634aa970ab164beb2be298b3ab1452786d411f081573a00c42fddcc896c48","deployedCodeHash":"19735bdf4d52c6f889cfd85f70fad899c9f4372c41ff8aa853bf043831e21b36","creationCodeBytes":44,"deployedCodeBytes":16},{"name":"SIMDVault","path":"src/SIMDVault.sol","abiHash":"ac5c8f0257b2d9f1a4735e5e28560921830d41f9bdaf5979a9d417c90446f87f","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"fd6a65817aa28dcbdae5ff1f58a7597cc9d29b39ee9efd6d76d09529c51abbbd","creationCodeHash":"cae90a2e16f1bf53df86f0245308ab2d6c8caaf2155327b9da413b072141b3cd","deployedCodeHash":"1ef827d0bab9a08429e9b36776d2b2fde11966f3107a1fcba8783d05aad7f3c8","creationCodeBytes":34669,"deployedCodeBytes":5996}],"manifest":{"kind":"evm_contracts","notes":"SIMDVault (src/SIMDVault.sol) is the only contract the factory deploys for this launch; its constructor takes no arguments and creates and permanently links the three other application contracts, JobsVault, CompensationVault and HolderRewards, exposing them as the immutable getters jobsVault(), compensationVault() and holderRewards(). Deploying separate copies of the children would not be linked to the vault and is intentionally not part of this manifest. No owner, admin, proxy, upgrade or pause exists, so there is no $owner argument. Every fixed address is a compile-time constant in src/Network.sol: IMD 0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127, Identity.md Intake 0xa43e6f75ee006411f79ac1c84120606c2330de82, launch factory 0x9c9d2fcb75c2c132c0ac0c42df3819a42347265e, Uniswap v4 PoolManager 0x8366a39cc670b4001a1121b8f6a443a643e40951, dev and marketing wallet 0xdfa1f1f6feaa04f7874eff0b7754b7ffaebd8bc0, burn destination 0x000000000000000000000000000000000000dEaD. The constructor calls no existing chain contract, so it deploys on an empty chain. The dev wallet has exactly two one-time powers: launch(bytes) pays Intake priceOf(\"launch.open@launch-1\", IMD) from the vault's own IMD so the vault becomes the launch's requester, and bindLaunch(uint64, address) stores the launch number and token for good after checking factory.positionOf(launchNumber).requester == vault, passing the token (and pool key) to the children. distribute() is callable by anyone at most every 7 days after binding: it tries factory.claimFees inside try/catch, splits the whole IMD balance 40% HolderRewards, 25.72% JobsVault, 17.14% dev, 17.14% marketing, burns the vault's whole balance of the launched token and forwards any native ETH to marketing. HolderRewards opens a weekly epoch per deposit, requests the holder Merkle root through Intake oracle.request@oracle-1, accepts answers only from Intake carrying an attestation signed by the swarm oracle signer constant 0x5598aa9146215bc13eb26f2c692ad1461fd32982, caps claims at each epoch's pot and rolls pot - claimed into the current epoch after 28 days. JobsVault lets a wallet holding at least 1,000,000 launched tokens open one Identity.md job per 24 hours, paid from its own IMD. CompensationVault holds the fixed migration refund list (Merkle root 0xe84256f66c03a4565c29addd32238495f1a0d5dda8c618e5f81ff8637c296347, total weight 201084680772174552329559308, 62 wallets), buys back the launched token through the PoolManager in at most ten 10% tranches no sooner than 30 minutes after binding and 10 minutes apart, each swap bounded to a 1.5% sqrt-price band around an earlier reference price (partial fills are not tranches; after 3 days anyone can end the buyback so the airdrop always opens), then airdrops the acquired tokens pro rata once per listed wallet. After deployment the vault must be funded with IMD for the launch price; deployment itself sends no ETH and makes no initialization call.","contracts":[{"contract":"SIMDVault","constructorArgs":[]}]},"manifestError":null},"attestationFailure":null,"deployFailure":null,"policyVersion":28,"economics":null,"poolFee":null,"requester":"0xdfa1f1f6feaa04f7874eff0b7754b7ffaebd8bc0","admissionChecks":[{"name":"provenance","detail":"8 node(s) accepted at 01d4f6c8","status":"passed"},{"name":"findings","detail":"8 accepted submission(s), no unresolved blocking findings","status":"passed"},{"name":"independent_review","detail":"5 independent review(s)","status":"passed"},{"name":"bytecode","detail":"7 contract(s) clean and reproducible","status":"passed"},{"name":"manifest","detail":"1 application contracts; no protocol token or pool","status":"passed"},{"name":"protected_invariants","detail":"invariants-72ac6e744789: Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 910.51µs (753.90µs CPU time)","status":"passed"},{"name":"economics","detail":"policy explicitly selects no on-chain contributor rewards","status":"passed"}],"assurances":[],"logo":null,"seeded":null,"createdAt":"2026-10-21T10:43:56.514Z","updatedAt":"2026-10-21T10:45:26.963Z","jobs":[{"id":"ed909f82-0fa3-4cb7-8219-952be6e3bde3","objective":"SIMD Vault on Robinhood Chain: the contract that pays for and owns the fees of the \"Test\" token launch and splits everything it receives every 7 days, plus a CompensationVault that refunds the wallets that lost $SIMD in the October 2026 migration. Four linked contracts, no owner, no admin, no upgrade, no pause.\r\n\r\nFixed addresses (Robinhood Chain):\r\n- IMD token: 0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127\r\n- Identity.md Intake: 0xa43e6f75ee006411f79ac1c84120606c2330de82 (request(bytes32 action, bytes body, (address target, bytes4 selector) callback, address asset, uint256 amount); price from priceOf(action, asset))\r\n- Identity.md launch factory: 0x9c9d2fcb75c2c132c0ac0c42df3819a42347265e (claimFees(uint64 launchNumber) can be called by anyone and pays the launch's requester; positionOf(uint64) returns (PoolKey key, int24 tickLower, int24 tickUpper, address requester))\r\n- Dev wallet: 0xdfa1f1f6feaa04f7874eff0b7754b7ffaebd8bc0\r\n- Marketing wallet: 0xdfa1f1f6feaa04f7874eff0b7754b7ffaebd8bc0\r\n\r\n1. SIMDVault\r\n   - launch(bytes body): callable only by the dev wallet, only once. Approves Intake for exactly priceOf(\"launch.open@launch-1\", IMD) and calls Intake.request(\"launch.open@launch-1\", body, no callback, IMD, that price), paid from the vault's own IMD. This makes the vault the launch's requester, so the factory pays it the launch's creator fees for good.\r\n   - bindLaunch(uint64 launchNumber, address token): callable only by the dev wallet, only once, and only if factory.positionOf(launchNumber).requester == address(this). Stores both for good and passes the token to HolderRewards, JobsVault and CompensationVault (their one-time setToken/setLaunch, callable only by the vault; CompensationVault also gets the pool key from factory.positionOf).\r\n   - distribute(): anyone, at most once every 7 days, only after bindLaunch. First calls factory.claimFees(launchNumber) inside try/catch (a failed claim never blocks distributing what the vault already holds). Then splits the vault's whole IMD balance: 40% to HolderRewards, 25.72% to JobsVault, 17.14% to the dev wallet, 17.14% to the marketing wallet (rounding dust stays for next week). The vault's whole balance of the launched token is burned (sent to 0x000000000000000000000000000000000000dEaD). Native ETH: the pool is TEST/IMD so the factory should never pay ETH, but the vault accepts it (receive()) so a native payout can never make claimFees revert; any native ETH balance is sent 100% to the marketing wallet in distribute(). No conversions.\r\n   - No other way for IMD or tokens to leave.\r\n   SIMDVault deploys HolderRewards, JobsVault and CompensationVault in its own constructor and exposes them as immutable public getters.\r\n2. HolderRewards: receives IMD each week and pays it to holders of the launched token pro rata to a weekly snapshot, so it cannot be gamed by buying just before a claim. On each IMD deposit from the vault it opens a new epoch and asks the swarm, through Intake.request(\"oracle.request@oracle-1\", ...), paid from its own IMD, for a Merkle root of every holder's balance at the deposit block, excluding pools, the PoolManager, the factory and these three contracts; the root arrives in the oracle callback (only Intake can call it). claim(epoch, amount, proof) pays each holder once per epoch, and an epoch can never pay out more than its pot: each epoch stores its pot and claimed total, and a claim reverts if claimed + amount would exceed the pot. After 28 days anyone can roll an epoch over: exactly pot - claimed moves into the current epoch and the old epoch closes for claims.\r\n3. JobsVault: receives IMD each week and pays Identity.md swarm jobs for holders. Any wallet holding at least 1,000,000 of the launched token can call requestJob(bytes body) at most once per 24 hours; the vault pays Intake.request(\"job.open@job-1\", body, no callback, IMD, priceOf) from its own IMD. No withdraw.\r\n4. CompensationVault: receives 10% of the launched token's supply from the launch factory and, in IMD, the launch's anti-sniper fee from the token's hook. It refunds the wallets on a fixed list, built from the public on-chain record of every $SIMD transfer to the migration wallet 0xE132be23CE6255930556a45406075E62fb6340C0 after snapshot block 26213125, each weighted by what it lost (sent, capped at its snapshot balance). The list is committed as constants: Merkle root 0xe84256f66c03a4565c29addd32238495f1a0d5dda8c618e5f81ff8637c296347 over leaves keccak256(bytes.concat(keccak256(abi.encode(address account, uint256 weight)))) with sorted-pair hashing (OpenZeppelin MerkleProof), total weight 201084680772174552329559308, 62 wallets. Nobody can change the list.\r\n   - buyback(): anyone, only from 30 minutes after the pool opened (the end of the anti-sniper window). Swaps the vault's IMD for the launched token in the launch's own Uniswap v4 pool through the PoolManager (0x8366a39cc670b4001a1121b8f6a443a643e40951), in up to 10 tranches: each call spends at most 10% of the IMD the vault held when buyback first ran, at most one call every 10 minutes, so no single swap can be sandwiched for much. Stops when the IMD is spent.\r\n   - airdrop(address[] accounts, uint256[] weights, bytes32[][] proofs): anyone, only after the last buyback tranche. Each listed wallet is paid once: tokenBalanceAtAirdropStart * weight / totalWeight of the launched token, sent straight to it (the balance is fixed the first time airdrop runs). Wallets not on the list or with a bad proof are skipped.\r\n   - No other way for tokens or IMD to leave.\r\n\r\nTests: fork tests against Robinhood Chain with the real Intake and factory addresses; launch and bindLaunch only by the dev wallet and only once; bindLaunch rejects a launch whose requester is not the vault; the 40 / 25.72 / 17.14 / 17.14 split and the token burn; the 7-day limit; JobsVault holding and daily limits; only Intake can deliver oracle answers; a native-ETH payout during distribute() goes to the marketing wallet without blocking the IMD split or the burn; an over-sized Merkle claim and a double claim revert; rollover moves exactly pot - claimed; CompensationVault: buyback only after 30 minutes, at most 10% per tranche and one tranche per 10 minutes, airdrop only after the buyback, each wallet paid once and pro rata, a bad proof or an unlisted wallet gets nothing, the list cannot change.\r\n\r\nTest harness note (Robinhood Chain is an Arbitrum Orbit chain): Foundry treats chain id 4663 like Arbitrum and answers ArbSys(address(100)).arbBlockNumber() with block.number, ignoring any mock etched at address(100). In tests never mock ArbSys: set the block number with vm.roll (and time with vm.warp) so arbBlockNumber() and block.number agree, and keep every test passing on chain id 4663.\r\n","state":"completed","attachedAt":"2026-10-21T10:43:56.514Z"}],"artifacts":[{"role":"other","name":"SIMDVault","address":"0xbba92992309c61e1c483ab630d0530f2c9edede7","creationCodeHash":"cae90a2e16f1bf53df86f0245308ab2d6c8caaf2155327b9da413b072141b3cd","txHash":"0x1d329c93de761114c40d699f36d58c2709b3bb8a5ff7dd17788b3ac7340d8eda","blockNumber":94222549,"verifiedAt":"2026-10-21T10:45:45.809Z","verifyFailure":null}],"allocations":[]}