{"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":"54b72fb6-80c8-4475-a6d5-5034a50b6bd3","kind":"skill:research-report","nodes":[{"acceptedSubmissionHash":"5401865049ae31fbee16f76ac69e2d9b14a9c2a34a563fec4f183490ebb9ff91","dependsOn":[],"execution":{"network":true,"profile":"none","requires":["network"],"skillHash":"3ddca93330036359dd721585e58e67820336a0398b7927b3c89369d6134f30f6","skillId":"research-report","tools":[]},"key":"research_report","kind":"code","role":"implement","skillHash":"3ddca93330036359dd721585e58e67820336a0398b7927b3c89369d6134f30f6","skillId":"research-report","state":"accepted"}],"objective":"Design isolated lending markets for long-tail tokens paired with IMD, Rari Fuse style, where part of the interest pays imdUSD liquidity providers who sit at the peg.\n\nWHAT. Every token launched on imd.fun gets a Uniswap v4 TOKEN/IMD pool. Anyone may open a market for such a token (or any ERC-20 with an IMD-paired v4 pool). Collateral: the token. Lenders supply IMD or imdUSD (the CDP stablecoin, which has an imdUSD/USDC v4 peg pool). Bad debt stays with that market's lenders. The token never backs imdUSD minting: markets lend existing imdUSD only.\n\nFACTS THAT SHAPE IT, measured by us. Launch pools carry the plane's shared hook with beforeInitialize only, so no TWAP can be added inside them. Many launch pools are one-sided or thin, and two were drained to the minimum tick. IMD's deep market is a v4 IMD/ETH 1% pool (about 1.9M USD of liquidity); ETH/USD from Chainlink. The imdUSD/USDC peg pool is thin: about 250 imdUSD fills before price leaves a $0.9975-$1.0025 band, and a single borrower selling borrowed imdUSD pushed it to $0.89 twice. Rari Fuse lost about 80M USD in April 2022 to reentrancy in its Compound fork, and smaller Fuse pools to price manipulation of thin assets and to pool admins who set bad parameters: design against all three. Oracle option: the swarm oracle attests a v4 pool's median price over a block window (recipe univ4-spot {poolManager, poolId, samples odd 1-61}); a request costs 0.5 IMD (about 4 USD) and arrives in minutes as an EIP-712 attestation from signer 0x5598aa9146215bc13eb26f2c692ad1461fd32982 (domain \"IdentityMD Oracle\" v2), with panelSize, quorum and agreed signed. A working verifier is github.com/fa11up/oracle-coop.\n\nANSWER, each separately:\n1. Price source per market: (a) an on-chain observer contract that records the pool price from permissionless pokes, (b) univ4-spot attestations, (c) observer by default, attestation above a market size, (d) no oracle at all, the Ajna model where lenders choose price buckets. Cost per market per day, the cost to move each by 10% at 50k and 500k USD of pool depth, and which survives a missed poke.\n2. Limits from the pool: a formula for the collateral cap from what it costs to sell the cap through the TOKEN/IMD pool (and IMD/ETH behind it) within the liquidation bonus; how often to recompute; and how to stop an opener who adds depth, opens a market, borrows, then pulls the depth (time-weighted depth, a cap that rises slowly, or a cap measured at borrow time). Minimum depth to open. Check it on two real launch pools and state the numbers.\n3. Market shape: one market per (collateral, loan asset) as Morpho Blue does, versus one pool lending both IMD and imdUSD. Compare Morpho Blue, Euler v2, Silo, Ajna and Fuse on isolation, oracle, liquidation and creator powers.\n4. Liquidation for thin collateral: Dutch auction versus fixed bonus, starting premium, duration, who bids, partial fills, and bad-debt socialisation inside one market. Behaviour when the pool is drained mid-auction.\n5. Interest rates with no admin: a fixed kink curve, an adaptive curve (Morpho's AdaptiveCurveIRM), or utilisation targets. Defaults and why.\n6. The LP mechanic: a reserve factor on imdUSD interest donated into the imdUSD/USDC peg pool with PoolManager.donate, which pays only liquidity in range at the current tick. Share, cadence, and defence against just-in-time liquidity added before a donation (small frequent donations, unpredictable timing, a donor that only donates while price is near $1). Expected yield to peg LPs at 1M and 10M of loans. What to do with the IMD-side interest.\n7. Token admission: fee-on-transfer, rebasing, blocklisting, pausable and upgradeable tokens; what a permissionless factory must refuse and how it detects each on chain.\n8. Spam and listing: permissionless creation of thousands of markets; what a front end shows by default.\n\nTHE CONTRACTS SECTION: we deploy these ourselves (not through a launch), so a factory may create markets permissionlessly. Hard rules: no admin keys and no parameter a market creator chooses (every limit derived on chain from facts); ERC-20 only, no ETH and no callbacks during a loan, checks-effects-interactions plus a reentrancy guard on every entry. For each contract give: purpose, constructor, storage, external functions with access rules, events, and the invariants a test must hold. Solidity interfaces, not full implementations. Then a Foundry test plan naming each test, including the adversarial ones (a pushed pool, depth added then pulled, a token that rebases or blocklists, a JIT donation snipe).\n\nFORMAT: one Markdown spec of roughly 3,000 to 6,000 words, in this order: (1) a one-paragraph recommendation; (2) a decisions table, one row per numbered question, with the choice, the figure, and the main reason; (3) each question in its own section; (4) the contracts; (5) the test plan; (6) risks ranked by severity; (7) open questions for the IdentityMD developer, each phrased so it can be asked as is. Tables for any comparison of more than two items. Mark every unverified statement about the IdentityMD plane as an ASSUMPTION. Cite at least six distinct sources (protocol docs, audits, post-mortems), each a page that states what it is cited for, with the date read.","parentJobId":null,"planHash":"8cfcd10d875fe15bb1c15bbe7b3631aac2681706140adaddd1a510a46112826c","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"54b72fb6-80c8-4475-a6d5-5034a50b6bd3","publication":{"commit":null,"deliveredAt":null,"repoUrl":null},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52360","feedbackHash":"e520b1fdbe5138a09195adc540ae5f5a8a491b2787367ca2b24f7ed7c2f12f44","nodeKey":"research_report","submissionHash":"5401865049ae31fbee16f76ac69e2d9b14a9c2a34a563fec4f183490ebb9ff91","tag1":"verification:structural","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"d251a66d02cf0a9da130dbac4f22e1b1b0b6029ec5f54aebc95e337975b80116","state":"completed","submissions":[{"artifacts":[{"bytes":46656,"hash":"efde11347f48aef20e236f0823d3342bd6e2189d98628676e792a8315106440d","mediaType":"text/markdown","name":"spec","path":"artifacts/spec.md"}],"attempt":1,"bundleHash":"bc88928cbb6e955185bb6f9b6cfa1c3517e0108543c97fc29d195c6b06f723a7","device":"9841ca91054c407d","findings":[],"hash":"5401865049ae31fbee16f76ac69e2d9b14a9c2a34a563fec4f183490ebb9ff91","nodeId":"a23ebdd1-cae6-4807-af94-2825eac20f5e","outcome":"completed","summary":"I've written the spec to `artifacts/spec.md`, in the order you asked for, at roughly 5,000 words. I've also written a short `README.md` at the repository root. Neither file is committed: every shell command failed with a sandbox permission error. `artifacts/spec.md` is meant to stay untracked anyway, but the README needs to be committed by whoever can.\n\nTwo parts of the brief were not done:\n- **The two real launch pools were not checked.** I had no pool IDs and no RPC for the plane's chain. The spec gives the method and a fork test, `test_capFromForkedLaunchPools`, and asks for the IDs as its first open question. From your own facts, the two pools drained to the minimum tick would get a cap of zero and be refused.\n- **The oracle-coop verifier was not read.** The attestation struct in the spec is marked ASSUMPTION until it's checked against that code.\n\nThe main recommendations:\n- **Market shape:** one immutable contract per (token, loan asset) pair, created by a factory with no admin key. Each token can have at most two markets, which also limits spam.\n- **Price source:** a permissionless on-chain observer of the TOKEN/IMD pool by default. Above a fixed market size, borrows also need a fresh swarm attestation, and the lower of the two prices is used.\n- **Observer weakness:** anyone can push the price, record a sample and reverse the push in one transaction for just the swap fees. By my constant-product estimate, moving the median 10% costs about $0.8k in a $50k pool and $7.6k in a $500k pool. The protection is therefore the size cap, not the oracle.\n- **Collateral cap:** in a full-range pool, the cap comes to about 3.2% of pool value. Depth is measured as the 7-day minimum, and the cap can rise at most 25% a day. Opening needs about $250k of pool value. This stops someone adding depth, borrowing and pulling the depth.\n- **Liquidation:** a Dutch auction that starts at 105% of the reference price, falls 1% a minute and lasts 6 hours. The oracle only decides when it starts, so a pool drained mid-auction delays recovery but doesn't misprice it. Anyone can bid, partial fills are allowed, and leftover bad debt is written off against that market's lenders only.\n- **Interest rates:** Morpho's adaptive curve, unchanged.\n- **Peg LPs:**\n  - **Share and cadence:** 20% of imdUSD interest is donated to the peg pool at most once an hour, and only while the price is between $0.9975 and $1.0025.\n  - **JIT defence:** a donation is skipped if the pool's active liquidity is above 1.25 times its recent median, which defeats liquidity added just before a donation.\n  - **Expected yield:** at an assumed 8% borrow rate, that pays about $16k a year on $1M of loans and $160k on $10M.\n- **imdUSD selling pressure:** new imdUSD borrowing across all markets is capped per hour by how much the peg pool can absorb before the price falls below $0.99.\n\nEvery number I worked out myself is labelled as derived. Unverified statements about the plane are marked ASSUMPTION, and there are nine sources, each dated 2026-10-21. Euler v2's liquidation discount and governor powers are not confirmed by the pages I read, and the spec says so.","treeHash":"cda3eeaedf3dee7e3c9e5c42fe08f35ec6a760f3","usage":{"cachedInputTokens":568013,"inputTokens":22,"model":"claude-opus-5-5","outputTokens":36497,"runtime":"claude","turns":23,"wallClockMs":394685}}],"verification":[{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"5401865049ae31fbee16f76ac69e2d9b14a9c2a34a563fec4f183490ebb9ff91","verifiedTreeHash":"cda3eeaedf3dee7e3c9e5c42fe08f35ec6a760f3","verifierVersion":"0.1.0+a26ee00d"}]}