# Contract Bindings This directory contains Go bindings generated from DEX contract ABIs using `abigen`. ## Generated Bindings ### UniswapV2 - **Router** (`uniswap_v2/router.go`): UniswapV2Router02 interface - `SwapExactTokensForTokens()` - `SwapTokensForExactTokens()` - `SwapExactETHForTokens()` - `SwapETHForExactTokens()` - `SwapExactTokensForETH()` - `SwapTokensForExactETH()` - **Pair** (`uniswap_v2/pair.go`): UniswapV2Pair interface - `Swap()` - Direct pool swap function - `GetReserves()` - Get pool reserves - `Token0()`, `Token1()` - Get token addresses - Swap event for parsing logs ### UniswapV3 - **Router** (`uniswap_v3/router.go`): SwapRouter interface - `ExactInputSingle()` - Single-hop exact input swap - `ExactInput()` - Multi-hop exact input swap - `ExactOutputSingle()` - Single-hop exact output swap - `ExactOutput()` - Multi-hop exact output swap ## Usage ### Detecting Swaps Using ABIs Instead of hardcoding function selectors, use the generated bindings to parse transaction data: ```go import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/your-org/mev-bot/bindings/uniswap_v2" ) // Parse UniswapV2 router ABI routerABI, err := abi.JSON(strings.NewReader(uniswap_v2.UniswapV2RouterABI)) if err != nil { log.Fatal(err) } // Detect swap function from calldata method, err := routerABI.MethodById(txData[:4]) if err != nil { // Not a known method return } // Check if it's a swap function isSwap := strings.Contains(method.Name, "swap") || strings.Contains(method.Name, "Swap") // Decode swap parameters if isSwap { params, err := method.Inputs.Unpack(txData[4:]) if err != nil { return err } // Access typed parameters // For swapExactTokensForTokens: amountIn, amountOutMin, path, to, deadline amountIn := params[0].(*big.Int) path := params[2].([]common.Address) // ... etc } ``` ### Parsing Swap Events ```go import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/your-org/mev-bot/bindings/uniswap_v2" ) // Parse swap event from logs pairABI, _ := abi.JSON(strings.NewReader(uniswap_v2.UniswapV2PairABI)) for _, log := range receipt.Logs { event, err := pairABI.EventByID(log.Topics[0]) if err != nil { continue } if event.Name == "Swap" { // Decode swap event var swapEvent struct { Sender common.Address Amount0In *big.Int Amount1In *big.Int Amount0Out *big.Int Amount1Out *big.Int To common.Address } err = pairABI.UnpackIntoInterface(&swapEvent, "Swap", log.Data) if err == nil { // Process swap event fmt.Printf("Swap: %s -> %s\n", swapEvent.Amount0In, swapEvent.Amount1Out) } } } ``` ## Adding New Bindings ### 1. Create ABI File Save the contract ABI in JSON format to the appropriate subdirectory: ```bash mkdir -p bindings/camelot # Create bindings/camelot/ICamelotRouter.json ``` ### 2. Generate Binding Run `abigen` to generate Go code: ```bash podman exec mev-go-dev sh -c "cd /workspace && \ /go/bin/abigen \ --abi=bindings/camelot/ICamelotRouter.json \ --pkg=camelot \ --type=CamelotRouter \ --out=bindings/camelot/router.go" ``` ### 3. Import in Your Code ```go import "github.com/your-org/mev-bot/bindings/camelot" // Use the generated ABI routerABI, _ := abi.JSON(strings.NewReader(camelot.CamelotRouterABI)) ``` ## ABI Sources Contract ABIs can be obtained from: 1. **Etherscan/Arbiscan**: Verified contract → Contract → Code → Contract ABI 2. **GitHub Repositories**: Official DEX repositories 3. **npm Packages**: `@uniswap/v2-periphery`, `@uniswap/v3-periphery`, etc. ## Regenerating All Bindings To regenerate all bindings after updating ABIs: ```bash ./scripts/generate-bindings.sh ``` Or manually: ```bash podman exec mev-go-dev sh -c "cd /workspace && \ /go/bin/abigen --abi=bindings/uniswap_v2/IUniswapV2Router02.json \ --pkg=uniswap_v2 \ --type=UniswapV2Router \ --out=bindings/uniswap_v2/router.go && \ /go/bin/abigen --abi=bindings/uniswap_v2/IUniswapV2Pair.json \ --pkg=uniswap_v2 \ --type=UniswapV2Pair \ --out=bindings/uniswap_v2/pair.go && \ /go/bin/abigen --abi=bindings/uniswap_v3/ISwapRouter.json \ --pkg=uniswap_v3 \ --type=SwapRouter \ --out=bindings/uniswap_v3/router.go" ``` ## Benefits of Using Bindings 1. **Type Safety**: Compile-time verification of parameters 2. **No Hardcoded Selectors**: Function signatures derived from ABIs 3. **Automatic Encoding/Decoding**: Built-in parameter packing/unpacking 4. **Event Parsing**: Type-safe event decoding 5. **Maintainability**: Single source of truth (ABI files) ## Next Steps To fully integrate ABI-based swap detection: 1. Replace hardcoded selectors in `pkg/sequencer/decoder.go` with ABI lookups 2. Use `MethodById()` to identify swap functions dynamically 3. Parse swap parameters using typed binding structs 4. Add bindings for Balancer, Curve, Kyber, Camelot 5. Implement event-based swap detection for pools