Address Contract Verified
Address
0xFC0693De26B7DD2B07b7566725141c93c817d993
Balance
0 ETH
Nonce
1
Code Size
5336 bytes
Creator
0x11a5C6FC...B917 at tx 0x13a20f42...0510b7
Indexed Transactions
0
Contract Bytecode
5336 bytes
0x6080604052600436101561001a575b3615610018575f80fd5b005b5f803560e01c806327de545b146109475780634e69d560146109005780636ff1c9bc1461075a5763ec301ebc14610051575061000e565b34610757578060031936011261075757610095337f00000000000000000000000011a5c6fc45cf379b21eee3a4cc472cef7357b9176001600160a01b031614611279565b6100a36002825414156112b4565b6002815560ff60075416156107205760085480156106e7576040519060c0820182811067ffffffffffffffff8211176106d35760405260018060a01b0360015416825260018060a01b0360025416602083015260035460408301526004546060830152600554608083015260065460a0830152604051906370a0823160e01b825230600483015260208260248173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25afa91821561054157849261069e575b50602083810151845160405163a9059cbb60e01b81526001600160a01b0391821660048201526024810194909452839160449183918991165af190811561054157849161066f575b5015610632578151604051630240bc6b60e21b81526001600160a01b0390911690606081600481855afa91821561062757859186936105ea575b50602060049160405192838092630dfe168160e01b82525afa80156105df576001600160701b039187916105b0575b5060208601516001600160a01b039182169116149283156105a757818316925b841561059f5750165b600854906103e59182810292818404149015171561058b5761025190826113e3565b916103e89081810291818304149015171561058b5761027a92916102749161140a565b90611417565b9060808401516127108181031161057757906102a861271061029f88948203866113e3565b04841015611442565b84516001600160a01b03169281156105705782915b1561056857905b833b156105645760405163022c0d9f60e01b815260048101919091526024810191909152306044820152608060648201525f6084820152918190839060a490829084905af1918261054c575b5050610399575060018060a01b0381511690602060018060a01b0391015116905f805160206114838339815191526060604051602081526013602082015272109858dadc9d5b881cddd85c0819985a5b1959606a1b6040820152a35b60ff1960075416600755806008558060015580600255806003558060045580600555806006556001815580f35b6040516370a0823160e01b81523060048201529060208260248173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25afa8015610541578490610509575b6103e19250611435565b60408201518111156104b95760408201516103fb91611435565b9061271061041260408301516060840151906113e3565b04821061045e5780516020918201516040519384526001600160a01b03908116939116917f51043ace84787ec4ad32026c97b48fb61d4678005346aedc2497f911ae81f6c591a361036c565b8051602091820151604080518481526014948101949094527310995b1bddc81b5a5b9a5b5d5b481c1c9bd99a5d60621b908401526001600160a01b03908116935016905f8051602061148383398151915290606090a361036c565b5060018060a01b0381511690602060018060a01b0391015116905f805160206114838339815191526060604051602081526009602082015268139bc81c1c9bd99a5d60ba1b6040820152a361036c565b506020823d602011610539575b8161052360209383611340565b81010312610535576103e191516103d7565b5f80fd5b3d9150610516565b6040513d86823e3d90fd5b6105559061132c565b61056057835f610310565b8380fd5b8280fd5b5081906102c4565b80916102bd565b634e487b7160e01b86526011600452602486fd5b634e487b7160e01b87526011600452602487fd5b90501661022f565b81811692610226565b6105d2915060203d6020116105d8575b6105ca8183611340565b810190611362565b5f610206565b503d6105c0565b6040513d88823e3d90fd5b6004919350602092506106149060603d606011610620575b61060c8183611340565b8101906113ad565b509290929391506101d7565b503d610602565b6040513d87823e3d90fd5b60405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b6044820152606490fd5b610691915060203d602011610697575b6106898183611340565b810190611381565b5f61019d565b503d61067f565b9091506020813d6020116106cb575b816106ba60209383611340565b810103126105355751906020610155565b3d91506106ad565b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b8152602060048201526011602482015270139bc81d1bdad95b9cc81d1bc81cd95b1b607a1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e09cdee840d2dc40e6c2dcc8eed2c6d608b1b6044820152606490fd5b80fd5b503461075757806020806003193601126108fd576001600160a01b0390600435828116908190036108f8577f00000000000000000000000011a5c6fc45cf379b21eee3a4cc472cef7357b917928316926107b5843314611279565b816107e9575050508180809247908282156107e0575bf1156107d45780f35b604051903d90823e3d90fd5b506108fc6107cb565b6040516370a0823160e01b81523060048201529294509092508382602481865afa90811561062757849286926108c5575b5060405163a9059cbb60e01b81526001600160a01b0390911660048201526024810191909152918290818681604481015b03925af19081156108ba57839161089d575b5015610867575080f35b6064906040519062461bcd60e51b82526004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152fd5b6108b49150823d8411610697576106898183611340565b5f61085d565b6040513d85823e3d90fd5b8381949293503d83116108f1575b6108dd8183611340565b81010312610535579051839161084b61081a565b503d6108d3565b505050fd5b50fd5b5034610757578060031936011261075757608060ff6007541660018060a01b0380600154169060025416600854916040519315158452602084015260408301526060820152f35b50346107575760c03660031901126107575761098d337f00000000000000000000000011a5c6fc45cf379b21eee3a4cc472cef7357b9176001600160a01b031614611279565b61099b6002825414156112b4565b600281556001600160a01b036109af611300565b16156112455760075460ff811661120a57604435156111c5576064351561118b57612710608435101561114f5760a4354211611114576040516370a0823160e01b815230600482015260208160248173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25afa9081156108ba5783916110e2575b506044351161109d576001600160a01b03610a3c611300565b16604051630dfe168160e01b8152602081600481855afa90811561054157849161107e575b506001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28103610ff1575060206004916040519283809263d21220a760e01b82525afa9081156108ba578391610fd2575b506001600160a01b03610abe611316565b6001600160a01b039092169116145b15610f97576001906001600160a01b03610ae5611300565b166bffffffffffffffffffffffff60a01b9081845416178355828060a01b03610b0c611316565b1690600254161760025560443560035560643560045560843560055560a43560065560ff191617600755610b756020610b43611300565b60405163a9059cbb60e01b81526001600160a01b03909116600482015260448035602483015290928391829190820190565b03818573c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25af1908115610f8c578291610f6d575b5015610f3157610bab611300565b610bb3611316565b604051630240bc6b60e21b8152916001600160a01b031690606083600481855afa9182156105415784938593610f03575b5090602060049260405193848092630dfe168160e01b82525afa908115610627576001600160701b03928692610ee2575b506001600160a01b03918216911614928315610ed957818316925b8415610ed15750165b6103e590816044350291604435830403610ebd57610c5790826113e3565b916103e890818102918183041490151715610ebd57610c7a92916102749161140a565b90608435612710036127108111610ea957612710610c9b610ca492856113e3565b04831015611442565b8115610e6e57826001600160a01b03610cbb611300565b16918015610e675783905b15610e605781925b803b156105645760405163022c0d9f60e01b815260048101929092526024820193909352306044820152608060648201525f608482015291829060a490829084905af19081610e4d575b50610d8f575060ff1960075416600755610d30611300565b610d38611316565b5f80516020611483833981519152606060405192602084526014602085015273119c9bdb9d1c9d5b881cddd85c0819985a5b195960621b604085015260018060a01b03169360018060a01b031692a35b6001815580f35b602460206001600160a01b03610da3611316565b16604051928380926370a0823160e01b82523060048301525afa9081156108ba578391610e1b575b50806008551015610d885760405162461bcd60e51b815260206004820152601c60248201527f496e73756666696369656e7420746f6b656e73207265636569766564000000006044820152606490fd5b90506020813d602011610e45575b81610e3660209383611340565b8101031261053557515f610dcb565b3d9150610e29565b610e599093919361132c565b915f610d18565b8392610cce565b8190610cc6565b60405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081cddd85c081bdd5d1c1d5d606a1b6044820152606490fd5b634e487b7160e01b84526011600452602484fd5b634e487b7160e01b85526011600452602485fd5b905016610c39565b81811692610c30565b610efc91925060203d6020116105d8576105ca8183611340565b905f610c15565b60209450600492919350610f249060603d81116106205761060c8183611340565b5094909493919250610be4565b60405162461bcd60e51b815260206004820152601460248201527315d15512081d1c985b9cd9995c8819985a5b195960621b6044820152606490fd5b610f86915060203d602011610697576106898183611340565b5f610b9d565b6040513d84823e3d90fd5b60405162461bcd60e51b8152602060048201526013602482015272496e76616c6964207061697220746f6b656e7360681b6044820152606490fd5b610feb915060203d6020116105d8576105ca8183611340565b5f610aad565b6001600160a01b03611001611316565b16149081611010575b50610acd565b60405163d21220a760e01b81529150602090829060049082905afa80156108ba5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291849161105f575b506001600160a01b0316145f61100a565b611078915060203d6020116105d8576105ca8183611340565b5f61104e565b611097915060203d6020116105d8576105ca8183611340565b5f610a61565b60405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420574554482062616c616e6365000000000000006044820152606490fd5b90506020813d60201161110c575b816110fd60209383611340565b8101031261056457515f610a23565b3d91506110f0565b60405162461bcd60e51b8152602060048201526013602482015272151c985b9cd858dd1a5bdb88195e1c1a5c9959606a1b6044820152606490fd5b60405162461bcd60e51b8152602060048201526014602482015273496e76616c6964206d617820736c69707061676560601b6044820152606490fd5b60405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081b5a5b881c1c9bd99a5d60721b6044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f496e76616c69642066726f6e7472756e20616d6f756e740000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526013602482015272082d8e4cac2c8f240d2dc40e6c2dcc8eed2c6d606b1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b24b73b30b634b2103830b4b960a11b6044820152606490fd5b1561128057565b60405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b6044820152606490fd5b156112bb57565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b6004356001600160a01b03811681036105355790565b6024356001600160a01b03811681036105355790565b67ffffffffffffffff81116106d357604052565b90601f8019910116810190811067ffffffffffffffff8211176106d357604052565b9081602091031261053557516001600160a01b03811681036105355790565b90816020910312610535575180151581036105355790565b51906001600160701b038216820361053557565b90816060910312610535576113c181611399565b9160406113d060208401611399565b92015163ffffffff811681036105355790565b818102929181159184041417156113f657565b634e487b7160e01b5f52601160045260245ffd5b919082018092116113f657565b8115611421570490565b634e487b7160e01b5f52601260045260245ffd5b919082039182116113f657565b1561144957565b60405162461bcd60e51b81526020600482015260116024820152700a6d8d2e0e0c2ceca40e8dede40d0d2ced607b1b6044820152606490fdfeb6e670f38f06842373ba4d2ceb74c95df399638e4f9579b830906e12765c070ba26469706673582212208ce9660d9684099ef857ae2b9a9e0459745b1b36a5f0e6cdf1bf2612ff202c8a64736f6c63430008140033
Verified Source Code Full Match
Compiler: v0.8.20+commit.a1b79de6
EVM: shanghai
Optimization: Yes (200 runs)
MEVSandwich.sol 271 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
abstract contract SimpleReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
interface IERC20 {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
}
interface IWETH {
function deposit() external payable;
function withdraw(uint256) external;
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
interface IUniswapV2Pair {
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function token0() external view returns (address);
function token1() external view returns (address);
}
contract MEVSandwich is SimpleReentrancyGuard {
address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address private immutable owner;
// Sandwich attack parameters
struct SandwichParams {
address pair;
address token;
uint256 frontrunAmount;
uint256 minProfitBps; // Minimum profit in basis points (100 = 1%)
uint256 maxSlippageBps; // Maximum slippage in basis points
uint256 deadline;
}
// State for current sandwich
SandwichParams private currentSandwich;
bool private inSandwich;
uint256 private frontrunTokens;
event SandwichExecuted(address indexed pair, address indexed token, uint256 profit);
event SandwichFailed(address indexed pair, address indexed token, string reason);
modifier onlyOwner() {
require(msg.sender == owner, "Unauthorized");
_;
}
modifier validPair(address pair) {
require(pair != address(0), "Invalid pair");
_;
}
constructor() {
owner = msg.sender;
}
/**
* @dev Execute frontrun part of sandwich attack
* @param params Sandwich parameters including pair, token, amounts, and limits
*/
function executeFrontrun(SandwichParams calldata params)
external
onlyOwner
nonReentrant
validPair(params.pair)
{
require(!inSandwich, "Already in sandwich");
require(params.frontrunAmount > 0, "Invalid frontrun amount");
require(params.minProfitBps > 0, "Invalid min profit");
require(params.maxSlippageBps < 10000, "Invalid max slippage");
// Deadline Check
require(block.timestamp <= params.deadline, "Transaction expired");
// Check contract has enough WETH
uint256 wethBalance = IWETH(WETH).balanceOf(address(this));
require(wethBalance >= params.frontrunAmount, "Insufficient WETH balance");
// Verify pair contains both WETH and the target token
IUniswapV2Pair pairContract = IUniswapV2Pair(params.pair);
address token0 = pairContract.token0();
bool isValidPair = (token0 == WETH) ?
(pairContract.token1() == params.token) :
(token0 == params.token && pairContract.token1() == WETH);
require(isValidPair, "Invalid pair tokens");
// Store sandwich parameters
currentSandwich = params;
inSandwich = true;
// Transfer WETH to pair for swap
require(IWETH(WETH).transfer(params.pair, params.frontrunAmount), "WETH transfer failed");
// Calculate expected output with slippage protection
(uint256 amountOut, bool isToken0) = _calculateSwapOutput(
params.pair,
params.token,
params.frontrunAmount,
params.maxSlippageBps
);
require(amountOut > 0, "Invalid swap output");
// Execute swap: WETH -> Token
try IUniswapV2Pair(params.pair).swap(
isToken0 ? amountOut : 0,
isToken0 ? 0 : amountOut,
address(this),
""
) {
frontrunTokens = IERC20(params.token).balanceOf(address(this));
require(frontrunTokens >= amountOut, "Insufficient tokens received");
} catch {
inSandwich = false;
emit SandwichFailed(params.pair, params.token, "Frontrun swap failed");
}
}
/**
* @dev Execute backrun part of sandwich attack
*/
function executeBackrun()
external
onlyOwner
nonReentrant
{
require(inSandwich, "Not in sandwich");
require(frontrunTokens > 0, "No tokens to sell");
SandwichParams memory params = currentSandwich;
// Track initial WETH balance for accurate profit calculation
uint256 initialWethBalance = IWETH(WETH).balanceOf(address(this));
// Transfer tokens to pair for swap back to WETH
require(IERC20(params.token).transfer(params.pair, frontrunTokens), "Token transfer failed");
// Get pair info
IUniswapV2Pair pairContract = IUniswapV2Pair(params.pair);
(uint112 reserve0, uint112 reserve1,) = pairContract.getReserves();
address token0 = pairContract.token0();
bool tokenIsToken0 = (token0 == params.token);
// Calculate reserves
uint256 tokenReserve = tokenIsToken0 ? uint256(reserve0) : uint256(reserve1);
uint256 wethReserve = tokenIsToken0 ? uint256(reserve1) : uint256(reserve0);
// Calculate WETH output
uint256 amountInWithFee = frontrunTokens * 997;
uint256 wethOut = (amountInWithFee * wethReserve) / (tokenReserve * 1000 + amountInWithFee);
// Slippage protection
uint256 minWethOut = (wethOut * (10000 - params.maxSlippageBps)) / 10000;
require(wethOut >= minWethOut, "Slippage too high");
// Execute swap: Token -> WETH
try IUniswapV2Pair(params.pair).swap(
tokenIsToken0 ? 0 : wethOut,
tokenIsToken0 ? wethOut : 0,
address(this),
""
) {
// Calculate actual profit (final - initial + spent)
uint256 finalWethBalance = IWETH(WETH).balanceOf(address(this));
uint256 wethReturned = finalWethBalance - initialWethBalance;
// Profit = what we got back vs what we spent
if (wethReturned > params.frontrunAmount) {
uint256 profit = wethReturned - params.frontrunAmount;
uint256 minProfit = (params.frontrunAmount * params.minProfitBps) / 10000;
if (profit >= minProfit) {
emit SandwichExecuted(params.pair, params.token, profit);
} else {
emit SandwichFailed(params.pair, params.token, "Below minimum profit");
}
} else {
emit SandwichFailed(params.pair, params.token, "No profit");
}
} catch {
emit SandwichFailed(params.pair, params.token, "Backrun swap failed");
}
// Reset state
inSandwich = false;
frontrunTokens = 0;
delete currentSandwich;
}
/**
* @dev Calculate swap output with slippage protection
*/
function _calculateSwapOutput(
address pair,
address tokenOut,
uint256 amountIn,
uint256 maxSlippageBps
) private view returns (uint256 amountOut, bool isToken0) {
IUniswapV2Pair pairContract = IUniswapV2Pair(pair);
(uint112 reserve0, uint112 reserve1,) = pairContract.getReserves();
address token0 = pairContract.token0();
isToken0 = token0 == tokenOut;
uint256 reserveIn = isToken0 ? uint256(reserve1) : uint256(reserve0);
uint256 reserveOut = isToken0 ? uint256(reserve0) : uint256(reserve1);
// Calculate output using Uniswap V2 formula
uint256 amountInWithFee = amountIn * 997;
amountOut = (amountInWithFee * reserveOut) / (reserveIn * 1000 + amountInWithFee);
// Apply slippage protection
uint256 minAmountOut = amountOut * (10000 - maxSlippageBps) / 10000;
require(amountOut >= minAmountOut, "Slippage too high");
}
/**
* @dev Check if sandwich attack would be profitable
*/
function isProfitable(SandwichParams memory params) private pure returns (bool) {
return params.frontrunAmount > 0 && params.minProfitBps > 0;
}
/**
* @dev Emergency withdrawal function
*/
function emergencyWithdraw(address token) external onlyOwner {
if (token == address(0)) {
payable(owner).transfer(address(this).balance);
} else {
uint256 balance = IERC20(token).balanceOf(address(this));
require(IERC20(token).transfer(owner, balance), "Transfer failed");
}
}
/**
* @dev Get contract status
*/
function getStatus() external view returns (
bool _inSandwich,
address currentPair,
address currentToken,
uint256 _frontrunTokens
) {
return (inSandwich, currentSandwich.pair, currentSandwich.token, frontrunTokens);
}
receive() external payable {}
}
Read Contract
getStatus 0x4e69d560 → bool, address, address, uint256
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
emergencyWithdraw 0x6ff1c9bc
address token
executeBackrun 0xec301ebc
No parameters
executeFrontrun 0x9b5779ef
tuple params
Recent Transactions
No transactions found for this address