ETH Price: $2,345.12 (-1.86%)

Contract

0x6f5d8A4479855bF0222EE8f7C1DFFfdD113f7Ca7
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040144982102022-04-01 4:29:07916 days ago1648787347IN
 Create: BalancerV2Adapter
0 ETH0.0274357149.53662416

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BalancerV2Adapter

Compiler Version
v0.6.9+commit.3e3065ac

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-01
*/

// File: contracts/SmartRoute/intf/IDODOAdapter.sol

/*

    Copyright 2022 DODO ZOO.
    SPDX-License-Identifier: Apache-2.0

*/

pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;

interface IDODOAdapter {
    
    function sellBase(address to, address pool, bytes memory data) external;

    function sellQuote(address to, address pool, bytes memory data) external;
}

// File: contracts/SmartRoute/intf/IAsset.sol



/**
 * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero
 * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like
 * types.
 *
 * This concept is unrelated to a Pool's Asset Managers.
 */
interface IAsset {
    // solhint-disable-previous-line no-empty-blocks
}

// File: contracts/SmartRoute/intf/IBalV2.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 IBalV2 {
    
    /*
    function getPoolTokenInfo(bytes32 poolId, IERC20 token)
        external
        view
        returns (
            uint256 cash,
            uint256 managed,
            uint256 lastChangeBlock,
            address assetManager
        );
    */
    /**
     * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of
     * the tokens' `balances` changed.
     *
     * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all
     * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order.
     *
     * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same
     * order as passed to `registerTokens`.
     *
     * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are
     * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo`
     * instead.
     */
     /*
    function getPoolTokens(bytes32 poolId)
        external
        view
        returns (
            IERC20[] memory tokens,
            uint256[] memory balances,
            uint256 lastChangeBlock
        );
    */


    // Swaps
    //
    // Users can swap tokens with Pools by calling the `swap` and `batchSwap` functions. To do this,
    // they need not trust Pool contracts in any way: all security checks are made by the Vault. They must however be
    // aware of the Pools' pricing algorithms in order to estimate the prices Pools will quote.
    //
    // The `swap` function executes a single swap, while `batchSwap` can perform multiple swaps in sequence.
    // In each individual swap, tokens of one kind are sent from the sender to the Pool (this is the 'token in'),
    // and tokens of another kind are sent from the Pool to the recipient in exchange (this is the 'token out').
    // More complex swaps, such as one token in to multiple tokens out can be achieved by batching together
    // individual swaps.
    //
    // There are two swap kinds:
    //  - 'given in' swaps, where the amount of tokens in (sent to the Pool) is known, and the Pool determines (via the
    // `onSwap` hook) the amount of tokens out (to send to the recipient).
    //  - 'given out' swaps, where the amount of tokens out (received from the Pool) is known, and the Pool determines
    // (via the `onSwap` hook) the amount of tokens in (to receive from the sender).
    //
    // Additionally, it is possible to chain swaps using a placeholder input amount, which the Vault replaces with
    // the calculated output of the previous swap. If the previous swap was 'given in', this will be the calculated
    // tokenOut amount. If the previous swap was 'given out', it will use the calculated tokenIn amount. These extended
    // swaps are known as 'multihop' swaps, since they 'hop' through a number of intermediate tokens before arriving at
    // the final intended token.
    //
    // In all cases, tokens are only transferred in and out of the Vault (or withdrawn from and deposited into Internal
    // Balance) after all individual swaps have been completed, and the net token balance change computed. This makes
    // certain swap patterns, such as multihops, or swaps that interact with the same token pair in multiple Pools, cost
    // much less gas than they would otherwise.
    //
    // It also means that under certain conditions it is possible to perform arbitrage by swapping with multiple
    // Pools in a way that results in net token movement out of the Vault (profit), with no tokens being sent in (only
    // updating the Pool's internal accounting).
    //
    // To protect users from front-running or the market changing rapidly, they supply a list of 'limits' for each token
    // involved in the swap, where either the maximum number of tokens to send (by passing a positive value) or the
    // minimum amount of tokens to receive (by passing a negative value) is specified.
    //
    // Additionally, a 'deadline' timestamp can also be provided, forcing the swap to fail if it occurs after
    // this point in time (e.g. if the transaction failed to be included in a block promptly).
    //
    // If interacting with Pools that hold WETH, it is possible to both send and receive ETH directly: the Vault will do
    // the wrapping and unwrapping. To enable this mechanism, the IAsset sentinel value (the zero address) must be
    // passed in the `assets` array instead of the WETH address. Note that it is possible to combine ETH and WETH in the
    // same swap. Any excess ETH will be sent back to the caller (not the sender, which is relevant for relayers).
    //
    // Finally, Internal Balance can be used when either sending or receiving tokens.

    enum SwapKind { GIVEN_IN, GIVEN_OUT }

    /**
     * @dev Performs a swap with a single Pool.
     *
     * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens
     * taken from the Pool, which must be greater than or equal to `limit`.
     *
     * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens
     * sent to the Pool, which must be less than or equal to `limit`.
     *
     * Internal Balance usage and the recipient are determined by the `funds` struct.
     *
     * Emits a `Swap` event.
     */
    function swap(
        SingleSwap memory singleSwap,
        FundManagement memory funds,
        uint256 limit,
        uint256 deadline
    ) external payable returns (uint256);

    /**
     * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on
     * the `kind` value.
     *
     * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address).
     * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault.
     *
     * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be
     * used to extend swap behavior.
     */
    struct SingleSwap {
        bytes32 poolId;
        SwapKind kind;
        IAsset assetIn;
        IAsset assetOut;
        uint256 amount;
        bytes userData;
    }

    /**
     * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either
     * the amount of tokens sent to or received from the Pool, depending on the `kind` value.
     *
     * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the
     * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at
     * the same index in the `assets` array.
     *
     * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a
     * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or
     * `amountOut` depending on the swap kind.
     *
     * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out
     * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal
     * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`.
     *
     * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses,
     * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and
     * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to
     * or unwrapped from WETH by the Vault.
     *
     * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies
     * the minimum or maximum amount of each token the vault is allowed to transfer.
     *
     * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the
     * equivalent `swap` call.
     *
     * Emits `Swap` events.
     */
    function batchSwap(
        SwapKind kind,
        BatchSwapStep[] memory swaps,
        IAsset[] memory assets,
        FundManagement memory funds,
        int256[] memory limits,
        uint256 deadline
    ) external payable returns (int256[] memory);

    /**
     * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the
     * `assets` array passed to that function, and ETH assets are converted to WETH.
     *
     * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out
     * from the previous swap, depending on the swap kind.
     *
     * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be
     * used to extend swap behavior.
     */
    struct BatchSwapStep {
        bytes32 poolId;
        uint256 assetInIndex;
        uint256 assetOutIndex;
        uint256 amount;
        bytes userData;
    }

    /**
     * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the
     * `recipient` account.
     *
     * If the caller is not `sender`, it must be an authorized relayer for them.
     *
     * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20
     * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender`
     * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of
     * `joinPool`.
     *
     * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of
     * transferred. This matches the behavior of `exitPool`.
     *
     * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a
     * revert.
     */
    struct FundManagement {
        address sender;
        bool fromInternalBalance;
        address payable recipient;
        bool toInternalBalance;
    }

    /**
     * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be
     * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result.
     *
     * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH)
     * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it
     * receives are the same that an equivalent `batchSwap` call would receive.
     *
     * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct.
     * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens,
     * approve them for the Vault, or even know a user's address.
     *
     * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute
     * eth_call instead of eth_sendTransaction.
     */
    function queryBatchSwap(
        SwapKind kind,
        BatchSwapStep[] memory swaps,
        IAsset[] memory assets,
        FundManagement memory funds
    ) external returns (int256[] memory assetDeltas);


}

// File: contracts/intf/IERC20.sol



/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    function decimals() external view returns (uint8);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    /**
     * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        uint256 amount
    ) external returns (bool);
}

// File: contracts/lib/SafeMath.sol




/**
 * @title SafeMath
 * @author DODO Breeder
 *
 * @notice Math operations with safety checks that revert on error
 */
library SafeMath {
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "MUL_ERROR");

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "DIVIDING_ERROR");
        return a / b;
    }

    function divCeil(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 quotient = div(a, b);
        uint256 remainder = a - quotient * b;
        if (remainder > 0) {
            return quotient + 1;
        } else {
            return quotient;
        }
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SUB_ERROR");
        return a - b;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "ADD_ERROR");
        return c;
    }

    function sqrt(uint256 x) internal pure returns (uint256 y) {
        uint256 z = x / 2 + 1;
        y = x;
        while (z < y) {
            y = z;
            z = (x / z + z) / 2;
        }
    }
}

// File: contracts/lib/SafeERC20.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 ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
        );
    }

    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'
        // solhint-disable-next-line max-line-length
        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 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.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) {
            // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: contracts/SmartRoute/lib/UniversalERC20.sol






library UniversalERC20 {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    function universalTransfer(
        IERC20 token,
        address payable to,
        uint256 amount
    ) internal {
        if (amount > 0) {
            if (isETH(token)) {
                to.transfer(amount);
            } else {
                token.safeTransfer(to, amount);
            }
        }
    }

    function universalApproveMax(
        IERC20 token,
        address to,
        uint256 amount
    ) internal {
        uint256 allowance = token.allowance(address(this), to);
        if (allowance < amount) {
            if (allowance > 0) {
                token.safeApprove(to, 0);
            }
            token.safeApprove(to, uint256(-1));
        }
    }

    function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) {
        if (isETH(token)) {
            return who.balance;
        } else {
            return token.balanceOf(who);
        }
    }

    function tokenBalanceOf(IERC20 token, address who) internal view returns (uint256) {
        return token.balanceOf(who);
    }

    function isETH(IERC20 token) internal pure returns (bool) {
        return token == ETH_ADDRESS;
    }
}

// File: contracts/SmartRoute/adapter/BalancerV2Adapter.sol

// for two tokens; to adapter like dodo V1
contract BalancerV2Adapter is IDODOAdapter {
    using SafeMath for uint;
    using UniversalERC20 for IERC20;

    // migrate struct from balv2
    enum SwapKind { GIVEN_IN, GIVEN_OUT }

    struct SingleSwap {
        bytes32 poolId;
        SwapKind kind;
        IAsset assetIn;
        IAsset assetOut;
        uint256 amount;
        bytes userData;
    }

    struct FundManagement {
        address sender;
        bool fromInternalBalance;
        address payable recipient;
        bool toInternalBalance;
    }
    
    //====================== swap =======================

    // As assets are saved by vault instead of pools, the follow pool = vault
    function _balV2Swap(address to, address pool, bytes memory moreInfo) internal {
        (bytes32 poolId, address fromToken, address toToken) = abi.decode(moreInfo, (bytes32, address, address));
        uint256 sellAmount = IERC20(fromToken).balanceOf(address(this));

        // construct SingleSwap
        IBalV2.SingleSwap memory singleSwap;
        singleSwap.poolId = poolId;
        singleSwap.kind = IBalV2.SwapKind.GIVEN_IN;
        singleSwap.assetIn = IAsset(fromToken);
        singleSwap.assetOut = IAsset(toToken);
        singleSwap.amount = sellAmount;
        singleSwap.userData = "0x";

        //construct fundmanagement
        IBalV2.FundManagement memory fundManagement;
        fundManagement.fromInternalBalance = false;
        fundManagement.toInternalBalance = false;
        fundManagement.sender = address(this);
        fundManagement.recipient = payable(to);

        // approve
        IERC20(fromToken).universalApproveMax(pool, sellAmount);
        // swap
        IBalV2(pool).swap(singleSwap, fundManagement, 0, 999999999999999999); //deadline: infinity
    }

    function sellBase(address to, address pool, bytes memory moreInfo) external override {
        _balV2Swap(to, pool, moreInfo);
    }

    function sellQuote(address to, address pool, bytes memory moreInfo) external override {
        _balV2Swap(to, pool, moreInfo);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"moreInfo","type":"bytes"}],"name":"sellBase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes","name":"moreInfo","type":"bytes"}],"name":"sellQuote","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061090e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806330e6ae311461003b5780636f7929f21461003b575b600080fd5b61004e61004936600461051b565b610050565b005b61005b838383610060565b505050565b6000806000838060200190518101906100799190610602565b9250925092506000826001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016100ad91906106e6565b60206040518083038186803b1580156100c557600080fd5b505afa1580156100d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fd9190610644565b90506101076104ab565b848152600060208201819052506001600160a01b0380851660408084019190915290841660608301526080820183905280518082019091526002815261060f60f31b602082015260a082015261015b6104f4565b60006020820181905260608201523081526001600160a01b03898116604083015261018f908616898563ffffffff61022816565b6040516352bbbe2960e01b81526001600160a01b038916906352bbbe29906101ca9085908590600090670de0b6b3a763ffff90600401610802565b602060405180830381600087803b1580156101e457600080fd5b505af11580156101f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061021c9190610644565b50505050505050505050565b604051636eb1769f60e11b81526000906001600160a01b0385169063dd62ed3e9061025990309087906004016106fa565b60206040518083038186803b15801561027157600080fd5b505afa158015610285573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a99190610644565b9050818110156102f05780156102d4576102d46001600160a01b03851684600063ffffffff6102f616565b6102f06001600160a01b0385168460001963ffffffff6102f616565b50505050565b80158061037e5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e9061032c90309086906004016106fa565b60206040518083038186803b15801561034457600080fd5b505afa158015610358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037c9190610644565b155b6103a35760405162461bcd60e51b815260040161039a906107ac565b60405180910390fd5b61005b8363095ea7b360e01b84846040516024016103c2929190610714565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915260006060836001600160a01b03168360405161041091906106ca565b6000604051808303816000865af19150503d806000811461044d576040519150601f19603f3d011682016040523d82523d6000602084013e610452565b606091505b5091509150816104745760405162461bcd60e51b815260040161039a9061072d565b8051156102f0578080602001905181019061048f91906105db565b6102f05760405162461bcd60e51b815260040161039a90610762565b6040805160c0810190915260008082526020820190815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001606081525090565b60408051608081018252600080825260208201819052918101829052606081019190915290565b60008060006060848603121561052f578283fd5b833561053a816108c0565b925060208481013561054b816108c0565b9250604085013567ffffffffffffffff80821115610567578384fd5b81870188601f820112610578578485fd5b8035925081831115610588578485fd5b604051601f8401601f19168101850183811182821017156105a7578687fd5b60405283815281840185018a10156105bd578586fd5b83858301868301378585858301015280955050505050509250925092565b6000602082840312156105ec578081fd5b815180151581146105fb578182fd5b9392505050565b600080600060608486031215610616578283fd5b835192506020840151610628816108c0565b6040850151909250610639816108c0565b809150509250925092565b600060208284031215610655578081fd5b5051919050565b60008151808452610674816020860160208601610894565b601f01601f19169290920160200192915050565b6001600160a01b03169052565b80516001600160a01b039081168352602080830151151590840152604080830151909116908301526060908101511515910152565b600082516106dc818460208701610894565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b600060e08252855160e083015260208601516002811061081e57fe5b6101008301526040860151610837610120840182610688565b50606086015161084b610140840182610688565b50608086015161016083015260a086015160c06101808401526108726101a084018261065c565b9150506108826020830186610695565b60a082019390935260c0015292915050565b60005b838110156108af578181015183820152602001610897565b838111156102f05750506000910152565b6001600160a01b03811681146108d557600080fd5b5056fea264697066735822122089c81e603f648fbbff423ec40e71b6b349b12c368b6f9a7f267eb35420afb22864736f6c63430006090033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100365760003560e01c806330e6ae311461003b5780636f7929f21461003b575b600080fd5b61004e61004936600461051b565b610050565b005b61005b838383610060565b505050565b6000806000838060200190518101906100799190610602565b9250925092506000826001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016100ad91906106e6565b60206040518083038186803b1580156100c557600080fd5b505afa1580156100d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fd9190610644565b90506101076104ab565b848152600060208201819052506001600160a01b0380851660408084019190915290841660608301526080820183905280518082019091526002815261060f60f31b602082015260a082015261015b6104f4565b60006020820181905260608201523081526001600160a01b03898116604083015261018f908616898563ffffffff61022816565b6040516352bbbe2960e01b81526001600160a01b038916906352bbbe29906101ca9085908590600090670de0b6b3a763ffff90600401610802565b602060405180830381600087803b1580156101e457600080fd5b505af11580156101f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061021c9190610644565b50505050505050505050565b604051636eb1769f60e11b81526000906001600160a01b0385169063dd62ed3e9061025990309087906004016106fa565b60206040518083038186803b15801561027157600080fd5b505afa158015610285573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a99190610644565b9050818110156102f05780156102d4576102d46001600160a01b03851684600063ffffffff6102f616565b6102f06001600160a01b0385168460001963ffffffff6102f616565b50505050565b80158061037e5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e9061032c90309086906004016106fa565b60206040518083038186803b15801561034457600080fd5b505afa158015610358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037c9190610644565b155b6103a35760405162461bcd60e51b815260040161039a906107ac565b60405180910390fd5b61005b8363095ea7b360e01b84846040516024016103c2929190610714565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915260006060836001600160a01b03168360405161041091906106ca565b6000604051808303816000865af19150503d806000811461044d576040519150601f19603f3d011682016040523d82523d6000602084013e610452565b606091505b5091509150816104745760405162461bcd60e51b815260040161039a9061072d565b8051156102f0578080602001905181019061048f91906105db565b6102f05760405162461bcd60e51b815260040161039a90610762565b6040805160c0810190915260008082526020820190815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001606081525090565b60408051608081018252600080825260208201819052918101829052606081019190915290565b60008060006060848603121561052f578283fd5b833561053a816108c0565b925060208481013561054b816108c0565b9250604085013567ffffffffffffffff80821115610567578384fd5b81870188601f820112610578578485fd5b8035925081831115610588578485fd5b604051601f8401601f19168101850183811182821017156105a7578687fd5b60405283815281840185018a10156105bd578586fd5b83858301868301378585858301015280955050505050509250925092565b6000602082840312156105ec578081fd5b815180151581146105fb578182fd5b9392505050565b600080600060608486031215610616578283fd5b835192506020840151610628816108c0565b6040850151909250610639816108c0565b809150509250925092565b600060208284031215610655578081fd5b5051919050565b60008151808452610674816020860160208601610894565b601f01601f19169290920160200192915050565b6001600160a01b03169052565b80516001600160a01b039081168352602080830151151590840152604080830151909116908301526060908101511515910152565b600082516106dc818460208701610894565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b600060e08252855160e083015260208601516002811061081e57fe5b6101008301526040860151610837610120840182610688565b50606086015161084b610140840182610688565b50608086015161016083015260a086015160c06101808401526108726101a084018261065c565b9150506108826020830186610695565b60a082019390935260c0015292915050565b60005b838110156108af578181015183820152602001610897565b838111156102f05750506000910152565b6001600160a01b03811681146108d557600080fd5b5056fea264697066735822122089c81e603f648fbbff423ec40e71b6b349b12c368b6f9a7f267eb35420afb22864736f6c63430006090033

Deployed Bytecode Sourcemap

21727:2101:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23548:134;;;;;;;;;:::i;:::-;;;23644:30;23655:2;23659:4;23665:8;23644:10;:30::i;:::-;23548:134;;;:::o;22421:1119::-;22511:14;22527:17;22546:15;22576:8;22565:49;;;;;;;;;;;;;;22510:104;;;;;;22625:18;22653:9;-1:-1:-1;;;;;22646:27:0;;22682:4;22646:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22625:63;;22734:35;;:::i;:::-;22780:26;;;:17;22817:15;;;22780:17;22817:42;;-1:-1:-1;;;;;;22870:38:0;;;:18;;;;:38;;;;22919:37;;;:19;;;:37;22967:17;;;:30;;;23008:26;;;;;;;;;;;-1:-1:-1;;;;23008:26:0;;;:19;;;:26;23083:43;;:::i;:::-;23174:5;23137:34;;;:42;;;23190:32;;;:40;23273:4;23241:37;;-1:-1:-1;;;;;23289:38:0;;;:24;;;:38;23360:55;;:37;;23398:4;23404:10;23360:55;:37;:55;:::i;:::-;23443:68;;-1:-1:-1;;;23443:68:0;;-1:-1:-1;;;;;23443:17:0;;;;;:68;;23461:10;;23473:14;;23489:1;;23492:18;;23443:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22421:1119;;;;;;;;;:::o;20754:374::-;20899:34;;-1:-1:-1;;;20899:34:0;;20879:17;;-1:-1:-1;;;;;20899:15:0;;;;;:34;;20923:4;;20930:2;;20899:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20879:54;;20960:6;20948:9;:18;20944:177;;;20987:13;;20983:78;;21021:24;-1:-1:-1;;;;;21021:17:0;;21039:2;21043:1;21021:24;:17;:24;:::i;:::-;21075:34;-1:-1:-1;;;;;21075:17:0;;21093:2;-1:-1:-1;;21075:34:0;:17;:34;:::i;:::-;20754:374;;;;:::o;18048:670::-;18466:10;;;18465:62;;-1:-1:-1;18482:39:0;;-1:-1:-1;;;18482:39:0;;-1:-1:-1;;;;;18482:15:0;;;;;:39;;18506:4;;18513:7;;18482:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:44;18465:62;18443:166;;;;-1:-1:-1;;;18443:166:0;;;;;;;;;;;;;;;;;18620:90;18640:5;18670:22;;;18694:7;18703:5;18647:62;;;;;;;;;;;;;;-1:-1:-1;;18647:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;18647:62:0;-1:-1:-1;;;;;;18647:62:0;;;;;;;;;;19769:12;19783:23;19818:5;-1:-1:-1;;;;;19810:19:0;19830:4;19810:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19768:67;;;;19854:7;19846:52;;;;-1:-1:-1;;;19846:52:0;;;;;;;;;19915:17;;:21;19911:237;;20070:10;20059:30;;;;;;;;;;;;;;20051:85;;;;-1:-1:-1;;;20051:85:0;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1165:595::-;;;;1312:2;1300:9;1291:7;1287:23;1283:32;1280:2;;;-1:-1;;1318:12;1280:2;85:6;72:20;97:33;124:5;97:33;;;1370:63;-1:-1;1470:2;1509:22;;;72:20;97:33;72:20;97:33;;;1478:63;-1:-1;1606:2;1591:18;;1578:32;1630:18;1619:30;;;1616:2;;;-1:-1;;1652:12;1616:2;1727:6;1716:9;1712:22;677:3;670:4;662:6;658:17;654:27;644:2;;-1:-1;;685:12;644:2;732:6;719:20;705:34;;1630:18;12091:6;12088:30;12085:2;;;-1:-1;;12121:12;12085:2;1606;11749:9;12194;12175:17;;-1:-1;;12171:33;11781:17;;;;11841:34;;;11877:22;;;11838:62;11835:2;;;-1:-1;;11903:12;11835:2;1606;11922:22;824:21;;;924:16;;;;;921:25;-1:-1;918:2;;;-1:-1;;949:12;918:2;14377:6;1470:2;866:6;862:17;1470:2;900:5;896:16;14354:30;-1:-1;1470:2;14424:6;900:5;14415:16;;14408:27;1672:72;;;;;;;;1274:486;;;;;;1767:257;;1879:2;1867:9;1858:7;1854:23;1850:32;1847:2;;;-1:-1;;1885:12;1847:2;380:6;374:13;15285:5;13168:13;13161:21;15263:5;15260:32;15250:2;;-1:-1;;15296:12;15250:2;1937:71;1841:183;-1:-1;;;1841:183;2031:567;;;;2196:2;2184:9;2175:7;2171:23;2167:32;2164:2;;;-1:-1;;2202:12;2164:2;518:6;512:13;2254:74;;2365:2;2427:9;2423:22;228:13;246:41;281:5;246:41;;;2492:2;2550:22;;228:13;2373:82;;-1:-1;246:41;228:13;246:41;;;2500:82;;;;2158:440;;;;;;2605:263;;2720:2;2708:9;2699:7;2695:23;2691:32;2688:2;;;-1:-1;;2726:12;2688:2;-1:-1;1102:13;;2682:186;-1:-1;2682:186;3450:323;;3582:5;12371:12;12517:6;12512:3;12505:19;3665:52;3710:6;12554:4;12549:3;12545:14;12554:4;3691:5;3687:16;3665:52;;;12194:9;14794:14;-1:-1;;14790:28;3729:39;;;;12554:4;3729:39;;3530:243;-1:-1;;3530:243;4143:142;-1:-1;;;;;13470:54;4217:63;;4211:74;5961:833;6182:23;;-1:-1;;;;;13470:54;;;2952:45;;6368:4;6357:16;;;6351:23;13168:13;13161:21;6422:14;;;3294:34;6521:4;6510:16;;;6504:23;13470:54;;;6597:14;;;2952:45;6704:4;6693:16;;;6687:23;13168:13;13161:21;6758:14;;3294:34;6087:707;8334:271;;3940:5;12371:12;4051:52;4096:6;4091:3;4084:4;4077:5;4073:16;4051:52;;;4115:16;;;;;8468:137;-1:-1;;8468:137;8612:222;-1:-1;;;;;13470:54;;;;2952:45;;8739:2;8724:18;;8710:124;8841:333;-1:-1;;;;;13470:54;;;2952:45;;13470:54;;9160:2;9145:18;;2952:45;8996:2;8981:18;;8967:207;9181:333;-1:-1;;;;;13470:54;;;;2952:45;;9500:2;9485:18;;3401:37;9336:2;9321:18;;9307:207;9521:416;9721:2;9735:47;;;9706:18;;;12505:19;5026:34;12545:14;;;5006:55;5080:12;;;9692:245;9944:416;10144:2;10158:47;;;5331:2;10129:18;;;12505:19;5367:34;12545:14;;;5347:55;-1:-1;;;5422:12;;;5415:34;5468:12;;;10115:245;10367:416;10567:2;10581:47;;;5719:2;10552:18;;;12505:19;5755:34;12545:14;;;5735:55;-1:-1;;;5810:12;;;5803:46;5868:12;;;10538:245;10790:896;;11146:3;11168:17;11161:47;7087:16;7081:23;11146:3;11135:9;11131:19;3401:37;7252:4;7245:5;7241:16;7235:23;14911:1;14904:5;14901:12;14891:2;;14917:9;14891:2;7321:14;;;4362:59;7418:4;7407:16;;7401:23;7430:76;7491:14;;;7401:23;7430:76;;;;7589:4;7582:5;7578:16;7572:23;7601:76;7662:14;11135:9;7662:14;7648:12;7601:76;;;;7758:4;7751:5;7747:16;7741:23;7818:14;11135:9;7818:14;3401:37;7916:4;7909:5;7905:16;7899:23;7013:4;7942:14;11135:9;7942:14;7935:38;7988:71;7004:14;11135:9;7004:14;8040:12;7988:71;;;11214:118;;;11343:132;7252:4;11460:9;11456:18;11447:6;11343:132;;;7916:4;11547:19;;3401:37;;;;7013:4;11656:19;3401:37;11117:569;;-1:-1;;11117:569;14450:268;14515:1;14522:101;14536:6;14533:1;14530:13;14522:101;;;14603:11;;;14597:18;14584:11;;;14577:39;14558:2;14551:10;14522:101;;;14638:6;14635:1;14632:13;14629:2;;;-1:-1;;14515:1;14685:16;;14678:27;14499:219;14940:117;-1:-1;;;;;13470:54;;14999:35;;14989:2;;15048:1;;15038:12;14989:2;14983:74;

Swarm Source

ipfs://89c81e603f648fbbff423ec40e71b6b349b12c368b6f9a7f267eb35420afb228

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  ]

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.