shape:chain
WORKFLOW CONTRACT STAGE CONTEXT: the stage produces implemented and tested contracts, ABI documentation and an independently reviewed launch.json. Each assignment contributes only within its own role and write scope. Source-producing assignments own implementation, tests and ABI exports at docs/abi/<Contract>.json where their scope permits. The generated manifest assignment writes only launch.json. Review assignments inspect accepted source and manifest and return findings without editing files; they do not implement contracts or generate ABI files. Use the supplied canonical manifest guidance: policy and signed artifact linkage belong to services, while concrete source, constructor, policy or authorization conflicts remain review findings. Services publish source, attest, admit and deploy after this stage, then start the frontend. Read .imd/reads/workflow.md for the complete approved requirements and apply them to your assigned contribution; later service outcomes are not prerequisites of this assignment.
b3b48187345fa441609c2646bbeeabf0bc4975e8VERDICT: all checks passed
VERDICT: all checks passed
Review complete. No files in the accepted tree were changed — `git diff HEAD` is empty, and `forge build` / `forge test` (14 passed) / `forge fmt --check` still pass. Findings are in `.imd-findings.json`. ## What I verified Everything below I checked directly, mostly by building an adversarial Foundry harness outside the repo (symlinked `lib/`, copied `src/`) so the tree stayed untouched. **Clean, and worth recording as such:** - `docs/abi/Cadence.json` and `docs/abi/SubscriptionRegistry.json` are byte-for-byte identical to the compiled ABIs (normalized JSON compare against `out/`). - `launch.json` validates against the canonical LaunchManifest schema: all five required keys, no extras, `notes` 2667/4000 chars, contract name 20/32 chars, `$token` fills the one address-typed constructor slot, pool fields exactly the Sepolia values, `initialPrice` a valid decimal sqrtPriceX96 < 2^256. Token has no constructor args; `MerkleDistributor` not used. - The registry constructor never touches `msg.sender` — it avoids the documented factory-ownership trap outright. - Runtime opcode scan with the floor's own PUSH-skipping algorithm: no `DELEGATECALL`/`CALLCODE`/`SELFDESTRUCT` in either contract (1240 and 1259 bytes, far under EIP-170). No selector collision between Cadence and the ten admin signatures the token floor probes. Supply is exactly 10^27 to the deployer, no second mint path. - Checks-effects-interactions and the reentrancy guard hold; the malicious-token test genuinely exercises the guard. Token self-transfer accounting is correct (`from == to` nets to zero, not to a doubled balance). **Findings, ranked:** 1. **medium** — `setBeneficiary` is permissionless and one-shot (the approved design), but *no actor in the stage plan is assigned to win that race*. The factory makes no init calls, the manifest has no field for it, contributors can't broadcast. Reproduced: `0xBAD` claims it, the operator's call reverts `BeneficiaryAlreadySet` forever, and alice's `subscribe(1)` pays `0xBAD` 10 CDNC. Permanent, no recovery. I did **not** mark this high: the code matches the brief exactly, so resolving it is a scope decision (authorized post-deploy step with evidence, or amend the brief to bind the beneficiary at construction), not a patch to send back. 2. **low** — `periods > type(uint256).max / PERIOD` guards the wrong product. `subscribe(type(uint256).max / 1e19 + 1)` returns `Panic(0x11)`, not the `InvalidPeriods` the ABI and README advertise. Fails closed, but the next-stage web client will decode it as an unknown error. 3. **low** — README:33 says the repo "intentionally does not include `launch.json`"; commit `b3b4818` added it. The manifest node's write scope couldn't fix the README. Same section names no protected-suite env vars. 4. **low** — CDNC transferred directly to the registry is unrecoverable (no outbound transfer path at all) and undocumented. Adding a rescue would violate the no-admin requirement, so the fix is documentation. 5. **low** — coverage: zero `vm.expectEmit` in the suite, so all four non-indexed `Subscribed` fields are unasserted; the insufficient-*balance* path is shadowed by the allowance check in the one test that looks like it covers it. I confirmed both behave correctly today — this is regression exposure, not a live bug. 6. **info** — the beneficiary subscribes for free (self-transfer nets zero). Economically neutral since it receives all revenue, but it's an undocumented privileged capability. 7. **info** — `lib/forge-std` is a 44-line hand-written stub. Sufficient to compile both protected floors, but it rules out fuzzing, `bound`, `deal`, `assertLt` and `log_*` — which is why the suite is fourteen fixed-input tests and why finding #2 survived. Out of everyone's write scope; recorded so admission doesn't over-read the green suite.
`launch.json` is written and validated. Summary: - **kind** `evm_project`; **token** `Cadence` / "Cadence" / "CDNC" / 18 decimals — matches `src/Cadence.sol:6-10` and its zero-argument constructor. - **contracts**: single entry `SubscriptionRegistry` with `["$token"]`, matching `constructor(address token_)` at `src/SubscriptionRegistry.sol:38` and `docs/abi/SubscriptionRegistry.json`. It's the only application contract in the accepted tree, so no `$contract` references and no ordering ambiguity. The registry has no owner/admin parameter, so no `$owner` and no wallet is named. - **pool**: native ETH (zero address), fee 3000, tickSpacing 60, `initialPrice` "79228162514264337593543950336" (1:1 sqrtPriceX96), no hook. - **notes** (2667 chars) record why price/period are source constants, that the beneficiary is first-caller-wins and therefore an operator step with no manifest field, and what belongs to policy/attestation rather than the manifest. Checks run: a schema check in `test/scratch/` (all schema fields, identifier/uniqueness/reserved-name rules, reference direction, address-typed reference placement, notes length) cross-referenced against the exported ABIs — passes; `forge build` and `forge test` on the accepted tree pass (14 tests, 0 failures). `git status` shows `launch.json` as the only change. One thing worth flagging to the review node, not a manifest defect: the permanent beneficiary can be claimed by anyone between deployment and the operator's `setBeneficiary` call. The constructor cannot preset it under the approved one-argument constraint, so the risk lives in the deployment runbook (`README.md`), which already documents it.
Wrote `{"findings":[]}` to [.imd-findings.json](.imd-findings.json). No substantiated defects found in the contracts, tests, or ABI exports. `launch.json` was absent and remains unreviewed. Existing files were unchanged; tests were inspected, not rerun.
Implemented the complete Cadence Foundry project: - Fixed-supply `Cadence` ERC-20: 1 billion CDNC, 18 decimals, no admin or mint backdoor. - `SubscriptionRegistry` with: - 10 CDNC fixed price per 30-day period - Multi-period prepayment - One-time, first-caller beneficiary selection - Direct, non-refundable beneficiary payments - Expiry tracking and `isActive` - Checks-effects-interactions and reentrancy protection - 14 success and failure tests, including timing boundaries, failed payments, insufficient allowance, invalid configuration, and malicious-token reentrancy. - Exact generated ABIs under `docs/abi/`. - Deployment assumptions, launch race risk, parameters, and operational responsibilities documented in [README.md](/home/worker/.imd/seat2/work/9d1cbe7e-6370-4fb8-bdd6-bca7d6f21dd6/2b547a31-8a3f-42f6-9219-71f842cb18ae/README.md). Validation passed: - `forge build` - `forge test` — 14 passed, 0 failed - `forge fmt --check` - ABI exports exactly match compiler output - `git diff --check`
Proof Of IMD pays $POI to the current owner of the seat whose submission passed verification. The owner is the ERC-721 holder reported by GET /seats/:tokenId.
No result files for this job.