diff --git a/components/research/ClaimFlowDiagram.jsx b/components/research/ClaimFlowDiagram.jsx new file mode 100644 index 0000000..3308419 --- /dev/null +++ b/components/research/ClaimFlowDiagram.jsx @@ -0,0 +1,100 @@ +export default function ClaimFlowDiagram({ className = '' }) { + return ( +
+ {formal}
+
+ ))}
+ + No user can claim more than their share. The round pool stays + solvent. The two token flows don't interfere. +
+
+ The{' '}
+
+ (address, shareWad)
+
+ , and stores only the root onchain.
+
+ Users sign an EIP-712 liability waiver, then call{' '}
+ claimUsdc or{' '}
+ claimWeth. The
+ contract verifies the Merkle proof against the stored root, computes{' '}
+
+ amount = shareWad × roundTotal / 1e18
+
+ , checks accounting bounds, and pays out.{' '}
+ claimBoth calls
+ both sequentially.
+
+ This contract distributes recovery funds to victims of an exploit. + A bug in the claim logic could let someone extract more than their + entitlement, claim twice, or drain the round pool, taking funds + that belong to other victims. The stakes are not abstract: every + dollar overclaimed is a dollar another affected user does not + receive. +
++ The proofs cover six property families across all three claim + functions: +
+
+ shareWad × roundTotal / 1e18
+
+
+ roundClaimed + totalAllocated
+ {' '}
+ is conserved per token
+
+ roundClaimed ≤ roundTotal
+ {' '}
+ per token
+ claimBoth{' '}
+ produces identical state to calling each claim separately
+
+ The model covers a single-round protocol slice. Multi-round
+ batching (
+
+ claimMultipleUsdc
+
+ ) is out of scope. The per-round accounting properties hold
+ identically for each round.
+
+ The claim functions were modeled in{' '}
+
+ The Lean model maps ten storage slots: round totals, claimed + counters, allocated counters, round-active flag, per-user waiver + and claim flags, split across USDC and WETH. Each function mutates + this state differently: +
+roundUsdcClaimed,
+ decrements{' '}
+
+ totalUsdcAllocated
+
+ , marks the user as claimed
+ claimUsdc on the
+ WETH slots
+ claimUsdc then{' '}
+ claimWeth{' '}
+ sequentially. The cross-token independence proof shows this
+ composition is safe: USDC accounting does not interfere with WETH
+ accounting
+
+ How do you prove the books stay balanced? You show that every
+ successful claim increases{' '}
+ roundClaimed and
+ decreases{' '}
+ totalAllocated by
+ exactly the same amount, so their sum is conserved. Combined with
+ the solvency bound (
+
+ roundClaimed ≤ roundTotal
+
+ ), this guarantees no value is created or destroyed and the round
+ pot is never overdrawn.
+
+ All proofs are verified by Lean 4's kernel and are provided
+ in{' '}
+
+ If the build succeeds, the proofs are correct.{' '}
+
+ All 18 theorems are proven.{' '}
+ sorry-free.
+
| + Function + | ++ Correct payout + | ++ Books balanced + | ++ Pool solvent + | ++ No double-dip + | ++ No overclaim + | ++ Cross-token + | +
|---|---|---|---|---|---|---|
| claimUsdc | ++ proven + | ++ proven + | ++ proven + | ++ proven + | ++ proven + | ++ — + | +
| claimWeth | ++ proven + | ++ proven + | ++ proven + | ++ proven + | ++ proven + | ++ — + | +
| claimBoth | ++ proven + | ++ proven + | ++ proven + | ++ proven + | ++ proven + | ++ proven + | +
+ The proofs use zero axioms. The only trust assumption is the + Merkle proof abstraction. All other conditions are consumed in + exactly the form the contract enforces them. +
+proofAccepted.
+ This is the one real trust assumption: we assume the Merkle tree
+ correctly binds{' '}
+
+ (msg.sender, shareWad)
+ {' '}
+ to the stored root. This is a cryptographic guarantee from
+ OpenZeppelin's MerkleProof library, not a contract-level
+ concern.
+
+ claimMultipleUsdc
+
+ ) is out of scope. The per-round accounting properties hold
+ identically for each round.
+ msg.sender is
+ authentic. This is an EVM-level guarantee, not a contract-level
+ concern.
+
+
+
+ + What is a formal proof? + {' '} + A short explanation for non-specialists. +
+