Summary
Introduce per-token accounting in our swap contracts so that tokens which end up stuck in the contract (but are not backing any active swap) can be withdrawn safely by an admin address.
Background
What happens to tokens that get stuck in a swap contract?
Why tokens get stuck
ERC20 transfers do not call the recipient contract — the contract has no hook and no awareness that a transfer happened. This means anyone can send arbitrary ERC20 tokens to our swap contract address at any time, and we cannot prevent it at the contract level.
Concrete example:
- You lock 5 USDT in a swap
- I lock 2 USDT in a swap
- Someone sends 3 USDT directly to the contract for no reason
- The contract now holds 10 USDT, but only 7 are backing real swaps
- The extra 3 USDT are stuck forever unless we do something
We also can't rely on tying withdrawals to specific swap-creation transactions, because ERC20 tokens are fungible by definition — there is no on-chain link between "a swap" and "the tokens that fund it".
Proposed solution: double accounting
Track, inside the contract, the total amount that should be locked per ERC20 token to cover outstanding swaps. Anything the contract holds above that accounted amount is by definition excess and can be withdrawn by an admin address.
- Source of truth for the locked amount is the contract itself, so it can't be cheated.
- Our contract is generic over any ERC20; today we happen to use it mainly for tBTC, but the accounting must be per-token.
Example state:
- tBTC locked for pending swaps:
0.1235233234 → contract must retain at least this much tBTC
- USDT0 locked for pending swaps:
0 → any USDT0 in the contract is withdrawable
- ARB locked for pending swaps:
0 → any ARB in the contract is withdrawable
- USDC locked for pending swaps:
0 → any USDC in the contract is withdrawable
Admin withdrawal is then "withdraw everything in excess of the locked accounting" — per token
Summary
Introduce per-token accounting in our swap contracts so that tokens which end up stuck in the contract (but are not backing any active swap) can be withdrawn safely by an admin address.
Background
What happens to tokens that get stuck in a swap contract?
Why tokens get stuck
ERC20 transfers do not call the recipient contract — the contract has no hook and no awareness that a transfer happened. This means anyone can send arbitrary ERC20 tokens to our swap contract address at any time, and we cannot prevent it at the contract level.
Concrete example:
We also can't rely on tying withdrawals to specific swap-creation transactions, because ERC20 tokens are fungible by definition — there is no on-chain link between "a swap" and "the tokens that fund it".
Proposed solution: double accounting
Track, inside the contract, the total amount that should be locked per ERC20 token to cover outstanding swaps. Anything the contract holds above that accounted amount is by definition excess and can be withdrawn by an admin address.
Example state:
0.1235233234→ contract must retain at least this much tBTC0→ any USDT0 in the contract is withdrawable0→ any ARB in the contract is withdrawable0→ any USDC in the contract is withdrawableAdmin withdrawal is then "withdraw everything in excess of the locked accounting" — per token