Skip to main content

Universal DEX Integration

Integrate Reflex MEV capture into any DEX and client applications using the TypeScript SDK and BackrunEnabledSwapProxy contract.

Overview​

The Universal DEX integration method enables MEV capture for:

  • Legacy DEXes that don't support hooks/plugins
  • Frontend applications and DApp interfaces
  • Any DEX router without requiring code changes

This approach uses a proxy contract to wrap existing DEX routers, combined with a TypeScript SDK for easy client-side integration.

Architecture​

Components​

1. BackrunEnabledSwapProxy Contract​

A smart contract that wraps any existing DEX router and adds MEV capture functionality.

Key Features:

  • Works with any DEX router (Uniswap, SushiSwap, PancakeSwap, etc.)
  • Atomic swap + backrun execution
  • Automatic token approval management
  • Returns leftover tokens and ETH to users
  • Reentrancy protected

Deployment: One proxy contract per target DEX router you want to support.

2. Reflex SDK with UniversalIntegration​

A client-side library that simplifies interaction with the SwapProxy and Reflex contracts.

Key Features:

  • Type-safe interfaces matching contract exactly
  • Automatic token approval helpers
  • Gas estimation
  • Multi-chain support
  • Built on ethers.js v6

Quick Start​

Step 1: Deploy SwapProxy (One-time Setup)​

Deploy a BackrunEnabledSwapProxy contract for your target DEX router:

// Deploy via Foundry script or directly
import {BackrunEnabledSwapProxy} from "@reflex/contracts/integrations/router/BackrunEnabledSwapProxy.sol";

// Constructor takes the target DEX router address
BackrunEnabledSwapProxy proxy = new BackrunEnabledSwapProxy(
0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D // Uniswap V2 Router
);

Or use the provided deployment script:

# Set environment variables
export TARGET_ROUTER_ADDRESS=0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D

# Deploy
forge script script/deploy-swap-proxy/DeployBackrunEnabledSwapProxy.s.sol \
--rpc-url <YOUR_RPC_URL> \
--private-key <YOUR_PRIVATE_KEY> \
--broadcast

Step 2: Install SDK​

npm install @reflex-mev/sdk ethers
# or
yarn add @reflex-mev/sdk ethers

Step 3: Initialize UniversalIntegration​

import { UniversalIntegration } from "@reflex-mev/sdk/integrations";
import { ethers } from "ethers";

// Initialize provider and signer
const provider = new ethers.JsonRpcProvider(
"https://mainnet.infura.io/v3/YOUR_KEY"
);
const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);

// Create UniversalIntegration instance
const integration = new UniversalIntegration(
provider,
signer,
"0xYourSwapProxyAddress", // SwapProxy contract address
"0xYourReflexRouterAddress" // Reflex Router address
);

Using the Universal Integration API​

Basic Swap with MEV Capture​

import { UniversalIntegration } from "@reflex-mev/sdk/integrations";
import { ethers } from "ethers";

// Initialize integration
const integration = new UniversalIntegration(
provider,
signer,
swapProxyAddress,
reflexRouterAddress
);

// Encode swap calldata for target DEX router
// Example: Uniswap V2 swapExactTokensForTokens
const targetDexInterface = new ethers.Interface([
"function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] path, address to, uint deadline)",
]);

const swapCalldata = targetDexInterface.encodeFunctionData(
"swapExactTokensForTokens",
[
ethers.parseEther("1.0"), // amountIn
ethers.parseEther("0.95"), // amountOutMin (with slippage)
[tokenInAddress, tokenOutAddress], // path
userAddress, // to
Math.floor(Date.now() / 1000) + 60 * 20, // deadline (20 min)
]
);

// Prepare swap metadata
const swapMetadata = {
swapTxCallData: swapCalldata,
tokenIn: tokenInAddress,
amountIn: ethers.parseEther("1.0"),
tokenOut: tokenOutAddress,
recipient: userAddress,
};

// Prepare backrun parameters
const backrunParams = [
{
triggerPoolId: poolAddress, // Pool being traded on
swapAmountIn: ethers.parseEther("1.0"), // Full swap amount
token0In: true, // Swap direction
recipient: userAddress,
configId: ethers.ZeroHash, // Use default config
},
];

// Approve tokens to SwapProxy first
await integration.approveTokens([
{
tokenAddress: tokenInAddress,
amount: ethers.parseEther("1.0"),
},
]);

// Execute swap with automatic MEV capture
const result = await integration.swapWithBackrun(
swapMetadata,
backrunParams,
{ gasLimit: 1500000n } // Optional: ethers Overrides
);

console.log("Transaction:", result.transactionHash);
console.log("Gas used:", result.gasUsed.toString());
console.log("Profits:", result.profits);
console.log("Profit tokens:", result.profitTokens);

SwapProxy Deployment Guide​

Deploying for Your DEX​

Deploy a SwapProxy for each DEX router you want to support:

# Clone the Reflex repository
git clone --recursive https://github.com/reflex-mev/reflex.git
cd reflex/core

# Set environment variables
export TARGET_ROUTER_ADDRESS=0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D # Uniswap V2 Router

# Deploy using Forge
forge script script/deploy-swap-proxy/DeployBackrunEnabledSwapProxy.s.sol \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast \
--verify

Configuration and Optimization​

Gas Management​

// Use ethers Overrides for transaction options
const result = await integration.swapWithBackrun(swapMetadata, backrunParams, {
gasLimit: 1500000n, // Recommended for MEV operations
maxFeePerGas: ethers.parseUnits("100", "gwei"),
maxPriorityFeePerGas: ethers.parseUnits("2", "gwei"),
});

Event Monitoring​

Monitor MEV capture events from the Reflex Router:

// Event monitoring through provider
import { Interface } from "ethers";
import { REFLEX_ROUTER_ABI } from "@reflex-mev/sdk";

const routerInterface = new Interface(REFLEX_ROUTER_ABI);

// Listen for BackrunExecuted events
provider.on(
{
address: reflexRouterAddress,
topics: [routerInterface.getEvent("BackrunExecuted").topicHash],
},
(log) => {
const event = routerInterface.parseLog(log);

console.log("MEV Captured!", {
profit: ethers.formatEther(event.args.profit),
profitToken: event.args.profitToken,
triggerPoolId: event.args.triggerPoolId,
recipient: event.args.recipient,
});

// Update UI or analytics
analytics.track("MEV_Captured", {
profit: event.args.profit,
timestamp: Date.now(),
});
}
);