# 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 Chainlink’s [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 contract’s 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)
