Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x1C7FAf18a4Ceb2eA10F27538E940681Dd02C99D4
Balance 0 ETH
Nonce 1
Code Size 4498 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4498 bytes
0x60806040526004361061007f5760003560e01c8063920f5c841161004e578063920f5c841461012a578063ad5c46481461015a578063e9240c2d14610182578063fe94df88146101a257600080fd5b806351cff8d91461008b5780636065c245146100ad578063735de9f7146100cd5780638da5cb5b1461010a57600080fd5b3661008657005b600080fd5b34801561009757600080fd5b506100ab6100a6366004610cfe565b6101d6565b005b3480156100b957600080fd5b506100ab6100c8366004610d22565b61030f565b3480156100d957600080fd5b506002546100ed906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561011657600080fd5b506001546100ed906001600160a01b031681565b34801561013657600080fd5b5061014a610145366004610d9a565b6104fe565b6040519015158152602001610101565b34801561016657600080fd5b506100ed73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561018e57600080fd5b506003546100ed906001600160a01b031681565b3480156101ae57600080fd5b506100ed7f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e281565b6001546001600160a01b031633146102265760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b60448201526064015b60405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561026d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102919190610e9f565b60015460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905291925083169063a9059cbb906044016020604051808303816000875af11580156102e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030a9190610eb8565b505050565b6001546001600160a01b0316331461035a5760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b604482015260640161021d565b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060408051600180825281830190925292935060009291506020808301908036833701905050905084836000815181106103d6576103d6610ef0565b60200260200101906001600160a01b031690816001600160a01b031681525050838260008151811061040a5761040a610ef0565b60200260200101818152505060008160008151811061042b5761042b610ef0565b6020026020010181815250507f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e26001600160a01b031663ab9c4b5d30858585308b8b6040516020016104929291906001600160a01b03929092168252602082015260400190565b60405160208183030381529060405260006040518863ffffffff1660e01b81526004016104c59796959493929190610f7a565b600060405180830381600087803b1580156104df57600080fd5b505af11580156104f3573d6000803e3d6000fd5b505050505050505050565b6000336001600160a01b037f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e216146105785760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206d757374206265206c656e64696e6720706f6f6c0000000000604482015260640161021d565b6001600160a01b03841630146105d05760405162461bcd60e51b815260206004820152601f60248201527f496e69746961746f72206d757374206265207468697320636f6e747261637400604482015260640161021d565b60008a8a60008181106105e5576105e5610ef0565b90506020020160208101906105fa9190610cfe565b905060008989600081811061061157610611610ef0565b90506020020135905060008888600081811061062f5761062f610ef0565b905060200201359050600080878781019061064a9190610d22565b91509150816001600160a01b0316856001600160a01b0316146106a05760405162461bcd60e51b815260206004820152600e60248201526d082e6e6cae840dad2e6dac2e8c6d60931b604482015260640161021d565b8084146106e15760405162461bcd60e51b815260206004820152600f60248201526e082dadeeadce840dad2e6dac2e8c6d608b1b604482015260640161021d565b60408051606080825260139082015272119b185cda081b1bd85b881c9958d95a5d9959606a1b60808201526001600160a01b03871660208201529081018590527fb515f8464a2e9f92f223836cb4d97889b194249a3f5a6bae6b346c6b0ac8fd559060a00160405180910390a1604080516002808252606082018352600092602083019080368337019050509050858160008151811061078357610783610ef0565b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106107cb576107cb610ef0565b6001600160a01b03928316602091820292909201015260025460405163095ea7b360e01b81529082166004820152602481018790529087169063095ea7b3906044016020604051808303816000875af115801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190610eb8565b506002546001600160a01b03166338ed173986600084306108734261012c611042565b6040518663ffffffff1660e01b815260040161089395949392919061105b565b6000604051808303816000875af11580156108b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108da9190810190611097565b5060408051600280825260608201835260009260208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160008151811061092457610924610ef0565b60200260200101906001600160a01b031690816001600160a01b031681525050868160018151811061095857610958610ef0565b6001600160a01b0392909216602092830291909101909101526040516370a0823160e01b815230600482015260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a0823190602401602060405180830381865afa1580156109c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e79190610e9f565b60035460405163095ea7b360e01b81526001600160a01b0390911660048201526024810182905290915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29063095ea7b3906044016020604051808303816000875af1158015610a4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a739190610eb8565b506003546001600160a01b03166338ed17398260008530610a964261012c611042565b6040518663ffffffff1660e01b8152600401610ab695949392919061105b565b6000604051808303816000875af1158015610ad5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610afd9190810190611097565b506000610b0a8789611042565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038b16906370a0823190602401602060405180830381865afa158015610b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b789190610e9f565b905081811015610bdb5760405162461bcd60e51b815260206004820152602860248201527f496e73756666696369656e742062616c616e636520746f20726570617920666c60448201526730b9b4103637b0b760c11b606482015260840161021d565b60405163095ea7b360e01b81526001600160a01b037f00000000000000000000000087870bca3f3fd6335c3f4ce8392d69350b4fa4e281166004830152602482018490528b169063095ea7b3906044016020604051808303816000875af1158015610c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6e9190610eb8565b506000610c7b8383611149565b90508e6001600160a01b03168b6001600160a01b03167f639acc6deb763ca53e1967f8d03e7bab23716b7eda3dc2908a798b2784c8e53183604051610cc291815260200190565b60405180910390a360019b5050505050505050505050509998505050505050505050565b6001600160a01b0381168114610cfb57600080fd5b50565b600060208284031215610d1057600080fd5b8135610d1b81610ce6565b9392505050565b60008060408385031215610d3557600080fd5b8235610d4081610ce6565b946020939093013593505050565b60008083601f840112610d6057600080fd5b50813567ffffffffffffffff811115610d7857600080fd5b6020830191508360208260051b8501011115610d9357600080fd5b9250929050565b600080600080600080600080600060a08a8c031215610db857600080fd5b893567ffffffffffffffff80821115610dd057600080fd5b610ddc8d838e01610d4e565b909b50995060208c0135915080821115610df557600080fd5b610e018d838e01610d4e565b909950975060408c0135915080821115610e1a57600080fd5b610e268d838e01610d4e565b909750955060608c01359150610e3b82610ce6565b90935060808b01359080821115610e5157600080fd5b818c0191508c601f830112610e6557600080fd5b813581811115610e7457600080fd5b8d6020828501011115610e8657600080fd5b6020830194508093505050509295985092959850929598565b600060208284031215610eb157600080fd5b5051919050565b600060208284031215610eca57600080fd5b81518015158114610d1b57600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015610f3f5781516001600160a01b031687529582019590820190600101610f1a565b509495945050505050565b600081518084526020808501945080840160005b83811015610f3f57815187529582019590820190600101610f5e565b600060018060a01b03808a168352602060e081850152610f9d60e085018b610f06565b8481036040860152610faf818b610f4a565b90508481036060860152610fc3818a610f4a565b92881660808601525083820360a085015285518083529160005b83811015610ff8578781018301518282018401528201610fdd565b506000818401830152601f909201601f191690910101905061102060c083018461ffff169052565b98975050505050505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156110555761105561102c565b92915050565b85815284602082015260a06040820152600061107a60a0830186610f06565b6001600160a01b0394909416606083015250608001529392505050565b600060208083850312156110aa57600080fd5b825167ffffffffffffffff808211156110c257600080fd5b818501915085601f8301126110d657600080fd5b8151818111156110e8576110e8610eda565b8060051b604051601f19603f8301168101818110858211171561110d5761110d610eda565b60405291825284820192508381018501918883111561112b57600080fd5b938501935b8285101561102057845184529385019392850192611130565b818103818111156110555761105561102c56fea264697066735822122060b94adbbc763ff8d5e197a0995473f48896efa79e646cef74a06a488b11f92064736f6c63430008140033

Verified Source Code Full Match

Compiler: v0.8.20+commit.a1b79de6 EVM: paris Optimization: Yes (200 runs)
FlashLoanArbitrage.sol 156 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

interface IUniswapV2Router {
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
}

interface IPool {
    function flashLoan(
        address receiverAddress,
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata modes,
        address onBehalfOf,
        bytes calldata params,
        uint16 referralCode
    ) external;
}

contract FlashLoanArbitrage is ReentrancyGuard {
    address public owner;
    address public immutable POOL_ADDRESS;
    address public uniswapRouter;
    address public sushiswapRouter;
    address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    
    event DebugLog(string message, address asset, uint256 amount);
    event ArbitrageExecuted(address indexed asset, uint256 profit, address indexed initiator);

    constructor(address _poolAddress, address _uniswapRouter, address _sushiswapRouter) {
        owner = msg.sender;
        POOL_ADDRESS = _poolAddress;
        uniswapRouter = _uniswapRouter;
        sushiswapRouter = _sushiswapRouter;
    }
    
    function executeFlashLoan(
        address asset,
        uint256 amount
    ) external {
        require(msg.sender == owner, "Not authorized");
        
        // Declare arrays for flash loan parameters
        address[] memory assets = new address[](1);
        uint256[] memory amounts = new uint256[](1);
        uint256[] memory modes = new uint256[](1);
        
        assets[0] = asset;
        amounts[0] = amount;
        modes[0] = 0; // No debt mode, full repayment expected
        
        IPool(POOL_ADDRESS).flashLoan(
            address(this),
            assets,
            amounts,
            modes,
            address(this),
            abi.encode(asset, amount),
            0
        );
    }
    
    function executeOperation(
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata premiums,
        address initiator,
        bytes calldata params
    ) external returns (bool) {
        require(msg.sender == POOL_ADDRESS, "Caller must be lending pool");
        require(initiator == address(this), "Initiator must be this contract");
        
        // Extract the borrowed asset and amount
        address asset = assets[0];
        uint256 amount = amounts[0];
        uint256 premium = premiums[0];
        
        // Decode parameters
        (address borrowedAsset, uint256 borrowedAmount) = abi.decode(params, (address, uint256));
        require(asset == borrowedAsset, "Asset mismatch");
        require(amount == borrowedAmount, "Amount mismatch");
        
        emit DebugLog("Flash loan received", asset, amount);
        
        // Create path for Uniswap swap (asset → WETH)
        address[] memory uniswapPath = new address[](2);
        uniswapPath[0] = asset;
        uniswapPath[1] = WETH;
        
        // Approve Uniswap router to spend our tokens
        IERC20(asset).approve(uniswapRouter, amount);
        
        // Execute swap on Uniswap (asset → WETH)
        IUniswapV2Router(uniswapRouter).swapExactTokensForTokens(
            amount,
            0, // Accept any amount
            uniswapPath,
            address(this),
            block.timestamp + 300
        );
        
        // Create path for SushiSwap swap (WETH → asset)
        address[] memory sushiswapPath = new address[](2);
        sushiswapPath[0] = WETH;
        sushiswapPath[1] = asset;
        
        // Get WETH balance
        uint256 wethBalance = IERC20(WETH).balanceOf(address(this));
        
        // Approve SushiSwap router to spend our WETH
        IERC20(WETH).approve(sushiswapRouter, wethBalance);
        
        // Execute swap on SushiSwap (WETH → asset)
        IUniswapV2Router(sushiswapRouter).swapExactTokensForTokens(
            wethBalance,
            0, // Accept any amount
            sushiswapPath,
            address(this),
            block.timestamp + 300
        );
        
        // Calculate amount to repay (initial amount + premium)
        uint256 amountToRepay = amount + premium;
        
        // Check if arbitrage was profitable
        uint256 finalBalance = IERC20(asset).balanceOf(address(this));
        require(finalBalance >= amountToRepay, "Insufficient balance to repay flash loan");
        
        // Approve the lending pool to pull the owed amount
        IERC20(asset).approve(POOL_ADDRESS, amountToRepay);
        
        // Calculate profit
        uint256 profit = finalBalance - amountToRepay;
        emit ArbitrageExecuted(asset, profit, initiator);
        
        return true;
    }
    
    function withdraw(address token) external {
        require(msg.sender == owner, "Not authorized");
        uint256 balance = IERC20(token).balanceOf(address(this));
        IERC20(token).transfer(owner, balance);
    }
    
    // Function to receive ETH
    receive() external payable {}
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
ReentrancyGuard.sol 87 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

Read Contract

POOL_ADDRESS 0xfe94df88 → address
WETH 0xad5c4648 → address
owner 0x8da5cb5b → address
sushiswapRouter 0xe9240c2d → address
uniswapRouter 0x735de9f7 → address

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

executeFlashLoan 0x6065c245
address asset
uint256 amount
executeOperation 0x920f5c84
address[] assets
uint256[] amounts
uint256[] premiums
address initiator
bytes params
returns: bool
withdraw 0x51cff8d9
address token

Recent Transactions

No transactions found for this address