- Organized 252 files across project - Root directory: 187 → 2 files (98.9% reduction) - Moved configuration guides to docs/04-configuration/ - Moved troubleshooting guides to docs/09-troubleshooting/ - Moved quick start guides to docs/01-getting-started/ - Moved reports to reports/ directory - Archived temporary files - Generated comprehensive reports and documentation - Created maintenance scripts and guides All files organized according to established standards.
353 lines
15 KiB
Bash
Executable File
353 lines
15 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Enhanced WETH → USDT Bridge Verification
|
|
# Checks actual deployed WETH address on ChainID 138 (not canonical)
|
|
# Usage: ./verify-weth-usdt-bridge-enhanced.sh
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[✗]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
|
log_section() { echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; echo -e "${CYAN}$1${NC}"; echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"; }
|
|
|
|
# Configuration
|
|
CHAIN138_RPC="${RPC_URL_138:-https://rpc-http-pub.d-bis.org}"
|
|
CHAIN138_ID=138
|
|
ETHEREUM_MAINNET_ID=1
|
|
|
|
# Token addresses
|
|
# IMPORTANT: WETH9 is NOT at canonical address on ChainID 138!
|
|
# Canonical address (mainnet): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
|
|
# Actual deployed address (ChainID 138): 0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6
|
|
WETH_CANONICAL="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
WETH_CHAIN138="0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6"
|
|
USDT_MAINNET="0xdAC17F958D2ee523a2206206994597C13D831ec7"
|
|
|
|
# Verification results
|
|
CANONICAL_BYTECODE_EXISTS=false
|
|
ACTUAL_BYTECODE_EXISTS=false
|
|
ERC20_VALID=false
|
|
BRIDGE_ROUTE_AVAILABLE=false
|
|
VERIFICATION_ERRORS=()
|
|
VERIFICATION_WARNINGS=()
|
|
|
|
log_section "Enhanced WETH → USDT Bridge Verification (ChainID 138 → Ethereum Mainnet)"
|
|
|
|
log_warn "IMPORTANT: WETH9 is NOT at canonical address on ChainID 138"
|
|
log_info "Canonical address (mainnet): $WETH_CANONICAL"
|
|
log_info "Actual deployed address (ChainID 138): $WETH_CHAIN138"
|
|
log_info "Reason: Cannot recreate CREATE-deployed contracts with CREATE2"
|
|
log_info ""
|
|
|
|
# ============================================================================
|
|
# STEP 1: Check Bytecode at Both Addresses
|
|
# ============================================================================
|
|
log_section "Step 1: Checking Bytecode at WETH Addresses on ChainID 138"
|
|
|
|
log_info "Checking canonical address: $WETH_CANONICAL"
|
|
if command -v cast &> /dev/null; then
|
|
CANONICAL_BYTECODE=$(cast code "$WETH_CANONICAL" --rpc-url "$CHAIN138_RPC" 2>/dev/null || echo "")
|
|
if [ -z "$CANONICAL_BYTECODE" ] || [ "$CANONICAL_BYTECODE" = "0x" ]; then
|
|
log_warn " ⚠ No bytecode at canonical address (expected)"
|
|
VERIFICATION_WARNINGS+=("No bytecode at canonical WETH address on ChainID 138 (expected)")
|
|
else
|
|
log_success " ✅ Bytecode exists at canonical address"
|
|
CANONICAL_BYTECODE_EXISTS=true
|
|
fi
|
|
else
|
|
log_error "cast tool not available"
|
|
fi
|
|
|
|
log_info ""
|
|
log_info "Checking actual deployed address: $WETH_CHAIN138"
|
|
if command -v cast &> /dev/null; then
|
|
ACTUAL_BYTECODE=$(cast code "$WETH_CHAIN138" --rpc-url "$CHAIN138_RPC" 2>/dev/null || echo "")
|
|
if [ -z "$ACTUAL_BYTECODE" ] || [ "$ACTUAL_BYTECODE" = "0x" ]; then
|
|
log_error " ❌ No bytecode at actual deployed address"
|
|
VERIFICATION_ERRORS+=("No bytecode at actual WETH address on ChainID 138: $WETH_CHAIN138")
|
|
else
|
|
BYTECODE_LENGTH=$((${#ACTUAL_BYTECODE} - 2))
|
|
BYTECODE_BYTES=$((BYTECODE_LENGTH / 2))
|
|
log_success " ✅ Bytecode exists at actual deployed address"
|
|
log_info " Bytecode length: $BYTECODE_LENGTH chars ($BYTECODE_BYTES bytes)"
|
|
ACTUAL_BYTECODE_EXISTS=true
|
|
fi
|
|
else
|
|
log_error "cast tool not available"
|
|
fi
|
|
|
|
# ============================================================================
|
|
# STEP 2: Verify ERC-20 Compliance at Actual Address
|
|
# ============================================================================
|
|
log_section "Step 2: Verifying ERC-20 Compliance at Actual Deployed Address"
|
|
|
|
if [ "$ACTUAL_BYTECODE_EXISTS" = true ]; then
|
|
log_info "Testing ERC-20 functions at: $WETH_CHAIN138"
|
|
log_info ""
|
|
|
|
# Check symbol()
|
|
log_info "1. Testing symbol()..."
|
|
SYMBOL_RESULT=$(cast call "$WETH_CHAIN138" "symbol()" --rpc-url "$CHAIN138_RPC" 2>&1 || echo "ERROR")
|
|
if [[ "$SYMBOL_RESULT" == *"ERROR"* ]] || [ -z "$SYMBOL_RESULT" ] || [ "$SYMBOL_RESULT" = "0x" ]; then
|
|
log_error " ❌ symbol() call failed or returned empty"
|
|
VERIFICATION_ERRORS+=("symbol() function failed at $WETH_CHAIN138")
|
|
else
|
|
SYMBOL_CLEAN=$(echo "$SYMBOL_RESULT" | cast --to-ascii 2>/dev/null | tr -d '\0' || echo "$SYMBOL_RESULT")
|
|
log_success " ✅ symbol() = $SYMBOL_CLEAN"
|
|
fi
|
|
|
|
# Check decimals()
|
|
log_info "2. Testing decimals()..."
|
|
DECIMALS_RESULT=$(cast call "$WETH_CHAIN138" "decimals()" --rpc-url "$CHAIN138_RPC" 2>&1 || echo "ERROR")
|
|
if [[ "$DECIMALS_RESULT" == *"ERROR"* ]] || [ -z "$DECIMALS_RESULT" ]; then
|
|
log_error " ❌ decimals() call failed"
|
|
VERIFICATION_ERRORS+=("decimals() function failed at $WETH_CHAIN138")
|
|
else
|
|
DECIMALS_DEC=$(cast --to-dec "$DECIMALS_RESULT" 2>/dev/null || echo "unknown")
|
|
if [ "$DECIMALS_DEC" = "18" ]; then
|
|
log_success " ✅ decimals() = $DECIMALS_DEC (expected: 18)"
|
|
else
|
|
log_warn " ⚠ decimals() = $DECIMALS_DEC (expected: 18)"
|
|
VERIFICATION_ERRORS+=("decimals() returned unexpected value: $DECIMALS_DEC")
|
|
fi
|
|
fi
|
|
|
|
# Check totalSupply()
|
|
log_info "3. Testing totalSupply()..."
|
|
TOTAL_SUPPLY_RESULT=$(cast call "$WETH_CHAIN138" "totalSupply()" --rpc-url "$CHAIN138_RPC" 2>&1 || echo "ERROR")
|
|
if [[ "$TOTAL_SUPPLY_RESULT" == *"ERROR"* ]] || [ -z "$TOTAL_SUPPLY_RESULT" ]; then
|
|
log_error " ❌ totalSupply() call failed"
|
|
VERIFICATION_ERRORS+=("totalSupply() function failed at $WETH_CHAIN138")
|
|
else
|
|
TOTAL_SUPPLY_DEC=$(cast --to-dec "$TOTAL_SUPPLY_RESULT" 2>/dev/null || echo "unknown")
|
|
log_success " ✅ totalSupply() = $TOTAL_SUPPLY_DEC"
|
|
fi
|
|
|
|
# Determine ERC-20 validity
|
|
ERC20_ERRORS_COUNT=0
|
|
for error in "${VERIFICATION_ERRORS[@]}"; do
|
|
if [[ "$error" == *"symbol()"* ]] || [[ "$error" == *"decimals()"* ]] || [[ "$error" == *"totalSupply()"* ]]; then
|
|
((ERC20_ERRORS_COUNT++))
|
|
fi
|
|
done
|
|
|
|
if [ $ERC20_ERRORS_COUNT -eq 0 ]; then
|
|
ERC20_VALID=true
|
|
log_success "✅ Contract behaves as valid ERC-20"
|
|
else
|
|
log_warn "⚠ Some ERC-20 functions failed"
|
|
fi
|
|
else
|
|
log_warn "⚠ Skipping ERC-20 verification (no bytecode found at actual address)"
|
|
fi
|
|
|
|
# ============================================================================
|
|
# STEP 3: Check thirdweb Bridge Route
|
|
# ============================================================================
|
|
log_section "Step 3: Checking thirdweb Bridge Route Availability"
|
|
|
|
log_info "Checking route: ChainID $CHAIN138_ID (WETH) → ChainID $ETHEREUM_MAINNET_ID (USDT)"
|
|
log_info "WETH Address (ChainID 138): $WETH_CHAIN138"
|
|
log_info "USDT Address (Ethereum Mainnet): $USDT_MAINNET"
|
|
log_info ""
|
|
log_warn "⚠ Using actual deployed address, NOT canonical address"
|
|
log_info ""
|
|
|
|
log_info "Attempting to query thirdweb Bridge API..."
|
|
log_warn "Note: thirdweb Bridge may not recognize ChainID 138 or this token address"
|
|
|
|
# Try multiple potential API endpoints
|
|
THIRDWEB_ENDPOINTS=(
|
|
"https://api.thirdweb.com/v1/bridge/quote"
|
|
"https://bridge.thirdweb.com/api/quote"
|
|
)
|
|
|
|
BRIDGE_QUOTE_SUCCESS=false
|
|
BRIDGE_ERROR_MESSAGE=""
|
|
|
|
for endpoint in "${THIRDWEB_ENDPOINTS[@]}"; do
|
|
log_info "Trying endpoint: $endpoint"
|
|
|
|
QUOTE_PAYLOAD=$(cat <<EOF
|
|
{
|
|
"fromChainId": $CHAIN138_ID,
|
|
"toChainId": $ETHEREUM_MAINNET_ID,
|
|
"fromTokenAddress": "$WETH_CHAIN138",
|
|
"toTokenAddress": "$USDT_MAINNET",
|
|
"amount": "1000000000000000000"
|
|
}
|
|
EOF
|
|
)
|
|
|
|
QUOTE_RESPONSE=$(curl -s -X POST "$endpoint" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$QUOTE_PAYLOAD" \
|
|
--max-time 10 \
|
|
2>&1 || echo "ERROR")
|
|
|
|
if [[ "$QUOTE_RESPONSE" != *"ERROR"* ]] && [[ "$QUOTE_RESPONSE" != *"404"* ]]; then
|
|
if command -v jq &> /dev/null && echo "$QUOTE_RESPONSE" | jq -e '.quoteId, .estimatedTime, .fee, .toAmount' >/dev/null 2>&1; then
|
|
log_success "✅ Valid route found via thirdweb Bridge!"
|
|
log_info " Response: $(echo "$QUOTE_RESPONSE" | jq -c '.' 2>/dev/null || echo "$QUOTE_RESPONSE")"
|
|
BRIDGE_ROUTE_AVAILABLE=true
|
|
BRIDGE_QUOTE_SUCCESS=true
|
|
break
|
|
elif command -v jq &> /dev/null && echo "$QUOTE_RESPONSE" | jq -e '.error, .message' >/dev/null 2>&1; then
|
|
ERROR_MSG=$(echo "$QUOTE_RESPONSE" | jq -r '.error // .message // "Unknown error"' 2>/dev/null || echo "API error")
|
|
log_warn " API returned error: $ERROR_MSG"
|
|
BRIDGE_ERROR_MESSAGE="$ERROR_MSG"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ "$BRIDGE_QUOTE_SUCCESS" = false ]; then
|
|
log_warn "⚠ Could not verify route via thirdweb Bridge API"
|
|
log_info " Possible reasons:"
|
|
log_info " 1. ChainID 138 not supported by thirdweb Bridge"
|
|
log_info " 2. WETH token at $WETH_CHAIN138 not recognized"
|
|
log_info " 3. Token address differs from canonical (thirdweb may only recognize canonical)"
|
|
log_info " 4. No liquidity available for WETH → USDT route"
|
|
log_info " 5. API requires authentication/API key"
|
|
VERIFICATION_ERRORS+=("thirdweb Bridge route verification inconclusive")
|
|
fi
|
|
|
|
# ============================================================================
|
|
# STEP 4: Alternative Routes Analysis
|
|
# ============================================================================
|
|
log_section "Step 4: Alternative Routes Analysis"
|
|
|
|
if [ "$BRIDGE_ROUTE_AVAILABLE" = false ]; then
|
|
log_info "Since direct route may not be available, here are alternative options:"
|
|
log_info ""
|
|
|
|
log_info "Option 1: Use CCIP Bridge (Recommended)"
|
|
log_info " - Use Chainlink CCIP for WETH bridging from ChainID 138"
|
|
log_info " - CCIPWETH9Bridge: 0x89dd12025bfCD38A168455A44B400e913ED33BE2"
|
|
log_info " - Swap WETH → USDT on Ethereum Mainnet after bridging"
|
|
log_info " Pros: Secure, audited, supports ChainID 138"
|
|
log_info " Cons: Requires CCIP bridge setup"
|
|
log_info ""
|
|
|
|
log_info "Option 2: Swap to Native Asset (ETH) → Bridge → Swap to USDT"
|
|
log_info " - Swap WETH → ETH on ChainID 138"
|
|
log_info " - Bridge ETH to Ethereum Mainnet"
|
|
log_info " - Swap ETH → USDT on Ethereum Mainnet"
|
|
log_info " Pros: Native asset bridging often has better support"
|
|
log_info " Cons: Multiple steps, additional fees"
|
|
log_info ""
|
|
|
|
log_info "Option 3: Bridge via Intermediate L2"
|
|
log_info " - Bridge WETH from ChainID 138 → Arbitrum/Optimism/Base"
|
|
log_info " - Swap WETH → USDT on L2"
|
|
log_info " - Bridge USDT from L2 → Ethereum Mainnet"
|
|
log_info " Pros: Lower fees on L2, better liquidity"
|
|
log_info " Cons: More complex route, longer time"
|
|
log_info ""
|
|
|
|
log_info "Option 4: Request Token Support from thirdweb"
|
|
log_info " - Contact thirdweb to request ChainID 138 support"
|
|
log_info " - Request WETH token recognition at $WETH_CHAIN138"
|
|
log_info " Pros: Enables direct route in future"
|
|
log_info " Cons: May take time for implementation"
|
|
fi
|
|
|
|
# ============================================================================
|
|
# FINAL VERDICT: GO / NO-GO
|
|
# ============================================================================
|
|
log_section "Final Verdict: GO / NO-GO"
|
|
|
|
log_info "Verification Summary:"
|
|
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_info ""
|
|
|
|
# Bytecode check
|
|
if [ "$ACTUAL_BYTECODE_EXISTS" = true ]; then
|
|
log_success "✓ Bytecode exists at actual WETH address on ChainID 138"
|
|
log_info " Address: $WETH_CHAIN138"
|
|
else
|
|
log_error "✗ No bytecode at actual WETH address on ChainID 138"
|
|
fi
|
|
|
|
if [ "$CANONICAL_BYTECODE_EXISTS" = false ]; then
|
|
log_warn "⚠ No bytecode at canonical address (expected - cannot recreate CREATE-deployed contracts)"
|
|
fi
|
|
|
|
# ERC-20 check
|
|
if [ "$ERC20_VALID" = true ]; then
|
|
log_success "✓ Contract behaves as valid ERC-20"
|
|
else
|
|
log_warn "⚠ ERC-20 verification incomplete or failed"
|
|
fi
|
|
|
|
# Bridge route check
|
|
if [ "$BRIDGE_ROUTE_AVAILABLE" = true ]; then
|
|
log_success "✓ Valid route available via thirdweb Bridge"
|
|
else
|
|
log_warn "⚠ Route availability inconclusive or not available"
|
|
fi
|
|
|
|
log_info ""
|
|
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_info ""
|
|
|
|
# Determine GO/NO-GO
|
|
if [ "$ACTUAL_BYTECODE_EXISTS" = true ] && [ "$ERC20_VALID" = true ] && [ "$BRIDGE_ROUTE_AVAILABLE" = true ]; then
|
|
log_success "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_success "✅ GO: Bridge route is viable"
|
|
log_success "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_info ""
|
|
log_info "All checks passed:"
|
|
log_info " • WETH contract exists at $WETH_CHAIN138 on ChainID 138"
|
|
log_info " • Contract implements ERC-20 correctly"
|
|
log_info " • thirdweb Bridge provides valid route to USDT on Ethereum Mainnet"
|
|
log_info ""
|
|
log_info "You can proceed with bridging WETH → USDT via thirdweb Bridge."
|
|
exit 0
|
|
elif [ "$ACTUAL_BYTECODE_EXISTS" = true ] && [ "$ERC20_VALID" = true ] && [ "$BRIDGE_ROUTE_AVAILABLE" = false ]; then
|
|
log_warn "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_warn "⚠ CONDITIONAL GO: Contract valid but route unverified"
|
|
log_warn "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_info ""
|
|
log_info "Contract verification passed, but bridge route needs manual verification:"
|
|
log_info " • WETH contract exists at $WETH_CHAIN138 on ChainID 138 ✓"
|
|
log_info " • Contract implements ERC-20 correctly ✓"
|
|
log_info " • thirdweb Bridge route verification inconclusive ⚠"
|
|
log_info ""
|
|
log_info "CRITICAL: WETH is NOT at canonical address on ChainID 138"
|
|
log_info " • Canonical: $WETH_CANONICAL (no bytecode)"
|
|
log_info " • Actual: $WETH_CHAIN138 (has bytecode)"
|
|
log_info ""
|
|
log_info "Next steps:"
|
|
log_info " 1. Verify route using thirdweb SDK with actual address: $WETH_CHAIN138"
|
|
log_info " 2. Consider using CCIP Bridge instead (supports ChainID 138)"
|
|
log_info " 3. Check thirdweb Bridge dashboard for ChainID 138 support"
|
|
log_info " 4. Request thirdweb to add support for ChainID 138 and token $WETH_CHAIN138"
|
|
exit 1
|
|
else
|
|
log_error "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_error "❌ NO-GO: Bridge route is NOT viable"
|
|
log_error "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_info ""
|
|
log_error "Critical issues found:"
|
|
for error in "${VERIFICATION_ERRORS[@]}"; do
|
|
log_error " • $error"
|
|
done
|
|
log_info ""
|
|
log_info "Recommendation:"
|
|
log_info " • Use CCIP Bridge instead (CCIPWETH9Bridge: 0x89dd12025bfCD38A168455A44B400e913ED33BE2)"
|
|
log_info " • Or fix contract deployment issues"
|
|
exit 2
|
|
fi
|