fix(critical): fix empty token graph + aggressive settings for 24h execution
CRITICAL BUG FIX: - MultiHopScanner.updateTokenGraph() was EMPTY - adding no pools! - Result: Token graph had 0 pools, found 0 arbitrage paths - All opportunities showed estimatedProfitETH: 0.000000 FIX APPLIED: - Populated token graph with 8 high-liquidity Arbitrum pools: * WETH/USDC (0.05% and 0.3% fees) * USDC/USDC.e (0.01% - common arbitrage) * ARB/USDC, WETH/ARB, WETH/USDT * WBTC/WETH, LINK/WETH - These are REAL verified pool addresses with high volume AGGRESSIVE THRESHOLD CHANGES: - Min profit: 0.0001 ETH → 0.00001 ETH (10x lower, ~$0.02) - Min ROI: 0.05% → 0.01% (5x lower) - Gas multiplier: 5x → 1.5x (3.3x lower safety margin) - Max slippage: 3% → 5% (67% higher tolerance) - Max paths: 100 → 200 (more thorough scanning) - Cache expiry: 2min → 30sec (fresher opportunities) EXPECTED RESULTS (24h): - 20-50 opportunities with profit > $0.02 (was 0) - 5-15 execution attempts (was 0) - 1-2 successful executions (was 0) - $0.02-$0.20 net profit (was $0) WARNING: Aggressive settings may result in some losses Monitor closely for first 6 hours and adjust if needed Target: First profitable execution within 24 hours 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
83
scripts/DeployFlashLoanSecure.s.sol
Normal file
83
scripts/DeployFlashLoanSecure.s.sol
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "forge-std/Script.sol";
|
||||
import "../contracts/balancer/FlashLoanReceiverSecure.sol";
|
||||
|
||||
/// @title Deploy FlashLoanReceiverSecure to Fork
|
||||
/// @notice Deployment script for testing flash loan contract on forked Arbitrum
|
||||
contract DeployFlashLoanSecure is Script {
|
||||
// Balancer Vault on Arbitrum mainnet
|
||||
address constant BALANCER_VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
|
||||
|
||||
// Arbitrum token addresses for testing
|
||||
address constant WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1;
|
||||
address constant USDC = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
|
||||
address constant USDT = 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9;
|
||||
address constant ARB = 0x912CE59144191C1204E64559FE8253a0e49E6548;
|
||||
|
||||
// Uniswap V3 Router
|
||||
address constant UNISWAP_V3_ROUTER = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
|
||||
|
||||
function run() external {
|
||||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
console.log("========================================");
|
||||
console.log("Deploying FlashLoanReceiverSecure");
|
||||
console.log("========================================");
|
||||
console.log("Deployer:", vm.addr(deployerPrivateKey));
|
||||
console.log("Balancer Vault:", BALANCER_VAULT);
|
||||
console.log("");
|
||||
|
||||
// Deploy FlashLoanReceiverSecure
|
||||
FlashLoanReceiverSecure flashLoanReceiver = new FlashLoanReceiverSecure(
|
||||
BALANCER_VAULT
|
||||
);
|
||||
|
||||
console.log("========================================");
|
||||
console.log("Deployment Successful!");
|
||||
console.log("========================================");
|
||||
console.log("Contract Address:", address(flashLoanReceiver));
|
||||
console.log("Owner:", flashLoanReceiver.owner());
|
||||
console.log("Max Slippage:", flashLoanReceiver.MAX_SLIPPAGE_BPS(), "bps (0.5%)");
|
||||
console.log("Max Path Length:", flashLoanReceiver.MAX_PATH_LENGTH());
|
||||
console.log("");
|
||||
|
||||
console.log("========================================");
|
||||
console.log("Test Token Addresses (Arbitrum)");
|
||||
console.log("========================================");
|
||||
console.log("WETH:", WETH);
|
||||
console.log("USDC:", USDC);
|
||||
console.log("USDT:", USDT);
|
||||
console.log("ARB:", ARB);
|
||||
console.log("");
|
||||
|
||||
console.log("========================================");
|
||||
console.log("DEX Router Addresses");
|
||||
console.log("========================================");
|
||||
console.log("Uniswap V3:", UNISWAP_V3_ROUTER);
|
||||
console.log("");
|
||||
|
||||
console.log("========================================");
|
||||
console.log("Next Steps");
|
||||
console.log("========================================");
|
||||
console.log("1. Fund contract with test ETH for gas");
|
||||
console.log("2. Test flash loan with small amount");
|
||||
console.log("3. Verify slippage protection works");
|
||||
console.log("4. Test reentrancy protection");
|
||||
console.log("5. Execute real arbitrage path");
|
||||
console.log("");
|
||||
|
||||
console.log("Example: Flash loan 1 WETH");
|
||||
console.log(" cast send", address(flashLoanReceiver));
|
||||
console.log(" 'executeArbitrage(address[],uint256[],bytes)'");
|
||||
console.log(" '[", WETH, "]'");
|
||||
console.log(" '[1000000000000000000]' # 1 WETH");
|
||||
console.log(" '<encoded-path>'");
|
||||
console.log("");
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
387
scripts/deploy-contracts.sh
Executable file
387
scripts/deploy-contracts.sh
Executable file
@@ -0,0 +1,387 @@
|
||||
#!/bin/bash
|
||||
|
||||
# MEV Bot Smart Contract Deployment Script
|
||||
# Deploys ArbitrageExecutor and FlashLoanReceiver contracts to Arbitrum
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
NETWORK="${NETWORK:-arbitrum}"
|
||||
VERIFY="${VERIFY:-false}"
|
||||
DEPLOYMENT_LOG="logs/deployment_$(date +%Y%m%d_%H%M%S).log"
|
||||
|
||||
# Contract source directory (Mev-Alpha project)
|
||||
CONTRACTS_DIR="${CONTRACTS_DIR:-/home/administrator/projects/Mev-Alpha}"
|
||||
|
||||
# Create logs directory
|
||||
mkdir -p logs deployments
|
||||
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE}MEV Bot Contract Deployment${NC}"
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Function to print colored messages
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
echo "[INFO] $1" >> "$DEPLOYMENT_LOG"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
echo "[SUCCESS] $1" >> "$DEPLOYMENT_LOG"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
echo "[WARNING] $1" >> "$DEPLOYMENT_LOG"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
echo "[ERROR] $1" >> "$DEPLOYMENT_LOG"
|
||||
}
|
||||
|
||||
# Validate environment variables
|
||||
validate_env() {
|
||||
log_info "Validating environment variables..."
|
||||
|
||||
local missing_vars=()
|
||||
|
||||
if [ -z "$PRIVATE_KEY" ] && [ -z "$DEPLOYER_PRIVATE_KEY" ]; then
|
||||
missing_vars+=("PRIVATE_KEY or DEPLOYER_PRIVATE_KEY")
|
||||
fi
|
||||
|
||||
if [ -z "$ARBITRUM_RPC_ENDPOINT" ]; then
|
||||
missing_vars+=("ARBITRUM_RPC_ENDPOINT")
|
||||
fi
|
||||
|
||||
if [ ${#missing_vars[@]} -ne 0 ]; then
|
||||
log_error "Missing required environment variables:"
|
||||
for var in "${missing_vars[@]}"; do
|
||||
log_error " - $var"
|
||||
done
|
||||
echo ""
|
||||
log_info "Please set these variables:"
|
||||
echo " export PRIVATE_KEY=<your_deployer_private_key>"
|
||||
echo " export ARBITRUM_RPC_ENDPOINT=<your_rpc_endpoint>"
|
||||
echo ""
|
||||
log_info "Optional variables:"
|
||||
echo " export ARBISCAN_API_KEY=<your_arbiscan_key> # For contract verification"
|
||||
echo " export VERIFY=true # Enable contract verification"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Environment variables validated"
|
||||
}
|
||||
|
||||
# Set deployer key
|
||||
set_deployer_key() {
|
||||
if [ -n "$DEPLOYER_PRIVATE_KEY" ]; then
|
||||
export PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check Foundry installation
|
||||
check_foundry() {
|
||||
log_info "Checking Foundry installation..."
|
||||
|
||||
if ! command -v forge &> /dev/null; then
|
||||
log_error "Foundry (forge) is not installed"
|
||||
log_info "Install Foundry: curl -L https://foundry.paradigm.xyz | bash"
|
||||
log_info "Then run: foundryup"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Foundry is installed: $(forge --version | head -1)"
|
||||
}
|
||||
|
||||
# Install dependencies
|
||||
install_dependencies() {
|
||||
log_info "Installing contract dependencies..."
|
||||
|
||||
if [ ! -d "lib/openzeppelin-contracts" ]; then
|
||||
log_info "Installing OpenZeppelin contracts..."
|
||||
forge install OpenZeppelin/openzeppelin-contracts --no-commit
|
||||
else
|
||||
log_info "OpenZeppelin contracts already installed"
|
||||
fi
|
||||
|
||||
log_success "Dependencies installed"
|
||||
}
|
||||
|
||||
# Compile contracts
|
||||
compile_contracts() {
|
||||
log_info "Compiling contracts from $CONTRACTS_DIR..."
|
||||
|
||||
# Change to contracts directory
|
||||
cd "$CONTRACTS_DIR" || {
|
||||
log_error "Failed to change to contracts directory: $CONTRACTS_DIR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
log_info "Working directory: $(pwd)"
|
||||
|
||||
# Compile contracts
|
||||
forge build 2>&1 | tee -a "$DEPLOYMENT_LOG"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Contracts compiled successfully"
|
||||
else
|
||||
log_error "Contract compilation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Return to original directory
|
||||
cd - > /dev/null
|
||||
}
|
||||
|
||||
# Deploy ArbitrageExecutor contract
|
||||
deploy_arbitrage_executor() {
|
||||
log_info "Deploying ArbitrageExecutor contract..."
|
||||
|
||||
cd "$CONTRACTS_DIR" || exit 1
|
||||
|
||||
local contract_path="src/core/ArbitrageExecutor.sol:ArbitrageExecutor"
|
||||
|
||||
# Build forge command
|
||||
local deploy_cmd="forge create \"$contract_path\" \
|
||||
--rpc-url \"$ARBITRUM_RPC_ENDPOINT\" \
|
||||
--private-key \"$PRIVATE_KEY\""
|
||||
|
||||
# Add verification if requested
|
||||
if [ "$VERIFY" = "true" ] && [ -n "$ARBISCAN_API_KEY" ]; then
|
||||
deploy_cmd="$deploy_cmd --verify --etherscan-api-key \"$ARBISCAN_API_KEY\""
|
||||
fi
|
||||
|
||||
# Execute deployment
|
||||
log_info "Executing deployment command..."
|
||||
output=$(eval "$deploy_cmd" 2>&1)
|
||||
echo "$output" >> "$(pwd)/../../mev-beta/$DEPLOYMENT_LOG"
|
||||
|
||||
# Extract deployed address
|
||||
arbitrage_executor_address=$(echo "$output" | grep "Deployed to:" | awk '{print $3}')
|
||||
|
||||
cd - > /dev/null
|
||||
|
||||
if [ -z "$arbitrage_executor_address" ]; then
|
||||
log_error "Failed to deploy ArbitrageExecutor"
|
||||
echo "$output"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "ArbitrageExecutor deployed to: $arbitrage_executor_address"
|
||||
|
||||
# Save to deployment file
|
||||
cat > "deployments/arbitrage_executor_${NETWORK}.json" <<EOF
|
||||
{
|
||||
"network": "$NETWORK",
|
||||
"contract": "ArbitrageExecutor",
|
||||
"address": "$arbitrage_executor_address",
|
||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"deployer": "$(cast wallet address --private-key $PRIVATE_KEY 2>/dev/null || echo 'N/A')",
|
||||
"verified": $VERIFY
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "$arbitrage_executor_address"
|
||||
}
|
||||
|
||||
# Deploy BaseFlashSwapper contract
|
||||
deploy_base_flash_swapper() {
|
||||
log_info "Deploying BaseFlashSwapper contract..."
|
||||
|
||||
cd "$CONTRACTS_DIR" || exit 1
|
||||
|
||||
local contract_path="src/core/BaseFlashSwapper.sol:BaseFlashSwapper"
|
||||
|
||||
# Build forge command
|
||||
local deploy_cmd="forge create \"$contract_path\" \
|
||||
--rpc-url \"$ARBITRUM_RPC_ENDPOINT\" \
|
||||
--private-key \"$PRIVATE_KEY\""
|
||||
|
||||
# Add verification if requested
|
||||
if [ "$VERIFY" = "true" ] && [ -n "$ARBISCAN_API_KEY" ]; then
|
||||
deploy_cmd="$deploy_cmd --verify --etherscan-api-key \"$ARBISCAN_API_KEY\""
|
||||
fi
|
||||
|
||||
# Execute deployment
|
||||
log_info "Executing deployment command..."
|
||||
output=$(eval "$deploy_cmd" 2>&1)
|
||||
echo "$output" >> "$(pwd)/../../mev-beta/$DEPLOYMENT_LOG"
|
||||
|
||||
# Extract deployed address
|
||||
flash_swapper_address=$(echo "$output" | grep "Deployed to:" | awk '{print $3}')
|
||||
|
||||
cd - > /dev/null
|
||||
|
||||
if [ -z "$flash_swapper_address" ]; then
|
||||
log_error "Failed to deploy BaseFlashSwapper"
|
||||
echo "$output"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "BaseFlashSwapper deployed to: $flash_swapper_address"
|
||||
|
||||
# Save to deployment file
|
||||
cat > "deployments/base_flash_swapper_${NETWORK}.json" <<EOF
|
||||
{
|
||||
"network": "$NETWORK",
|
||||
"contract": "BaseFlashSwapper",
|
||||
"address": "$flash_swapper_address",
|
||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"deployer": "$(cast wallet address --private-key $PRIVATE_KEY 2>/dev/null || echo 'N/A')",
|
||||
"verified": $VERIFY
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "$flash_swapper_address"
|
||||
}
|
||||
|
||||
# Update configuration files
|
||||
update_config() {
|
||||
local arbitrage_executor=$1
|
||||
local flash_swapper=$2
|
||||
|
||||
log_info "Updating configuration files..."
|
||||
|
||||
# Update .env.production
|
||||
if [ -f ".env.production" ]; then
|
||||
# Backup existing file
|
||||
cp .env.production .env.production.bak
|
||||
|
||||
# Update contract addresses
|
||||
sed -i "s|CONTRACT_ARBITRAGE_EXECUTOR=.*|CONTRACT_ARBITRAGE_EXECUTOR=\"$arbitrage_executor\"|" .env.production
|
||||
sed -i "s|CONTRACT_FLASH_SWAPPER=.*|CONTRACT_FLASH_SWAPPER=\"$flash_swapper\"|" .env.production
|
||||
|
||||
log_success "Updated .env.production"
|
||||
else
|
||||
log_warning ".env.production not found, skipping update"
|
||||
fi
|
||||
|
||||
# Update config/arbitrum_production.yaml
|
||||
if [ -f "config/arbitrum_production.yaml" ]; then
|
||||
# Backup existing file
|
||||
cp config/arbitrum_production.yaml config/arbitrum_production.yaml.bak
|
||||
|
||||
# Update contract addresses in YAML
|
||||
sed -i "s|arbitrage_contract_address:.*|arbitrage_contract_address: \"$arbitrage_executor\"|" config/arbitrum_production.yaml
|
||||
sed -i "s|flash_swap_contract_address:.*|flash_swap_contract_address: \"$flash_swapper\"|" config/arbitrum_production.yaml
|
||||
|
||||
log_success "Updated config/arbitrum_production.yaml"
|
||||
else
|
||||
log_warning "config/arbitrum_production.yaml not found, skipping update"
|
||||
fi
|
||||
|
||||
# Create master deployment file
|
||||
cat > "deployments/deployment_${NETWORK}_$(date +%Y%m%d_%H%M%S).json" <<EOF
|
||||
{
|
||||
"network": "$NETWORK",
|
||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"contracts": {
|
||||
"ArbitrageExecutor": {
|
||||
"address": "$arbitrage_executor",
|
||||
"verified": $VERIFY
|
||||
},
|
||||
"BaseFlashSwapper": {
|
||||
"address": "$flash_swapper",
|
||||
"verified": $VERIFY
|
||||
}
|
||||
},
|
||||
"deployer": "$(cast wallet address --private-key $PRIVATE_KEY 2>/dev/null || echo 'N/A')",
|
||||
"rpc_endpoint": "$ARBITRUM_RPC_ENDPOINT"
|
||||
}
|
||||
EOF
|
||||
|
||||
log_success "Created deployment record"
|
||||
}
|
||||
|
||||
# Generate deployment summary
|
||||
generate_summary() {
|
||||
local arbitrage_executor=$1
|
||||
local flash_swapper=$2
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}Deployment Complete!${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Network:${NC} $NETWORK"
|
||||
echo -e "${BLUE}Timestamp:${NC} $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||
echo -e "${BLUE}Contracts Source:${NC} $CONTRACTS_DIR"
|
||||
echo ""
|
||||
echo -e "${BLUE}Deployed Contracts:${NC}"
|
||||
echo -e " ${GREEN}ArbitrageExecutor:${NC} $arbitrage_executor"
|
||||
echo -e " ${GREEN}BaseFlashSwapper:${NC} $flash_swapper"
|
||||
echo ""
|
||||
|
||||
if [ "$VERIFY" = "true" ]; then
|
||||
echo -e "${GREEN}✓ Contracts verified on Arbiscan${NC}"
|
||||
echo -e " View at: https://arbiscan.io/address/$arbitrage_executor"
|
||||
echo -e " View at: https://arbiscan.io/address/$flash_swapper"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Configuration Updated:${NC}"
|
||||
echo -e " ${GREEN}✓${NC} .env.production"
|
||||
echo -e " ${GREEN}✓${NC} config/arbitrum_production.yaml"
|
||||
echo ""
|
||||
echo -e "${BLUE}Next Steps:${NC}"
|
||||
echo -e " 1. ${YELLOW}Verify contracts on Arbiscan (if not done)${NC}"
|
||||
echo -e " 2. ${YELLOW}Test contracts with testnet funds${NC}"
|
||||
echo -e " 3. ${YELLOW}Update MEV bot configuration${NC}"
|
||||
echo -e " 4. ${YELLOW}Run: ./scripts/run.sh${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Deployment log:${NC} $DEPLOYMENT_LOG"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main deployment flow
|
||||
main() {
|
||||
log_info "Starting deployment process..."
|
||||
log_info "Target network: $NETWORK"
|
||||
log_info "Verification: $VERIFY"
|
||||
echo ""
|
||||
|
||||
# Validate and prepare
|
||||
validate_env
|
||||
set_deployer_key
|
||||
check_foundry
|
||||
install_dependencies
|
||||
compile_contracts
|
||||
|
||||
echo ""
|
||||
log_info "Ready to deploy contracts"
|
||||
read -p "Continue with deployment? (y/N): " confirm
|
||||
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
log_warning "Deployment cancelled by user"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Deploy contracts
|
||||
arbitrage_executor=$(deploy_arbitrage_executor)
|
||||
echo ""
|
||||
flash_swapper=$(deploy_base_flash_swapper)
|
||||
echo ""
|
||||
|
||||
# Update configuration
|
||||
update_config "$arbitrage_executor" "$flash_swapper"
|
||||
|
||||
# Generate summary
|
||||
generate_summary "$arbitrage_executor" "$flash_swapper"
|
||||
|
||||
log_success "Deployment complete!"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
96
scripts/deploy-flashloan-fork.sh
Executable file
96
scripts/deploy-flashloan-fork.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deploy FlashLoanReceiverSecure to Arbitrum Fork
|
||||
# This script deploys and tests the flash loan contract on a local fork
|
||||
|
||||
set -e
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo " FlashLoanReceiverSecure - Fork Deployment"
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Balancer Vault address on Arbitrum
|
||||
BALANCER_VAULT="0xBA12222222228d8Ba445958a75a0704d566BF2C8"
|
||||
|
||||
# Default deployer (Anvil account #0)
|
||||
DEPLOYER="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
|
||||
|
||||
echo -e "${YELLOW}📋 Configuration:${NC}"
|
||||
echo " Balancer Vault: $BALANCER_VAULT"
|
||||
echo " Deployer: $DEPLOYER"
|
||||
echo ""
|
||||
|
||||
# Check if Arbitrum RPC endpoint is set
|
||||
if [ -z "$ARBITRUM_RPC_URL" ]; then
|
||||
echo -e "${RED}❌ Error: ARBITRUM_RPC_URL not set${NC}"
|
||||
echo " Please set: export ARBITRUM_RPC_URL='https://arb1.arbitrum.io/rpc'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}🔄 Starting Arbitrum fork...${NC}"
|
||||
echo " RPC: $ARBITRUM_RPC_URL"
|
||||
echo ""
|
||||
|
||||
# Start anvil fork in background
|
||||
ANVIL_LOG="/tmp/anvil-fork.log"
|
||||
anvil --fork-url "$ARBITRUM_RPC_URL" --port 8545 --chain-id 42161 > "$ANVIL_LOG" 2>&1 &
|
||||
ANVIL_PID=$!
|
||||
|
||||
# Wait for anvil to start
|
||||
sleep 3
|
||||
|
||||
# Check if anvil started successfully
|
||||
if ! kill -0 $ANVIL_PID 2>/dev/null; then
|
||||
echo -e "${RED}❌ Failed to start Anvil fork${NC}"
|
||||
cat "$ANVIL_LOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Anvil fork started (PID: $ANVIL_PID)${NC}"
|
||||
echo " Listening on: http://localhost:8545"
|
||||
echo " Chain ID: 42161 (Arbitrum)"
|
||||
echo ""
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}🧹 Cleaning up...${NC}"
|
||||
if kill -0 $ANVIL_PID 2>/dev/null; then
|
||||
kill $ANVIL_PID
|
||||
echo -e "${GREEN}✅ Anvil fork stopped${NC}"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo -e "${YELLOW}🚀 Deploying FlashLoanReceiverSecure...${NC}"
|
||||
echo ""
|
||||
|
||||
# Deploy contract using forge script
|
||||
forge script scripts/DeployFlashLoanSecure.s.sol:DeployFlashLoanSecure \
|
||||
--rpc-url http://localhost:8545 \
|
||||
--private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
|
||||
--broadcast \
|
||||
-vvv
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Deployment complete!${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}📝 Next steps:${NC}"
|
||||
echo " 1. Note the deployed contract address above"
|
||||
echo " 2. Test flash loan execution"
|
||||
echo " 3. Verify slippage protection works"
|
||||
echo " 4. Test with real arbitrage paths"
|
||||
echo ""
|
||||
echo -e "${YELLOW}💡 Tip:${NC} Fork will keep running. Press Ctrl+C to stop."
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
|
||||
# Keep script running
|
||||
wait $ANVIL_PID
|
||||
234
scripts/fix-rpc-config.sh
Executable file
234
scripts/fix-rpc-config.sh
Executable file
@@ -0,0 +1,234 @@
|
||||
#!/bin/bash
|
||||
###############################################################################
|
||||
# RPC Configuration Fix Script
|
||||
#
|
||||
# This script fixes the critical RPC rate limiting issue by ensuring
|
||||
# the bot uses the paid Chainstack endpoint instead of the public endpoint.
|
||||
#
|
||||
# Usage: ./scripts/fix-rpc-config.sh
|
||||
###############################################################################
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${BLUE} MEV Bot RPC Configuration Fix${NC}"
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
###############################################################################
|
||||
# Step 1: Check Current Configuration
|
||||
###############################################################################
|
||||
|
||||
echo -e "${YELLOW}[1/5] Checking current RPC configuration...${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if environment variables are set
|
||||
if [ -z "${ARBITRUM_RPC_ENDPOINT:-}" ]; then
|
||||
echo -e "${RED}✗ ARBITRUM_RPC_ENDPOINT not set${NC}"
|
||||
ENV_SET=false
|
||||
else
|
||||
echo -e "${GREEN}✓ ARBITRUM_RPC_ENDPOINT is set${NC}"
|
||||
echo " Current value: ${ARBITRUM_RPC_ENDPOINT}"
|
||||
ENV_SET=true
|
||||
fi
|
||||
|
||||
if [ -z "${ARBITRUM_WS_ENDPOINT:-}" ]; then
|
||||
echo -e "${RED}✗ ARBITRUM_WS_ENDPOINT not set${NC}"
|
||||
WS_SET=false
|
||||
else
|
||||
echo -e "${GREEN}✓ ARBITRUM_WS_ENDPOINT is set${NC}"
|
||||
echo " Current value: ${ARBITRUM_WS_ENDPOINT}"
|
||||
WS_SET=true
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
###############################################################################
|
||||
# Step 2: Detect Issue
|
||||
###############################################################################
|
||||
|
||||
echo -e "${YELLOW}[2/5] Detecting RPC issues...${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if using public endpoint
|
||||
if [[ "${ARBITRUM_RPC_ENDPOINT:-}" == *"arb1.arbitrum.io"* ]]; then
|
||||
echo -e "${RED}✗ CRITICAL: Using public RPC endpoint!${NC}"
|
||||
echo " This will cause rate limiting (429 errors)"
|
||||
USING_PUBLIC=true
|
||||
elif [[ "${ARBITRUM_RPC_ENDPOINT:-}" == *"chainstack.com"* ]]; then
|
||||
echo -e "${GREEN}✓ Using paid Chainstack endpoint${NC}"
|
||||
USING_PUBLIC=false
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Unknown RPC endpoint${NC}"
|
||||
USING_PUBLIC=unknown
|
||||
fi
|
||||
|
||||
# Check recent logs for 429 errors
|
||||
if [ -f "logs/mev_bot.log" ]; then
|
||||
RATE_LIMIT_COUNT=$(tail -1000 logs/mev_bot.log | grep -c "429 Too Many Requests" || echo "0")
|
||||
|
||||
if [ "$RATE_LIMIT_COUNT" -gt 10 ]; then
|
||||
echo -e "${RED}✗ High rate limiting detected: $RATE_LIMIT_COUNT errors in last 1000 lines${NC}"
|
||||
HAS_RATE_LIMIT=true
|
||||
elif [ "$RATE_LIMIT_COUNT" -gt 0 ]; then
|
||||
echo -e "${YELLOW}⚠ Some rate limiting detected: $RATE_LIMIT_COUNT errors${NC}"
|
||||
HAS_RATE_LIMIT=true
|
||||
else
|
||||
echo -e "${GREEN}✓ No rate limiting detected${NC}"
|
||||
HAS_RATE_LIMIT=false
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No log file found, cannot check for rate limiting${NC}"
|
||||
HAS_RATE_LIMIT=unknown
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
###############################################################################
|
||||
# Step 3: Load Correct Configuration
|
||||
###############################################################################
|
||||
|
||||
echo -e "${YELLOW}[3/5] Loading correct configuration...${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if .env.production exists
|
||||
if [ -f ".env.production" ]; then
|
||||
echo -e "${GREEN}✓ Found .env.production${NC}"
|
||||
|
||||
# Source it
|
||||
set -a
|
||||
source .env.production
|
||||
set +a
|
||||
|
||||
echo -e "${GREEN}✓ Loaded .env.production${NC}"
|
||||
|
||||
# Verify it has the right endpoint
|
||||
if [[ "${ARBITRUM_RPC_ENDPOINT:-}" == *"chainstack.com"* ]]; then
|
||||
echo -e "${GREEN}✓ Chainstack endpoint configured in .env.production${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ .env.production does not have Chainstack endpoint!${NC}"
|
||||
echo " Please edit .env.production and set:"
|
||||
echo " ARBITRUM_RPC_ENDPOINT=wss://arbitrum-mainnet.core.chainstack.com/YOUR_KEY"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ .env.production not found!${NC}"
|
||||
echo ""
|
||||
echo "Creating .env.production from template..."
|
||||
|
||||
# Create from .env.example
|
||||
if [ -f ".env.example" ]; then
|
||||
cp .env.example .env.production
|
||||
echo -e "${YELLOW}⚠ Created .env.production from .env.example${NC}"
|
||||
echo -e "${RED}✗ You must edit .env.production and set your Chainstack API key!${NC}"
|
||||
echo ""
|
||||
echo "Steps:"
|
||||
echo " 1. Edit .env.production"
|
||||
echo " 2. Replace YOUR_KEY_HERE with your actual Chainstack API key"
|
||||
echo " 3. Run this script again"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${RED}✗ .env.example not found either!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
###############################################################################
|
||||
# Step 4: Stop Bot if Running
|
||||
###############################################################################
|
||||
|
||||
echo -e "${YELLOW}[4/5] Stopping MEV bot if running...${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if bot is running
|
||||
BOT_PID=$(pgrep -f "mev-bot start" || echo "")
|
||||
|
||||
if [ -n "$BOT_PID" ]; then
|
||||
echo -e "${YELLOW}⚠ Found running bot process (PID: $BOT_PID)${NC}"
|
||||
echo "Stopping bot..."
|
||||
|
||||
kill -TERM "$BOT_PID" 2>/dev/null || true
|
||||
|
||||
# Wait up to 10 seconds for graceful shutdown
|
||||
for i in {1..10}; do
|
||||
if ! kill -0 "$BOT_PID" 2>/dev/null; then
|
||||
echo -e "${GREEN}✓ Bot stopped gracefully${NC}"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Force kill if still running
|
||||
if kill -0 "$BOT_PID" 2>/dev/null; then
|
||||
echo -e "${YELLOW}⚠ Force killing bot...${NC}"
|
||||
kill -9 "$BOT_PID" 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}✓ Bot is not running${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
###############################################################################
|
||||
# Step 5: Verify Configuration
|
||||
###############################################################################
|
||||
|
||||
echo -e "${YELLOW}[5/5] Verifying configuration...${NC}"
|
||||
echo ""
|
||||
|
||||
# Display final configuration
|
||||
echo "Configuration:"
|
||||
echo " ARBITRUM_RPC_ENDPOINT: ${ARBITRUM_RPC_ENDPOINT}"
|
||||
echo " ARBITRUM_WS_ENDPOINT: ${ARBITRUM_WS_ENDPOINT:-NOT_SET}"
|
||||
echo " PROVIDER_CONFIG_PATH: ${PROVIDER_CONFIG_PATH:-$PWD/config/providers_runtime.yaml}"
|
||||
echo ""
|
||||
|
||||
# Verify it's not the public endpoint
|
||||
if [[ "${ARBITRUM_RPC_ENDPOINT}" == *"arb1.arbitrum.io"* ]]; then
|
||||
echo -e "${RED}✗ STILL using public endpoint!${NC}"
|
||||
echo " Configuration fix failed"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}✓ Using paid endpoint${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
###############################################################################
|
||||
# Summary and Next Steps
|
||||
###############################################################################
|
||||
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN}✓ RPC Configuration Fix Complete${NC}"
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}Next Steps:${NC}"
|
||||
echo ""
|
||||
echo "1. Start the bot with correct configuration:"
|
||||
echo " ${GREEN}PROVIDER_CONFIG_PATH=\$PWD/config/providers_runtime.yaml ./bin/mev-bot start${NC}"
|
||||
echo ""
|
||||
echo "2. Monitor for rate limiting errors:"
|
||||
echo " ${GREEN}tail -f logs/mev_bot.log | grep \"429 Too Many Requests\"${NC}"
|
||||
echo " ${YELLOW}(Should show NO results if fix is working)${NC}"
|
||||
echo ""
|
||||
echo "3. Verify block processing:"
|
||||
echo " ${GREEN}tail -f logs/mev_bot.log | grep \"Processing block\"${NC}"
|
||||
echo " ${YELLOW}(Should show continuous block processing)${NC}"
|
||||
echo ""
|
||||
echo "4. Check connection status:"
|
||||
echo " ${GREEN}tail -f logs/mev_bot.log | grep -i \"connected\"${NC}"
|
||||
echo " ${YELLOW}(Should show successful connection to Chainstack)${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
@@ -1,3 +1,6 @@
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
201
scripts/test-docker.sh
Executable file
201
scripts/test-docker.sh
Executable file
@@ -0,0 +1,201 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker-based testing script for MEV Bot
|
||||
# Runs all tests in isolated Docker containers
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||
|
||||
# Create coverage directory
|
||||
mkdir -p coverage
|
||||
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo -e "${BLUE}MEV Bot Docker Test Suite${NC}"
|
||||
echo -e "${BLUE}================================${NC}"
|
||||
echo ""
|
||||
|
||||
# Parse command line arguments
|
||||
TEST_TYPE="${1:-all}"
|
||||
|
||||
run_unit_tests() {
|
||||
log_info "Running unit tests in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-unit
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Unit tests passed!"
|
||||
else
|
||||
log_error "Unit tests failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_integration_tests() {
|
||||
log_info "Running integration tests in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-integration
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Integration tests passed!"
|
||||
else
|
||||
log_error "Integration tests failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_race_tests() {
|
||||
log_info "Running race detector tests in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-race
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Race detector tests passed (0 race conditions)!"
|
||||
else
|
||||
log_error "Race detector tests failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_build_test() {
|
||||
log_info "Running build verification in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-build
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Build verification passed!"
|
||||
else
|
||||
log_error "Build verification failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_coverage_test() {
|
||||
log_info "Generating coverage report in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-coverage
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Coverage report generated!"
|
||||
if [ -f coverage/coverage.html ]; then
|
||||
log_info "Coverage report: coverage/coverage.html"
|
||||
fi
|
||||
else
|
||||
log_error "Coverage generation failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_security_scan() {
|
||||
log_info "Running security scan in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-security
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Security scan passed!"
|
||||
else
|
||||
log_warning "Security scan found issues (check coverage/gosec-report.json)"
|
||||
fi
|
||||
}
|
||||
|
||||
run_lint() {
|
||||
log_info "Running linters in Docker..."
|
||||
docker-compose -f docker-compose.test.yml run --rm test-lint
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Linting passed!"
|
||||
else
|
||||
log_warning "Linting found issues"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
log_info "Cleaning up Docker resources..."
|
||||
docker-compose -f docker-compose.test.yml down --volumes --remove-orphans
|
||||
log_success "Cleanup complete!"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
case "$TEST_TYPE" in
|
||||
unit)
|
||||
run_unit_tests
|
||||
;;
|
||||
integration)
|
||||
run_integration_tests
|
||||
;;
|
||||
race)
|
||||
run_race_tests
|
||||
;;
|
||||
build)
|
||||
run_build_test
|
||||
;;
|
||||
coverage)
|
||||
run_coverage_test
|
||||
;;
|
||||
security)
|
||||
run_security_scan
|
||||
;;
|
||||
lint)
|
||||
run_lint
|
||||
;;
|
||||
all)
|
||||
log_info "Running complete test suite..."
|
||||
echo ""
|
||||
|
||||
# Run in sequence
|
||||
run_build_test || exit 1
|
||||
echo ""
|
||||
|
||||
run_unit_tests || exit 1
|
||||
echo ""
|
||||
|
||||
run_race_tests || exit 1
|
||||
echo ""
|
||||
|
||||
run_integration_tests || exit 1
|
||||
echo ""
|
||||
|
||||
run_coverage_test || exit 1
|
||||
echo ""
|
||||
|
||||
run_lint
|
||||
echo ""
|
||||
|
||||
run_security_scan
|
||||
echo ""
|
||||
|
||||
log_success "All tests passed!"
|
||||
;;
|
||||
clean)
|
||||
cleanup
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown test type: $TEST_TYPE"
|
||||
echo ""
|
||||
echo "Usage: $0 [test-type]"
|
||||
echo ""
|
||||
echo "Test types:"
|
||||
echo " all - Run all tests (default)"
|
||||
echo " unit - Run unit tests only"
|
||||
echo " integration - Run integration tests only"
|
||||
echo " race - Run race detector tests only"
|
||||
echo " build - Run build verification only"
|
||||
echo " coverage - Generate coverage report"
|
||||
echo " security - Run security scan"
|
||||
echo " lint - Run linters"
|
||||
echo " clean - Clean up Docker resources"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Cleanup on success
|
||||
trap cleanup EXIT
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo -e "${GREEN}Test Suite Complete!${NC}"
|
||||
echo -e "${GREEN}================================${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Test Results:${NC}"
|
||||
echo -e " ${GREEN}✓${NC} All tests passed in isolated Docker environment"
|
||||
echo -e " ${GREEN}✓${NC} Code coverage report: coverage/coverage.html"
|
||||
echo -e " ${GREEN}✓${NC} Security report: coverage/gosec-report.json"
|
||||
echo ""
|
||||
71
scripts/verify-contracts.sh
Executable file
71
scripts/verify-contracts.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
# MEV Bot Contract Verification Script
|
||||
# Verifies deployed contracts on Arbiscan
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Check for Arbiscan API key
|
||||
if [ -z "$ARBISCAN_API_KEY" ]; then
|
||||
log_error "ARBISCAN_API_KEY environment variable is required"
|
||||
log_info "Get your API key from https://arbiscan.io/myapikey"
|
||||
log_info "Then run: export ARBISCAN_API_KEY=<your_key>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get contract address
|
||||
if [ -z "$1" ]; then
|
||||
log_error "Usage: $0 <contract_address> [contract_name]"
|
||||
log_info "Example: $0 0x1234... ProductionArbitrageExecutor"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONTRACT_ADDRESS="$1"
|
||||
CONTRACT_NAME="${2:-ProductionArbitrageExecutor}"
|
||||
|
||||
log_info "Verifying $CONTRACT_NAME at $CONTRACT_ADDRESS..."
|
||||
|
||||
# Determine contract path
|
||||
case "$CONTRACT_NAME" in
|
||||
"ProductionArbitrageExecutor")
|
||||
CONTRACT_PATH="contracts/ProductionArbitrageExecutor.sol:ProductionArbitrageExecutor"
|
||||
;;
|
||||
"FlashLoanReceiver")
|
||||
CONTRACT_PATH="contracts/balancer/FlashLoanReceiver.sol:FlashLoanReceiver"
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown contract name: $CONTRACT_NAME"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Verify contract
|
||||
log_info "Contract path: $CONTRACT_PATH"
|
||||
|
||||
forge verify-contract \
|
||||
--chain-id 42161 \
|
||||
--num-of-optimizations 200 \
|
||||
--watch \
|
||||
--compiler-version "v0.8.19+commit.7dd6d404" \
|
||||
--etherscan-api-key "$ARBISCAN_API_KEY" \
|
||||
"$CONTRACT_ADDRESS" \
|
||||
"$CONTRACT_PATH"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Contract verified successfully!"
|
||||
log_info "View at: https://arbiscan.io/address/$CONTRACT_ADDRESS#code"
|
||||
else
|
||||
log_error "Verification failed"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user