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>
8.5 KiB
MEV Bot Contract Binding Consistency Guide
Overview
This document provides a comprehensive guide to ensuring contract binding consistency between the Mev-Alpha Solidity contracts and the mev-beta Go implementation.
Current Status
Findings
-
Existing Bindings: The
/home/administrator/projects/mev-beta/bindingsdirectory contains Go bindings for contracts, but they may not be up-to-date with the latest Solidity contracts in Mev-Alpha. -
Mixed Approach: The codebase currently uses a combination of:
- Generated bindings (
bindings/contracts/*.go) - Manual ABI packing (
pkg/uniswap/contracts.go,pkg/arbitrum/abi_decoder.go) - Function selector computation (
pkg/common/selectors/selectors.go)
- Generated bindings (
-
Inconsistency Risk: Using manual ABI calls alongside bindings creates potential for:
- Function signature mismatches
- Type conversion errors
- Missed contract updates
- Maintenance overhead
Recommended Approach
Phase 1: Generate Fresh Bindings
Script Created: /home/administrator/projects/mev-beta/scripts/generate-bindings.sh
This script will:
- Compile all Mev-Alpha Solidity contracts using Foundry
- Extract ABI from compiled JSON artifacts
- Generate Go bindings using
abigen - Organize bindings by contract type:
bindings/contracts/- Core contracts (ArbitrageExecutor, BaseFlashSwapper)bindings/interfaces/- Interfaces (IArbitrage, IFlashSwapper)bindings/dex/- DEX-specific contracts (UniswapV2/V3FlashSwapper)bindings/utils/- Math and utility librariesbindings/tokens/- Token interfaces
To Run:
cd /home/administrator/projects/mev-beta
./scripts/generate-bindings.sh
Note: Compilation of Mev-Alpha contracts may take several minutes due to the large dependency tree (108 files).
Phase 2: Refactor Contract Interactions
Current Anti-Patterns
❌ Manual ABI Packing (pkg/uniswap/contracts.go:156-160):
// DON'T DO THIS
data, err := p.abi.Pack("slot0")
if err != nil {
return nil, fmt.Errorf("failed to pack slot0 call: %w", err)
}
✅ Use Generated Bindings:
// DO THIS
import "github.com/yourusername/mev-beta/bindings/tokens"
pool, err := tokens.NewIUniswapV3PoolActions(poolAddress, client)
if err != nil {
return nil, fmt.Errorf("failed to create pool binding: %w", err)
}
slot0, err := pool.Slot0(&bind.CallOpts{})
if err != nil {
return nil, fmt.Errorf("failed to call slot0: %w", err)
}
Files Requiring Updates
-
pkg/uniswap/contracts.go(lines 155-332)- Replace manual
abi.Pack()calls with binding methods - Use typed struct returns instead of
UnpackIntoInterface
- Replace manual
-
pkg/arbitrum/abi_decoder.go(entire file)- Consider using binding-generated events for parsing
- Keep for multi-protocol ABI decoding where bindings don't exist
-
pkg/common/selectors/selectors.go(entire file)- KEEP THIS FILE - selectors are useful for quick function ID checks
- But prefer bindings for actual contract calls
-
Other files using
crypto.Keccak256for selectors:/home/administrator/projects/mev-beta/pkg/events/parser.go/home/administrator/projects/mev-beta/pkg/monitor/concurrent.go/home/administrator/projects/mev-beta/pkg/calldata/swaps.go
Phase 3: Binding Usage Patterns
Pattern 1: Contract Instantiation
import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/yourusername/mev-beta/bindings/contracts"
)
// Create contract instance
arbitrageExecutor, err := contracts.NewArbitrageExecutor(
common.HexToAddress("0x..."),
client,
)
if err != nil {
return err
}
Pattern 2: Reading Contract State
// Use binding methods for view functions
isAuthorized, err := arbitrageExecutor.AuthorizedCallers(
&bind.CallOpts{},
userAddress,
)
if err != nil {
return err
}
Pattern 3: Writing Transactions
// Prepare transaction options
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID)
if err != nil {
return err
}
// Build arbitrage params using generated struct
params := contracts.IArbitrageArbitrageParams{
Tokens: []common.Address{token0, token1, token2},
Pools: []common.Address{pool1, pool2},
Amounts: []*big.Int{amount1, amount2},
SwapData: [][]byte{data1, data2},
MinProfit: minProfit,
}
// Execute transaction
tx, err := arbitrageExecutor.ExecuteArbitrage(auth, params)
if err != nil {
return err
}
Pattern 4: Event Parsing
// Filter logs
logs, err := client.FilterLogs(ctx, ethereum.FilterQuery{
FromBlock: startBlock,
ToBlock: endBlock,
Addresses: []common.Address{contractAddress},
})
// Parse events using bindings
for _, log := range logs {
event, err := arbitrageExecutor.ParseArbitrageExecuted(log)
if err != nil {
continue
}
// Use typed fields
fmt.Printf("Arbitrage executed by %s with profit %s\n",
event.Initiator.Hex(),
event.Profit.String(),
)
}
Phase 4: Contract Address Management
Created: bindings/addresses.go
This file centralizes all deployed contract addresses:
package bindings
import "github.com/ethereum/go-ethereum/common"
var (
// Core contracts (update after deployment)
ArbitrageExecutorAddress = common.HexToAddress("0x...")
UniswapV3FlashSwapperAddress = common.HexToAddress("0x...")
// Known DEX addresses on Arbitrum
UniswapV3Factory = common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984")
SushiswapRouter = common.HexToAddress("0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506")
// ...
}
Usage:
import "github.com/yourusername/mev-beta/bindings"
executor, err := contracts.NewArbitrageExecutor(
bindings.ArbitrageExecutorAddress,
client,
)
Benefits of Binding Consistency
- Type Safety: Compile-time checking of function signatures and parameters
- Reduced Errors: No manual ABI encoding/decoding mistakes
- Easier Maintenance: Contract updates automatically propagate via re-generation
- Better IDE Support: Auto-completion and type hints
- Cleaner Code: More readable and self-documenting
Migration Checklist
- Audit existing contract interaction patterns
- Create binding generation script
- Compile Mev-Alpha Solidity contracts
- Generate fresh Go bindings
- Update
pkg/uniswap/contracts.goto use bindings - Update
pkg/arbitrum/abi_decoder.gowhere applicable - Update contract address constants
- Test all contract interactions
- Run integration tests
- Update documentation
Testing Strategy
Unit Tests
For each refactored file, ensure:
- All contract calls use bindings
- Error handling is preserved
- Return types are correctly converted
Integration Tests
Test against:
- Arbitrum testnet (Sepolia)
- Local Anvil fork
- Mainnet fork (read-only)
Validation Script
# Check for manual ABI packing (should be minimal)
grep -r "abi.Pack" pkg/ --exclude-dir=test
# Check for manual Keccak256 selector computation (review each)
grep -r "crypto.Keccak256" pkg/ --exclude-dir=test
# Ensure bindings compile
go build ./bindings/...
# Run tests
go test ./pkg/... -v
Troubleshooting
Issue: abigen fails with "no type MyStruct"
Solution: Ensure structs are defined in interfaces or export them from contracts.
Issue: Binding import conflicts
Solution: Use package aliases:
import (
contractsArbitrage "github.com/yourusername/mev-beta/bindings/contracts"
interfacesArbitrage "github.com/yourusername/mev-beta/bindings/interfaces"
)
Issue: Contract ABI changed but bindings not updated
Solution: Re-run generation script:
./scripts/generate-bindings.sh
go mod tidy
Best Practices
- Always regenerate bindings after contract changes
- Use semantic versioning for contract deployments
- Keep function selectors file for reference, but prefer bindings
- Document which contracts are deployed vs. mocks
- Use typed structs from bindings, not map[string]interface{}
References
Last Updated: 2025-10-26 Status: In Progress - Awaiting contract compilation