11 Guides
Examples
Real transcripts of a claim, an undo, an expiry refund, a front-run attempt, a fee-on-transfer token and the caps, produced by running the code.
Everything on this page is output that was actually printed, not written by hand. Addresses are random on every run, so yours will differ. Amounts, revert names and selectors are stable.
There are two sources, and the difference matters.
- Engine transcripts come from
scripts/docs-examples.mjs, which runs the JavaScript port of the contract (site/assets/engine.js). The port reproduces the Solidity test vectors exactly, see Architecture. Amounts are shown in ETH. - Chain transcript comes from
scripts/docs-e2e.mjs, which deploys the compiledOopsend.solto a localanvilwith chain id 4663 and calls it with ethers.
#A claim, relayed, to a wallet with no ETH
Alice sends 1.5 ETH. A relayer submits the claim to Bob, who never held any ETH. Then anyone sweeps the fee.
create ok LinkCreated sender=0x6338…317D token=0x0000…0000 amount=1.5000 expiresAt=1800604800
escrow holds 1.5000 ETH
claim ok LinkClaimed recipient=0x834F…656d net=1.4955 fee=0.0045
bob 1.4955 ETH (had 0, paid no gas)
fees accrued 0.0045 ETH
sweep ok FeesSwept token=0x0000…0000 amount=0.0045
fee wallet 0.0045 ETH; escrow 0.0000 ETH
The escrow ends at zero: 1.4955 went to Bob and 0.0045 (0.3%) went to the fee wallet.
#Undo, then try to claim
alice before undo 9.0000
undo ok LinkUndone amount=1.0000
alice after undo 10.0000 (whole send back, no fee)
claim revert NoLink 0x0fb67a93
Alice gets all of the 1 ETH back, and a later claim finds no link.
#Expiry: refused early, refused late, refunded by a stranger
crank early revert NotExpired 0xd0404f85
claim late revert Expired 0x203d82d8
crank ok LinkExpired amount=1.0000
alice got back 1.0000 ETH
Before the deadline the refund reverts. After it, the claim reverts and a stranger (Mallory) calls the refund, which pays Alice, not Mallory.
#A front-run attempt
Mallory sees Bob's signed claim and resubmits it with herself as the recipient.
mallory redirects bob's signature to herself:
revert BadSignature 0x5cd5d233
the intended claim still lands:
ok LinkClaimed recipient=0x6D83…69b7 net=0.9970 fee=0.0030
bob 0.9970 ETH
The signature covers Bob's address, so over Mallory's address it recovers to the wrong key. The original claim, submitted by Mallory herself, still pays Bob.
#A token that takes 1% on every transfer
alice sends 1000, escrow records 990
escrow actually holds 990
undo ok LinkUndone amount=990.0000
alice token balance 999,980 (1% lost per hop to the token itself, twice)
The contract records what arrived (990), not what was requested (1000), so it can always pay out what it holds. Alice loses 1% twice to the token itself, which is the token's behaviour, not Oopsend's. Tokens like this work but cost the sender money on every hop.
#Caps and bounds
2 ETH + 1 wei revert OverCap 0x342fa66d
2 ETH ok LinkCreated sender=0xc1c8…F709 token=0x0000…0000 amount=2.0000 expiresAt=1800604800
expiry 9 min revert BadExpiry 0xf4ad9a1f
333 wei claim fee: 0n wei
The default ETH cap is 2 ETH. The shortest window is 10 minutes. A claim of 333 wei carries no fee because the fee rounds down.
#The same flow on a real contract
This run deploys the compiled contract to a local chain and makes real calls. The gas figures are what the chain reported for each transaction.
deployed Oopsend on chain 4663n runtime bytes 6101
createLinkEth gas 101934n escrow 1.5 ETH
links(key): amount 1.5 feeBps 30n claimKey ok true
onchain digest == off-chain digest: true
redirected claim reverts: BadSignature
claim gas 93131n bob 1.4955 ETH fees accrued 0.0045
sweepFees gas 60306n fee wallet 0.0045 ETH
undo gas 42398n
expireRefund gas 44899n
createLinkToken gas 165107n
token claim gas 92394n bob tokens 4985.0
my link id 48213 1.5 ETH closed
my link id 7 0.4 ETH closed
my link id 8 0.2 ETH closed
my link id 9 5000.0 token closed
events seen: ParamsUpdated, LinkCreated, LinkClaimed, FeesSwept, LinkUndone, LinkExpired
OK
Reading it line by line: after the claim Bob holds 1.4955 ETH and the contract has accrued 0.0045; the on-chain claimDigest equals the digest ethers computes off chain; a claim redirected to the relayer's own address reverts with BadSignature; a token link of 5,000 tokens pays Bob 4,985.0 (99.7%); and the four my link id lines are Alice listing her own links from LinkCreated events, all closed by now.
#Run them yourself
node scripts/docs-examples.mjs # engine transcripts above
node scripts/docs-examples.mjs selectors # the error selector table
node scripts/docs-e2e.mjs # the chain transcript (starts its own anvil)
cd contracts && forge test # 30 Solidity tests
node --test tests-js/engine.test.mjs # 15 engine parity tests
The scripts import ethers from a sibling project's node_modules, so nothing needs installing in this repository.