Inspiration
Every banking app has an undo. No crypto wallet does. A mistyped address, a fake "support agent" or a poisoned lookalike address in your history costs you everything, forever. We wanted reversibility without bringing back chargeback fraud or slowing down everyday payments.
What it does
Rewind holds each payment in a short rewind window before it settles:
- the sender can rewind it (full refund) or release it early
- the recipient can refuse it (bounce it back)
- after the window, anyone can settle it to the recipient
The window adapts to trust:
$$ w = \begin{cases} 0 & \text{if you've paid this address } \ge 3 \text{ times and never rewound it} \ \min\left(w_{base} \cdot (1 + r),\ 7\text{ days}\right) & \text{otherwise} \end{cases} $$
where \( r \) is the number of distinct senders who have rewound payments to that address.
| Situation | Window |
|---|---|
| Trusted payee (3+ settled payments) | Instant |
| First payment to a clean address | Base window (5 min on Sepolia) |
| 3 different victims rewound on it | 4× longer |
| It imitates an address you've paid | Blocked until you confirm |
The key idea: the victims build the blocklist. Every rewind is recorded on-chain against the recipient and counted by distinct senders, so one person can't grief an honest address. Nobody curates anything. Each victim's undo automatically protects the next sender. Honest recipients who bounce an unexpected payment are credited, not penalised.
Address-poisoning defence: attackers mine vanity addresses matching the first and last characters of someone you pay, then plant them in your history with a dust transfer. Rewind compares every recipient against addresses you've actually paid, blocks lookalikes, and highlights every character that differs.
How we built it
- Smart contract,
Rewind.sol(Solidity 0.8.24): ETH and any ERC-20;send / rewind / refuse / release / claim; adaptivewindowFor(); on-chain reputation (settled, rewinds, distinct rewinders, refused) - Security: OpenZeppelin
ReentrancyGuard+SafeERC20, checks-effects-interactions, balance-delta accounting for fee-on-transfer tokens, and no admin keys or upgrade proxy - 13 Hardhat/Chai tests covering windows, trust, reputation, the 7-day cap, ERC-20 and access control
- Frontend: React + Vite + ethers v6, with a live risk card while you type, countdown rings, one-tap rewind, and MetaMask on Sepolia
- Deployed on Sepolia at
0x95Ad0FC04f5a0Eb1BB354dFA5Ba129153F433Ceb, with a real MetaMask payment sent and rewound - Demo tooling: a seeded local chain with characters (Alice, Bob the trusted landlord, Mallory the scammer), time fast-forward, and a one-click real address-poisoning attack simulation
Challenges we ran into
- Safety vs. friction. A fixed delay on every payment would make daily use miserable, so the window had to be adaptive and per pair.
- Making reputation hard to grief. We count distinct senders, not raw rewinds, and a pair where the sender ever rewound can never become "trusted".
- Clock drift. Chain time and wall-clock time diverge after fast-forwarding a dev chain, so the countdowns follow block time.
What we learned
A small amount of reversibility, applied only where trust is missing, removes most of the damage from the most common scams without touching the payments people make every day.
What's next
- An ERC-4337 / ERC-7579 smart-account module, so every outgoing transfer is rewindable by default
- A MetaMask Snap that brings the lookalike detector to every dApp
- Sybil resistance: weight rewinds by sender history and proof-of-personhood
- Merchant bonds: staked recipients opt into instant settlement
- Keeper-based auto-settlement and a reputation registry shared across L2s
Built With
- ethereum
- ethers.js
- hardhat
- javascript
- metamask
- openzeppelin
- react
- sepolia
- smart-contracts
- solidity
- vite
Log in or sign up for Devpost to join the conversation.