- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
7.7 KiB
7.7 KiB
WETH9 and WETH10 with CCIP Cross-Chain Deployment Guide
Overview
This guide covers the deployment of WETH9 and WETH10 contracts with Chainlink CCIP (Cross-Chain Interoperability Protocol) for complete cross-chain token transfer functionality.
Contracts
WETH9 (contracts/tokens/WETH.sol)
- Standard WETH9 implementation
- ERC-20 compatible
- Deposit/withdraw functionality
- Transfer/approve functionality
WETH10 (contracts/tokens/WETH10.sol)
- Enhanced WETH implementation
- ERC-3156 flash loan support
- Zero flash loan fees
- Advanced features for DeFi integrations
CCIPWETH9Bridge (contracts/ccip/CCIPWETH9Bridge.sol)
- Cross-chain WETH9 transfer bridge
- CCIP integration for token transfers
- Replay protection with nonces
- Admin-controlled destination chains
CCIPWETH10Bridge (contracts/ccip/CCIPWETH10Bridge.sol)
- Cross-chain WETH10 transfer bridge
- CCIP integration for token transfers
- Replay protection with nonces
- Admin-controlled destination chains
Prerequisites
- Chainlink CCIP Router: Deployed CCIP Router on your chain
- LINK Token: LINK token address for paying CCIP fees
- Private Key: Deployer private key with sufficient balance
- Environment Variables: Configured in
.envfile
Environment Variables
Create a .env file with the following variables:
# Deployer private key
PRIVATE_KEY=your_private_key_here
# CCIP Configuration
CCIP_ROUTER=0x... # CCIP Router address
CCIP_FEE_TOKEN=0x... # LINK token address
# WETH9 Address (if not deploying)
WETH9_ADDRESS=0x... # Optional: existing WETH9 address
# WETH10 Address (if not deploying)
WETH10_ADDRESS=0x... # Optional: existing WETH10 address
# Deployment Flags
DEPLOY_WETH9=true
DEPLOY_WETH10=true
DEPLOY_BRIDGES=true
Deployment Steps
Option 1: Deploy All Contracts (Recommended)
Deploy WETH9, WETH10, and both bridges in a single transaction:
forge script script/DeployWETHWithCCIP.s.sol:DeployWETHWithCCIP \
--rpc-url $RPC_URL \
--broadcast \
--verify \
-vvvv
Option 2: Deploy Individually
1. Deploy WETH9
forge script script/DeployWETH.s.sol:DeployWETH \
--rpc-url $RPC_URL \
--broadcast \
--verify \
-vvvv
2. Deploy WETH10
forge script script/DeployWETH10.s.sol:DeployWETH10 \
--rpc-url $RPC_URL \
--broadcast \
--verify \
-vvvv
3. Deploy CCIPWETH9Bridge
forge script script/DeployCCIPWETH9Bridge.s.sol:DeployCCIPWETH9Bridge \
--rpc-url $RPC_URL \
--broadcast \
--verify \
-vvvv
4. Deploy CCIPWETH10Bridge
forge script script/DeployCCIPWETH10Bridge.s.sol:DeployCCIPWETH10Bridge \
--rpc-url $RPC_URL \
--broadcast \
--verify \
-vvvv
Configuration
1. Add Destination Chains
After deployment, configure destination chains for cross-chain transfers:
// Add destination chain for WETH9 bridge
bridge.addDestination(
destinationChainSelector, // Chain selector (e.g., Ethereum: 5009297550715157269)
receiverBridgeAddress // Address of corresponding bridge on destination chain
);
// Add destination chain for WETH10 bridge
bridge10.addDestination(
destinationChainSelector,
receiverBridgeAddress
);
2. Verify Configuration
// Check if destination is enabled
(bool enabled, uint64 chainSelector, address receiver) = bridge.destinations(chainSelector);
// Get all destination chains
uint64[] memory chains = bridge.getDestinationChains();
Usage
Sending WETH9 Cross-Chain
// 1. Approve bridge to spend WETH9
weth9.approve(bridgeAddress, amount);
// 2. Approve LINK token for fees
linkToken.approve(bridgeAddress, feeAmount);
// 3. Send cross-chain
bytes32 messageId = bridge.sendCrossChain(
destinationChainSelector,
recipientAddress,
amount
);
Sending WETH10 Cross-Chain
// 1. Approve bridge to spend WETH10
weth10.approve(bridgeAddress, amount);
// 2. Approve LINK token for fees
linkToken.approve(bridgeAddress, feeAmount);
// 3. Send cross-chain
bytes32 messageId = bridge10.sendCrossChain(
destinationChainSelector,
recipientAddress,
amount
);
Calculating Fees
// Calculate fee for cross-chain transfer
uint256 fee = bridge.calculateFee(
destinationChainSelector,
amount
);
Receiving Cross-Chain Transfers
The bridge automatically receives tokens via CCIP and transfers them to the recipient. No user action required.
Testing
Run tests to verify functionality:
# Test WETH9
forge test --match-contract WETHTest -vvvv
# Test WETH10
forge test --match-contract WETH10Test -vvvv
# Test CCIPWETH9Bridge
forge test --match-contract CCIPWETH9BridgeTest -vvvv
# Test CCIPWETH10Bridge
forge test --match-contract CCIPWETH10BridgeTest -vvvv
Chain Selectors
Common chain selectors for reference:
| Chain | Chain Selector |
|---|---|
| Ethereum Mainnet | 5009297550715157269 |
| Arbitrum One | 4949039107694359620 |
| Optimism | 3734403246176062136 |
| Polygon | 4051577828743386545 |
| Base | 15971525489660198786 |
| Avalanche | 6433500567565415381 |
Security Considerations
- Admin Controls: Bridge admin has full control over destination chains
- Replay Protection: Messages are protected against replay attacks
- Fee Management: Users must approve LINK tokens for fees
- Token Approvals: Users must approve bridges to spend tokens
- Destination Validation: Always verify destination chain addresses
Monitoring
Monitor cross-chain transfers:
// Check if transfer was processed
bool processed = bridge.processedTransfers(messageId);
// Get user nonce
uint256 nonce = bridge.getUserNonce(userAddress);
// Listen for events
event CrossChainTransferInitiated(
bytes32 indexed messageId,
address indexed sender,
uint64 indexed destinationChainSelector,
address recipient,
uint256 amount,
uint256 nonce
);
event CrossChainTransferCompleted(
bytes32 indexed messageId,
uint64 indexed sourceChainSelector,
address indexed recipient,
uint256 amount
);
Troubleshooting
Common Issues
- Insufficient LINK: Ensure user has enough LINK for fees
- Destination Not Enabled: Verify destination chain is added and enabled
- Invalid Token: Ensure correct WETH9/WETH10 address
- Replay Attack: Message ID already processed
Error Messages
CCIPWETH9Bridge: destination not enabled- Destination chain not configuredCCIPWETH9Bridge: transfer already processed- Replay attack detectedCCIPWETH9Bridge: insufficient repayment- Insufficient token balanceCCIPWETH9Bridge: zero recipient- Invalid recipient address
Next Steps
- ✅ Deploy WETH9 and WETH10 contracts
- ✅ Deploy CCIP bridges
- ✅ Configure destination chains
- ✅ Test cross-chain transfers
- ✅ Monitor deployments
- ✅ Update documentation with deployed addresses
Support
For issues or questions:
- Check contract documentation
- Review test files for examples
- Verify CCIP router configuration
- Check chain selector compatibility
Deployment Checklist
- CCIP Router deployed and verified
- LINK token address confirmed
- WETH9 deployed (if new)
- WETH10 deployed (if new)
- CCIPWETH9Bridge deployed
- CCIPWETH10Bridge deployed
- Destination chains configured
- Tests passed
- Contracts verified on explorer
- Documentation updated