The problem
A user who swaps through a router picks the route and eats whatever MEV comes with it. With intents, the user says what they want ("at least X of token B for Y of token A, before T") and solvers compete to fill it.
How it works
user ── create_intent(in, min_out, expiry) ──► Intent PDA, input locked in a vault
solver ── register_solver(stake) ──► Solver PDA with reputation
solver ── submit_solution(out) ──► best output wins
winner ── execute_settlement ──► output to user, fees to protocol and solver
user ── cancel_intent (before execution) ──► input refundedFees are 0.15% total: 0.05% protocol and 0.10% to the solver, with a reputation score updated on every settlement.
Design decisions
- Solvers stake to play. A minimum stake makes spamming fake solutions costly, and the stake is what a future slashing rule would take.
- Only the winning solver settles.
execute_settlementchecks the signer againstintent.winning_solver. - Expiry is enforced on-chain. Intents can't settle or be cancelled once they expire, using the Clock sysvar.
What could go wrong
When I came back to this project, it looked finished but didn't work. The first bid closed the auction, so there was no competition. Settlement paid the user their minimum (minus fees) instead of the winning quote, never released the locked input to the solver, and overflowed the BPF stack, so it couldn't run at all. The original tests never initialised the vault and didn't pass either.
| Vector | Status |
|---|---|
| No real auction | Fixed: bids accepted for 20 seconds; only strictly better quotes take the lead |
| User paid the minimum, not the quote | Fixed: the user receives the winning quote minus a 0.05% fee, never below their minimum |
| Input never released | Fixed: the solver pays and receives the input in the same transaction |
| Solver pays someone else | Fixed: settlement is bound to the intent's user and both mints |
| Tokens stuck after expiry | Fixed: refund before any bid, or after expiry if the winner didn't settle (the winner loses reputation) |
| Fake stake | Fixed: the stake moves into the solver's account and comes back on exit |
| Front-running between solvers | Open: bids are public; a commit-reveal round would hide them |
What I learned
A complete-looking instruction list says nothing about whether the protocol works. Writing the tests as a user and as a competing solver is what showed that none of the economics held up.
Where it stands
A self-study project, deployed to Solana devnet with a rewritten test suite (7 tests). The demo has a faucet for two worthless test tokens; the user's wallet pays the fees and account rent, and the faucet only co-signs as mint authority, so scripted requests can't drain it.