Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xFC0693De26B7DD2B07b7566725141c93c817d993
Balance 0 ETH
Nonce 1
Code Size 5336 bytes
Indexed Transactions 0
External Etherscan · Sourcify

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