Files
mev-beta/docs/FLASH_LOAN_DEPLOYMENT_GUIDE.md
Krypto Kajun 432bcf0819 docs: add flash loan, binding, and testing documentation
Additional documentation and testing infrastructure:

## Documentation Added
- PROFIT_ROADMAP.md - 4-week profitability roadmap
- PRODUCTION_DEPLOYMENT.md - Production deployment guide
- docs/FLASH_LOAN_DEPLOYMENT_GUIDE.md - Flash loan implementation
- docs/FLASH_LOAN_IMPLEMENTATION_SUMMARY.md - Flash loan summary
- docs/BINDING_CONSISTENCY_GUIDE.md - Contract binding guidelines
- docs/BINDING_QUICK_START.md - Quick start for bindings
- docs/COMPLETE_FORK_TESTING_GUIDE.md - Fork testing guide

## Testing Scripts Added
- scripts/generate-test-report.sh - Generate test reports
- scripts/monitor-24h-test.sh - 24-hour monitoring
- scripts/start-24h-test.sh - Start long-running tests
- scripts/stop-24h-test.sh - Stop test runs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 05:51:44 -05:00

574 lines
15 KiB
Markdown

# 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*