{"rewardSnapshot":null,"merkleRoot":null,"claims":null,"id":"3ded72c6-510b-490c-a6ae-ac8b21704a7f","launchNumber":825,"kind":"univ4_hook","status":"parked","chainId":1,"sourceRepoUrl":"https://github.com/identity-md-launches/launch-825-build-uniswap-v4-hook","sourceCommit":"a580c0fbd7e2404b619c0b458834b102fa32f447","parkedReason":"findings: 1 blocking finding(s) never resolved — audit_judge: launch.json still names the bare PaperHook implementation, which cannot initialize or operate the pool; the working PaperProxy cannot be expressed in the manifest and its runtime fails the protected D","artifactCount":0,"manifestHash":"9a6e5cd007456b6af1c6c5662042b86c1ff944931ce84b4c638899f4b1c1dcc7","attestationHash":"8a1353b43e88255c7e92d177a34871f25fb741eec82eb24650089da04eb3a8e2","attestation":{"treeHash":"7162c4b1f03dd6bc9bf235439c922f3547a33fa8","verifierVersion":"0.1.0+94826a22","verifierKey":"68249df1f422fa72f61ca7f0ddaf9b62043959c5c134498441d5e552a9921782","toolchain":{"solc":"0.8.26","forge":"forge Version: 1.8.3","viaIR":false,"optimizer":true,"evmVersion":"cancun","bytecodeHash":"none","optimizerRuns":200},"contracts":[{"name":"HookFlags","path":"src/HookFlags.sol","abiHash":"518674ab2b227e5f11e9084f615d57663cde47bce1ba168b4c19c7ee22a73d70","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"402c4eef4e5ce85c80e136e56d6de14fbe9ffa43ede619a36f14e44c9a6fa20d","creationCodeHash":"03f00af6a2c1e216c5142290f5a7c5a73b7dca9ff4182f298fb7a6b46fc82bef","deployedCodeHash":"324d2f77e170e519647f21af4dd0b9d0c4677a0d6fe8cd1d41c195a62780eeba","creationCodeBytes":94,"deployedCodeBytes":44},{"name":"Paper","path":"src/Paper.sol","abiHash":"38880b8e56d42ce900f744a7908c7139632a49f1c3f33385c64ceaed29d37bee","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"7fcb2b7e8467c3d5b29132c366b17d4b2bd6c03697fdb869d140eb60d4807c9f","creationCodeHash":"af284385dcad28225440d2c6aa05d93a34f11f84b64b56d74c0ee1fdbdc2436a","deployedCodeHash":"4b31f2c8acd7927be8cd8343fab9dd61cad18478e5e65d8113e54186ea32a88e","creationCodeBytes":2590,"deployedCodeBytes":1723},{"name":"PaperDeployment","path":"src/PaperDeployment.sol","abiHash":"d7f788aeeab918f496520516a1c503f5837e74dfaa7c63bab05ca132e5291f84","opcodes":{"callcode":false,"delegatecall":true,"selfdestruct":false},"metadataHash":"9ba520102a298a00ab4af6850639fa4b557085be544f4b2cb0493222260c039c","creationCodeHash":"8098eb03a2f6cf509f07543565fd9d6b1e593fe6fec0f8da51622f10e57cc9d3","deployedCodeHash":"4ef39ff9ff123918c6a19c918777793345bb09f7efd9d1d3cbd6a708f6a6f6a7","creationCodeBytes":10968,"deployedCodeBytes":10940},{"name":"PaperHook","path":"src/PaperHook.sol","abiHash":"9b0089d29d9f2c9c679ca35c702b8ac4a391ab26e1abef3a2049a475d90cded8","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"fd5a851883c267eb68dee0d8519aa97888be82665e53f1d1a87ad31245d5f2ec","creationCodeHash":"e18bb8b33391445ad796bfa3460b33848dfa1049142887c9ecb242a25fcc5fc0","deployedCodeHash":"95289d3166cb8a8454664900441f7c2a30d029051c0607ed7001b3e3492ab169","creationCodeBytes":12628,"deployedCodeBytes":12266},{"name":"PaperHookV2","path":"src/PaperHookV2.sol","abiHash":"9b0089d29d9f2c9c679ca35c702b8ac4a391ab26e1abef3a2049a475d90cded8","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"15a6c7169461468277a26018df1adc9d89e48c41d27d02264529069b4edbaedb","creationCodeHash":"eb80132e3f2d28c9b4a88e2b2ade834fc55b6ca282261ac83b23be7983d3057d","deployedCodeHash":"180ed849a05ea535d8a0ccb749d7dac9b9f01109ed8dab4d8ecf4d36fbe46415","creationCodeBytes":12630,"deployedCodeBytes":12266},{"name":"PaperProxy","path":"src/PaperProxy.sol","abiHash":"4aa6657bc1c64cd31c444f56dd3f4c81da9b0c5eef4a572254d04961a4369661","opcodes":{"callcode":false,"delegatecall":true,"selfdestruct":false},"metadataHash":"a4dbcb87ac1b2b05dae3c0f5bce19ac338ee347db005934550172194b3cde835","creationCodeHash":"314c9497a2334fc560ee17efd4dde93457614d8578927f454c6339a18dd3f95b","deployedCodeHash":"cb81c7afa312fe9021a7017427591ec582232b13f951ed4a46b8a0bca6907d38","creationCodeBytes":4687,"deployedCodeBytes":1583},{"name":"PaperSwapRouter","path":"src/PaperSwapRouter.sol","abiHash":"ecbce139e39e90f81d8f8879bb63b49251ed8e94a489d5dcf0a7d1e592c2986e","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"ce5e0bff369afc472336bcfd7c5820c95363e52b911ddb4d807872cd96336f9a","creationCodeHash":"d4a93d93e0ff399101cd96978ac391d0750e32409dfd3dc04f1520effbfb6904","deployedCodeHash":"2fc50ed31119c21675d05d8b2383dc47251e6ea5e138ce4dddaeb375d466b379","creationCodeBytes":4580,"deployedCodeBytes":3726}],"manifest":{"hook":{"contract":"PaperHook","permissions":["beforeInitialize","afterInitialize","beforeAddLiquidity","afterAddLiquidity","beforeRemoveLiquidity","afterRemoveLiquidity","beforeSwap","afterSwap","beforeDonate","afterDonate","beforeSwapReturnDelta","afterSwapReturnDelta","afterAddLiquidityReturnDelta","afterRemoveLiquidityReturnDelta"],"constructorArgs":["$poolManager"]},"kind":"univ4_hook","pool":{"fee":3000,"tickSpacing":60,"initialPrice":"79228162514264337593543950336","pairedCurrency":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7"},"notes":"BLOCKING, read first: this manifest cannot launch as written. hook.contract names PaperHook, the V1 implementation that declares getHookPermissions and whose only constructor argument is IPoolManager. Its constructor disables initialization, so a bare PaperHook at a mined address has no manager, token or owner in storage: every callback reverts Unauthorized and PoolManager.initialize fails (reproduced locally). The working hook is PaperProxy(implementation, initialization), a TransparentUpgradeableProxy CREATE2-mined so address & 0x3fff == 0x3fff, whose constructor delegatecalls initialize($token, hookOwner, imdUsdWad). This schema cannot express the implementation-then-proxy sequence, the initializer inputs or the hook owner, and the protected runtime scan rejects DELEGATECALL, which every proxy executes. The protected permission and callback-refusal checks on bare logic do not verify the proxy lifecycle. Launch needs deployer support for PaperDeployment.deployHook (atomic proxy deployment plus pool initialization) and a proxy admission exception, or a non-proxy redesign.\n\nPermissions: getHookPermissions returns all 14 flags true in PaperHook and PaperHookV2, as the brief requires. beforeInitialize binds one sorted paper/IMD pool, accepts LP fee 500, 3000 or 10000 with positive tick spacing, records the launch price, and allows initialization only by the recorded launcher or hook owner. Every callback requires PoolManager as caller; unused callbacks validate the pool and return their selector with zero deltas. Paper has no constructor arguments and 18 decimals.\n\nPool: paper/IMD on Ethereum mainnet, LP fee 3000 and tick spacing 60 (the brief names no other tier). initialPrice is 2^96, raw currency1/currency0 = 1. Assuming 18 IMD decimals, this is 1 paper = 1 IMD; live decimals require verification. This raw ratio is independent of token address order. It is an assumption, not a reviewed launch price.\n\nFee: a constant 200 bps of the IMD leg in both directions via beforeSwap/afterSwap return deltas, separate from the LP fee. Defaults are 50 bps to orders 0x721F8232e19c92516eB753FEF53d8A33a3637989 and 150 bps to dev 0xb59eac9882Ba98f4170d99D5F402C3EDb6D50D75. Owner-only setSplit requires the parts to sum to 200. Fees are paid with PoolManager.take in the same swap; nothing accumulates and no claims are minted, so a swap reverts with InsufficientFeeBacking when the manager holds less IMD than the fee. Integrate the input-prepaying PaperSwapRouter whenever IMD backing is insufficient, including first buys in paper-only pools; historical manager balances do not guarantee backing. Partially filled IMD-specified swaps revert.\n\nUpgradeability: the ProxyAdmin initial owner is the constant dev address, not a constructor argument. State uses one ERC-7201 namespace. PaperProxy pins the runtime hashes of the delivered PaperHook and PaperHookV2 with the same manager, so no other implementation can be installed. PaperHookV2 reverses the default split to 150/50 for fresh proxies only; an upgrade keeps existing state and split.\n\nVoting: postFeeUsd starts at 1 whole USD. postFeeTokens uses the pool sqrtPriceX96 and owner-set imdUsd (1e18 scale); no chain-readable USD source is configured. With zero active liquidity it uses the launch price or the last post-swap price seen with liquidity. postDraft(bytes32) is uncapped; postDraft(bytes32,uint256) reverts above the caller's maximum. postDraft and burn send paper to 0x000000000000000000000000000000000000dEaD and emit DraftPosted/Burned. Rounds, quorum and winners are not stored. The spot price is manipulable, and a manipulated saved quote can persist after liquidity removal; clients should use the capped postDraft overload.\n\nEvidence: forge build succeeds with lint warnings; forge test passes 202 tests in 22 suites, zero failures or skips (unit, fuzz, upgrade, invariant). No mainnet fork rehearsal or independent admission has run.","token":{"name":"paper","symbol":"paper","contract":"Paper","decimals":18}},"manifestError":null},"attestationFailure":null,"deployFailure":null,"policyVersion":29,"economics":{"poolBps":8000,"remainderTo":"0xb59eac9882ba98f4170d99d5f402c3edb6d50d75"},"poolFee":null,"requester":"0xb59eac9882ba98f4170d99d5f402c3edb6d50d75","admissionChecks":[{"name":"provenance","detail":"8 node(s) accepted at a580c0fb","status":"passed"},{"name":"findings","detail":"1 blocking finding(s) never resolved — audit_judge: launch.json still names the bare PaperHook implementation, which cannot initialize or operate the pool; the working PaperProxy cannot be expressed in the manifest and its runtime fails the protected D","status":"failed"},{"name":"independent_review","detail":"5 independent review(s)","status":"passed"},{"name":"bytecode","detail":"PaperDeployment contains DELEGATECALL; PaperProxy contains DELEGATECALL","status":"failed"},{"name":"manifest","detail":"fee tier 3000 is not on the policy allowlist","status":"failed"},{"name":"protected_invariants","detail":"invariants-f2c2ff10a634: Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.94ms (2.47ms CPU time)","status":"passed"},{"name":"economics","detail":"302 allocation(s), root 0x4a9b4a90","status":"passed"}],"assurances":[],"logo":null,"seeded":null,"createdAt":"2026-10-06T20:04:44.755Z","updatedAt":"2026-10-06T20:05:00.864Z","jobs":[{"id":"17d14f70-4f1b-4de2-8289-95465e51b17b","objective":"Build a Uniswap v4 hook for a new token paired with IMD on Ethereum mainnet. Token name \"paper\", symbol \"paper\".\n\nFee:\n- The hook charges 2% of every swap in IMD, both directions (buys and sells), via beforeSwap/afterSwap return deltas. This total is a constant; nothing can raise it.\n- Inside the total, the split is a storage setting: 0.5% to the orders wallet 0x721F8232e19c92516eB753FEF53d8A33a3637989, 1.5% to the dev wallet 0xb59eac9882Ba98f4170d99D5F402C3EDb6D50D75. Only the owner can call setSplit(ordersWallet, ordersBps, devWallet, devBps); the two parts must sum to the constant.\n- Fees are paid out to the two wallets in IMD in the same swap, with no accumulation inside the hook.\n\nUpgradeability:\n- The hook is a TransparentUpgradeableProxy whose address is mined with all 14 hook flag bits set (addr & 0x3fff == 0x3fff), so later implementations can use any callback. Unused callbacks are no-ops in v1.\n- ProxyAdmin owner is the constant 0xb59eac9882Ba98f4170d99D5F402C3EDb6D50D75 (not a constructor argument, not the launch wallet). Storage uses namespaced ERC-7201 slots so an upgrade keeps all state.\n- Deliver two implementations with tests: v1 as specified, and a demo v2 identical except the default split is reversed, used only to rehearse an upgrade.\n\nVoting by burning (in the hook, reads the pool):\n- postDraft(bytes32 textHash) returns draftId: pulls from the caller the token amount worth postFeeUsd dollars at the current pool price (IMD per token from the pool, USD per IMD from a chain-readable source agreed at review; if none, owner-set imdUsd), transfers it to 0x000000000000000000000000000000000000dEaD, emits DraftPosted(draftId, author, textHash, burned). The burned amount counts as the author's votes.\n- burn(uint256 draftId, uint256 amount): pulls amount tokens from the caller to the dead address, emits Burned(draftId, voter, amount). Any amount, any number of times, any existing draft.\n- postFeeUsd starts at 1; owner-only setPostFeeUsd. Views: feeBps(), split(), postFeeUsd(), postFeeTokens().\n- Rounds, quorum and winners are computed off-chain from the events; the hook stores nothing about rounds.\n\nPool:\n- Pair with IMD 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7; economics poolBps 8000, remainderTo 0xb59eac9882Ba98f4170d99D5F402C3EDb6D50D75. Fee tier and tick spacing as the policy allows.\n\nDeliver a Foundry project with unit tests for fees in both directions, split changes, the post and burn paths, the upgrade to v2 keeping state, and an adversarial review. English only in code and docs.","state":"completed","attachedAt":"2026-10-06T20:04:44.755Z"}],"artifacts":[],"allocations":[]}