chore: sync submodule state (parent ref update)

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-02 12:14:09 -08:00
parent 50ab378da9
commit 5efe36b1e0
1100 changed files with 155024 additions and 8674 deletions

View File

@@ -0,0 +1,120 @@
# CCIP Configuration and SwapBridgeSwapCoordinator
This document covers CCIP setup for the trustless bridge and the **SwapBridgeSwapCoordinator** contract used for atomic swap-then-bridge flows (Dodoex PMM on source chain → CCIP bridge).
## Overview
- **UniversalCCIPBridge**: Main bridge contract; accepts any caller. It pulls tokens from `msg.sender`, sends a CCIP message, and emits `BridgeExecuted` with `msg.sender` as the sender.
- **SwapBridgeSwapCoordinator**: Wraps “swap on source chain” + “bridge” in one transaction. The user approves the coordinator; the coordinator swaps via `EnhancedSwapRouter` (Dodoex), then calls `UniversalCCIPBridge.bridge()`. When the bridge runs, `msg.sender` is the coordinator (which holds the bridgeable tokens after the swap), so no extra allowlist is required for the coordinator.
## CCIP Configuration
### Prerequisites
1. **CCIP Router** deployed and configured on each chain (138, 651940, and any target chains).
2. **Chain selectors** known for every source and destination chain.
3. **UniversalCCIPBridge** (or equivalent) deployed and initialized with the correct CCIP router and asset registry.
### Chain selectors
- Obtain selectors from your CCIP Router (e.g. `getChainSelector()`) or from Chainlinks [CCIP supported networks](https://docs.chain.link/ccip/supported-networks).
- For Chain 138 and custom chains, see `docs/deployment/CHAIN138_SELECTOR_NOTES.md` and your `networks.json` / relay config.
- Common reference (see `docs/deployment/BRIDGE_CONFIGURATION.md` for full table):
- Ethereum Mainnet: `5009297550715157269`
- Polygon: `4051577828743386545`
- Base: `15971525489660198786`
- Arbitrum: `4949039107694359620`
- Optimism: `3734403246176062136`
### Destinations and LINK
1. **Destinations**: For each bridgeable token, configure `destinations[token][destinationChainSelector]` (receiver bridge address and enabled flag) on `UniversalCCIPBridge`. Use the contracts admin/configuration interface (e.g. addDestination / setDestination).
2. **LINK**: Fund each bridge contract with LINK so it can pay CCIP fees. Example:
```bash
cast send $LINK_TOKEN "transfer(address,uint256)" $UNIVERSAL_CCIP_BRIDGE $AMOUNT --rpc-url $RPC_URL --private-key $PRIVATE_KEY
```
Recommended: start with ~10 LINK per bridge; adjust based on traffic.
### References
- Bridge configuration and chain table: `docs/deployment/BRIDGE_CONFIGURATION.md`
- Operations: `docs/operations/integrations/BRIDGE_CONFIGURATION.md`, `docs/operations/integrations/CCIP_ROUTER_SETUP.md`
- Env vars: `docs/bridge/trustless/ENV_VARIABLES_REFERENCE.md`
---
## SwapBridgeSwapCoordinator
### Role
- **Problem**: Users often hold token A but want to bridge token B (e.g. WETH or a stable). Doing “swap then bridge” in two steps is two transactions and worse UX.
- **Solution**: SwapBridgeSwapCoordinator performs in one transaction:
1. Pull `sourceToken` from the user.
2. If `sourceToken != bridgeableToken`, swap to `bridgeableToken` via `EnhancedSwapRouter.swapTokenToToken` (Dodoex).
3. Call `UniversalCCIPBridge.bridge()` with the bridgeable token; the bridge pulls from the coordinator (`msg.sender`).
### Deployment
**Env (required):**
- `PRIVATE_KEY` deployer.
- `ENHANCED_SWAP_ROUTER` EnhancedSwapRouter address on the same chain.
- `UNIVERSAL_CCIP_BRIDGE` or `BRIDGE_ORCHESTRATOR` bridge contract address.
**Deploy:**
```bash
# From repo root (smom-dbis-138)
export RPC_URL=... # Chain 138 or 651940 RPC
export ENHANCED_SWAP_ROUTER=0x...
export UNIVERSAL_CCIP_BRIDGE=0x...
forge script script/bridge/trustless/DeploySwapBridgeSwapCoordinator.s.sol:DeploySwapBridgeSwapCoordinator \
--rpc-url $RPC_URL --broadcast --legacy
```
Then set in env and frontend:
```bash
export SWAP_BRIDGE_SWAP_COORDINATOR=0x...
```
Script path: `script/bridge/trustless/DeploySwapBridgeSwapCoordinator.s.sol`.
### Contract interface (summary)
- **Constructor**: `SwapBridgeSwapCoordinator(swapRouter, bridge)`.
- **Main entry**: `swapAndBridge(sourceToken, amountIn, amountOutMin, bridgeableToken, destinationChainSelector, recipient, assetType, usePMM, useVault)`.
- User must approve the coordinator for `sourceToken` (and for native gas, the call can send `msg.value` to the bridge).
- `amountOutMin` is slippage protection when a swap is performed; ignored if `sourceToken == bridgeableToken`.
- **Events**: `SwapAndBridgeExecuted(sourceToken, bridgeableToken, amountIn, amountBridged, destinationChainSelector, recipient, messageId)`.
### Access control (msg.sender)
- **UniversalCCIPBridge.bridge()** does not restrict callers. It does:
- `IERC20(op.token).safeTransferFrom(msg.sender, address(this), op.amount)`
- Then sends the CCIP message and uses `msg.sender` for nonces and events.
- When the **SwapBridgeSwapCoordinator** calls `bridge()`, `msg.sender` is the coordinator. The coordinator holds the bridgeable tokens after the swap and has approved the bridge, so the transfer and CCIP send succeed. No separate allowlist or role for the coordinator is required on the bridge.
### Integration checklist
- [ ] CCIP router and chain selectors set for 138, 651940, and target chains.
- [ ] Bridge contracts funded with LINK.
- [ ] `UniversalCCIPBridge` destinations set for each token and destination chain.
- [ ] SwapBridgeSwapCoordinator deployed and `SWAP_BRIDGE_SWAP_COORDINATOR` set in env and frontend.
- [ ] Dodoex PMM pools and `EnhancedSwapRouter` configured for the tokens you use (see `docs/bridge/DODO_PMM_NEXT_STEPS.md`).
---
## End-to-end flow
1. **Quote**: Frontend or backend calls `POST /api/bridge/quote` with swap+bridge+swap parameters; response can include `sourceSwapQuote`, `destinationSwapQuote`, and bridge fee/minReceived (see `docs/bridge/API_DOCUMENTATION.md`).
2. **User approval**: User approves `SWAP_BRIDGE_SWAP_COORDINATOR` for `sourceToken` (and optionally sends native token for CCIP fees).
3. **Execute**: User (or relayer) calls `SwapBridgeSwapCoordinator.swapAndBridge(...)` with the same parameters as the quote (or derived from it).
4. **On-chain**: Coordinator swaps then calls `UniversalCCIPBridge.bridge()`; CCIP delivers to the destination receiver contract; recipient receives the bridgeable token (or downstream swap is done separately on destination).
For full path quote and frontend wiring, see:
- `docs/bridge/DODO_PMM_NEXT_STEPS.md`
- `docs/bridge/API_DOCUMENTATION.md` (quote and swap+bridge+swap)
- `docs/bridge/trustless/ENV_VARIABLES_REFERENCE.md` (all env vars, including quote service and coordinator)

View File

@@ -318,6 +318,20 @@ cast call $STABLECOIN_PEG_MANAGER \
4. **Liquidity Pool Empty**: Provide initial liquidity
5. **Reserve Insufficient**: Fund ReserveSystem
### Live-test cast errors (lock / claim / finalize)
- **`-32602: Invalid params`** — Wrong RPC for the tx (e.g. mainnet RPC for a 138 lock), or missing/corrupt env (PRIVATE_KEY, RPC_URL_138, ETHEREUM_MAINNET_RPC). Ensure lock uses `--rpc-url $RPC_URL_138` and claim/finalize use `--rpc-url $ETHEREUM_MAINNET_RPC`. Check `.env` has no typos (e.g. `PRIVATE_KEYIT_ID`).
- **`invalid string length` (e.g. for `1000000000000000`)** — You passed the **amount** (AMOUNT_WEI) where an **address** or **depositId** is expected. **DEPOSIT_ID** must be the **depositId** from the Lockbox `Deposit` event (a large uint256 from the event), **not** the amount. Get it with:
```bash
cast logs <LOCK_TX_HASH> "Deposit(uint256,address,uint256,address,bytes32,address,uint256)" --rpc-url $RPC_URL_138
```
Use the first decoded argument as `DEPOSIT_ID`.
- **`encode length mismatch: expected 1 types, got 0`** — **DEPOSIT_ID** is empty or unset for `claim` or `finalize`. Set it from the lock tx event as above.
**Quick DEPOSIT_ID from lock tx:**
`export DEPOSIT_ID=$(./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH>)`
Then run `AMOUNT_WEI=1000000000000000 ./scripts/deployment/run-e2e-trustless-live-test.sh claim`.
### Emergency Procedures
1. **Pause System**: Use pause functions if available
@@ -337,3 +351,15 @@ After deployment:
See `OPERATIONS_GUIDE.md` for operational procedures.
---
## Deploy, Configure, and Live Test (single flow)
**Deploy:** Run trustless phase: `./scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh trustless` (from smom-dbis-138). Set LOCKBOX_138, BOND_MANAGER, LIQUIDITY_POOL, INBOX_ETH, CHALLENGE_MANAGER in .env.
**Configure:** (1) Verify Inbox is authorized on LP: `cast call $LIQUIDITY_POOL "authorizedRelease(address)(bool)" $INBOX_ETH --rpc-url $ETHEREUM_MAINNET_RPC`. (2) Initialize if using router: `forge script script/bridge/trustless/InitializeBridgeSystem.s.sol:InitializeBridgeSystem --rpc-url $ETHEREUM_MAINNET_RPC --broadcast --via-ir`. (3) Fund LP: `./scripts/deployment/fund-mainnet-lp.sh --eth 2 --weth 1`.
**Verify:** `./scripts/deployment/verify-trustless-deployments.sh`.
**Live test with actual tokens (138 to mainnet):** (1) Lock: `cast send $LOCKBOX_138 "depositNative(address,bytes32)" RECIPIENT NONCE --value 0.01ether --rpc-url $RPC_URL_138 --private-key $PRIVATE_KEY --legacy`. (2) Get depositId from Deposit event. (3) Submit claim: `cast send $INBOX_ETH "submitClaim(uint256,address,uint256,address,bytes)" DEPOSIT_ID 0x0 AMOUNT_WEI RECIPIENT 0x --value BOND --rpc-url $ETHEREUM_MAINNET_RPC --private-key $PRIVATE_KEY` (BOND = getRequiredBond(amount)). (4) Wait challenge window. (5) Finalize: `cast send $CHALLENGE_MANAGER "finalizeClaim(uint256)" DEPOSIT_ID ...`. (6) Release bond: `cast send $BOND_MANAGER "releaseBond(uint256)" DEPOSIT_ID ...`. See runbook: `scripts/deployment/live-test-trustless-bridge.sh` (prints commands and optional checks).

View File

@@ -0,0 +1 @@
# Deploy Configure Live Test

View File

@@ -0,0 +1,153 @@
# Optional Upgrade: EnhancedSwapRouter
This runbook describes what you need to do to deploy and use the **EnhancedSwapRouter** (multi-protocol swap: Uniswap V3, Dodoex, Curve, Balancer, 1inch) on Ethereum Mainnet.
---
## 1. Prerequisites
- **Chain**: Ethereum Mainnet (Chain ID 1) only (script enforces this).
- **.env** (in `smom-dbis-138/` or project root) with:
- `PRIVATE_KEY` — deployer key (has mainnet ETH for gas).
- `ETHEREUM_MAINNET_RPC` — mainnet RPC (Infura/Alchemy recommended).
- `ETHERSCAN_API_KEY` — for contract verification (optional but recommended).
---
## 2. Deploy EnhancedSwapRouter
From repo root `smom-dbis-138/`:
```bash
cd /home/intlc/projects/proxmox/smom-dbis-138
set -a && [ -f .env ] && source .env && set +a
forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter \
--rpc-url "$ETHEREUM_MAINNET_RPC" \
--broadcast \
--via-ir \
--verify \
--etherscan-api-key "$ETHERSCAN_API_KEY"
```
Or use the phase-3 script:
```bash
./scripts/deployment/phase3-deploy-router.sh
```
**Save the deployed address** from the script output and add to `.env`:
```bash
ENHANCED_SWAP_ROUTER=0x...
```
---
## 3. Configure Balancer pool IDs (optional)
EnhancedSwapRouter uses Balancer for medium/large swaps. If you use those tiers, set pool IDs for the pairs you need (e.g. WETHUSDC, WETHUSDT):
```bash
# Example: WETHUSDT Balancer pool ID (replace <poolId> with actual bytes32)
cast send $ENHANCED_SWAP_ROUTER \
"setBalancerPoolId(address,address,bytes32)" \
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \
0xdAC17F958D2ee523a2206206994597C13D831ec7 \
<poolId> \
--rpc-url "$ETHEREUM_MAINNET_RPC" \
--private-key "$PRIVATE_KEY"
```
Find pool IDs from [Balancer](https://app.balancer.fi/) or their subgraph for mainnet.
---
## 4. Grant COORDINATOR_ROLE (for future coordinator use)
If you later deploy a coordinator that uses EnhancedSwapRouter (see §6), that coordinator must have `COORDINATOR_ROLE` on EnhancedSwapRouter. You can grant it to the **existing** BridgeSwapCoordinator so its ready if you switch to a coordinator that calls EnhancedSwapRouter:
```bash
# Role hash (COORDINATOR_ROLE)
cast keccak "COORDINATOR_ROLE"
# Grant to BridgeSwapCoordinator (replace with your BRIDGE_SWAP_COORDINATOR address)
cast send $ENHANCED_SWAP_ROUTER \
"grantRole(bytes32,address)" \
$(cast keccak "COORDINATOR_ROLE") \
"$BRIDGE_SWAP_COORDINATOR" \
--rpc-url "$ETHEREUM_MAINNET_RPC" \
--private-key "$PRIVATE_KEY"
```
---
## 5. Customize routing (optional)
Default routing is:
- **Small** (&lt; $10k): Uniswap V3, Dodoex
- **Medium** ($10k$100k): Dodoex, Balancer, Uniswap V3
- **Large** (&gt; $100k): Dodoex, Curve, Balancer
To change providers per size category (e.g. `setRoutingConfig`), use the contracts `setRoutingConfig(sizeCategory, providers[])` with the provider enum values (see `EnhancedSwapRouter.SwapProvider`).
---
## 6. Important: BridgeSwapCoordinator and EnhancedSwapRouter
The **current** **BridgeSwapCoordinator** (trustless bridge payout) is wired to the **basic SwapRouter** in code:
- It calls `swapRouter.swapToStablecoin(..., bytes calldata routeData)` and expects a single `uint256` return.
- **EnhancedSwapRouter** exposes `swapToStablecoin(..., SwapProvider preferredProvider)` and returns `(uint256, SwapProvider)`.
So the existing coordinator **cannot** call EnhancedSwapRouter without a contract change. Today:
- **bridgeAndSwap** (Lockbox → claim → release → swap to USDT/USDC) still uses the **basic SwapRouter** only.
- Deploying EnhancedSwapRouter gives you:
- Multi-protocol routing for **other** callers (e.g. quote services, liquidity engine, or direct `EnhancedSwapRouter.swapToStablecoin` calls).
- A path ready for a **future** coordinator (or upgraded coordinator) that uses EnhancedSwapRouter once one is implemented and deployed.
To actually use EnhancedSwapRouter for the trustless payout flow you would need to:
- Implement and deploy a new coordinator (or upgrade) that takes an EnhancedSwapRouter-compatible interface and calls `swapToStablecoin(..., preferredProvider)` with the right parameters and return handling, and
- Point the LPs authorized releaser (or users) at that new coordinator instead of the current BridgeSwapCoordinator.
---
## 7. Summary checklist
| Step | Action |
|------|--------|
| 1 | Set `PRIVATE_KEY`, `ETHEREUM_MAINNET_RPC`, `ETHERSCAN_API_KEY` in `.env`. |
| 2 | Run `DeployEnhancedSwapRouter.s.sol` (or `phase3-deploy-router.sh`) on mainnet. |
| 3 | Add `ENHANCED_SWAP_ROUTER=<address>` to `.env`. |
| 4 | (Optional) Configure Balancer pool IDs for WETHstable pairs. |
| 5 | (Optional) Grant `COORDINATOR_ROLE` on EnhancedSwapRouter to BridgeSwapCoordinator for future use. |
| 6 | (Optional) Adjust routing via `setRoutingConfig` if needed. |
**References:** `DEPLOYMENT_GUIDE.md`, `DEPLOYMENT_SUMMARY.md`, `script/bridge/trustless/DeployEnhancedSwapRouter.s.sol`, `scripts/deployment/phase3-deploy-router.sh`.
---
## 8. Completed deployment (2026-02-20)
- **EnhancedSwapRouter** deployed at `0xc99f13275a3a85f556570767f1Fc3e58788f777d` (Ethereum Mainnet).
- Default routing configured (small: Uniswap V3 + Dodoex; medium: Dodoex + Balancer + Uniswap V3; large: Dodoex + Curve + Balancer).
- **COORDINATOR_ROLE** granted to BridgeSwapCoordinator (`0xF51581eee46f5A7Ef2A035C5B3Ac4a89bF6FbaAa`).
- **Balancer pool IDs**: optional; set via `setBalancerPoolId(tokenA, tokenB, poolId)` when you have pool IDs from [Balancer](https://app.balancer.fi/) or the Balancer subgraph.
---
## 9. DualRouterBridgeSwapCoordinator (bridgeAndSwap with basic or enhanced router)
A **DualRouterBridgeSwapCoordinator** contract is deployed so that one coordinator can perform `bridgeAndSwap` using either the basic SwapRouter or the EnhancedSwapRouter.
- **Contract**: `contracts/bridge/trustless/DualRouterBridgeSwapCoordinator.sol`
- **Deployed at (Ethereum Mainnet)**: `0x5BB7e48DA5f571344E08BDB4f0d3CE2198963EcD`
- **Signature**: `bridgeAndSwap(depositId, recipient, outputAsset, stablecoinToken, amountOutMin, routeData, useEnhancedRouter)`
- `useEnhancedRouter == false`: uses basic SwapRouter (same as existing BridgeSwapCoordinator).
- `useEnhancedRouter == true`: uses EnhancedSwapRouter (multi-protocol routing).
- **Deploy script**: `script/bridge/trustless/DeployDualRouterBridgeSwapCoordinator.s.sol` (env: INBOX_ETH_MAINNET, LIQUIDITY_POOL_ETH_MAINNET, SWAP_ROUTER_MAINNET, ENHANCED_SWAP_ROUTER, CHALLENGE_MANAGER_MAINNET).
- **Wiring**: After deploy, the script calls `LiquidityPoolETH.authorizeRelease(coordinator)` and `EnhancedSwapRouter.grantRole(COORDINATOR_ROLE, coordinator)`.
- **.env**: Set `DUAL_ROUTER_BRIDGE_SWAP_COORDINATOR` to the deployed address.

View File

@@ -112,6 +112,38 @@ ONEINCH_ROUTER=0x1111111254EEB25477B68fb85Ed929f73A960582
# Add more pool IDs as needed
```
## Dodoex PMM / Full Swappable (Chains 138, 651940)
For PMM coverage of all tokens and swap+bridge+swap flow:
```bash
# Per-chain DODO (set for each chain)
CHAIN_138_DODO_POOL_MANAGER=0x...
CHAIN_138_DODO_VENDING_MACHINE=0x...
CHAIN_651940_DODO_POOL_MANAGER=0x...
CHAIN_651940_DODO_VENDING_MACHINE=0x...
# Token coverage script (create-all-dodo-pools-from-token-api.sh)
TOKEN_AGGREGATION_API_URL=http://localhost:3000
CHAIN_ID=138
QUOTE_TOKEN_ADDRESS=0x... # WETH or canonical stable per chain
DODO_PMM_INTEGRATION_ADDRESS=0x...
ENHANCED_SWAP_ROUTER_ADDRESS=0x...
UNIVERSAL_ASSET_REGISTRY_ADDRESS=0x...
RPC_URL=...
PRIVATE_KEY=0x...
# Quote service (swap+bridge+swap)
ENHANCED_SWAP_ROUTER_ADDRESS=0x... # Source chain router
DESTINATION_RPC_URL=...
DESTINATION_SWAP_ROUTER_ADDRESS=0x...
# SwapBridgeSwapCoordinator (atomic swap then bridge)
SWAP_BRIDGE_SWAP_COORDINATOR=0x...
```
Run pool creation for all tokens: `scripts/create-all-dodo-pools-from-token-api.sh` (use `DRY_RUN=true` to preview). Ensure CCIP router and chain selectors are set for 138, 651940, and target chains; LINK funded for bridge contracts.
## Service Configuration
### Market Reporting Service