One signature. Any token. Any chain.
ChainRoutes is a trustless cross-chain intent solver. Sign one intent and ChainRoutes handles the swap and bridge automatically — no more juggling between DEXs and bridges manually.
User signs intent
|
v
BridgeSwap verifies EIP-712 signature
|
v
Swaps tokenIn -> USDC via Uniswap V3 (source chain)
|
v
Bridges USDC cross-chain via Stargate V2 (taxi mode)
|
v
ReceiverSwap receives USDC on destination chain
|
v
Swaps USDC -> tokenOut via Uniswap V3 (destination chain)
|
v
User receives tokenOut on destination chain
contracts/
|-- BridgeSwap.sol # Main solver - verifies intents, swaps, bridges
|-- destination/
| |-- ReceiverSwap.sol # Receives bridged tokens, swaps to tokenOut
|-- adapters/
| |-- UniswapAdapter.sol # Wraps Uniswap V3 swap logic
| |-- StargateAdapter.sol # Wraps Stargate V2 bridge logic
|-- interfaces/
| |-- IDex.sol # Standardized DEX interface
|-- utils/
|-- IntentVerifier.sol # EIP-712 intent signing and verification
- Intent-based - users sign a typed EIP-712 struct, solver executes on their behalf
- Trustless adapters - UniswapAdapter has one immutable authorizedCaller, set at deploy and locked forever. No owner backdoors
- Set-once pattern - BridgeSwap and ReceiverSwap use a set-once setUniswapAdapter() that can never be called twice, eliminating rug vectors
- Taxi mode - Stargate V2 taxi mode for immediate cross-chain execution
- Compose messaging - swap instructions are packed into the LayerZero compose message and executed automatically on the destination chain
| Layer | Protocol |
|---|---|
| Swap | Uniswap V3 |
| Bridge | Stargate V2 |
| Messaging | LayerZero V2 |
| Signatures | EIP-712 + ECDSA |
| Framework | Foundry |
| Contract | Chain | Address |
|---|---|---|
| BridgeSwap | Sepolia | 0xa6D61e5B83e269E62848924E3eE617AaC580D918 |
| ReceiverSwap | OP Sepolia | 0x34654e06ACc8a3CcD7eDc3BE17182e4310473A3d |
struct Intent {
address user; // signer
address tokenIn; // token on source chain
address tokenOut; // token wanted on destination chain
uint256 amountIn; // amount of tokenIn
uint256 minAmountOut; // slippage protection
uint256 srcChainId; // source chain LZ endpoint ID
uint256 dstChainId; // destination chain LZ endpoint ID
uint256 deadline; // expiry timestamp
uint256 nonce; // replay protection
address dstReceiver; // recipient on destination chain
uint24 poolFee; // Uniswap pool fee tier
}- Foundry
- RPC URLs for Sepolia and Optimism Sepolia
git clone https://github.com/yourusername/chainroutes
cd chainroutes
forge installforge buildforge testSet up your .env file:
SOLVER_ADDRESS=0xYourAddress
SEPOLIA_RPC=https://...
OP_SEPOLIA_RPC=https://...
Import your wallet securely:
cast wallet import chainroutes-deployer --interactiveDeploy destination chain first (Optimism Sepolia):
forge script script/DeployDestination.s.sol --rpc-url $OP_SEPOLIA_RPC --account chainroutes-deployer --broadcast --verifyThen deploy source chain (Sepolia):
forge script script/DeploySource.s.sol --rpc-url $SEPOLIA_RPC --account chainroutes-deployer --broadcast --verify- Solver fee capped at 3% (300 bps)
- All intent fields signed by user via EIP-712 - solver cannot tamper with parameters
- Nonce tracking prevents replay attacks
- Deadline prevents stale intents from being executed
- UniswapAdapter authorizedCaller is immutable - cannot be changed after deployment
- setUniswapAdapter() can only be called once on both BridgeSwap and ReceiverSwap
MIT