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.
a21df802e3cca4a1ae93456b49cbc197bab92de5VERDICT: all checks passed
VERDICT: all checks passed
Review complete. No files were modified — `git status` shows no changes to any tracked file; the only additions are the required `.imd-findings.json` and the gitignored `test/scratch/` rehearsal directory. ## What I checked - **Build/tests/format**: `forge build --offline`, `forge test --offline` (45 passed), `forge fmt --check` all pass on the committed tree. - **Protected suites**, rehearsed in `test/scratch/` against real compiled creation code (CREATE2 factory `0x…0f4c70`, chain 11155111, supply 10^27, TipSplitter encoded with the predicted token address): `Token.protected.t.sol` 6/6, `Project.protected.t.sol` 2/2. `docs/VERIFICATION.md` is accurate. - **Manifest**: `launch.json` validates against the canonical LaunchManifest schema, including the refinements — `initialPrice` is exactly 2^96 and below 2^256, names are unique, `MerkleDistributor` unused, `$token` fills TipSplitter's single address argument, token has no constructor args, notes are 591/4000 chars. - **ABIs**: `docs/abi/Splitwise.json` and `docs/abi/TipSplitter.json` are byte-exact matches to the freshly compiled artifacts. - **Adversarial probing** (scratch fuzz, 512 runs each): solvency and equal-lifetime-entitlement under claim-and-redeposit recycling that pushes `totalDeposited` past the 10^27 supply; claim ordering across 1–10 members; whole-supply tips; the reentrancy guard's inability to brick the contract. ## Findings (6, ranked, in `.imd-findings.json`) **No blocking correctness defect.** Accounting is sound: `claimable()` cannot underflow because the entitlement basis is monotonic and `members.length` is immutable; the pool is always solvent because `n·floor(T/n) ≤ T`; CEI holds in both `claim()` and `_deposit`; the guard blocks reentry through every mutating entry point from both incoming and outgoing token calls. I could not construct an input that breaks any of these. | Sev | Finding | |---|---| | medium | First registrant permanently owns every future tip; ProjectFactory makes no init calls, so the race window is unavoidable. **Design-conformant** (the brief mandates it) and documented in the README — filed as a trust-assumption observation with an operational mitigation, not a code fix. | | low | `registerMembers` rejects `address(0)` and `address(this)` but accepts `address(token)`; that member's share burns into the token contract. Fixing it invalidates `TipSplitterAdversarial.t.sol`, which uses `address(token)` as its member. | | low | Plain transfers to the pool are uncredited and unrecoverable — relevant to the website reviewer, since "tip" maps naturally to `transfer`. | | low | `totalDeposited % n` dust is stranded permanently; with 10 members, any tip under 10 base units leaves a non-zero balance and zero claimable. | | info | `approve(address(0), x)` reverts, which EIP-20 does not license. | | info | Coverage gap: no test exercises recycling past the supply, and the stateful invariant is pinned to `n == 3`. I fuzzed it — behaviour is correct, so this is a test addition, not a source change. |
Created `launch.json` with `Splitwise` (SPLT), `TipSplitter(["$token"])`, and the supplied native ETH pool parameters. Verified manifest constraints and compiled constructor ABI compatibility. `forge build` succeeded with existing source lint warnings; `forge test` passed all 45 tests. Only `launch.json` changed.
Review complete. No substantiated defects found. Created `.imd-findings.json` with: ```json {"findings":[]} ``` All 45 Foundry tests passed, including adversarial and invariant suites.
Implemented fixed-supply SPLT and ownerless TipSplitter, with ABI exports, vendored dependencies, and deployment documentation. Validation passed: - Offline `forge build` and `forge test`: 45 tests. - Supplied protected checks: 8 tests. - `forge fmt --check`. [README](/home/imd2/.identitymd/work/f425ad3b-2f98-48ee-9dc4-fa17a578ff94/5c03fa28-f1e8-4127-8f2a-663b3b957121/README.md) documents registration risks, rounding, direct-transfer limitations, and operational responsibilities. Manifest generation, independent review, and deployment remain separate workflow steps.
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.