Escrow contract — design for review
Draft only. Not compiled, tested, audited or deployed. Funds are not protected by anything on this page yet.
State machine
- ›Created → SellerFunded / BuyerFunded → BothFunded → Settled
- ›Any funded state → Cancelled (before taker match, maker only) — refunds exactly what each party deposited
- ›Any non-settled state past deadline → Expired — each party pulls back their own deposit (pull-payment)
- ›Every transition checked with a single `require(state == X)`; terminal states are final
Settlement
- ›settle() callable by either party once both deposits are in and before deadline
- ›Atomic: base asset → buyer, quote asset minus fee → seller, fee → treasury, in one tx
- ›Exact amounts: deposits measured by balance delta; mismatched amounts revert
Fees
- ›feeBps is immutable per offer, snapshot at creation
- ›Global MAX_FEE_BPS = 100 (1%) hard-coded constant; owner can only lower
- ›Fee changes emit FeeUpdated and apply only to new offers
Safety
- ›OpenZeppelin ReentrancyGuard + SafeERC20; checks-effects-interactions
- ›No admin withdraw, no upgradeability, no pause on refunds
- ›Events: OfferCreated, Funded, Settled, Cancelled, Expired, Refunded
Asset compatibility assumptions
- ›Only allow-listed ERC-20s with verified source on HyperEVM
- ›Fee-on-transfer, rebasing and ERC-777 hook tokens rejected
- ›Native HYPE wrapped to WHYPE before deposit
- ›HyperCore spot balances are NOT visible to contracts; users must bridge Core → EVM first
Testing plan (Foundry)
- ›Unit test for every state transition and every revert path
- ›Cancellation, expiry refunds, incorrect amounts, failed transfers (mock false-returning token)
- ›Reentrancy via malicious token callback; unauthorized settle/cancel
- ›Fuzz amounts and deadlines; invariant: contract balance == sum of open deposits
- ›Testnet (chain 998) deployment only after review; mainnet only after external audit