# Flash Loan Execution - Deployment & Integration Guide **Status:** Framework Complete, Contracts Ready for Deployment **Last Updated:** October 26, 2025 --- ## πŸ“‹ Overview This guide covers the deployment and integration of the MEV bot's flash loan execution system, which enables real arbitrage execution using flash loans from multiple providers. ### Architecture Summary ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MEV Bot Go Process β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Arbitrage │────────▢│ Flash Loan β”‚ β”‚ β”‚ β”‚ Detector β”‚ β”‚ Provider β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ RPC Call β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ FlashLoanReceiver Contract β”‚ β”‚ (Deployed on Arbitrum) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Balancer β”‚ β”‚ Uniswap V2 β”‚ β”‚ Uniswap V3 β”‚ β”‚ Vault β”‚ β”‚ Router β”‚ β”‚ Router β”‚ β”‚ (0% fee) β”‚ β”‚ (0.3% fee) β”‚ β”‚ (0.05%-1% fee) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## 🎯 Implementation Status ### βœ… Complete 1. **Solidity Smart Contract** - Location: `contracts/balancer/FlashLoanReceiver.sol` - Features: - Balancer flash loan integration - Uniswap V2/V3 swap execution - Profit calculation and validation - Owner-only access control - Emergency withdrawal 2. **Go Execution Framework** - Location: `pkg/execution/` - Files: - `executor.go` - Core execution engine (316 lines) - `flashloan_providers.go` - Provider implementations (360+ lines) - `alerts.go` - Alert system (291 lines) 3. **ABI Bindings** - Location: `bindings/balancer/vault.go` - Generated with abigen for Balancer Vault 4. **Calldata Encoding** - Function: `encodeArbitragePath()` in flashloan_providers.go - Encodes ArbitragePath struct for contract ### ⏳ Pending 1. **Smart Contract Deployment** - Deploy FlashLoanReceiver.sol to Arbitrum - Set receiver address in BalancerFlashLoanProvider - Fund contract with gas if needed 2. **Transaction Signing** - Implement private key management - Add transaction signer - Gas estimation logic 3. **ABI Encoding/Decoding** - Complete ABI encoding for ArbitragePath struct - Parse execution results from contract events 4. **Integration Testing** - Test on Arbitrum testnet - Fork testing with Tenderly/Hardhat - Mainnet dry-run testing --- ## πŸš€ Deployment Steps ### Prerequisites ```bash # Install dependencies npm install --save-dev hardhat @nomiclabs/hardhat-ethers ethers npm install @openzeppelin/contracts # Or use Foundry (recommended for production) curl -L https://foundry.paradigm.xyz | bash foundryup ``` ### Step 1: Compile Contract **Using Hardhat:** ```bash npx hardhat compile contracts/balancer/FlashLoanReceiver.sol ``` **Using Foundry:** ```bash forge build contracts/balancer/FlashLoanReceiver.sol ``` ### Step 2: Deploy to Arbitrum **Deployment Script (Hardhat):** ```javascript // scripts/deploy-flash-receiver.js const hre = require("hardhat"); async function main() { const BALANCER_VAULT = "0xBA12222222228d8Ba445958a75a0704d566BF2C8"; console.log("Deploying FlashLoanReceiver..."); const FlashLoanReceiver = await hre.ethers.getContractFactory("FlashLoanReceiver"); const receiver = await FlashLoanReceiver.deploy(BALANCER_VAULT); await receiver.deployed(); console.log("βœ… FlashLoanReceiver deployed to:", receiver.address); console.log(" Owner:", await receiver.owner()); console.log(" Vault:", await receiver.vault()); // Save deployment info const fs = require("fs"); fs.writeFileSync("deployment.json", JSON.stringify({ address: receiver.address, owner: await receiver.owner(), vault: BALANCER_VAULT, timestamp: new Date().toISOString() }, null, 2)); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); }); ``` **Deploy:** ```bash npx hardhat run scripts/deploy-flash-receiver.js --network arbitrum ``` **Using Foundry:** ```bash forge create contracts/balancer/FlashLoanReceiver.sol:FlashLoanReceiver \ --rpc-url $ARBITRUM_RPC \ --private-key $PRIVATE_KEY \ --constructor-args 0xBA12222222228d8Ba445958a75a0704d566BF2C8 \ --verify ``` ### Step 3: Configure MEV Bot After deployment, update the Go code with the deployed contract address: ```go // pkg/execution/flashloan_providers.go func NewBalancerFlashLoanProvider(client *ethclient.Client, logger *logger.Logger) *BalancerFlashLoanProvider { return &BalancerFlashLoanProvider{ client: client, logger: logger, vaultAddress: common.HexToAddress("0xBA12222222228d8Ba445958a75a0704d566BF2C8"), // UPDATE THIS with deployed contract address: receiverAddress: common.HexToAddress("0xYOUR_DEPLOYED_CONTRACT_ADDRESS"), } } ``` Or use environment variable: ```bash export FLASH_LOAN_RECEIVER="0xYOUR_DEPLOYED_CONTRACT_ADDRESS" ``` ### Step 4: Generate Contract Bindings Generate Go bindings for the deployed contract: ```bash # Get contract ABI cat contracts/balancer/FlashLoanReceiver.sol | \ solc --abi - > contracts/balancer/FlashLoanReceiver.abi # Generate Go bindings abigen --abi contracts/balancer/FlashLoanReceiver.abi \ --pkg execution \ --type FlashLoanReceiver \ --out pkg/execution/flashloan_receiver.go ``` --- ## πŸ”§ Integration Implementation ### Complete the TODO Items **1. Transaction Signing (`pkg/execution/transaction_signer.go` - NEW FILE)** ```go package execution import ( "context" "crypto/ecdsa" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" ) type TransactionSigner struct { privateKey *ecdsa.PrivateKey chainID *big.Int client *ethclient.Client } func NewTransactionSigner(privateKeyHex string, client *ethclient.Client) (*TransactionSigner, error) { privateKey, err := crypto.HexToECDSA(privateKeyHex) if err != nil { return nil, err } chainID, err := client.ChainID(context.Background()) if err != nil { return nil, err } return &TransactionSigner{ privateKey: privateKey, chainID: chainID, client: client, }, nil } func (ts *TransactionSigner) SignAndSend(ctx context.Context, tx *types.Transaction) (common.Hash, error) { signedTx, err := types.SignTx(tx, types.NewEIP155Signer(ts.chainID), ts.privateKey) if err != nil { return common.Hash{}, err } err = ts.client.SendTransaction(ctx, signedTx) if err != nil { return common.Hash{}, err } return signedTx.Hash(), nil } func (ts *TransactionSigner) GetTransactor() (*bind.TransactOpts, error) { auth, err := bind.NewKeyedTransactorWithChainID(ts.privateKey, ts.chainID) if err != nil { return nil, err } return auth, nil } ``` **2. Complete ABI Encoding** Update `encodeArbitragePath()` to use proper ABI encoding: ```go import ( "github.com/ethereum/go-ethereum/accounts/abi" "strings" ) func (b *BalancerFlashLoanProvider) encodeArbitragePath( opportunity *arbitrage.ArbitragePath, config *ExecutionConfig, ) ([]byte, error) { // Define ABI for ArbitragePath struct arbitragePathABI := `[{ "components": [ {"name": "tokens", "type": "address[]"}, {"name": "exchanges", "type": "address[]"}, {"name": "fees", "type": "uint24[]"}, {"name": "isV3", "type": "bool[]"}, {"name": "minProfit", "type": "uint256"} ], "name": "path", "type": "tuple" }]` contractABI, err := abi.JSON(strings.NewReader(arbitragePathABI)) if err != nil { return nil, err } // Prepare data (same as before) numHops := len(opportunity.TokenPath) - 1 exchanges := make([]common.Address, numHops) fees := make([]*big.Int, numHops) isV3 := make([]bool, numHops) // ... (populate arrays) ... // Encode using ABI encoded, err := contractABI.Pack("path", opportunity.TokenPath, exchanges, fees, isV3, minProfit, ) if err != nil { return nil, err } return encoded, nil } ``` **3. Complete ExecuteFlashLoan** ```go func (b *BalancerFlashLoanProvider) ExecuteFlashLoan( ctx context.Context, opportunity *arbitrage.ArbitragePath, config *ExecutionConfig, ) (*ExecutionResult, error) { startTime := time.Now() // ... (validation and encoding as before) ... // Create contract instance receiver, err := NewFlashLoanReceiver(b.receiverAddress, b.client) if err != nil { return nil, err } // Get transactor auth, err := config.Signer.GetTransactor() if err != nil { return nil, err } // Set gas price and limit auth.GasPrice = config.MaxGasPrice auth.GasLimit = 500000 // Estimate based on path length // Call executeArbitrage tx, err := receiver.ExecuteArbitrage(auth, tokens, amounts, userData) if err != nil { return &ExecutionResult{ OpportunityID: opportunity.ID, Success: false, Error: err, ExecutionTime: time.Since(startTime), }, err } // Wait for receipt receipt, err := bind.WaitMined(ctx, b.client, tx) if err != nil { return &ExecutionResult{ OpportunityID: opportunity.ID, Success: false, TxHash: tx.Hash(), Error: err, ExecutionTime: time.Since(startTime), }, err } // Parse events to get actual profit var actualProfit *big.Int for _, log := range receipt.Logs { event, err := receiver.ParseArbitrageExecuted(*log) if err == nil { actualProfit = event.Profit break } } return &ExecutionResult{ OpportunityID: opportunity.ID, Success: receipt.Status == 1, TxHash: tx.Hash(), GasUsed: receipt.GasUsed, ActualProfit: actualProfit, EstimatedProfit: opportunity.NetProfit, ExecutionTime: time.Since(startTime), Timestamp: time.Now(), }, nil } ``` --- ## βœ… Testing Strategy ### 1. Local Fork Testing ```bash # Start Hardhat node with Arbitrum fork npx hardhat node --fork https://arb1.arbitrum.io/rpc # Deploy contract to local fork npx hardhat run scripts/deploy-flash-receiver.js --network localhost # Run Go tests against local fork export ARBITRUM_RPC_ENDPOINT="http://localhost:8545" export FLASH_LOAN_RECEIVER="0x..." go test ./pkg/execution/... -v ``` ### 2. Arbitrum Testnet ```bash # Deploy to Arbitrum Sepolia testnet npx hardhat run scripts/deploy-flash-receiver.js --network arbitrum-sepolia # Test with testnet RPC export ARBITRUM_RPC_ENDPOINT="https://sepolia-rollup.arbitrum.io/rpc" ./mev-bot start --dry-run ``` ### 3. Mainnet Dry-Run ```bash # Test on mainnet without executing export EXECUTION_MODE="simulation" ./mev-bot start ``` --- ## πŸ“Š Gas Optimization ### Estimated Gas Costs | Operation | Gas Estimate | Cost (@ 0.1 gwei) | |-----------|-------------|-------------------| | Contract deployment | 1,500,000 | 0.00015 ETH | | 2-hop arbitrage | 300,000 | 0.00003 ETH | | 3-hop arbitrage | 450,000 | 0.000045 ETH | | 4-hop arbitrage | 600,000 | 0.00006 ETH | ### Optimization Tips 1. **Batch token approvals** - Approve max once instead of per transaction 2. **Use V3 single-hop when possible** - Lower gas than multi-contract calls 3. **Optimize path length** - 2-hop paths preferred 4. **Monitor gas prices** - Only execute when gas < threshold --- ## πŸ” Security Considerations ### Smart Contract Security 1. **Access Control** - Only owner can call `executeArbitrage()` - Only Balancer Vault can call `receiveFlashLoan()` 2. **Profit Validation** - Minimum profit threshold enforced on-chain - Prevents unprofitable execution 3. **Emergency Functions** - `emergencyWithdraw()` for stuck funds - `withdrawProfit()` for profit extraction ### Operational Security 1. **Private Key Management** ```bash # NEVER commit private keys to git # Use environment variables or secret managers export EXECUTOR_PRIVATE_KEY="0x..." # Or use hardware wallets (Ledger/Trezor) # Or use AWS KMS / Google Cloud KMS ``` 2. **Gas Price Limits** ```go config := &ExecutionConfig{ MaxGasPrice: big.NewInt(1000000000), // 1 gwei max // ... } ``` 3. **Slippage Protection** - Set `MaxSlippage` appropriately - Default 5% is reasonable for volatile markets --- ## πŸ“ˆ Monitoring & Alerts ### Integration with Alert System ```go // In main.go or orchestrator alertSystem := execution.NewAlertSystem(&execution.AlertConfig{ EnableConsoleAlerts: true, EnableWebhook: true, WebhookURL: os.Getenv("SLACK_WEBHOOK"), MinProfitForAlert: big.NewInt(1e16), // 0.01 ETH MinROIForAlert: 0.05, // 5% }, logger) // Send execution alerts result, err := executor.ExecuteOpportunity(ctx, opportunity) if err == nil { alertSystem.SendExecutionAlert(result) } ``` ### Dashboard Metrics Add to `monitoring/dashboard.sh`: ```bash # Execution metrics EXECUTIONS=$(grep -c "Arbitrage executed successfully" "${LATEST_LOG}") EXECUTION_PROFIT=$(grep "profit=" "${LATEST_LOG}" | awk '{sum+=$NF} END {print sum}') echo " Executions: ${EXECUTIONS}" echo " Total Profit: ${EXECUTION_PROFIT} ETH" ``` --- ## 🎯 Next Steps 1. **Deploy FlashLoanReceiver contract** to Arbitrum 2. **Implement transaction signing** in Go 3. **Complete ABI encoding** for ArbitragePath 4. **Test on Arbitrum testnet** 5. **Conduct security audit** of smart contract 6. **Monitor 24-hour test results** before enabling execution 7. **Start with small amounts** (0.01-0.1 ETH) 8. **Scale gradually** as confidence builds --- ## πŸ“š Reference - **Balancer Vault:** 0xBA12222222228d8Ba445958a75a0704d566BF2C8 - **Flash Loan Docs:** https://docs.balancer.fi/reference/contracts/flash-loans.html - **Arbitrum RPC:** https://docs.arbitrum.io/build-decentralized-apps/reference/node-providers - **Go-Ethereum Docs:** https://geth.ethereum.org/docs --- *Last Updated: October 26, 2025* *Status: Ready for Deployment*