ETH Price: $2,284.73 (-4.58%)

Contract

0xd2667072a2a30e8C21fa276B474FD047ab5FF0F7

Overview

ETH Balance

0.062642181442590737 ETH

ETH Value

$143.12 (@ $2,284.73/ETH)

Token Holdings

More Info

Private Name Tags

Transaction Hash
Block
From
To
Swap With Fees O...3752784692025-09-03 14:02:39151 days ago1756908159IN
0xd2667072...7ab5FF0F7
0 ETH0.000005530.034483
Swap From Eth Wi...3751227062025-09-03 3:14:33152 days ago1756869273IN
0xd2667072...7ab5FF0F7
0.00429761 ETH0.00000140.01
Swap With Fees O...3748837522025-09-02 10:39:50153 days ago1756809590IN
0xd2667072...7ab5FF0F7
0 ETH0.000001470.01
Swap With Fees O...3738519542025-08-30 11:04:25156 days ago1756551865IN
0xd2667072...7ab5FF0F7
0 ETH0.000004230.01
Swap With Fees O...3736217622025-08-29 19:06:43156 days ago1756494403IN
0xd2667072...7ab5FF0F7
0 ETH0.000004980.01
Swap With Fees O...3732801582025-08-28 19:25:52157 days ago1756409152IN
0xd2667072...7ab5FF0F7
0 ETH0.000001610.01
Swap From Eth Wi...3702719312025-08-20 2:51:04166 days ago1755658264IN
0xd2667072...7ab5FF0F7
0.0000625 ETH0.000004860.01
Swap From Eth Wi...3690734492025-08-16 15:42:04169 days ago1755358924IN
0xd2667072...7ab5FF0F7
0.00254209 ETH0.000004670.010048
Swap With Fees O...3686991092025-08-15 13:44:24170 days ago1755265464IN
0xd2667072...7ab5FF0F7
0 ETH0.000007520.047169
Swap From Eth Wi...3686474482025-08-15 10:09:38171 days ago1755252578IN
0xd2667072...7ab5FF0F7
0.00006974 ETH0.000004740.01
Swap With Fees O...3683319992025-08-14 12:17:20171 days ago1755173840IN
0xd2667072...7ab5FF0F7
0 ETH0.000004860.030321
Swap With Fees O...3683296652025-08-14 12:07:36171 days ago1755173256IN
0xd2667072...7ab5FF0F7
0 ETH0.000004820.030308
Swap From Eth Wi...3682047012025-08-14 3:27:52172 days ago1755142072IN
0xd2667072...7ab5FF0F7
0.0002 ETH0.000004560.01
Swap With Fees O...3676367342025-08-12 12:05:52173 days ago1755000352IN
0xd2667072...7ab5FF0F7
0 ETH0.000001610.01
Swap With Fees O...3676343482025-08-12 11:55:55174 days ago1754999755IN
0xd2667072...7ab5FF0F7
0 ETH0.000001610.01
Swap With Fees O...3676319022025-08-12 11:45:45174 days ago1754999145IN
0xd2667072...7ab5FF0F7
0 ETH0.000001610.01
Swap With Fees O...3672910002025-08-11 12:07:30174 days ago1754914050IN
0xd2667072...7ab5FF0F7
0 ETH0.000003330.020121
Swap With Fees O...3672900782025-08-11 12:03:40175 days ago1754913820IN
0xd2667072...7ab5FF0F7
0 ETH0.000003150.020691
Swap With Fees O...3672856552025-08-11 11:45:16175 days ago1754912716IN
0xd2667072...7ab5FF0F7
0 ETH0.000001780.010136
Swap With Fees O...3672799362025-08-11 11:21:29175 days ago1754911289IN
0xd2667072...7ab5FF0F7
0 ETH0.000003340.02055
Swap With Fees O...3672780072025-08-11 11:13:28175 days ago1754910808IN
0xd2667072...7ab5FF0F7
0 ETH0.000002440.015207
Swap With Fees O...3672772232025-08-11 11:10:11175 days ago1754910611IN
0xd2667072...7ab5FF0F7
0 ETH0.000003610.022687
Swap With Fees O...3672753572025-08-11 11:02:27175 days ago1754910147IN
0xd2667072...7ab5FF0F7
0 ETH0.000001510.01
Swap With Fees O...3672750662025-08-11 11:01:14175 days ago1754910074IN
0xd2667072...7ab5FF0F7
0 ETH0.000001630.01
Swap With Fees O...3672744732025-08-11 10:58:45175 days ago1754909925IN
0xd2667072...7ab5FF0F7
0 ETH0.000001630.01
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
3751227062025-09-03 3:14:33152 days ago1756869273
0xd2667072...7ab5FF0F7
0.00426139 ETH
3739093942025-08-30 15:03:25155 days ago1756566205
0xd2667072...7ab5FF0F7
0.00002059 ETH
3728204392025-08-27 11:33:45159 days ago1756294425
0xd2667072...7ab5FF0F7
0.00000034 ETH
3714715242025-08-23 14:02:00162 days ago1755957720
0xd2667072...7ab5FF0F7
0.00004573 ETH
3702719312025-08-20 2:51:04166 days ago1755658264
0xd2667072...7ab5FF0F7
0.00006197 ETH
3700916702025-08-19 14:21:00166 days ago1755613260
0xd2667072...7ab5FF0F7
0.00000008 ETH
3700909942025-08-19 14:18:10166 days ago1755613090
0xd2667072...7ab5FF0F7
0.00000008 ETH
3700751142025-08-19 13:12:08166 days ago1755609128
0xd2667072...7ab5FF0F7
0.00000085 ETH
3690782912025-08-16 16:02:13169 days ago1755360133
0xd2667072...7ab5FF0F7
0.00000085 ETH
3690734492025-08-16 15:42:04169 days ago1755358924
0xd2667072...7ab5FF0F7
0.00252066 ETH
3686519412025-08-15 10:28:18171 days ago1755253698
0xd2667072...7ab5FF0F7
0.00000081 ETH
3686474482025-08-15 10:09:38171 days ago1755252578
0xd2667072...7ab5FF0F7
0.00006915 ETH
3686125492025-08-15 7:44:30171 days ago1755243870
0xd2667072...7ab5FF0F7
0.00001466 ETH
3682047012025-08-14 3:27:52172 days ago1755142072
0xd2667072...7ab5FF0F7
0.00019831 ETH
3679277352025-08-13 8:16:24173 days ago1755072984
0xd2667072...7ab5FF0F7
0.00000008 ETH
3673487752025-08-11 16:07:44174 days ago1754928464
0xd2667072...7ab5FF0F7
0.00000085 ETH
3673425192025-08-11 15:41:43174 days ago1754926903
0xd2667072...7ab5FF0F7
0.00000025 ETH
3672711432025-08-11 10:44:53175 days ago1754909093
0xd2667072...7ab5FF0F7
0.00000991 ETH
3672656142025-08-11 10:21:55175 days ago1754907715
0xd2667072...7ab5FF0F7
0.00000991 ETH
3672044602025-08-11 6:07:32175 days ago1754892452
0xd2667072...7ab5FF0F7
0.00849575 ETH
3665434602025-08-09 8:17:58177 days ago1754727478
0xd2667072...7ab5FF0F7
0.0000017 ETH
3656367782025-08-06 17:25:58179 days ago1754501158
0xd2667072...7ab5FF0F7
0.00003527 ETH
3655886462025-08-06 14:04:51179 days ago1754489091
0xd2667072...7ab5FF0F7
0.02382256 ETH
3651743292025-08-05 9:14:19181 days ago1754385259
0xd2667072...7ab5FF0F7
0.00027274 ETH
3640950592025-08-02 6:18:38184 days ago1754115518
0xd2667072...7ab5FF0F7
0.00001079 ETH
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SwapFeeRouter

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion
// SPDX-License-Identifier: MIT

pragma solidity 0.8.16;

import { IERC20, SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import { Ownable } from "./Ownable.sol";

// NOTE: There is no non-arbitrary upper-limit for the `feeBasisPoints`, and setting it above 10_000 just pauses the swap functions.

contract SwapFeeRouter is Ownable {

    error ETHTransferFailed(bytes errorData);
    error FeeBasisPointsNotRespected(uint256 expectedFeeBasisPoints_, uint256 actualFeeBasisPoints_);
    error ContractNotWhitelisted(address callee);
    error RenterAttempted();
    error SwapCallFailed(bytes errorData);

    event ContractAddedToWhitelist(address indexed contract_);
    event ContractRemovedFromWhitelist(address indexed contract_);
    event ETHPulled(address indexed destination_, uint256 amount_);
    event FeeSet(uint256 feeBasisPoints_);
    event TokensPulled(address indexed token_, address indexed destination_, uint256 amount_);

    uint256 internal _locked = 1;

    uint256 public feeBasisPoints;  // 1 = 0.01%, 100 = 1%, 10_000 = 100%

    mapping(address => bool) public isWhitelisted;

    constructor(address owner_, uint256 feeBasisPoints_, address[] memory whitelist_) {
        _setOwner(owner_);
        _setFees(feeBasisPoints_);
        _addToWhitelist(whitelist_);
    }

    modifier noRenter() {
        if (_locked == 2) revert RenterAttempted();

        _locked = 2;

        _;

        _locked = 1;
    }

    modifier feeBasisPointsRespected(uint256 feeBasisPoints_) {
        // Revert if the expected fee is less than the current fee.
        if (feeBasisPoints_ < feeBasisPoints) revert FeeBasisPointsNotRespected(feeBasisPoints_, feeBasisPoints);

        _;
    }

    function swapWithFeesOnInput(
        address inAsset_,
        uint256 swapAmount_,
        uint256 feeBasisPoints_,
        address swapContract_,
        address tokenPuller_,
        bytes calldata swapCallData_
    ) public payable noRenter feeBasisPointsRespected(feeBasisPoints_) {
        // Pull funds plus fees from caller.
        // NOTE: Assuming `swapCallData_` is correct, fees will remain in this contract.
        // NOTE: Worst case, assuming `swapCallData_` is incorrect/malicious, this contract loses nothing, but gains nothing.
        SafeERC20.safeTransferFrom(IERC20(inAsset_), msg.sender, address(this), getAmountWithFees(swapAmount_, feeBasisPoints_));

        // Perform the swap (set allowance, swap, unset allowance).
        // NOTE: This assume that the `swapCallData_` instructs the swapContract to send outAsset to correct destination.
        _performSwap(inAsset_, swapAmount_, swapContract_, tokenPuller_, swapCallData_);
    }

    function swapWithFeesOnOutput(
        address inAsset_,
        uint256 swapAmount_,
        address outAsset_,
        uint256 feeBasisPoints_,
        address swapContract_,
        address tokenPuller_,
        bytes calldata swapCallData_
    ) external noRenter feeBasisPointsRespected(feeBasisPoints_) {
        // Track this contract's starting outAsset balance to determine its increase later.
        uint256 startingOutAssetBalance = IERC20(outAsset_).balanceOf(address(this));

        // Pull funds from caller.
        SafeERC20.safeTransferFrom(IERC20(inAsset_), msg.sender, address(this), swapAmount_);

        // Perform the swap (set allowance, swap, unset allowance).
        // NOTE: This assume that the `swapCallData_` instructs the swapContract to send outAsset to this contract.
        _performSwap(inAsset_, swapAmount_, swapContract_, tokenPuller_, swapCallData_);

        // Send the amount of outAsset the swap produced, minus fees, to the destination.
        SafeERC20.safeTransfer(
            IERC20(outAsset_),
            msg.sender,
            getAmountWithoutFees(
                IERC20(outAsset_).balanceOf(address(this)) - startingOutAssetBalance,
                feeBasisPoints_
            )
        );
    }

    function swapFromEthWithFeesOnInput(
        uint256 feeBasisPoints_,
        address swapContract_,
        bytes calldata swapCallData_
    ) external payable noRenter feeBasisPointsRespected(feeBasisPoints_) {
        // Perform the swap (attaching ETH minus fees to call).
        // NOTE: This assume that the `swapCallData_` instructs the swapContract to send outAsset to correct destination.
        _performSwap(getAmountWithoutFees(msg.value, feeBasisPoints_), swapContract_, swapCallData_);
    }

    function swapFromEthWithFeesOnOutput(
        address outAsset_,
        uint256 feeBasisPoints_,
        address swapContract_,
        bytes calldata swapCallData_
    ) external payable noRenter feeBasisPointsRespected(feeBasisPoints_) {
        // Track this contract's starting outAsset balance to determine its increase later.
        uint256 startingOutAssetBalance = IERC20(outAsset_).balanceOf(address(this));

        // Perform the swap (attaching ETH to call).
        // NOTE: This assume that the `swapCallData_` instructs the swapContract to send outAsset to this contract.
        _performSwap(msg.value, swapContract_, swapCallData_);

        // Send the amount of outAsset the swap produced, minus fees, to the destination.
        SafeERC20.safeTransfer(
            IERC20(outAsset_),
            msg.sender,
            getAmountWithoutFees(
                IERC20(outAsset_).balanceOf(address(this)) - startingOutAssetBalance,
                feeBasisPoints_
            )
        );
    }

    function swapToEthWithFeesOnInput(
        address inAsset_,
        uint256 swapAmount_,
        uint256 feeBasisPoints_,
        address swapContract_,
        address tokenPuller_,
        bytes calldata swapCallData_
    ) external feeBasisPointsRespected(feeBasisPoints_) {
        // NOTE: Ths is functionally the same as `swapWithFeesOnInput` since the output is irrelevant.
        // NOTE: No `noRenter` needed since `swapWithFeesOnInput` will check that.
        swapWithFeesOnInput(inAsset_, swapAmount_, feeBasisPoints_, swapContract_, tokenPuller_, swapCallData_);
    }

    function swapToEthWithFeesOnOutput(
        address inAsset_,
        uint256 swapAmount_,
        uint256 feeBasisPoints_,
        address swapContract_,
        address tokenPuller_,
        bytes calldata swapCallData_
    ) external noRenter feeBasisPointsRespected(feeBasisPoints_) {
        // Track this contract's starting ETH balance to determine its increase later.
        uint256 startingETHBalance = address(this).balance;

        // Pull funds from caller.
        SafeERC20.safeTransferFrom(IERC20(inAsset_), msg.sender, address(this), swapAmount_);

        // Perform the swap (set allowance, swap, unset allowance).
        // NOTE: This assume that the `swapCallData_` instructs the swapContract to send ETH to this contract.
        _performSwap(inAsset_, swapAmount_, swapContract_, tokenPuller_, swapCallData_);

        // Send the amount of ETH the swap produced, minus fees, to the destination, and revert if it fails.
        _transferETH(
            msg.sender,
            getAmountWithoutFees(
                address(this).balance - startingETHBalance,
                feeBasisPoints_
            )
        );
    }

    function addToWhitelist(address[] calldata whitelist_) external onlyOwner {
        _addToWhitelist(whitelist_);
    }

    function removeFromWhitelist(address[] calldata whitelist_) external onlyOwner {
        _removeFromWhitelist(whitelist_);
    }

    function setFee(uint256 feeBasisPoints_) external onlyOwner {
        _setFees(feeBasisPoints_);
    }

    function pullToken(address token_, address destination_) public onlyOwner {
        if (destination_ == address(0)) revert ZeroAddress();

        uint256 amount = IERC20(token_).balanceOf(address(this));

        emit TokensPulled(token_, destination_, amount);

        SafeERC20.safeTransfer(IERC20(token_), destination_, amount);
    }

    function pullTokens(address[] calldata tokens_, address destination_) external onlyOwner {
        for (uint256 i; i < tokens_.length; ++i) {
            pullToken(tokens_[i], destination_);
        }
    }

    function pullETH(address destination_) external onlyOwner {
        if (destination_ == address(0)) revert ZeroAddress();

        uint256 amount = address(this).balance;

        emit ETHPulled(destination_, amount);

        _transferETH(destination_, amount);
    }

    function getAmountWithFees(uint256 amountWithoutFees_, uint256 feeBasisPoints_) public pure returns (uint256 amountWithFees_) {
        amountWithFees_ = (amountWithoutFees_ * (10_000 + feeBasisPoints_)) / 10_000;
    }

    function getAmountWithoutFees(uint256 amountWithFees_, uint256 feeBasisPoints_) public pure returns (uint256 amountWithoutFees_) {
        amountWithoutFees_ = (10_000 * amountWithFees_) / (10_000 + feeBasisPoints_);
    }

    function _addToWhitelist(address[] memory whitelist_) internal {
        for (uint256 i; i < whitelist_.length; ++i) {
            address account = whitelist_[i];
            isWhitelisted[whitelist_[i]] = true;
            emit ContractAddedToWhitelist(account);
        }
    }

    function _performSwap(address inAsset_, uint256 swapAmount_, address swapContract_, address tokenPuller_, bytes calldata swapCallData_) internal {
        // Prevent calling contracts that are not whitelisted.
        if (!isWhitelisted[swapContract_]) revert ContractNotWhitelisted(swapContract_);

        // Approve the contract that will pull inAsset.
        SafeERC20.forceApprove(IERC20(inAsset_), tokenPuller_, swapAmount_);

        // Call the swap contract as defined by `swapCallData_`, and revert if it fails.
        ( bool success, bytes memory errorData ) = swapContract_.call{ value: msg.value }(swapCallData_);
        if (!success) revert SwapCallFailed(errorData);

        // Un-approve the contract that pulled inAsset.
        // NOTE: This is important to prevent exploits that rely on allowances to arbitrary swapContracts to be non-zero after swap calls.
        SafeERC20.forceApprove(IERC20(inAsset_), tokenPuller_, 0);
    }

    function _performSwap(uint256 swapAmount_, address swapContract_, bytes calldata swapCallData_) internal {
        // Prevent calling contracts that are not whitelisted.
        if (!isWhitelisted[swapContract_]) revert ContractNotWhitelisted(swapContract_);

        // Call the swap contract as defined by `swapCallData_`, and revert if it fails.
        ( bool success, bytes memory errorData ) = swapContract_.call{ value: swapAmount_ }(swapCallData_);
        if (!success) revert SwapCallFailed(errorData);
    }

    function _removeFromWhitelist(address[] memory whitelist_) internal {
        for (uint256 i; i < whitelist_.length; ++i) {
            address account = whitelist_[i];
            isWhitelisted[whitelist_[i]] = false;
            emit ContractRemovedFromWhitelist(account);
        }
    }

    function _setFees(uint256 feeBasisPoints_) internal {
        emit FeeSet(feeBasisPoints = feeBasisPoints_);
    }

    function _transferETH(address destination_, uint256 amount_) internal {
        // NOTE: callers of this function are validating `destination_` to not be zero.
        ( bool success, bytes memory errorData ) = destination_.call{ value: amount_ }("");
        if (!success) revert ETHTransferFailed(errorData);
    }

    receive() external payable {}

}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` 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 amount) external returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.16;

abstract contract Ownable {

    error Unauthorized();
    error ZeroAddress();

    event OwnerSet(address indexed newOwner_);
    event PendingOwnerSet(address indexed pendingOwner_);

    address public owner;
    address public pendingOwner;

    modifier onlyOwner() {
        if (msg.sender != owner) revert Unauthorized();

        _;
    }

    function setPendingOwner(address pendingOwner_) external onlyOwner {
        _setPendingOwner(pendingOwner_);
    }

    function acceptOwnership() external {
        if (msg.sender != pendingOwner) revert Unauthorized();

        _setPendingOwner(address(0));
        _setOwner(msg.sender);
    }

    function _setOwner(address owner_) internal {
        if (owner_ == address(0)) revert ZeroAddress();

        emit OwnerSet(owner = owner_);
    }

    function _setPendingOwner(address pendingOwner_) internal {
        emit PendingOwnerSet(pendingOwner = pendingOwner_);
    }

}

Settings
{
  "evmVersion": "london",
  "optimizer": {
    "enabled": true,
    "runs": 200,
    "details": {
      "peephole": true,
      "inliner": true,
      "jumpdestRemover": true,
      "orderLiterals": true,
      "deduplicate": true,
      "cse": true,
      "constantOptimizer": true,
      "yul": true,
      "yulDetails": {
        "stackAllocation": true
      }
    }
  },
  "metadata": {
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address[]","name":"whitelist_","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"callee","type":"address"}],"name":"ContractNotWhitelisted","type":"error"},{"inputs":[{"internalType":"bytes","name":"errorData","type":"bytes"}],"name":"ETHTransferFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedFeeBasisPoints_","type":"uint256"},{"internalType":"uint256","name":"actualFeeBasisPoints_","type":"uint256"}],"name":"FeeBasisPointsNotRespected","type":"error"},{"inputs":[],"name":"RenterAttempted","type":"error"},{"inputs":[{"internalType":"bytes","name":"errorData","type":"bytes"}],"name":"SwapCallFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contract_","type":"address"}],"name":"ContractAddedToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contract_","type":"address"}],"name":"ContractRemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"destination_","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"ETHPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner_","type":"address"}],"name":"OwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner_","type":"address"}],"name":"PendingOwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token_","type":"address"},{"indexed":true,"internalType":"address","name":"destination_","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"TokensPulled","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"whitelist_","type":"address[]"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountWithoutFees_","type":"uint256"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"}],"name":"getAmountWithFees","outputs":[{"internalType":"uint256","name":"amountWithFees_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountWithFees_","type":"uint256"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"}],"name":"getAmountWithoutFees","outputs":[{"internalType":"uint256","name":"amountWithoutFees_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"destination_","type":"address"}],"name":"pullETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"destination_","type":"address"}],"name":"pullToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens_","type":"address[]"},{"internalType":"address","name":"destination_","type":"address"}],"name":"pullTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"whitelist_","type":"address[]"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner_","type":"address"}],"name":"setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address","name":"swapContract_","type":"address"},{"internalType":"bytes","name":"swapCallData_","type":"bytes"}],"name":"swapFromEthWithFeesOnInput","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"outAsset_","type":"address"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address","name":"swapContract_","type":"address"},{"internalType":"bytes","name":"swapCallData_","type":"bytes"}],"name":"swapFromEthWithFeesOnOutput","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"inAsset_","type":"address"},{"internalType":"uint256","name":"swapAmount_","type":"uint256"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address","name":"swapContract_","type":"address"},{"internalType":"address","name":"tokenPuller_","type":"address"},{"internalType":"bytes","name":"swapCallData_","type":"bytes"}],"name":"swapToEthWithFeesOnInput","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"inAsset_","type":"address"},{"internalType":"uint256","name":"swapAmount_","type":"uint256"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address","name":"swapContract_","type":"address"},{"internalType":"address","name":"tokenPuller_","type":"address"},{"internalType":"bytes","name":"swapCallData_","type":"bytes"}],"name":"swapToEthWithFeesOnOutput","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"inAsset_","type":"address"},{"internalType":"uint256","name":"swapAmount_","type":"uint256"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address","name":"swapContract_","type":"address"},{"internalType":"address","name":"tokenPuller_","type":"address"},{"internalType":"bytes","name":"swapCallData_","type":"bytes"}],"name":"swapWithFeesOnInput","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"inAsset_","type":"address"},{"internalType":"uint256","name":"swapAmount_","type":"uint256"},{"internalType":"address","name":"outAsset_","type":"address"},{"internalType":"uint256","name":"feeBasisPoints_","type":"uint256"},{"internalType":"address","name":"swapContract_","type":"address"},{"internalType":"address","name":"tokenPuller_","type":"address"},{"internalType":"bytes","name":"swapCallData_","type":"bytes"}],"name":"swapWithFeesOnOutput","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405260016002553480156200001657600080fd5b5060405162001dfa38038062001dfa833981016040819052620000399162000217565b620000448362000063565b6200004f82620000d3565b6200005a816200010e565b50505062000347565b6001600160a01b0381166200008b5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe291a250565b60038190556040518181527f20461e09b8e557b77e107939f9ce6544698123aad0fc964ac5cc59b7df2e608f9060200160405180910390a150565b60005b8151811015620001e057600082828151811062000132576200013262000309565b6020026020010151905060016004600085858151811062000157576200015762000309565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167f6e52dd2f27ea2ff599396dc0473c7f182d40ad3a9efe860f37f0c3fce64a851460405160405180910390a250620001d8816200031f565b905062000111565b5050565b80516001600160a01b0381168114620001fc57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156200022d57600080fd5b6200023884620001e4565b60208581015160408701519295509350906001600160401b03808211156200025f57600080fd5b818701915087601f8301126200027457600080fd5b81518181111562000289576200028962000201565b8060051b604051601f19603f83011681018181108582111715620002b157620002b162000201565b60405291825284820192508381018501918a831115620002d057600080fd5b938501935b82851015620002f957620002e985620001e4565b84529385019392850192620002d5565b8096505050505050509250925092565b634e487b7160e01b600052603260045260246000fd5b6000600182016200034057634e487b7160e01b600052601160045260246000fd5b5060010190565b611aa380620003576000396000f3fe6080604052600436106101235760003560e01c806379ba5097116100a0578063b8606eef11610064578063b8606eef14610337578063c42069ec1461034d578063e30c39781461036d578063e3d90acf1461038d578063e679b6f5146103a057600080fd5b806379ba50971461028a5780637f6497831461029f578063871bb2c9146102bf5780638bf6e374146102df5780638da5cb5b146102ff57600080fd5b806358d18b3f116100e757806358d18b3f146101f757806359856af01461021757806368443f2e14610237578063685c587a1461025757806369fe0e2d1461026a57600080fd5b806313bfbc4d1461012f5780631640ff3e146101625780632c0f0e87146101775780633af32abf14610197578063548db174146101d757600080fd5b3661012a57005b600080fd5b34801561013b57600080fd5b5061014f61014a36600461156c565b6103c0565b6040519081526020015b60405180910390f35b6101756101703660046115f3565b6103eb565b005b34801561018357600080fd5b5061014f61019236600461156c565b61046f565b3480156101a357600080fd5b506101c76101b236600461164d565b60046020526000908152604090205460ff1681565b6040519015158152602001610159565b3480156101e357600080fd5b506101756101f23660046116ad565b610488565b34801561020357600080fd5b506101756102123660046116ef565b6104f2565b34801561022357600080fd5b506101756102323660046116ef565b61053d565b34801561024357600080fd5b50610175610252366004611778565b6105de565b6101756102653660046117cc565b610659565b34801561027657600080fd5b5061017561028536600461183b565b6107bf565b34801561029657600080fd5b506101756107f5565b3480156102ab57600080fd5b506101756102ba3660046116ad565b610834565b3480156102cb57600080fd5b506101756102da366004611854565b61089a565b3480156102eb57600080fd5b506101756102fa366004611887565b6109b5565b34801561030b57600080fd5b5060005461031f906001600160a01b031681565b6040516001600160a01b039091168152602001610159565b34801561034357600080fd5b5061014f60035481565b34801561035957600080fd5b5061017561036836600461164d565b610b2d565b34801561037957600080fd5b5060015461031f906001600160a01b031681565b61017561039b3660046116ef565b610b60565b3480156103ac57600080fd5b506101756103bb36600461164d565b610bec565b60006103ce82612710611936565b6103da84612710611949565b6103e49190611968565b9392505050565b60025460020361040e5760405163729668f560e11b815260040160405180910390fd5b60028055600354849081101561044e576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b60405180910390fd5b61046361045b34876103c0565b858585610c87565b50506001600255505050565b600061271061047e8382611936565b6103da9085611949565b6000546001600160a01b031633146104b2576040516282b42960e81b815260040160405180910390fd5b6104ee828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610d5892505050565b5050565b84600354811015610524576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b61053388888888888888610b60565b5050505050505050565b6002546002036105605760405163729668f560e11b815260040160405180910390fd5b600280556003548590811015610597576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b476105a48933308b610e20565b6105b2898988888888610e8b565b6105ce336105c96105c3844761198a565b8a6103c0565b610f6b565b5050600160025550505050505050565b6000546001600160a01b03163314610608576040516282b42960e81b815260040160405180910390fd5b60005b82811015610653576106438484838181106106285761062861199d565b905060200201602081019061063d919061164d565b8361089a565b61064c816119b3565b905061060b565b50505050565b60025460020361067c5760405163729668f560e11b815260040160405180910390fd5b6002805560035484908110156106b3576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b6040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa1580156106fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071e91906119cc565b905061072c34868686610c87565b6040516370a0823160e01b81523060048201526107b190889033906107ac9085906001600160a01b038516906370a0823190602401602060405180830381865afa15801561077e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a291906119cc565b6105c3919061198a565b610fe3565b505060016002555050505050565b6000546001600160a01b031633146107e9576040516282b42960e81b815260040160405180910390fd5b6107f281611013565b50565b6001546001600160a01b0316331461081f576040516282b42960e81b815260040160405180910390fd5b610829600061104e565b61083233611098565b565b6000546001600160a01b0316331461085e576040516282b42960e81b815260040160405180910390fd5b6104ee82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061110792505050565b6000546001600160a01b031633146108c4576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166108eb5760405163d92e233d60e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610932573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095691906119cc565b9050816001600160a01b0316836001600160a01b03167ff247aed45b8afd5ae54bd3f6f884eb78df14bc00208ca905e6ae335ffe678d8c8360405161099d91815260200190565b60405180910390a36109b0838383610fe3565b505050565b6002546002036109d85760405163729668f560e11b815260040160405180910390fd5b600280556003548590811015610a0f576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b6040516370a0823160e01b81523060048201526000906001600160a01b038916906370a0823190602401602060405180830381865afa158015610a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7a91906119cc565b9050610a888a33308c610e20565b610a968a8a88888888610e8b565b6040516370a0823160e01b8152306004820152610b1c90899033906107ac9085906001600160a01b038516906370a0823190602401602060405180830381865afa158015610ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0c91906119cc565b610b16919061198a565b8b6103c0565b505060016002555050505050505050565b6000546001600160a01b03163314610b57576040516282b42960e81b815260040160405180910390fd5b6107f28161104e565b600254600203610b835760405163729668f560e11b815260040160405180910390fd5b600280556003548590811015610bba576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b610bcf883330610bca8b8b61046f565b610e20565b610bdd888887878787610e8b565b50506001600255505050505050565b6000546001600160a01b03163314610c16576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610c3d5760405163d92e233d60e01b815260040160405180910390fd5b60405147808252906001600160a01b038316907f9f15f0df128ea65ddf3aaa8d614e5f49a3c1e64d78f072b28aabdc36c9d27bf29060200160405180910390a26104ee8282610f6b565b6001600160a01b03831660009081526004602052604090205460ff16610ccb576040516340d53e3360e11b81526001600160a01b0384166004820152602401610445565b600080846001600160a01b0316868585604051610ce99291906119e5565b60006040518083038185875af1925050503d8060008114610d26576040519150601f19603f3d011682016040523d82523d6000602084013e610d2b565b606091505b509150915081610d50578060405163729a0b5b60e01b81526004016104459190611a45565b505050505050565b60005b81518110156104ee576000828281518110610d7857610d7861199d565b60200260200101519050600060046000858581518110610d9a57610d9a61199d565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167ffb8b462bd4e3db069eb434596fcfb88044cfe688f7329d1c4bdfbb113257b1ac60405160405180910390a250610e19816119b3565b9050610d5b565b6040516001600160a01b03808516602483015283166044820152606481018290526106539085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526111cf565b6001600160a01b03841660009081526004602052604090205460ff16610ecf576040516340d53e3360e11b81526001600160a01b0385166004820152602401610445565b610eda8684876112a4565b600080856001600160a01b0316348585604051610ef89291906119e5565b60006040518083038185875af1925050503d8060008114610f35576040519150601f19603f3d011682016040523d82523d6000602084013e610f3a565b606091505b509150915081610f5f578060405163729a0b5b60e01b81526004016104459190611a45565b610533888660006112a4565b600080836001600160a01b03168360405160006040518083038185875af1925050503d8060008114610fb9576040519150601f19603f3d011682016040523d82523d6000602084013e610fbe565b606091505b50915091508161065357806040516311c9b8f560e01b81526004016104459190611a45565b6040516001600160a01b0383166024820152604481018290526109b090849063a9059cbb60e01b90606401610e54565b60038190556040518181527f20461e09b8e557b77e107939f9ce6544698123aad0fc964ac5cc59b7df2e608f9060200160405180910390a150565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f590600090a250565b6001600160a01b0381166110bf5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe291a250565b60005b81518110156104ee5760008282815181106111275761112761199d565b602002602001015190506001600460008585815181106111495761114961199d565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167f6e52dd2f27ea2ff599396dc0473c7f182d40ad3a9efe860f37f0c3fce64a851460405160405180910390a2506111c8816119b3565b905061110a565b6000611224826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113339092919063ffffffff16565b90508051600014806112455750808060200190518101906112459190611a58565b6109b05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610445565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526112f5848261134a565b610653576040516001600160a01b03841660248201526000604482015261132990859063095ea7b360e01b90606401610e54565b61065384826111cf565b606061134284846000856113f3565b949350505050565b6000806000846001600160a01b0316846040516113679190611a7a565b6000604051808303816000865af19150503d80600081146113a4576040519150601f19603f3d011682016040523d82523d6000602084013e6113a9565b606091505b50915091508180156113d35750805115806113d35750808060200190518101906113d39190611a58565b80156113e857506001600160a01b0385163b15155b925050505b92915050565b6060824710156114545760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610445565b600080866001600160a01b031685876040516114709190611a7a565b60006040518083038185875af1925050503d80600081146114ad576040519150601f19603f3d011682016040523d82523d6000602084013e6114b2565b606091505b50915091506114c3878383876114ce565b979650505050505050565b6060831561153d578251600003611536576001600160a01b0385163b6115365760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610445565b5081611342565b61134283838151156115525781518083602001fd5b8060405162461bcd60e51b81526004016104459190611a45565b6000806040838503121561157f57600080fd5b50508035926020909101359150565b80356001600160a01b03811681146115a557600080fd5b919050565b60008083601f8401126115bc57600080fd5b50813567ffffffffffffffff8111156115d457600080fd5b6020830191508360208285010111156115ec57600080fd5b9250929050565b6000806000806060858703121561160957600080fd5b843593506116196020860161158e565b9250604085013567ffffffffffffffff81111561163557600080fd5b611641878288016115aa565b95989497509550505050565b60006020828403121561165f57600080fd5b6103e48261158e565b60008083601f84011261167a57600080fd5b50813567ffffffffffffffff81111561169257600080fd5b6020830191508360208260051b85010111156115ec57600080fd5b600080602083850312156116c057600080fd5b823567ffffffffffffffff8111156116d757600080fd5b6116e385828601611668565b90969095509350505050565b600080600080600080600060c0888a03121561170a57600080fd5b6117138861158e565b9650602088013595506040880135945061172f6060890161158e565b935061173d6080890161158e565b925060a088013567ffffffffffffffff81111561175957600080fd5b6117658a828b016115aa565b989b979a50959850939692959293505050565b60008060006040848603121561178d57600080fd5b833567ffffffffffffffff8111156117a457600080fd5b6117b086828701611668565b90945092506117c390506020850161158e565b90509250925092565b6000806000806000608086880312156117e457600080fd5b6117ed8661158e565b9450602086013593506118026040870161158e565b9250606086013567ffffffffffffffff81111561181e57600080fd5b61182a888289016115aa565b969995985093965092949392505050565b60006020828403121561184d57600080fd5b5035919050565b6000806040838503121561186757600080fd5b6118708361158e565b915061187e6020840161158e565b90509250929050565b60008060008060008060008060e0898b0312156118a357600080fd5b6118ac8961158e565b9750602089013596506118c160408a0161158e565b9550606089013594506118d660808a0161158e565b93506118e460a08a0161158e565b925060c089013567ffffffffffffffff81111561190057600080fd5b61190c8b828c016115aa565b999c989b5096995094979396929594505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156113ed576113ed611920565b600081600019048311821515161561196357611963611920565b500290565b60008261198557634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156113ed576113ed611920565b634e487b7160e01b600052603260045260246000fd5b6000600182016119c5576119c5611920565b5060010190565b6000602082840312156119de57600080fd5b5051919050565b8183823760009101908152919050565b60005b83811015611a105781810151838201526020016119f8565b50506000910152565b60008151808452611a318160208601602086016119f5565b601f01601f19169290920160200192915050565b6020815260006103e46020830184611a19565b600060208284031215611a6a57600080fd5b815180151581146103e457600080fd5b60008251611a8c8184602087016119f5565b919091019291505056fea164736f6c6343000810000a0000000000000000000000008597a795366eb248e081418b6fa7b1ffb788796d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000070000000000000000000000001111111254eeb25477b68fb85ed929f73a9605820000000000000000000000006352a56caadc4f1e25cd6c75970fa768a3304e6400000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff000000000000000000000000def171fe48cf0115b1d80b88dc8eab59176fee570000000000000000000000003a23f943181408eac424116af7b7790c94cb97a5000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666

Deployed Bytecode

0x6080604052600436106101235760003560e01c806379ba5097116100a0578063b8606eef11610064578063b8606eef14610337578063c42069ec1461034d578063e30c39781461036d578063e3d90acf1461038d578063e679b6f5146103a057600080fd5b806379ba50971461028a5780637f6497831461029f578063871bb2c9146102bf5780638bf6e374146102df5780638da5cb5b146102ff57600080fd5b806358d18b3f116100e757806358d18b3f146101f757806359856af01461021757806368443f2e14610237578063685c587a1461025757806369fe0e2d1461026a57600080fd5b806313bfbc4d1461012f5780631640ff3e146101625780632c0f0e87146101775780633af32abf14610197578063548db174146101d757600080fd5b3661012a57005b600080fd5b34801561013b57600080fd5b5061014f61014a36600461156c565b6103c0565b6040519081526020015b60405180910390f35b6101756101703660046115f3565b6103eb565b005b34801561018357600080fd5b5061014f61019236600461156c565b61046f565b3480156101a357600080fd5b506101c76101b236600461164d565b60046020526000908152604090205460ff1681565b6040519015158152602001610159565b3480156101e357600080fd5b506101756101f23660046116ad565b610488565b34801561020357600080fd5b506101756102123660046116ef565b6104f2565b34801561022357600080fd5b506101756102323660046116ef565b61053d565b34801561024357600080fd5b50610175610252366004611778565b6105de565b6101756102653660046117cc565b610659565b34801561027657600080fd5b5061017561028536600461183b565b6107bf565b34801561029657600080fd5b506101756107f5565b3480156102ab57600080fd5b506101756102ba3660046116ad565b610834565b3480156102cb57600080fd5b506101756102da366004611854565b61089a565b3480156102eb57600080fd5b506101756102fa366004611887565b6109b5565b34801561030b57600080fd5b5060005461031f906001600160a01b031681565b6040516001600160a01b039091168152602001610159565b34801561034357600080fd5b5061014f60035481565b34801561035957600080fd5b5061017561036836600461164d565b610b2d565b34801561037957600080fd5b5060015461031f906001600160a01b031681565b61017561039b3660046116ef565b610b60565b3480156103ac57600080fd5b506101756103bb36600461164d565b610bec565b60006103ce82612710611936565b6103da84612710611949565b6103e49190611968565b9392505050565b60025460020361040e5760405163729668f560e11b815260040160405180910390fd5b60028055600354849081101561044e576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b60405180910390fd5b61046361045b34876103c0565b858585610c87565b50506001600255505050565b600061271061047e8382611936565b6103da9085611949565b6000546001600160a01b031633146104b2576040516282b42960e81b815260040160405180910390fd5b6104ee828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610d5892505050565b5050565b84600354811015610524576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b61053388888888888888610b60565b5050505050505050565b6002546002036105605760405163729668f560e11b815260040160405180910390fd5b600280556003548590811015610597576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b476105a48933308b610e20565b6105b2898988888888610e8b565b6105ce336105c96105c3844761198a565b8a6103c0565b610f6b565b5050600160025550505050505050565b6000546001600160a01b03163314610608576040516282b42960e81b815260040160405180910390fd5b60005b82811015610653576106438484838181106106285761062861199d565b905060200201602081019061063d919061164d565b8361089a565b61064c816119b3565b905061060b565b50505050565b60025460020361067c5760405163729668f560e11b815260040160405180910390fd5b6002805560035484908110156106b3576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b6040516370a0823160e01b81523060048201526000906001600160a01b038816906370a0823190602401602060405180830381865afa1580156106fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071e91906119cc565b905061072c34868686610c87565b6040516370a0823160e01b81523060048201526107b190889033906107ac9085906001600160a01b038516906370a0823190602401602060405180830381865afa15801561077e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a291906119cc565b6105c3919061198a565b610fe3565b505060016002555050505050565b6000546001600160a01b031633146107e9576040516282b42960e81b815260040160405180910390fd5b6107f281611013565b50565b6001546001600160a01b0316331461081f576040516282b42960e81b815260040160405180910390fd5b610829600061104e565b61083233611098565b565b6000546001600160a01b0316331461085e576040516282b42960e81b815260040160405180910390fd5b6104ee82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061110792505050565b6000546001600160a01b031633146108c4576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166108eb5760405163d92e233d60e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015610932573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095691906119cc565b9050816001600160a01b0316836001600160a01b03167ff247aed45b8afd5ae54bd3f6f884eb78df14bc00208ca905e6ae335ffe678d8c8360405161099d91815260200190565b60405180910390a36109b0838383610fe3565b505050565b6002546002036109d85760405163729668f560e11b815260040160405180910390fd5b600280556003548590811015610a0f576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b6040516370a0823160e01b81523060048201526000906001600160a01b038916906370a0823190602401602060405180830381865afa158015610a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7a91906119cc565b9050610a888a33308c610e20565b610a968a8a88888888610e8b565b6040516370a0823160e01b8152306004820152610b1c90899033906107ac9085906001600160a01b038516906370a0823190602401602060405180830381865afa158015610ae8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0c91906119cc565b610b16919061198a565b8b6103c0565b505060016002555050505050505050565b6000546001600160a01b03163314610b57576040516282b42960e81b815260040160405180910390fd5b6107f28161104e565b600254600203610b835760405163729668f560e11b815260040160405180910390fd5b600280556003548590811015610bba576003546040516306a215ad60e21b8152610445918391600401918252602082015260400190565b610bcf883330610bca8b8b61046f565b610e20565b610bdd888887878787610e8b565b50506001600255505050505050565b6000546001600160a01b03163314610c16576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116610c3d5760405163d92e233d60e01b815260040160405180910390fd5b60405147808252906001600160a01b038316907f9f15f0df128ea65ddf3aaa8d614e5f49a3c1e64d78f072b28aabdc36c9d27bf29060200160405180910390a26104ee8282610f6b565b6001600160a01b03831660009081526004602052604090205460ff16610ccb576040516340d53e3360e11b81526001600160a01b0384166004820152602401610445565b600080846001600160a01b0316868585604051610ce99291906119e5565b60006040518083038185875af1925050503d8060008114610d26576040519150601f19603f3d011682016040523d82523d6000602084013e610d2b565b606091505b509150915081610d50578060405163729a0b5b60e01b81526004016104459190611a45565b505050505050565b60005b81518110156104ee576000828281518110610d7857610d7861199d565b60200260200101519050600060046000858581518110610d9a57610d9a61199d565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167ffb8b462bd4e3db069eb434596fcfb88044cfe688f7329d1c4bdfbb113257b1ac60405160405180910390a250610e19816119b3565b9050610d5b565b6040516001600160a01b03808516602483015283166044820152606481018290526106539085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526111cf565b6001600160a01b03841660009081526004602052604090205460ff16610ecf576040516340d53e3360e11b81526001600160a01b0385166004820152602401610445565b610eda8684876112a4565b600080856001600160a01b0316348585604051610ef89291906119e5565b60006040518083038185875af1925050503d8060008114610f35576040519150601f19603f3d011682016040523d82523d6000602084013e610f3a565b606091505b509150915081610f5f578060405163729a0b5b60e01b81526004016104459190611a45565b610533888660006112a4565b600080836001600160a01b03168360405160006040518083038185875af1925050503d8060008114610fb9576040519150601f19603f3d011682016040523d82523d6000602084013e610fbe565b606091505b50915091508161065357806040516311c9b8f560e01b81526004016104459190611a45565b6040516001600160a01b0383166024820152604481018290526109b090849063a9059cbb60e01b90606401610e54565b60038190556040518181527f20461e09b8e557b77e107939f9ce6544698123aad0fc964ac5cc59b7df2e608f9060200160405180910390a150565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f68f49b346b94582a8b5f9d10e3fe3365318fe8f191ff8dce7c59c6cad06b02f590600090a250565b6001600160a01b0381166110bf5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe291a250565b60005b81518110156104ee5760008282815181106111275761112761199d565b602002602001015190506001600460008585815181106111495761114961199d565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167f6e52dd2f27ea2ff599396dc0473c7f182d40ad3a9efe860f37f0c3fce64a851460405160405180910390a2506111c8816119b3565b905061110a565b6000611224826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113339092919063ffffffff16565b90508051600014806112455750808060200190518101906112459190611a58565b6109b05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610445565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526112f5848261134a565b610653576040516001600160a01b03841660248201526000604482015261132990859063095ea7b360e01b90606401610e54565b61065384826111cf565b606061134284846000856113f3565b949350505050565b6000806000846001600160a01b0316846040516113679190611a7a565b6000604051808303816000865af19150503d80600081146113a4576040519150601f19603f3d011682016040523d82523d6000602084013e6113a9565b606091505b50915091508180156113d35750805115806113d35750808060200190518101906113d39190611a58565b80156113e857506001600160a01b0385163b15155b925050505b92915050565b6060824710156114545760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610445565b600080866001600160a01b031685876040516114709190611a7a565b60006040518083038185875af1925050503d80600081146114ad576040519150601f19603f3d011682016040523d82523d6000602084013e6114b2565b606091505b50915091506114c3878383876114ce565b979650505050505050565b6060831561153d578251600003611536576001600160a01b0385163b6115365760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610445565b5081611342565b61134283838151156115525781518083602001fd5b8060405162461bcd60e51b81526004016104459190611a45565b6000806040838503121561157f57600080fd5b50508035926020909101359150565b80356001600160a01b03811681146115a557600080fd5b919050565b60008083601f8401126115bc57600080fd5b50813567ffffffffffffffff8111156115d457600080fd5b6020830191508360208285010111156115ec57600080fd5b9250929050565b6000806000806060858703121561160957600080fd5b843593506116196020860161158e565b9250604085013567ffffffffffffffff81111561163557600080fd5b611641878288016115aa565b95989497509550505050565b60006020828403121561165f57600080fd5b6103e48261158e565b60008083601f84011261167a57600080fd5b50813567ffffffffffffffff81111561169257600080fd5b6020830191508360208260051b85010111156115ec57600080fd5b600080602083850312156116c057600080fd5b823567ffffffffffffffff8111156116d757600080fd5b6116e385828601611668565b90969095509350505050565b600080600080600080600060c0888a03121561170a57600080fd5b6117138861158e565b9650602088013595506040880135945061172f6060890161158e565b935061173d6080890161158e565b925060a088013567ffffffffffffffff81111561175957600080fd5b6117658a828b016115aa565b989b979a50959850939692959293505050565b60008060006040848603121561178d57600080fd5b833567ffffffffffffffff8111156117a457600080fd5b6117b086828701611668565b90945092506117c390506020850161158e565b90509250925092565b6000806000806000608086880312156117e457600080fd5b6117ed8661158e565b9450602086013593506118026040870161158e565b9250606086013567ffffffffffffffff81111561181e57600080fd5b61182a888289016115aa565b969995985093965092949392505050565b60006020828403121561184d57600080fd5b5035919050565b6000806040838503121561186757600080fd5b6118708361158e565b915061187e6020840161158e565b90509250929050565b60008060008060008060008060e0898b0312156118a357600080fd5b6118ac8961158e565b9750602089013596506118c160408a0161158e565b9550606089013594506118d660808a0161158e565b93506118e460a08a0161158e565b925060c089013567ffffffffffffffff81111561190057600080fd5b61190c8b828c016115aa565b999c989b5096995094979396929594505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156113ed576113ed611920565b600081600019048311821515161561196357611963611920565b500290565b60008261198557634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156113ed576113ed611920565b634e487b7160e01b600052603260045260246000fd5b6000600182016119c5576119c5611920565b5060010190565b6000602082840312156119de57600080fd5b5051919050565b8183823760009101908152919050565b60005b83811015611a105781810151838201526020016119f8565b50506000910152565b60008151808452611a318160208601602086016119f5565b601f01601f19169290920160200192915050565b6020815260006103e46020830184611a19565b600060208284031215611a6a57600080fd5b815180151581146103e457600080fd5b60008251611a8c8184602087016119f5565b919091019291505056fea164736f6c6343000810000a

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

0000000000000000000000008597a795366eb248e081418b6fa7b1ffb788796d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000070000000000000000000000001111111254eeb25477b68fb85ed929f73a9605820000000000000000000000006352a56caadc4f1e25cd6c75970fa768a3304e6400000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff000000000000000000000000def171fe48cf0115b1d80b88dc8eab59176fee570000000000000000000000003a23f943181408eac424116af7b7790c94cb97a5000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666

-----Decoded View---------------
Arg [0] : owner_ (address): 0x8597a795366eB248E081418B6fa7B1FfB788796D
Arg [1] : feeBasisPoints_ (uint256): 0
Arg [2] : whitelist_ (address[]): 0x1111111254EEB25477B68fb85Ed929f73A960582,0x6352a56caadC4F1E25CD6c75970Fa768A3304e64,0x19330d10D9Cc8751218eaf51E8885D058642E08A,0xDef1C0ded9bec7F1a1670819833240f027b25EfF,0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57,0x3a23F943181408EAC424116Af7b7790c94Cb97a5,0xce16F69375520ab01377ce7B88f5BA8C48F8D666

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000008597a795366eb248e081418b6fa7b1ffb788796d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [4] : 0000000000000000000000001111111254eeb25477b68fb85ed929f73a960582
Arg [5] : 0000000000000000000000006352a56caadc4f1e25cd6c75970fa768a3304e64
Arg [6] : 00000000000000000000000019330d10d9cc8751218eaf51e8885d058642e08a
Arg [7] : 000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff
Arg [8] : 000000000000000000000000def171fe48cf0115b1d80b88dc8eab59176fee57
Arg [9] : 0000000000000000000000003a23f943181408eac424116af7b7790c94cb97a5
Arg [10] : 000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0xd2667072a2a30e8C21fa276B474FD047ab5FF0F7
Net Worth in USD
$17,653.29

Net Worth in ETH
7.726642

Token Allocations
USDC 23.39%
RETH 20.45%
ETH 18.84%
Others 37.32%
Chain Token Portfolio % Price Amount Value
ETH20.11%$2,644.231.3423$3,549.28
ETH17.68%$2,283.421.3667$3,120.66
ETH15.46%$0.9997342,730.3935$2,729.67
ETH6.25%$77,6570.0142$1,103.72
ETH5.97%$0.9990481,054.5726$1,053.57
ETH1.06%$0.01530412,200.3353$186.72
ETH0.83%$103.221.4225$146.83
ETH0.78%$9.5514.4711$138.2
ETH0.75%$77,7630.00169508$131.81
ETH0.74%$2,283.420.0574$131.18
ETH0.69%$127.440.9579$122.08
ETH0.69%$0.999574121.9808$121.93
ETH0.68%$77,7950.00154284$120.03
ETH0.60%$1.5568.5616$106.27
ETH0.40%$0.0628861,123.848$70.67
ETH0.29%$2,283.760.0221$50.43
ETH0.22%$0.279574139.239$38.93
ETH0.18%$0.0298851,053.995$31.5
ETH0.17%$2,445.360.012$29.23
ETH0.16%$0.34228884.0031$28.75
ETH0.16%$0.0000046,731,633.7217$28.21
ETH0.14%$0.00183213,488.9062$24.72
ETH0.14%$1.7713.829$24.48
ETH0.12%$2,423.90.00854752$20.72
ETH0.11%$0.99893419.4663$19.45
ETH0.10%$0.060655288.2524$17.48
ETH0.09%$4,815.650.00344246$16.58
ETH0.09%$0.028454533.0613$15.17
ETH0.08%$2,792.780.00511987$14.3
ETH0.07%$4.292.8787$12.35
ETH0.07%$0.0056672,078.298$11.78
ETH0.06%$0.107676101.6159$10.94
ETH0.05%$0.40982322.6424$9.28
ETH0.04%$0.004751,460.2037$6.94
ETH0.03%$16.139$6.15
ETH0.03%$77,7720.00007765$6.04
ETH0.03%$3.911.283$5.02
ETH0.03%$0.14753831.7328$4.68
ETH0.03%$0.18015725.1689$4.53
ETH0.02%$0.14590428.3721$4.14
ETH0.02%$2,823.110.00118449$3.34
ETH0.02%$0.00003985,000$3.32
ETH0.02%<$0.00000116,983,027.2597$3.22
ETH0.02%$1.182.549$3.01
ETH0.02%$0.0007993,367.7938$2.69
ETH0.01%$3.620.728$2.63
ETH0.01%$0.0016171,605.1646$2.6
ETH0.01%$0.00007532,300$2.43
ETH0.01%<$0.000001136,645,898.8847$2.33
ETH0.01%$0.7186753.1589$2.27
ETH0.01%$0.10389220.7725$2.16
ETH0.01%$1,426.820.00150248$2.14
ETH0.01%$0.1819710.8976$1.98
ETH0.01%$67.660.0287$1.94
ETH0.01%$763.740.002465$1.88
ETH0.01%$0.05949829.9103$1.78
ETH<0.01%$0.0006612,622.168$1.73
ETH<0.01%$0.11707312.7706$1.5
ETH<0.01%$0.0008271,674.9901$1.39
ETH<0.01%$0.00001136,417.8159$1.38
ETH<0.01%$0.0524.1943$1.21
ETH<0.01%$0.1283578.5$1.09
ETH<0.01%$0.02631641.4$1.09
ETH<0.01%$0.002815380.9328$1.07
ETH<0.01%$0.0000196,493.856$0.9552
ETH<0.01%$0.1308426.8611$0.8977
ETH<0.01%$0.06145514.4138$0.8857
ETH<0.01%$0.9997210.7986$0.7983
ETH<0.01%$4,796.670.00016297$0.7817
ETH<0.01%$0.02451631.2579$0.7663
ETH<0.01%$0.00003620,686.439$0.7465
ETH<0.01%$0.397981.8111$0.7207
ETH<0.01%$1.560.4318$0.6736
ETH<0.01%$0.9969920.6288$0.6269
ETH<0.01%$68.020.00884848$0.6018
ETH<0.01%$0.00242219.4723$0.5312
ETH<0.01%$0.01711129.219$0.4999
ETH<0.01%$0.02273820.9015$0.4752
ETH<0.01%$0.1342683.393$0.4555
ETH<0.01%$0.001205369.0643$0.4448
ETH<0.01%$0.3007141.4624$0.4397
ETH<0.01%$15.980.0273$0.4367
ETH<0.01%<$0.00000151,000,000$0.4341
ETH<0.01%$0.01942121.0899$0.4095
ETH<0.01%$0.02293517.505$0.4014
ETH<0.01%$0.00000755,180.7229$0.3724
ETH<0.01%$0.1382332.5285$0.3495
ETH<0.01%$1.340.2465$0.3303
ETH<0.01%$0.01398422.7893$0.3186
ETH<0.01%$1.160.268$0.3109
ETH<0.01%$0.1249582.4557$0.3068
ETH<0.01%$0.0740754.1039$0.3039
ETH<0.01%<$0.0000013,204,027.7478$0.2906
ETH<0.01%$0.0000873,167.5445$0.2744
ETH<0.01%$0.01705115.4698$0.2637
ETH<0.01%$3.860.0617$0.2383
ETH<0.01%$763.920.00030946$0.2364
ETH<0.01%$0.1393221.5457$0.2153
ETH<0.01%$0.1135381.8443$0.2093
ETH<0.01%$19.720.00913252$0.18
ETH<0.01%$1.120.1569$0.1762
ETH<0.01%$0.2539680.6561$0.1666
ETH<0.01%$8.340.0196$0.1635
ETH<0.01%$0.0424133.7204$0.1577
ETH<0.01%$0.0000354,296.7943$0.1485
ETH<0.01%$0.00428933.0734$0.1418
ETH<0.01%$0.1007861.3685$0.1379
ETH<0.01%$0.00790415.5732$0.123
ETH<0.01%$0.796930.1413$0.1125
ETH<0.01%$0.0390622.626$0.1025
ETH<0.01%$0.00597517.0339$0.1017
ARB5.29%$0.999703933.3299$933.05
ARB3.57%$77,7180.00810433$629.85
ARB1.14%$0.998866202.2551$202.03
ARB
Ether (ETH)
0.81%$2,288.730.0626$143.37
ARB0.35%$2,652.130.0231$61.38
ARB0.22%$0.99970339.1958$39.18
ARB0.14%$2,293.280.0104$23.96
ARB0.13%$6.153.6187$22.26
ARB0.09%$0.93441116.1146$15.06
ARB0.07%$9.561.2424$11.88
ARB0.06%$0.13584680.9921$11
ARB0.04%$0.9993466.3508$6.35
ARB0.02%$1.192.9821$3.55
ARB0.02%$1.561.7821$2.78
ARB0.01%$0.2387188.4857$2.03
ARB<0.01%$0.006893174$1.2
ARB<0.01%$0.000215,688.2639$1.19
ARB<0.01%$0.000.00528913$0.00
ARB<0.01%$0.0298679.7323$0.2906
ARB<0.01%$0.9993570.2622$0.262
ARB<0.01%$2.530.0931$0.2354
AVAX4.95%$1087.3675$873.82
AVAX0.32%$0.99970955.9824$55.97
AVAX0.09%$0.9990715.9498$15.93
AVAX0.09%$0.99970915.4476$15.44
AVAX0.07%$77,6630.00014781$11.48
AVAX0.05%$2,277.010.00369349$8.41
AVAX0.02%<$0.00000137,467,597.6145$4.33
AVAX0.02%$0.0025411,138.2544$2.89
AVAX<0.01%$9.560.0318$0.3043
AVAX<0.01%$0.0429463.2648$0.1402
BSC1.41%$0.998999249.8961$249.65
BSC0.84%$764.960.1947$148.97
BSC0.50%$1.6254.5857$88.63
BSC0.43%$0.99970975.2601$75.24
BSC0.08%$0.99946314.8491$14.84
BSC0.08%$0.99859914.45$14.43
BSC0.07%$2,292.820.00576803$13.23
BSC0.06%$1.526.6898$10.15
BSC0.05%$3.572.3653$8.45
BSC0.02%$9.560.4437$4.24
BSC0.02%$764.280.00410128$3.13
BSC0.01%$77,742.040.00002323$1.81
BSC<0.01%$1.541.135$1.75
BSC<0.01%$0.2230676.021$1.34
BSC<0.01%$102.840.00914768$0.9407
BSC<0.01%$1.30.6929$0.9027
BSC<0.01%$0.00691120.0329$0.8294
BSC<0.01%$0.104496.9299$0.7241
BSC<0.01%$3.610.1881$0.679
BSC<0.01%$0.00003519,339.5184$0.6672
BSC<0.01%$0.00000784,708.9231$0.6005
BSC<0.01%$0.1051444.0754$0.4285
BSC<0.01%$0.02407716.5026$0.3973
BSC<0.01%$0.01142230.0001$0.3426
BSC<0.01%$0.2937751.1399$0.3348
BSC<0.01%$0.9978870.3129$0.3122
BSC<0.01%$0.0502496.0484$0.3039
BSC<0.01%$0.2834431.0651$0.3018
BSC<0.01%$1.950.137$0.2667
BSC<0.01%$0.0914522.7989$0.2559
BSC<0.01%$0.01957210.9214$0.2137
BSC<0.01%$0.9997450.2074$0.2073
BSC<0.01%$0.0637652.15$0.137
BSC<0.01%$3.920.0316$0.1238
BSC<0.01%$0.00648216.9681$0.1099
BSC<0.01%$127.610.00085149$0.1086
BSC<0.01%<$0.0000017,454,439.8936$0.1041
POL1.38%$0.999743243.9563$243.89
POL0.45%$0.99908979.2643$79.19
POL0.10%$2,292.820.0077281$17.72
POL0.06%$102.860.105$10.8
POL0.05%$18.742$8.75
POL0.03%$0.9997434.5026$4.5
POL0.02%$0.029825111.279$3.32
POL0.02%$0.10058129.2931$2.95
POL0.02%$77,3950.00003548$2.75
POL0.01%$0.2815376.7532$1.9
POL<0.01%$0.07086214.9641$1.06
POL<0.01%$0.1038119.6584$1
POL<0.01%$3.920.2265$0.8879
POL<0.01%$9.540.0711$0.6781
POL<0.01%$1.560.3612$0.5634
POL<0.01%$0.9310460.5168$0.4811
POL<0.01%$127.260.00366319$0.4661
POL<0.01%$0.1038514.4225$0.4592
POL<0.01%$4,784.730.00006972$0.3336
POL<0.01%$2,801.230.00006204$0.1737
POL<0.01%$0.000.9843$0.00
POL<0.01%$0.1129921.1179$0.1263
POL<0.01%$10.050.01$0.1005
OP0.48%$0.99962284.3228$84.29
OP0.08%$2,288.210.00583709$13.36
OP0.06%$77,5490.00014679$11.38
OP0.03%$0.9990175.6168$5.61
OP0.01%$0.2298411.3112$2.6
OP<0.01%$0.3419560.8978$0.307
OP<0.01%$0.9996220.1251$0.125
BASE0.20%$2,288.980.0154$35.22
BASE0.07%$0.99836112.9047$12.88
BASE0.04%$0.9996226.5134$6.51
BASE0.04%$0.019895320$6.37
BASE<0.01%$0.6401391.564$1
BASE<0.01%$77,7590.00000991$0.7705
BASE<0.01%$0.3878031.6355$0.6342
BASE<0.01%$1.190.4262$0.5071
BASE<0.01%$0.0001072,630.5461$0.2803
GNO<0.01%$0.9997270.3301$0.330046
GNO<0.01%$114.70.00119887$0.1375
LINEA<0.01%$2,283.420.000000085$0.000194
Loading...
Loading
Loading...
Loading
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.