ETH Price: $2,856.76 (-9.76%)
Gas: 9 Gwei

Contract

0x60CFf949c22b7136dc750Af1F1a8e0a2D2A7556F
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Flash185190532023-11-07 9:02:23240 days ago1699347743IN
0x60CFf949...2D2A7556F
0 ETH0.0055504624.16273409
Flash184221032023-10-24 19:08:35254 days ago1698174515IN
0x60CFf949...2D2A7556F
0 ETH0.0139301230.04732863
Flash183131612023-10-09 13:17:47269 days ago1696857467IN
0x60CFf949...2D2A7556F
0 ETH0.0062470613.43530884
Flash183124382023-10-09 10:52:35269 days ago1696848755IN
0x60CFf949...2D2A7556F
0 ETH0.001220314.58547279
Flash183124182023-10-09 10:48:23269 days ago1696848503IN
0x60CFf949...2D2A7556F
0 ETH0.0012381214.79847284
Flash183124092023-10-09 10:46:35269 days ago1696848395IN
0x60CFf949...2D2A7556F
0 ETH0.0012158414.53215655
Flash183123992023-10-09 10:44:23269 days ago1696848263IN
0x60CFf949...2D2A7556F
0 ETH0.0011577613.83792323
Flash183123882023-10-09 10:42:11269 days ago1696848131IN
0x60CFf949...2D2A7556F
0 ETH0.0012909115.42942804
Flash183123792023-10-09 10:40:23269 days ago1696848023IN
0x60CFf949...2D2A7556F
0 ETH0.0013879616.5893971
Flash183123682023-10-09 10:38:11269 days ago1696847891IN
0x60CFf949...2D2A7556F
0 ETH0.0014740817.61870012
Flash183123592023-10-09 10:36:23269 days ago1696847783IN
0x60CFf949...2D2A7556F
0 ETH0.0015560918.59889059
Flash183123492023-10-09 10:34:23269 days ago1696847663IN
0x60CFf949...2D2A7556F
0 ETH0.0016150419.30349606
Flash183123382023-10-09 10:32:11269 days ago1696847531IN
0x60CFf949...2D2A7556F
0 ETH0.0016599319.84003522
Flash183123352023-10-09 10:31:35269 days ago1696847495IN
0x60CFf949...2D2A7556F
0 ETH0.0016674819.93019933
Flash183123292023-10-09 10:30:23269 days ago1696847423IN
0x60CFf949...2D2A7556F
0 ETH0.001900622.71655737
Flash183123182023-10-09 10:28:11269 days ago1696847291IN
0x60CFf949...2D2A7556F
0 ETH0.0017272520.64462001
Flash183123082023-10-09 10:26:11269 days ago1696847171IN
0x60CFf949...2D2A7556F
0 ETH0.001566418.7221435
Flash183122982023-10-09 10:24:11269 days ago1696847051IN
0x60CFf949...2D2A7556F
0 ETH0.0015217618.1885185
Flash183122882023-10-09 10:22:11269 days ago1696846931IN
0x60CFf949...2D2A7556F
0 ETH0.0015071118.01348564
Flash183122782023-10-09 10:20:11269 days ago1696846811IN
0x60CFf949...2D2A7556F
0 ETH0.0015498218.52395905
Flash183122682023-10-09 10:18:11269 days ago1696846691IN
0x60CFf949...2D2A7556F
0 ETH0.0017104420.44377015
Flash183122602023-10-09 10:16:35269 days ago1696846595IN
0x60CFf949...2D2A7556F
0 ETH0.0017127920.47179121
Flash183122482023-10-09 10:14:11269 days ago1696846451IN
0x60CFf949...2D2A7556F
0 ETH0.0015613918.66228399
Flash183122382023-10-09 10:12:11269 days ago1696846331IN
0x60CFf949...2D2A7556F
0 ETH0.0017039720.36635576
Flash183122282023-10-09 10:10:11269 days ago1696846211IN
0x60CFf949...2D2A7556F
0 ETH0.0017852921.33830644
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To Value
170659892023-04-17 10:45:11444 days ago1681728311  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FlashMEV

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion
File 1 of 11 : FlashMEV.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.8.17 <0.9.0;

/// ============ Imports ============

import {ERC20} from "solmate/tokens/ERC20.sol";
import {IFlashBorrower} from "./interfaces/IFlashBorrower.sol";
import {IFlashLoanReceiver} from "./interfaces/IFlashLoanReceiver.sol";
import {IFlashLoanRecipient} from "./interfaces/IFlashLoanRecipient.sol";
import {IVault} from "./interfaces/IVault.sol";
import {ILendingPool} from "./interfaces/ILendingPool.sol";
import {IBentoBoxV1} from "./interfaces/IBentoBoxV1.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
import {IProtocolDataProvider} from "./interfaces/IProtocolDataProvider.sol";
import {IUniswapV2Router02} from "./interfaces/IUniswapV2Router02.sol";

/// @title FlashMEV
/// @author Sandy Bradley <@sandybradley>
/// @notice Generic flash loan for MEV execution (loans from Balancer (0% fee), BentoBox (0.05%), Aave (0.09%))
contract FlashMEV is IFlashLoanRecipient, IFlashBorrower, IFlashLoanReceiver {
    using SafeTransferLib for ERC20;

    error ZeroAddress();
    error Unauthorized();
    error UnsupportedToken();
    error InsufficientOutputAmount();

    event MEV(address indexed token, uint256 value);

    uint8 internal GOV_FEE;
    address internal GOV;
    address internal mevETH;
    address internal ORACLE_ROUTER;
    address internal constant WETH09 =
        0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address internal constant BENTO =
        0xF5BCE5077908a1b7370B9ae04AdC565EBd643966; // bentobox vault
    address internal constant LENDING_POOL_ADDRESS =
        0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9; // aave lending pool address
    address internal constant AAVE_DATA_PROVIDER =
        0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d; // aave data provider
    address internal constant VAULT =
        0xBA12222222228d8Ba445958a75a0704d566BF2C8; // balancer vault
    mapping(address => bool) internal FLASH_FRIEND; // flashloan execute user access

    // address internal constant SPLIT_SWAP =
    //     0x77337dEEA78720542f0A1325394Def165918D562;  // Manifold split swap router

    /// @dev setup contract with governance fee and mevETH address
    /// @param _govFee governance fee on mev profit as 1/100 th of a decimal i.e. 1 == 0.01%
    /// @param _mevETH mevETH address
    /// @param _oracleRouter uni V2 style router for eth value lookup
    constructor(uint8 _govFee, address _mevETH, address _oracleRouter) {
        GOV = tx.origin; // tx.origin used over msg.sender for create2 deployment
        mevETH = _mevETH;
        GOV_FEE = _govFee;
        ORACLE_ROUTER = _oracleRouter;
        FLASH_FRIEND[GOV] = true;
    }

    /// @notice Admin can change ownership
    /// @param newGov Address of new owner
    function updateGov(address newGov) external {
        if (msg.sender != GOV) revert Unauthorized();
        if (newGov == address(0)) revert ZeroAddress();
        GOV = newGov;
    }

    /// @notice Admin can change fee
    /// @param _newFee New fee (1 == 0.01%)
    function updateFee(uint8 _newFee) external {
        if (msg.sender != GOV) revert Unauthorized();
        GOV_FEE = _newFee;
    }

    /// @notice Admin can change oracle router
    /// @param _oracleRouter uni V2 style router
    function updateOracle(address _oracleRouter) external {
        if (msg.sender != GOV) revert Unauthorized();
        ORACLE_ROUTER = _oracleRouter;
    }

    /// @notice Update internal Flash friend list
    /// @param flashAllowed Boolean flagging if user is allowed to execute
    /// @param friend Address of friend
    function updateFriend(bool flashAllowed, address friend) external {
        if (msg.sender != GOV) revert Unauthorized();
        FLASH_FRIEND[friend] = flashAllowed;
    }

    /// @notice Admin can change mevETH address
    /// @param newMevEth Address of new mevETH
    function updateMevETH(address newMevEth) external {
        if (msg.sender != GOV) revert Unauthorized();
        if (newMevEth == address(0)) revert ZeroAddress();
        mevETH = newMevEth;
    }

    /// @notice returns flash freind mapping for given address
    /// @param friend user address to query
    function isFriend(address friend) external view returns (bool) {
        return FLASH_FRIEND[friend];
    }

    /// @notice returns governance address
    function gov() external view returns (address) {
        return GOV;
    }

    /// @notice Main Flash loan call to execute MEV
    /// @param useBalancer true if its okay to use balancer flashloan (reentrancy protection makes it impossible to use balancer flashloan with balancer swaps)
    /// @param token token to loan
    /// @param amount Amount to loan of token
    /// @param transactions packed list of transaction data (value(256),contract(160),data_len(16),data(data_len*8))
    function flash(
        bool useBalancer,
        address token,
        uint256 amount,
        bytes calldata transactions
    ) external {
        if (!FLASH_FRIEND[msg.sender]) revert Unauthorized();
        address me = address(this);
        address sender = msg.sender;
        uint256 startGas = gasleft();
        uint256 balBefore = ERC20(token).balanceOf(me);

        // loan preference
        // 1) balancer
        // 2) bentobox
        // 3) aave
        if (useBalancer && ERC20(token).balanceOf(VAULT) >= amount) {
            // addresses of the reserves to flashloan
            address[] memory assets = new address[](1);
            assets[0] = token;
            // amounts of assets to flashloan.
            uint256[] memory amounts = new uint256[](1);
            amounts[0] = amount;
            IVault(VAULT).flashLoan(
                IFlashLoanRecipient(me),
                assets,
                amounts,
                transactions
            );
        } else if (ERC20(token).balanceOf(BENTO) >= amount) {
            IBentoBoxV1(BENTO).flashLoan(
                IFlashBorrower(me),
                me,
                token,
                amount,
                transactions
            );
        } else if (
            IProtocolDataProvider(AAVE_DATA_PROVIDER).getReserveData(token) >=
            amount
        ) {
            {
                // addresses of the reserves to flashloan
                address[] memory assets = new address[](1);
                assets[0] = token;
                // amounts of assets to flashloan.
                uint256[] memory amounts = new uint256[](1);
                amounts[0] = amount;
                // 0 = no debt (just revert), 1 = stable, 2 = variable
                uint256[] memory modes = new uint256[](1);
                modes[0] = 0;
                ILendingPool(LENDING_POOL_ADDRESS).flashLoan(
                    me,
                    assets,
                    amounts,
                    modes,
                    me,
                    transactions,
                    uint16(0)
                );
            }
        } else {
            revert UnsupportedToken();
        }
        // check profit exceeds gas cost
        uint256 profit = ((ERC20(token).balanceOf(me) - balBefore) *
            (10000 - uint256(GOV_FEE))) / 10000;
        if ((startGas - gasleft()) * block.basefee > _ethValue(token, profit))
            revert InsufficientOutputAmount();
        ERC20(token).safeTransfer(sender, profit);
        emit MEV(token, profit); // emit MEV event
    }

    /// @notice Sweep tokens and eth to recipient
    /// @param tokens Array of token addresses
    /// @param recipient Address of recipient
    function sweep(address[] calldata tokens, address recipient) external {
        if (msg.sender != GOV) revert Unauthorized();
        for (uint256 i; i < tokens.length; i++) {
            address token = tokens[i];
            ERC20(token).safeTransfer(
                recipient,
                ERC20(token).balanceOf(address(this))
            );
        }
        SafeTransferLib.safeTransferETH(recipient, address(this).balance);
    }

    /// @notice Admin function to remove code from blockchain and receive rebate
    /// @param recipient Address of rebate recipient
    function destroy(address payable recipient) external {
        if (msg.sender != GOV) revert Unauthorized();
        selfdestruct(recipient);
    }

    /// @notice Called from BentoBox Lending pool after contract has received the flash loaned amount
    /// @dev Reverts if not profitable.
    /// @param sender Address of flashloan initiator
    /// @param token Token to loan
    /// @param amount Amount to loan
    /// @param fee Fee to repay on loan amount
    /// @param data Encoded factories and tokens
    function onFlashLoan(
        address sender,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external {
        if (msg.sender != BENTO) revert Unauthorized();
        _executeTransactions(data);
        ERC20(token).safeTransfer(BENTO, amount + fee);
    }

    /// @notice Called from Aave Lending pool after contract has received the flash loaned amount (https://docs.aave.com/developers/v/2.0/guides/flash-loans)
    /// @dev Reverts if not profitable.
    /// @param assets Array of tokens to loan
    /// @param amounts Array of amounts to loan
    /// @param premiums Array of premiums to repay on loan amounts
    /// @param initiator Address of flashloan initiator
    /// @param params Encoded factories and tokens
    /// @return success indicating success
    function executeOperation(
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata premiums,
        address initiator,
        bytes calldata params
    ) external returns (bool) {
        if (msg.sender != LENDING_POOL_ADDRESS) revert Unauthorized();
        _executeTransactions(params);
        ERC20(assets[0]).safeApprove(
            LENDING_POOL_ADDRESS,
            amounts[0] + premiums[0]
        );
        return true;
    }

    /// @notice Called from Balancer vault after contract has received flashloan
    /// @param tokens Array of tokens to loan
    /// @param amounts Array of amounts to loan
    /// @param feeAmounts Array of fees to repay on loan amounts
    function receiveFlashLoan(
        address[] memory tokens,
        uint256[] memory amounts,
        uint256[] memory feeAmounts,
        bytes memory userData
    ) external override {
        if (msg.sender != VAULT) revert Unauthorized();
        _executeTransactions(userData);
        ERC20(tokens[0]).safeTransfer(VAULT, amounts[0] + feeAmounts[0]);
    }

    /// @notice Calculate eth value of a token amount
    /// @param token Address of token
    /// @param amount Amount of token
    /// @return eth value
    function _ethValue(
        address token,
        uint256 amount
    ) internal view returns (uint256) {
        if (token == WETH09) return amount;
        if (token == mevETH) return amount;
        address[] memory path = new address[](2);
        path[0] = token;
        path[1] = WETH09;
        uint256[] memory amounts = IUniswapV2Router02(ORACLE_ROUTER)
            .getAmountsOut(amount, path);
        if (amounts.length < 2) return 0;
        return amounts[1];
    }

    /// @dev Sends multiple transactions
    /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of
    ///                     value as a uint256 (=> 32 bytes),
    ///                     contract address (20 bytes)
    ///                     data length as a uint16 (=> 2 bytes),
    ///                     data as bytes.
    ///                     see abi.encodePacked for more information on packed encoding
    function _executeTransactions(bytes memory transactions) internal {
        assembly ("memory-safe") {
            let length := mload(transactions)
            let i := 0x20
            for {
                // Pre block is not used in "while mode"
            } lt(i, length) {
                // Post block is not used in "while mode"
            } {
                // let value = mload(add(transactions, i))
                let to := and(
                    shr(96, mload(add(transactions, add(i, 0x20)))),
                    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                )
                let dataLength := and(
                    shr(240, mload(add(transactions, add(i, 0x34)))),
                    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                )
                let success := call(
                    gas(), // gas left
                    to, // router
                    mload(add(transactions, i)), // value
                    add(transactions, add(i, 0x36)), // input data (0x(4 byte func sig hash)(abi encoded args))
                    dataLength, // input data byte length
                    0, // output
                    0 // output byte length
                )
                if iszero(success) {
                    revert(0, 0)
                }
                // Next entry starts at 0x35 byte + data length
                i := add(i, add(0x36, dataLength))
            }
        }
    }

    /// @notice Function to receive Ether. msg.data must be empty
    receive() external payable {}

    /// @notice Fallback function is called when msg.data is not empty
    fallback() external payable {}
}

File 2 of 11 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 3 of 11 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

File 4 of 11 : IBentoBoxV1.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.17 <0.9.0;

import "./IFlashBorrower.sol";

/// @notice Minimal interface for BentoBox token vault (V1) interactions
interface IBentoBoxV1 {
    function flashLoan(
        IFlashBorrower borrower,
        address receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external;
}

File 5 of 11 : IFlashBorrower.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.17 <0.9.0;

interface IFlashBorrower {
    /// @notice The flashloan callback. `amount` + `fee` needs to repayed to msg.sender before this call returns.
    /// @param sender The address of the invoker of this flashloan.
    /// @param token The address of the token that is loaned.
    /// @param amount of the `token` that is loaned.
    /// @param fee The fee that needs to be paid on top for this loan. Needs to be the same as `token`.
    /// @param data Additional data that was passed to the flashloan function.
    function onFlashLoan(
        address sender,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external;
}

File 6 of 11 : IFlashLoanReceiver.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity >=0.8.17 <0.9.0;

/**
 * @title IFlashLoanReceiver interface
 * @notice Interface for the Aave fee IFlashLoanReceiver.
 * @author Aave
 * @dev implement this interface to develop a flashloan-compatible flashLoanReceiver contract
 **/
interface IFlashLoanReceiver {
    function executeOperation(
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata premiums,
        address initiator,
        bytes calldata params
    ) external returns (bool);
}

File 7 of 11 : IFlashLoanRecipient.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.7.0 <0.9.0;

// Inspired by Aave Protocol's IFlashLoanReceiver.

interface IFlashLoanRecipient {
    /**
     * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient.
     *
     * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this
     * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the
     * Vault, or else the entire flash loan will revert.
     *
     * `userData` is the same value passed in the `IVault.flashLoan` call.
     */
    function receiveFlashLoan(
        address[] memory tokens,
        uint256[] memory amounts,
        uint256[] memory feeAmounts,
        bytes memory userData
    ) external;
}

File 8 of 11 : ILendingPool.sol
// SPDX-License-Identifier: agpl-3.0

pragma solidity >=0.8.17 <0.9.0;

interface ILendingPool {
    /**
     * @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
     * as long as the amount taken plus a fee is returned.
     * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration.
     * For further details please visit https://developers.aave.com
     * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface
     * @param assets The addresses of the assets being flash-borrowed
     * @param amounts The amounts amounts being flash-borrowed
     * @param modes Types of the debt to open if the flash loan is not returned:
     *   0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
     *   1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
     *   2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
     * @param onBehalfOf The address  that will receive the debt in the case of using on `modes` 1 or 2
     * @param params Variadic packed params to pass to the receiver as extra information
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     **/
    function flashLoan(
        address receiverAddress,
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata modes,
        address onBehalfOf,
        bytes calldata params,
        uint16 referralCode
    ) external;
}

File 9 of 11 : IProtocolDataProvider.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity >=0.8.17 <0.9.0;

interface IProtocolDataProvider {
    /**
     * @notice getReserveData() allows users to get the available liquidity of a given asset.
     * @dev getReserveData() takes an address of an asset as an argument and returns the available liquidity of that asset.
     */
    function getReserveData(
        address asset
    ) external view returns (uint256 availableLiquidity);
}

File 10 of 11 : IUniswapV2Router02.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.8.13 <0.9.0;

interface IUniswapV2Router02 {
    function getAmountsOut(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable returns (uint[] memory amounts);
}

File 11 of 11 : IVault.sol
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.8.17 <0.9.0;

import "./IFlashLoanRecipient.sol";

/**
 * @dev Full external interface for the Vault core contract - no external or public methods exist in the contract that
 * don't override one of these declarations.
 */
interface IVault {
    // Flash Loans

    /**
     * @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,
     * and then reverting unless the tokens plus a proportional protocol fee have been returned.
     *
     * The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount
     * for each token contract. `tokens` must be sorted in ascending order.
     *
     * The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the
     * `receiveFlashLoan` call.
     *
     * Emits `FlashLoan` events.
     */
    function flashLoan(
        IFlashLoanRecipient recipient,
        address[] memory tokens,
        uint256[] memory amounts,
        bytes memory userData
    ) external;
}

Settings
{
  "remappings": [
    "ds-test/=lib/solmate/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 2000,
    "details": {
      "constantOptimizer": true,
      "yul": true,
      "yulDetails": {
        "stackAllocation": true
      }
    }
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint8","name":"_govFee","type":"uint8"},{"internalType":"address","name":"_mevETH","type":"address"},{"internalType":"address","name":"_oracleRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnsupportedToken","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"MEV","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"premiums","type":"uint256[]"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"useBalancer","type":"bool"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"transactions","type":"bytes"}],"name":"flash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"friend","type":"address"}],"name":"isFriend","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"feeAmounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"receiveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_newFee","type":"uint8"}],"name":"updateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"flashAllowed","type":"bool"},{"internalType":"address","name":"friend","type":"address"}],"name":"updateFriend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGov","type":"address"}],"name":"updateGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMevEth","type":"address"}],"name":"updateMevETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracleRouter","type":"address"}],"name":"updateOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080346100da57601f6116da38819003918201601f19168301916001600160401b038311848410176100df578084926060946040528339810103126100da5780519060ff82168092036100da57610064604061005d602084016100f5565b92016100f5565b9060005460018060a01b039384918260018060a01b03199416846001541617600155610100600160a81b033260081b169060018060a81b031916171792836000551690600254161760025560081c1660005260036020526040600020600160ff198254161790556040516115d0908161010a8239f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036100da5756fe608080604052600436101561001a575b50361561001857005b005b600090813560e01c908162f55d9d1461104e575080630b33ba7a14610fd257806312d43a5114610fa95780631cb44dfc14610f4c57806323e30c8b14610e4b57806359ea653114610df457806368125a1b14610db7578063920f5c8414610bf1578063949c09b814610bb2578063b763ed2214610b25578063d20c88bd146109a6578063e11e40c1146102b35763f04f27070361000f57346102b05760806003193601126102b05760043567ffffffffffffffff8082116102ac57366023830112156102ac578160040135906100ef826111b0565b6100fc604051918261118d565b8281526020938482016024809560051b830101913683116102a8578501905b8282106102845750505082358281116102805761013c9036906004016111c8565b9160443581811161027c576101559036906004016111c8565b9060643590811161027c573660238201121561027c5761017e9036908681600401359101611226565b9173ba12222222228d8ba445958a75a0704d566bf2c8908133036102525786946101de6044946101d76101d06001600160a01b036101c860009a976101c38c99611550565b61126d565b51169461126d565b519161126d565b51906113b6565b6040519363a9059cbb60e01b85526004850152878401525af13d15601f3d116001600051141617161561020f578280f35b90600f6064926040519262461bcd60e51b845260048401528201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b60046040517f82b42900000000000000000000000000000000000000000000000000000000008152fd5b8680fd5b8580fd5b81356001600160a01b03811681036102a357815290860190860161011b565b600080fd5b8780fd5b8280fd5b80fd5b50346102b05760806003193601126102b0576102cd611107565b6102d56110c3565b6044359160643567ffffffffffffffff8111610596576102f99036906004016110d9565b9190913386526020926003845260ff604088205416156102525786915a96604051946370a0823160e01b865230600487015286866024816001600160a01b038c165afa95861561096c578596610977575b50806108eb575b156105a5576040519161036383611171565b600183528636818501376001600160a01b0388166103808461126d565b526040519161038e83611171565b600183528736818501376103a18361126d565b5273ba12222222228d8ba445958a75a0704d566bf2c890813b15610280578580946104356104239761041194604051998a98899788967f5c38449e0000000000000000000000000000000000000000000000000000000088523060048901526080602489015260848801906112a0565b906003198783030160448801526112dd565b91600319858403016064860152611311565b03925af1801561059a57610582575b50505b604051906370a0823160e01b825230600483015282826024816001600160a01b0388165afa8015610577578690610548575b6104839250611332565b60ff855416906127109182039082821161053457916104a86104b1926104b894611355565b04945a90611332565b4890611355565b6104c284846113c3565b1061050a576001600160a01b037fefc93621c32b1131b9091d3b843e27aca33a49c5d94aeaeae14d5612a45a8083926104fe8533848416611368565b6040519485521692a280f35b60046040517f42301c23000000000000000000000000000000000000000000000000000000008152fd5b602487634e487b7160e01b81526011600452fd5b508282813d8311610570575b61055e818361118d565b810103126102a3576104839151610479565b503d610554565b6040513d88823e3d90fd5b61058b90611147565b610596578438610444565b8480fd5b6040513d84823e3d90fd5b6040929192516370a0823160e01b815273f5bce5077908a1b7370b9ae04adc565ebd6439669081600482015287816024816001600160a01b038d165afa801561057757839187916108ba575b501061068c57803b15610596576001600160a01b0385896106628296604051988997889687957ff1676d37000000000000000000000000000000000000000000000000000000008752306004880152306024880152166044860152606485015260a0608485015260a4840191611311565b03925af1801561059a57610678575b5050610447565b61068190611147565b610596578438610671565b509250906040517f35ea6a750000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152858160248173057835ad21a177dbdd3090bb1cae03eacf78fc6d5afa80156108af5784918a9161087a575b501061085057604051889261070482611171565b600182528636818401376001600160a01b0388166107218361126d565b526040519461072f86611171565b600186528736818801376107428661126d565b526040519061075082611171565b60018252873681840137846107648361126d565b52737d2768de32b0b80b7a3454c06bdac94a69ddc7a93b15610596576107d0936107f461080c936107e2604051998a9889987fab9c4b5d000000000000000000000000000000000000000000000000000000008a523060048b015260e060248b015260e48a01906112a0565b906003198983030160448a01526112dd565b906003198783030160648801526112dd565b913060848601526003198584030160a4860152611311565b8360c4830152038183737d2768de32b0b80b7a3454c06bdac94a69ddc7a95af180156105775761083d575b50610447565b61084990959195611147565b9338610837565b60046040517f6a172882000000000000000000000000000000000000000000000000000000008152fd5b809250878092503d83116108a8575b610893818361118d565b810103126108a457839051386106f0565b8880fd5b503d610889565b6040513d8b823e3d90fd5b809250898092503d83116108e4575b6108d3818361118d565b8101031261028057829051386105f1565b503d6108c9565b506040516370a0823160e01b815273ba12222222228d8ba445958a75a0704d566bf2c8600482015286816024816001600160a01b038c165afa801561096c578291869161093b575b501015610351565b809250888092503d8311610965575b610954818361118d565b810103126105965781905138610933565b503d61094a565b6040513d87823e3d90fd5b9095508681813d831161099f575b61098f818361118d565b810103126105965751943861034a565b503d610985565b50346102b05760406003193601126102b05760043567ffffffffffffffff8111610b21576109d8903690600401611116565b91906109e26110c3565b906001600160a01b039081845460081c16330361025257835b858110610a5757848080808047895af115610a135780f35b606460405162461bcd60e51b815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152fd5b82610a668260051b84016113a2565b166040516370a0823160e01b81523060048201526020908181602481865afa918215610b16579087918993610ae4575b5050610aa192611368565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610ad0576001016109fb565b602485634e487b7160e01b81526011600452fd5b8193508092503d8311610b0f575b610afc818361118d565b8101031261027c575185610aa138610a96565b503d610af2565b6040513d8a823e3d90fd5b5080fd5b50346102b05760206003193601126102b057610b3f6110ad565b6001600160a01b039081835460081c16330361025257168015610b88577fffffffffffffffffffffffff0000000000000000000000000000000000000000600154161760015580f35b60046040517fd92e233d000000000000000000000000000000000000000000000000000000008152fd5b50346102b05760206003193601126102b05760043560ff8116809103610b215781546001600160a01b038160081c1633036102525760ff191617815580f35b50346102b05760a06003193601126102b05767ffffffffffffffff90600435828111610b2157610c25903690600401611116565b90602493843581811161059657610c40903690600401611116565b939060443583811161027c57610c5a903690600401611116565b90936001600160a01b0390606435828116036108a4576084359081116108a457610c889036906004016110d9565b969094737d2768de32b0b80b7a3454c06bdac94a69ddc7a99586330361025257610cb8610cbd918c9a3691611226565b611550565b15610da457610ccb906113a2565b169515610d915715610d7e57602094610cea85926044953590356113b6565b604051937f095ea7b30000000000000000000000000000000000000000000000000000000085526004850152888401525af19051600114601f3d11163d15171615610d3a57602060405160018152f35b606490600e6040519162461bcd60e51b8352602060048401528201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152fd5b8684634e487b7160e01b81526032600452fd5b8785634e487b7160e01b81526032600452fd5b8987634e487b7160e01b81526032600452fd5b50346102b05760206003193601126102b05760ff60406020926001600160a01b03610de06110ad565b168152600384522054166040519015158152f35b50346102b05760406003193601126102b057610e0e611107565b610e166110c3565b6001600160a01b039081845460081c163303610252571682526003602052604082209060ff60ff198354169115151617905580f35b50346102b05760a06003193601126102b057610e656110ad565b50610e6e6110c3565b60843567ffffffffffffffff81116102ac57610e8e9036906004016110d9565b909173f5bce5077908a1b7370b9ae04adc565ebd64396680330361025257846001600160a01b03604493610eca610cb860209885983691611226565b610ed760643586356113b6565b6040519463a9059cbb60e01b865260048601526024850152165af13d15601f3d11600184511416171615610f085780f35b606460405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b50346102b05760206003193601126102b057610f666110ad565b6001600160a01b039081835460081c16330361025257167fffffffffffffffffffffffff0000000000000000000000000000000000000000600254161760025580f35b50346102b057806003193601126102b0576001600160a01b036020915460081c16604051908152f35b50346102b05760206003193601126102b057610fec6110ad565b8154906001600160a01b03808360081c16330361025257811615610b885774ffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffff0000000000000000000000000000000000000000ff9160081b16911617815580f35b905034610b21576020600319360112610b2157600435916001600160a01b039081841684036102b0575460081c1633036110855750ff5b807f82b429000000000000000000000000000000000000000000000000000000000060049252fd5b600435906001600160a01b03821682036102a357565b602435906001600160a01b03821682036102a357565b9181601f840112156102a35782359167ffffffffffffffff83116102a357602083818601950101116102a357565b6004359081151582036102a357565b9181601f840112156102a35782359167ffffffffffffffff83116102a3576020808501948460051b0101116102a357565b67ffffffffffffffff811161115b57604052565b634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff82111761115b57604052565b90601f601f19910116810190811067ffffffffffffffff82111761115b57604052565b67ffffffffffffffff811161115b5760051b60200190565b81601f820112156102a3578035916111df836111b0565b926111ed604051948561118d565b808452602092838086019260051b8201019283116102a3578301905b828210611217575050505090565b81358152908301908301611209565b92919267ffffffffffffffff821161115b57604051916112506020601f19601f840116018461118d565b8294818452818301116102a3578281602093846000960137010152565b80511561127a5760200190565b634e487b7160e01b600052603260045260246000fd5b80516001101561127a5760400190565b90815180825260208080930193019160005b8281106112c0575050505090565b83516001600160a01b0316855293810193928101926001016112b2565b90815180825260208080930193019160005b8281106112fd575050505090565b8351855293810193928101926001016112ef565b601f8260209493601f19938186528686013760008582860101520116010190565b9190820391821161133f57565b634e487b7160e01b600052601160045260246000fd5b8181029291811591840414171561133f57565b600091826044926020956040519363a9059cbb60e01b8552600485015260248401525af13d15601f3d1160016000511416171615610f0857565b356001600160a01b03811681036102a35790565b9190820180921161133f57565b6001600160a01b038091169173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28084146115495782600154168414611549576040918251606081019467ffffffffffffffff958281108782111761115b578552600282526020938483019786368a3783511561127a57611485985261143b83611290565b52600254169184519283917fd06ca61f000000000000000000000000000000000000000000000000000000008352600483015285602483015281806000998a9560448301906112a0565b03915afa93841561153f5785946114b6575b5050505060028151106114b2576114ae9150611290565b5190565b5090565b90919293503d8086843e6114ca818461118d565b8201918381840312610280578051918211610280570181601f82011215610596578051906115036114fa836111b0565b9551958661118d565b818552838086019260051b820101928311610280578301905b828210611530575050505038808080611497565b8151815290830190830161151c565b83513d87823e3d90fd5b5091505090565b90815191602090815b848110611567575050509050565b8082018381015160601c91603482015160f01c80926000809281926036978882019151905af1156102b05750010161155956fea2646970667358221220c10190cb8257d6aab42b7a7354fadd44bd6fb7189e796cd0f12e4600a468409164736f6c6343000811003300000000000000000000000000000000000000000000000000000000000000010000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca000000000000000000000000077337deea78720542f0a1325394def165918d562

Deployed Bytecode

0x608080604052600436101561001a575b50361561001857005b005b600090813560e01c908162f55d9d1461104e575080630b33ba7a14610fd257806312d43a5114610fa95780631cb44dfc14610f4c57806323e30c8b14610e4b57806359ea653114610df457806368125a1b14610db7578063920f5c8414610bf1578063949c09b814610bb2578063b763ed2214610b25578063d20c88bd146109a6578063e11e40c1146102b35763f04f27070361000f57346102b05760806003193601126102b05760043567ffffffffffffffff8082116102ac57366023830112156102ac578160040135906100ef826111b0565b6100fc604051918261118d565b8281526020938482016024809560051b830101913683116102a8578501905b8282106102845750505082358281116102805761013c9036906004016111c8565b9160443581811161027c576101559036906004016111c8565b9060643590811161027c573660238201121561027c5761017e9036908681600401359101611226565b9173ba12222222228d8ba445958a75a0704d566bf2c8908133036102525786946101de6044946101d76101d06001600160a01b036101c860009a976101c38c99611550565b61126d565b51169461126d565b519161126d565b51906113b6565b6040519363a9059cbb60e01b85526004850152878401525af13d15601f3d116001600051141617161561020f578280f35b90600f6064926040519262461bcd60e51b845260048401528201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b60046040517f82b42900000000000000000000000000000000000000000000000000000000008152fd5b8680fd5b8580fd5b81356001600160a01b03811681036102a357815290860190860161011b565b600080fd5b8780fd5b8280fd5b80fd5b50346102b05760806003193601126102b0576102cd611107565b6102d56110c3565b6044359160643567ffffffffffffffff8111610596576102f99036906004016110d9565b9190913386526020926003845260ff604088205416156102525786915a96604051946370a0823160e01b865230600487015286866024816001600160a01b038c165afa95861561096c578596610977575b50806108eb575b156105a5576040519161036383611171565b600183528636818501376001600160a01b0388166103808461126d565b526040519161038e83611171565b600183528736818501376103a18361126d565b5273ba12222222228d8ba445958a75a0704d566bf2c890813b15610280578580946104356104239761041194604051998a98899788967f5c38449e0000000000000000000000000000000000000000000000000000000088523060048901526080602489015260848801906112a0565b906003198783030160448801526112dd565b91600319858403016064860152611311565b03925af1801561059a57610582575b50505b604051906370a0823160e01b825230600483015282826024816001600160a01b0388165afa8015610577578690610548575b6104839250611332565b60ff855416906127109182039082821161053457916104a86104b1926104b894611355565b04945a90611332565b4890611355565b6104c284846113c3565b1061050a576001600160a01b037fefc93621c32b1131b9091d3b843e27aca33a49c5d94aeaeae14d5612a45a8083926104fe8533848416611368565b6040519485521692a280f35b60046040517f42301c23000000000000000000000000000000000000000000000000000000008152fd5b602487634e487b7160e01b81526011600452fd5b508282813d8311610570575b61055e818361118d565b810103126102a3576104839151610479565b503d610554565b6040513d88823e3d90fd5b61058b90611147565b610596578438610444565b8480fd5b6040513d84823e3d90fd5b6040929192516370a0823160e01b815273f5bce5077908a1b7370b9ae04adc565ebd6439669081600482015287816024816001600160a01b038d165afa801561057757839187916108ba575b501061068c57803b15610596576001600160a01b0385896106628296604051988997889687957ff1676d37000000000000000000000000000000000000000000000000000000008752306004880152306024880152166044860152606485015260a0608485015260a4840191611311565b03925af1801561059a57610678575b5050610447565b61068190611147565b610596578438610671565b509250906040517f35ea6a750000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152858160248173057835ad21a177dbdd3090bb1cae03eacf78fc6d5afa80156108af5784918a9161087a575b501061085057604051889261070482611171565b600182528636818401376001600160a01b0388166107218361126d565b526040519461072f86611171565b600186528736818801376107428661126d565b526040519061075082611171565b60018252873681840137846107648361126d565b52737d2768de32b0b80b7a3454c06bdac94a69ddc7a93b15610596576107d0936107f461080c936107e2604051998a9889987fab9c4b5d000000000000000000000000000000000000000000000000000000008a523060048b015260e060248b015260e48a01906112a0565b906003198983030160448a01526112dd565b906003198783030160648801526112dd565b913060848601526003198584030160a4860152611311565b8360c4830152038183737d2768de32b0b80b7a3454c06bdac94a69ddc7a95af180156105775761083d575b50610447565b61084990959195611147565b9338610837565b60046040517f6a172882000000000000000000000000000000000000000000000000000000008152fd5b809250878092503d83116108a8575b610893818361118d565b810103126108a457839051386106f0565b8880fd5b503d610889565b6040513d8b823e3d90fd5b809250898092503d83116108e4575b6108d3818361118d565b8101031261028057829051386105f1565b503d6108c9565b506040516370a0823160e01b815273ba12222222228d8ba445958a75a0704d566bf2c8600482015286816024816001600160a01b038c165afa801561096c578291869161093b575b501015610351565b809250888092503d8311610965575b610954818361118d565b810103126105965781905138610933565b503d61094a565b6040513d87823e3d90fd5b9095508681813d831161099f575b61098f818361118d565b810103126105965751943861034a565b503d610985565b50346102b05760406003193601126102b05760043567ffffffffffffffff8111610b21576109d8903690600401611116565b91906109e26110c3565b906001600160a01b039081845460081c16330361025257835b858110610a5757848080808047895af115610a135780f35b606460405162461bcd60e51b815260206004820152601360248201527f4554485f5452414e534645525f4641494c4544000000000000000000000000006044820152fd5b82610a668260051b84016113a2565b166040516370a0823160e01b81523060048201526020908181602481865afa918215610b16579087918993610ae4575b5050610aa192611368565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610ad0576001016109fb565b602485634e487b7160e01b81526011600452fd5b8193508092503d8311610b0f575b610afc818361118d565b8101031261027c575185610aa138610a96565b503d610af2565b6040513d8a823e3d90fd5b5080fd5b50346102b05760206003193601126102b057610b3f6110ad565b6001600160a01b039081835460081c16330361025257168015610b88577fffffffffffffffffffffffff0000000000000000000000000000000000000000600154161760015580f35b60046040517fd92e233d000000000000000000000000000000000000000000000000000000008152fd5b50346102b05760206003193601126102b05760043560ff8116809103610b215781546001600160a01b038160081c1633036102525760ff191617815580f35b50346102b05760a06003193601126102b05767ffffffffffffffff90600435828111610b2157610c25903690600401611116565b90602493843581811161059657610c40903690600401611116565b939060443583811161027c57610c5a903690600401611116565b90936001600160a01b0390606435828116036108a4576084359081116108a457610c889036906004016110d9565b969094737d2768de32b0b80b7a3454c06bdac94a69ddc7a99586330361025257610cb8610cbd918c9a3691611226565b611550565b15610da457610ccb906113a2565b169515610d915715610d7e57602094610cea85926044953590356113b6565b604051937f095ea7b30000000000000000000000000000000000000000000000000000000085526004850152888401525af19051600114601f3d11163d15171615610d3a57602060405160018152f35b606490600e6040519162461bcd60e51b8352602060048401528201527f415050524f56455f4641494c45440000000000000000000000000000000000006044820152fd5b8684634e487b7160e01b81526032600452fd5b8785634e487b7160e01b81526032600452fd5b8987634e487b7160e01b81526032600452fd5b50346102b05760206003193601126102b05760ff60406020926001600160a01b03610de06110ad565b168152600384522054166040519015158152f35b50346102b05760406003193601126102b057610e0e611107565b610e166110c3565b6001600160a01b039081845460081c163303610252571682526003602052604082209060ff60ff198354169115151617905580f35b50346102b05760a06003193601126102b057610e656110ad565b50610e6e6110c3565b60843567ffffffffffffffff81116102ac57610e8e9036906004016110d9565b909173f5bce5077908a1b7370b9ae04adc565ebd64396680330361025257846001600160a01b03604493610eca610cb860209885983691611226565b610ed760643586356113b6565b6040519463a9059cbb60e01b865260048601526024850152165af13d15601f3d11600184511416171615610f085780f35b606460405162461bcd60e51b815260206004820152600f60248201527f5452414e534645525f4641494c454400000000000000000000000000000000006044820152fd5b50346102b05760206003193601126102b057610f666110ad565b6001600160a01b039081835460081c16330361025257167fffffffffffffffffffffffff0000000000000000000000000000000000000000600254161760025580f35b50346102b057806003193601126102b0576001600160a01b036020915460081c16604051908152f35b50346102b05760206003193601126102b057610fec6110ad565b8154906001600160a01b03808360081c16330361025257811615610b885774ffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffff0000000000000000000000000000000000000000ff9160081b16911617815580f35b905034610b21576020600319360112610b2157600435916001600160a01b039081841684036102b0575460081c1633036110855750ff5b807f82b429000000000000000000000000000000000000000000000000000000000060049252fd5b600435906001600160a01b03821682036102a357565b602435906001600160a01b03821682036102a357565b9181601f840112156102a35782359167ffffffffffffffff83116102a357602083818601950101116102a357565b6004359081151582036102a357565b9181601f840112156102a35782359167ffffffffffffffff83116102a3576020808501948460051b0101116102a357565b67ffffffffffffffff811161115b57604052565b634e487b7160e01b600052604160045260246000fd5b6040810190811067ffffffffffffffff82111761115b57604052565b90601f601f19910116810190811067ffffffffffffffff82111761115b57604052565b67ffffffffffffffff811161115b5760051b60200190565b81601f820112156102a3578035916111df836111b0565b926111ed604051948561118d565b808452602092838086019260051b8201019283116102a3578301905b828210611217575050505090565b81358152908301908301611209565b92919267ffffffffffffffff821161115b57604051916112506020601f19601f840116018461118d565b8294818452818301116102a3578281602093846000960137010152565b80511561127a5760200190565b634e487b7160e01b600052603260045260246000fd5b80516001101561127a5760400190565b90815180825260208080930193019160005b8281106112c0575050505090565b83516001600160a01b0316855293810193928101926001016112b2565b90815180825260208080930193019160005b8281106112fd575050505090565b8351855293810193928101926001016112ef565b601f8260209493601f19938186528686013760008582860101520116010190565b9190820391821161133f57565b634e487b7160e01b600052601160045260246000fd5b8181029291811591840414171561133f57565b600091826044926020956040519363a9059cbb60e01b8552600485015260248401525af13d15601f3d1160016000511416171615610f0857565b356001600160a01b03811681036102a35790565b9190820180921161133f57565b6001600160a01b038091169173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28084146115495782600154168414611549576040918251606081019467ffffffffffffffff958281108782111761115b578552600282526020938483019786368a3783511561127a57611485985261143b83611290565b52600254169184519283917fd06ca61f000000000000000000000000000000000000000000000000000000008352600483015285602483015281806000998a9560448301906112a0565b03915afa93841561153f5785946114b6575b5050505060028151106114b2576114ae9150611290565b5190565b5090565b90919293503d8086843e6114ca818461118d565b8201918381840312610280578051918211610280570181601f82011215610596578051906115036114fa836111b0565b9551958661118d565b818552838086019260051b820101928311610280578301905b828210611530575050505038808080611497565b8151815290830190830161151c565b83513d87823e3d90fd5b5091505090565b90815191602090815b848110611567575050509050565b8082018381015160601c91603482015160f01c80926000809281926036978882019151905af1156102b05750010161155956fea2646970667358221220c10190cb8257d6aab42b7a7354fadd44bd6fb7189e796cd0f12e4600a468409164736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000010000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca000000000000000000000000077337deea78720542f0a1325394def165918d562

-----Decoded View---------------
Arg [0] : _govFee (uint8): 1
Arg [1] : _mevETH (address): 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0
Arg [2] : _oracleRouter (address): 0x77337dEEA78720542f0A1325394Def165918D562

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [1] : 0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0
Arg [2] : 00000000000000000000000077337deea78720542f0a1325394def165918d562


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.