ETH Price: $2,965.34 (+1.16%)
Gas: 1 Gwei

Contract

0x1e8020cFB10b6a6a9B5F06e3ABAe140f7DE541E1
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Create ERC4626160451792022-11-25 6:21:47588 days ago1669357307IN
0x1e8020cF...f7DE541E1
0 ETH0.0188555311.43259291
Create ERC4626160451652022-11-25 6:18:59588 days ago1669357139IN
0x1e8020cF...f7DE541E1
0 ETH0.0185578711.19630522
Create ERC4626155806292022-09-21 8:36:59653 days ago1663749419IN
0x1e8020cF...f7DE541E1
0 ETH0.006999954.25870872
Create ERC4626154992072022-09-08 22:34:33666 days ago1662676473IN
0x1e8020cF...f7DE541E1
0 ETH0.0555175833.67661421
Create ERC4626154864172022-09-06 21:25:36668 days ago1662499536IN
0x1e8020cF...f7DE541E1
0 ETH0.028110917.05098721
Create ERC4626154863612022-09-06 21:13:06668 days ago1662498786IN
0x1e8020cF...f7DE541E1
0 ETH0.0302049518.31637675
0x60c06040154862012022-09-06 20:36:47668 days ago1662496607IN
 Create: EulerERC4626Factory
0 ETH0.0686907928.47271597

Latest 6 internal transactions

Advanced mode:
Parent Transaction Hash Block From To Value
160451792022-11-25 6:21:47588 days ago1669357307
0x1e8020cF...f7DE541E1
 Contract Creation0 ETH
160451652022-11-25 6:18:59588 days ago1669357139
0x1e8020cF...f7DE541E1
 Contract Creation0 ETH
155806292022-09-21 8:36:59653 days ago1663749419
0x1e8020cF...f7DE541E1
 Contract Creation0 ETH
154992072022-09-08 22:34:33666 days ago1662676473
0x1e8020cF...f7DE541E1
 Contract Creation0 ETH
154864172022-09-06 21:25:36668 days ago1662499536
0x1e8020cF...f7DE541E1
 Contract Creation0 ETH
154863612022-09-06 21:13:06668 days ago1662498786
0x1e8020cF...f7DE541E1
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EulerERC4626Factory

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
default evmVersion
File 1 of 10 : EulerERC4626Factory.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {ERC4626} from "solmate/mixins/ERC4626.sol";

import {EulerERC4626} from "./EulerERC4626.sol";
import {IEulerEToken} from "./external/IEulerEToken.sol";
import {ERC4626Factory} from "../base/ERC4626Factory.sol";
import {IEulerMarkets} from "./external/IEulerMarkets.sol";

/// @title EulerERC4626Factory
/// @author zefram.eth
/// @notice Factory for creating EulerERC4626 contracts
contract EulerERC4626Factory is ERC4626Factory {
    /// -----------------------------------------------------------------------
    /// Errors
    /// -----------------------------------------------------------------------

    /// @notice Thrown when trying to deploy an EulerERC4626 vault using an asset without an eToken
    error EulerERC4626Factory__ETokenNonexistent();

    /// -----------------------------------------------------------------------
    /// Immutable params
    /// -----------------------------------------------------------------------

    /// @notice The Euler main contract address
    /// @dev Target of ERC20 approval when depositing
    address public immutable euler;

    /// @notice The Euler markets module address
    IEulerMarkets public immutable markets;

    /// -----------------------------------------------------------------------
    /// Constructor
    /// -----------------------------------------------------------------------

    constructor(address euler_, IEulerMarkets markets_) {
        euler = euler_;
        markets = markets_;
    }

    /// -----------------------------------------------------------------------
    /// External functions
    /// -----------------------------------------------------------------------

    /// @inheritdoc ERC4626Factory
    function createERC4626(ERC20 asset) external virtual override returns (ERC4626 vault) {
        address eTokenAddress = markets.underlyingToEToken(address(asset));
        if (eTokenAddress == address(0)) {
            revert EulerERC4626Factory__ETokenNonexistent();
        }

        vault = new EulerERC4626{salt: bytes32(0)}(asset, euler, IEulerEToken(eTokenAddress));

        emit CreateERC4626(asset, vault);
    }

    /// @inheritdoc ERC4626Factory
    function computeERC4626Address(ERC20 asset) external view virtual override returns (ERC4626 vault) {
        vault = ERC4626(
            _computeCreate2Address(
                keccak256(
                    abi.encodePacked(
                        // Deployment bytecode:
                        type(EulerERC4626).creationCode,
                        // Constructor arguments:
                        abi.encode(asset, euler, IEulerEToken(markets.underlyingToEToken(address(asset))))
                    )
                )
            )
        );
    }
}

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

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

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

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

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

    string public name;

    string public symbol;

    uint8 public immutable decimals;

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

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

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

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

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

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

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

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

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

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

        return true;
    }

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

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

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

        return true;
    }

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

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

        balanceOf[from] -= amount;

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

        emit Transfer(from, to, amount);

        return true;
    }

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

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

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

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

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

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

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

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

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

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

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

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

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

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

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

import {ERC20} from "../tokens/ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";

/// @notice Minimal ERC4626 tokenized Vault implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)
abstract contract ERC4626 is ERC20 {
    using SafeTransferLib for ERC20;
    using FixedPointMathLib for uint256;

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);

    event Withdraw(
        address indexed caller,
        address indexed receiver,
        address indexed owner,
        uint256 assets,
        uint256 shares
    );

    /*//////////////////////////////////////////////////////////////
                               IMMUTABLES
    //////////////////////////////////////////////////////////////*/

    ERC20 public immutable asset;

    constructor(
        ERC20 _asset,
        string memory _name,
        string memory _symbol
    ) ERC20(_name, _symbol, _asset.decimals()) {
        asset = _asset;
    }

    /*//////////////////////////////////////////////////////////////
                        DEPOSIT/WITHDRAWAL LOGIC
    //////////////////////////////////////////////////////////////*/

    function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {
        // Check for rounding error since we round down in previewDeposit.
        require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {
        assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual returns (uint256 assets) {
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        // Check for rounding error since we round down in previewRedeem.
        require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    /*//////////////////////////////////////////////////////////////
                            ACCOUNTING LOGIC
    //////////////////////////////////////////////////////////////*/

    function totalAssets() public view virtual returns (uint256);

    function convertToShares(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
    }

    function convertToAssets(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
    }

    function previewDeposit(uint256 assets) public view virtual returns (uint256) {
        return convertToShares(assets);
    }

    function previewMint(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
    }

    function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
    }

    function previewRedeem(uint256 shares) public view virtual returns (uint256) {
        return convertToAssets(shares);
    }

    /*//////////////////////////////////////////////////////////////
                     DEPOSIT/WITHDRAWAL LIMIT LOGIC
    //////////////////////////////////////////////////////////////*/

    function maxDeposit(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxMint(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxWithdraw(address owner) public view virtual returns (uint256) {
        return convertToAssets(balanceOf[owner]);
    }

    function maxRedeem(address owner) public view virtual returns (uint256) {
        return balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HOOKS LOGIC
    //////////////////////////////////////////////////////////////*/

    function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}

    function afterDeposit(uint256 assets, uint256 shares) internal virtual {}
}

File 4 of 10 : EulerERC4626.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {ERC4626} from "solmate/mixins/ERC4626.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";

import {IEulerEToken} from "./external/IEulerEToken.sol";

/// @title EulerERC4626
/// @author zefram.eth
/// @notice ERC4626 wrapper for Euler Finance
contract EulerERC4626 is ERC4626 {
    /// -----------------------------------------------------------------------
    /// Libraries usage
    /// -----------------------------------------------------------------------

    using SafeTransferLib for ERC20;

    /// -----------------------------------------------------------------------
    /// Immutable params
    /// -----------------------------------------------------------------------

    /// @notice The Euler main contract address
    /// @dev Target of ERC20 approval when depositing
    address public immutable euler;

    /// @notice The Euler eToken contract
    IEulerEToken public immutable eToken;

    /// -----------------------------------------------------------------------
    /// Constructor
    /// -----------------------------------------------------------------------

    constructor(ERC20 asset_, address euler_, IEulerEToken eToken_)
        ERC4626(asset_, _vaultName(asset_), _vaultSymbol(asset_))
    {
        euler = euler_;
        eToken = eToken_;
    }

    /// -----------------------------------------------------------------------
    /// ERC4626 overrides
    /// -----------------------------------------------------------------------

    function totalAssets() public view virtual override returns (uint256) {
        return eToken.balanceOfUnderlying(address(this));
    }

    function beforeWithdraw(uint256 assets, uint256 /*shares*/ ) internal virtual override {
        /// -----------------------------------------------------------------------
        /// Withdraw assets from Euler
        /// -----------------------------------------------------------------------

        eToken.withdraw(0, assets);
    }

    function afterDeposit(uint256 assets, uint256 /*shares*/ ) internal virtual override {
        /// -----------------------------------------------------------------------
        /// Deposit assets into Euler
        /// -----------------------------------------------------------------------

        // approve to euler
        asset.safeApprove(address(euler), assets);

        // deposit into eToken
        eToken.deposit(0, assets);
    }

    function maxWithdraw(address owner) public view override returns (uint256) {
        uint256 cash = asset.balanceOf(euler);
        uint256 assetsBalance = convertToAssets(balanceOf[owner]);
        return cash < assetsBalance ? cash : assetsBalance;
    }

    function maxRedeem(address owner) public view override returns (uint256) {
        uint256 cash = asset.balanceOf(euler);
        uint256 cashInShares = convertToShares(cash);
        uint256 shareBalance = balanceOf[owner];
        return cashInShares < shareBalance ? cashInShares : shareBalance;
    }

    /// -----------------------------------------------------------------------
    /// ERC20 metadata generation
    /// -----------------------------------------------------------------------

    function _vaultName(ERC20 asset_) internal view virtual returns (string memory vaultName) {
        vaultName = string.concat("ERC4626-Wrapped Euler ", asset_.symbol());
    }

    function _vaultSymbol(ERC20 asset_) internal view virtual returns (string memory vaultSymbol) {
        vaultSymbol = string.concat("we", asset_.symbol());
    }
}

File 5 of 10 : IEulerEToken.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

/// @notice Tokenised representation of assets
interface IEulerEToken {
    /// @notice Balance of a particular account, in underlying units (increases as interest is earned)
    function balanceOfUnderlying(address account) external view returns (uint256);

    /// @notice Transfer underlying tokens from sender to the Euler pool, and increase account's eTokens
    /// @param subAccountId 0 for primary, 1-255 for a sub-account
    /// @param amount In underlying units (use max uint256 for full underlying token balance)
    function deposit(uint256 subAccountId, uint256 amount) external;

    /// @notice Transfer underlying tokens from Euler pool to sender, and decrease account's eTokens
    /// @param subAccountId 0 for primary, 1-255 for a sub-account
    /// @param amount In underlying units (use max uint256 for full pool balance)
    function withdraw(uint256 subAccountId, uint256 amount) external;
}

File 6 of 10 : ERC4626Factory.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {ERC4626} from "solmate/mixins/ERC4626.sol";
import {Bytes32AddressLib} from "solmate/utils/Bytes32AddressLib.sol";

/// @title ERC4626Factory
/// @author zefram.eth
/// @notice Abstract base contract for deploying ERC4626 wrappers
/// @dev Uses CREATE2 deterministic deployment, so there can only be a single
/// vault for each asset.
abstract contract ERC4626Factory {
    /// -----------------------------------------------------------------------
    /// Library usage
    /// -----------------------------------------------------------------------

    using Bytes32AddressLib for bytes32;

    /// -----------------------------------------------------------------------
    /// Events
    /// -----------------------------------------------------------------------

    /// @notice Emitted when a new ERC4626 vault has been created
    /// @param asset The base asset used by the vault
    /// @param vault The vault that was created
    event CreateERC4626(ERC20 indexed asset, ERC4626 vault);

    /// -----------------------------------------------------------------------
    /// External functions
    /// -----------------------------------------------------------------------

    /// @notice Creates an ERC4626 vault for an asset
    /// @dev Uses CREATE2 deterministic deployment, so there can only be a single
    /// vault for each asset. Will revert if a vault has already been deployed for the asset.
    /// @param asset The base asset used by the vault
    /// @return vault The vault that was created
    function createERC4626(ERC20 asset) external virtual returns (ERC4626 vault);

    /// @notice Computes the address of the ERC4626 vault corresponding to an asset. Returns
    /// a valid result regardless of whether the vault has already been deployed.
    /// @param asset The base asset used by the vault
    /// @return vault The vault corresponding to the asset
    function computeERC4626Address(ERC20 asset) external view virtual returns (ERC4626 vault);

    /// -----------------------------------------------------------------------
    /// Internal functions
    /// -----------------------------------------------------------------------

    /// @notice Computes the address of a contract deployed by this factory using CREATE2, given
    /// the bytecode hash of the contract. Can also be used to predict addresses of contracts yet to
    /// be deployed.
    /// @dev Always uses bytes32(0) as the salt
    /// @param bytecodeHash The keccak256 hash of the creation code of the contract being deployed concatenated
    /// with the ABI-encoded constructor arguments.
    /// @return The address of the deployed contract
    function _computeCreate2Address(bytes32 bytecodeHash) internal view virtual returns (address) {
        return keccak256(abi.encodePacked(bytes1(0xFF), address(this), bytes32(0), bytecodeHash))
            // Prefix:
            // Creator:
            // Salt:
            // Bytecode hash:
            .fromLast20Bytes(); // Convert the CREATE2 hash into an address.
    }
}

File 7 of 10 : IEulerMarkets.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

/// @notice Activating and querying markets, and maintaining entered markets lists
interface IEulerMarkets {
    /// @notice Given an underlying, lookup the associated EToken
    /// @param underlying Token address
    /// @return EToken address, or address(0) if not activated
    function underlyingToEToken(address underlying) external view returns (address);
}

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

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

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

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

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

        require(success, "ETH_TRANSFER_FAILED");
    }

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

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

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

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

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

        require(success, "TRANSFER_FROM_FAILED");
    }

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

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

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

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

        require(success, "TRANSFER_FAILED");
    }

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

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

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

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

        require(success, "APPROVE_FAILED");
    }
}

File 9 of 10 : FixedPointMathLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        assembly {
            // Start off with z at 1.
            z := 1

            // Used below to help find a nearby power of 2.
            let y := x

            // Find the lowest power of 2 that is at least sqrt(x).
            if iszero(lt(y, 0x100000000000000000000000000000000)) {
                y := shr(128, y) // Like dividing by 2 ** 128.
                z := shl(64, z) // Like multiplying by 2 ** 64.
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z) // Like multiplying by 2 ** 32.
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z) // Like multiplying by 2 ** 16.
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z) // Like multiplying by 2 ** 8.
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z) // Like multiplying by 2 ** 4.
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z) // Like multiplying by 2 ** 2.
            }
            if iszero(lt(y, 0x8)) {
                // Equivalent to 2 ** z.
                z := shl(1, z)
            }

            // Shifting right by 1 is like dividing by 2.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // Compute a rounded down version of z.
            let zRoundDown := div(x, z)

            // If zRoundDown is smaller, use it.
            if lt(zRoundDown, z) {
                z := zRoundDown
            }
        }
    }
}

File 10 of 10 : Bytes32AddressLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Library for converting between addresses and bytes32 values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/Bytes32AddressLib.sol)
library Bytes32AddressLib {
    function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
        return address(uint160(uint256(bytesValue)));
    }

    function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {
        return bytes32(bytes20(addressValue));
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"euler_","type":"address"},{"internalType":"contract IEulerMarkets","name":"markets_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EulerERC4626Factory__ETokenNonexistent","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract ERC20","name":"asset","type":"address"},{"indexed":false,"internalType":"contract ERC4626","name":"vault","type":"address"}],"name":"CreateERC4626","type":"event"},{"inputs":[{"internalType":"contract ERC20","name":"asset","type":"address"}],"name":"computeERC4626Address","outputs":[{"internalType":"contract ERC4626","name":"vault","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ERC20","name":"asset","type":"address"}],"name":"createERC4626","outputs":[{"internalType":"contract ERC4626","name":"vault","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"euler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"markets","outputs":[{"internalType":"contract IEulerMarkets","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b50604051612bd0380380612bd083398101604081905261002f9161005e565b6001600160a01b039182166080521660a052610098565b6001600160a01b038116811461005b57600080fd5b50565b6000806040838503121561007157600080fd5b825161007c81610046565b602084015190925061008d81610046565b809150509250929050565b60805160a051612af96100d760003960008181605d015281816101af01526102fa01526000818160dc0152818161018d01526103bf0152612af96000f3fe60806040523480156200001157600080fd5b5060043610620000525760003560e01c80633ac2a032146200005757806380cfde3c14620000a8578063abeccaa414620000bf578063db661b7114620000d6575b600080fd5b6200007f7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6200007f620000b93660046200054d565b620000fe565b6200007f620000d03660046200054d565b620002b0565b6200007f7f000000000000000000000000000000000000000000000000000000000000000081565b6000620002aa60405180602001620001169062000519565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f9091011660408190527f8948874900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015285917f0000000000000000000000000000000000000000000000000000000000000000917f00000000000000000000000000000000000000000000000000000000000000001690638948874990602401602060405180830381865afa158015620001f7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021d919062000574565b6040805173ffffffffffffffffffffffffffffffffffffffff9485166020820152928416908301529091166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526200028e9291602001620005c6565b6040516020818303038152906040528051906020012062000493565b92915050565b6040517f8948874900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015260009182917f00000000000000000000000000000000000000000000000000000000000000001690638948874990602401602060405180830381865afa15801562000342573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000368919062000574565b905073ffffffffffffffffffffffffffffffffffffffff8116620003b8576040517f9c8b003300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b837f000000000000000000000000000000000000000000000000000000000000000083604051620003ed9062000519565b73ffffffffffffffffffffffffffffffffffffffff9384168152918316602083015290911660408201526060018190604051809103906000f59050801580156200043b573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff8083168252919350908416907fcbd4e5d1362721c7fd10daaabb1a046344447d4798be55684b8a6b4fc1765d729060200160405180910390a250919050565b6040517fff0000000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660218201526000603582018190526055820183905290620002aa906075016040516020818303038152906040528051906020012090565b6124dc80620005e883390190565b73ffffffffffffffffffffffffffffffffffffffff811681146200054a57600080fd5b50565b6000602082840312156200056057600080fd5b81356200056d8162000527565b9392505050565b6000602082840312156200058757600080fd5b81516200056d8162000527565b6000815160005b81811015620005b757602081850181015186830152016200059b565b50600093019283525090919050565b6000620005df620005d8838662000594565b8462000594565b94935050505056fe6101406040523480156200001257600080fd5b50604051620024dc380380620024dc8339810160408190526200003591620002d4565b8262000041816200010f565b6200004c85620001a2565b8181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b3919062000328565b6000620000c18482620003f9565b506001620000d08382620003f9565b5060ff81166080524660a052620000e66200021f565b60c0525050506001600160a01b0392831660e05250509182166101005216610120525062000694565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000150573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200017a9190810190620004eb565b6040516020016200018c9190620005a3565b6040516020818303038152906040529050919050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200020d9190810190620004eb565b6040516020016200018c9190620005ea565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405162000253919062000616565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0381168114620002d157600080fd5b50565b600080600060608486031215620002ea57600080fd5b8351620002f781620002bb565b60208501519093506200030a81620002bb565b60408501519092506200031d81620002bb565b809150509250925092565b6000602082840312156200033b57600080fd5b815160ff811681146200034d57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200037f57607f821691505b602082108103620003a057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003f457600081815260208120601f850160051c81016020861015620003cf5750805b601f850160051c820191505b81811015620003f057828155600101620003db565b5050505b505050565b81516001600160401b0381111562000415576200041562000354565b6200042d816200042684546200036a565b84620003a6565b602080601f8311600181146200046557600084156200044c5750858301515b600019600386901b1c1916600185901b178555620003f0565b600085815260208120601f198616915b82811015620004965788860151825594840194600190910190840162000475565b5085821015620004b55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60005b83811015620004e2578181015183820152602001620004c8565b50506000910152565b600060208284031215620004fe57600080fd5b81516001600160401b03808211156200051657600080fd5b818401915084601f8301126200052b57600080fd5b81518181111562000540576200054062000354565b604051601f8201601f19908116603f011681019083821181831017156200056b576200056b62000354565b816040528281528760208487010111156200058557600080fd5b62000598836020830160208801620004c5565b979650505050505050565b7f455243343632362d577261707065642045756c65722000000000000000000000815260008251620005dd816016850160208701620004c5565b9190910160160192915050565b61776560f01b81526000825162000609816002850160208701620004c5565b9190910160020192915050565b600080835462000626816200036a565b60018281168015620006415760018114620006575762000688565b60ff198416875282151583028701945062000688565b8760005260208060002060005b858110156200067f5781548a82015290840190820162000664565b50505082870194505b50929695505050505050565b60805160a05160c05160e0516101005161012051611d9d6200073f600039600081816103b20152818161050c015281816116a6015261175201526000818161047b01528181610eb8015281816112f8015261164b0152600081816102ba01528181610921015281816109d701528181610c5d01528181610e3401528181610ee50152818161132501526116290152600061085e0152600061082e015260006102790152611d9d6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c806394bf804d11610104578063c63d75b6116100a2578063d905777e11610071578063d905777e14610463578063db661b7114610476578063dd62ed3e1461049d578063ef8b30f7146104c857600080fd5b8063c63d75b614610301578063c6e6f59214610428578063ce96cb771461043b578063d505accf1461044e57600080fd5b8063a9059cbb116100de578063a9059cbb146103dc578063b3d7f6b9146103ef578063b460af9414610402578063ba0876521461041557600080fd5b806394bf804d1461039a578063953d9cf1146103ad57806395d89b41146103d457600080fd5b8063313ce5671161017c5780634cdad5061161014b5780634cdad506146103345780636e553f651461034757806370a082311461035a5780637ecebe001461037a57600080fd5b8063313ce567146102745780633644e515146102ad57806338d52e0f146102b5578063402d267d1461030157600080fd5b8063095ea7b3116101b8578063095ea7b3146102225780630a28a4771461024557806318160ddd1461025857806323b872dd1461026157600080fd5b806301e1d114146101df57806306fdde03146101fa57806307a2d13a1461020f575b600080fd5b6101e76104db565b6040519081526020015b60405180910390f35b610202610591565b6040516101f1919061199c565b6101e761021d366004611a08565b61061f565b610235610230366004611a4a565b61064c565b60405190151581526020016101f1565b6101e7610253366004611a08565b6106c6565b6101e760025481565b61023561026f366004611a74565b6106e6565b61029b7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016101f1565b6101e761082a565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f1565b6101e761030f366004611ab0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b6101e7610342366004611a08565b610880565b6101e7610355366004611acb565b61088b565b6101e7610368366004611ab0565b60036020526000908152604090205481565b6101e7610388366004611ab0565b60056020526000908152604090205481565b6101e76103a8366004611acb565b6109b0565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b610202610a66565b6102356103ea366004611a4a565b610a73565b6101e76103fd366004611a08565b610af8565b6101e7610410366004611af7565b610b17565b6101e7610423366004611af7565b610c84565b6101e7610436366004611a08565b610e5b565b6101e7610449366004611ab0565b610e7b565b61046161045c366004611b33565b610f9c565b005b6101e7610471366004611ab0565b6112bb565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b6101e76104ab366004611ba6565b600460209081526000928352604080842090915290825290205481565b6101e76104d6366004611a08565b6113de565b6040517f3af9e6690000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690633af9e66990602401602060405180830381865afa158015610568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058c9190611bd0565b905090565b6000805461059e90611be9565b80601f01602080910402602001604051908101604052809291908181526020018280546105ca90611be9565b80156106175780601f106105ec57610100808354040283529160200191610617565b820191906000526020600020905b8154815290600101906020018083116105fa57829003601f168201915b505050505081565b60025460009080156106435761063e6106366104db565b8490836113e9565b610645565b825b9392505050565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106b49086815260200190565b60405180910390a35060015b92915050565b60025460009080156106435761063e816106de6104db565b859190611408565b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461077a576107488382611c6b565b73ffffffffffffffffffffffffffffffffffffffff861660009081526004602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff8516600090815260036020526040812080548592906107af908490611c6b565b909155505073ffffffffffffffffffffffffffffffffffffffff808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906108179087815260200190565b60405180910390a3506001949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461085b5761058c611436565b507f000000000000000000000000000000000000000000000000000000000000000090565b60006106c08261061f565b6000610896836113de565b905080600003610907576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a45524f5f53484152455300000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61094973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330866114d0565b6109538282611596565b604080518481526020810183905273ffffffffffffffffffffffffffffffffffffffff84169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a36106c0838261160f565b60006109bb83610af8565b90506109ff73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846114d0565b610a098284611596565b604080518281526020810185905273ffffffffffffffffffffffffffffffffffffffff84169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a36106c0818461160f565b6001805461059e90611be9565b33600090815260036020526040812080548391908390610a94908490611c6b565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906106b49086815260200190565b60025460009080156106435761063e610b0f6104db565b849083611408565b6000610b22846106c6565b90503373ffffffffffffffffffffffffffffffffffffffff831614610bd75773ffffffffffffffffffffffffffffffffffffffff821660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bd557610ba38282611c6b565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020555b505b610be1848261171c565b610beb8282611796565b604080518581526020810183905273ffffffffffffffffffffffffffffffffffffffff808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461064573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168486611824565b60003373ffffffffffffffffffffffffffffffffffffffff831614610d395773ffffffffffffffffffffffffffffffffffffffff821660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d3757610d058582611c6b565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020555b505b610d4284610880565b905080600003610dae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a45524f5f41535345545300000000000000000000000000000000000000000060448201526064016108fe565b610db8818561171c565b610dc28285611796565b604080518281526020810186905273ffffffffffffffffffffffffffffffffffffffff808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461064573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483611824565b60025460009080156106435761063e81610e736104db565b8591906113e9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610f2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f509190611bd0565b73ffffffffffffffffffffffffffffffffffffffff841660009081526003602052604081205491925090610f839061061f565b9050808210610f925780610f94565b815b949350505050565b42841015611006576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016108fe565b6000600161101261082a565b73ffffffffffffffffffffffffffffffffffffffff8a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611164573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906111df57508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e455200000000000000000000000000000000000060448201526064016108fe565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561136c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113909190611bd0565b9050600061139d82610e5b565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600360205260409020549091508082106113d357806113d5565b815b95945050505050565b60006106c082610e5b565b82820281151584158583048514171661140157600080fd5b0492915050565b82820281151584158583048514171661142057600080fd5b6001826001830304018115150290509392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516114689190611c7e565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061158f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064016108fe565b5050505050565b80600260008282546115a89190611d54565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b61167073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000846118e3565b6040517fe2bbb15800000000000000000000000000000000000000000000000000000000815260006004820152602481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e2bbb158906044015b600060405180830381600087803b15801561170057600080fd5b505af1158015611714573d6000803e3d6000fd5b505050505050565b6040517f441a3e7000000000000000000000000000000000000000000000000000000000815260006004820152602481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063441a3e70906044016116e6565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080548392906117cb908490611c6b565b909155505060028054829003905560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611603565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806118dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016108fe565b50505050565b60006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806118dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c454400000000000000000000000000000000000060448201526064016108fe565b600060208083528351808285015260005b818110156119c9578581018301518582016040015282016119ad565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600060208284031215611a1a57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a4557600080fd5b919050565b60008060408385031215611a5d57600080fd5b611a6683611a21565b946020939093013593505050565b600080600060608486031215611a8957600080fd5b611a9284611a21565b9250611aa060208501611a21565b9150604084013590509250925092565b600060208284031215611ac257600080fd5b61064582611a21565b60008060408385031215611ade57600080fd5b82359150611aee60208401611a21565b90509250929050565b600080600060608486031215611b0c57600080fd5b83359250611b1c60208501611a21565b9150611b2a60408501611a21565b90509250925092565b600080600080600080600060e0888a031215611b4e57600080fd5b611b5788611a21565b9650611b6560208901611a21565b95506040880135945060608801359350608088013560ff81168114611b8957600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611bb957600080fd5b611bc283611a21565b9150611aee60208401611a21565b600060208284031215611be257600080fd5b5051919050565b600181811c90821680611bfd57607f821691505b602082108103611c36577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c0576106c0611c3c565b600080835481600182811c915080831680611c9a57607f831692505b60208084108203611cd2577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015611ce65760018114611d1957611d46565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952841515850289019650611d46565b60008a81526020902060005b86811015611d3e5781548b820152908501908301611d25565b505084890196505b509498975050505050505050565b808201808211156106c0576106c0611c3c56fea2646970667358221220e73f52cfbf7ad27baebb95b7efd129676c5a6a3278bab0624709f82e891c5bd264736f6c63430008100033a2646970667358221220959abefaab83efd6e7d611fba8301a2b8c4ef04e78b1c76f5a4222026e33ea1364736f6c6343000810003300000000000000000000000027182842e098f60e3d576794a5bffb0777e025d30000000000000000000000003520d5a913427e6f0d6a83e07ccd4a4da316e4d3

Deployed Bytecode

0x60806040523480156200001157600080fd5b5060043610620000525760003560e01c80633ac2a032146200005757806380cfde3c14620000a8578063abeccaa414620000bf578063db661b7114620000d6575b600080fd5b6200007f7f0000000000000000000000003520d5a913427e6f0d6a83e07ccd4a4da316e4d381565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6200007f620000b93660046200054d565b620000fe565b6200007f620000d03660046200054d565b620002b0565b6200007f7f00000000000000000000000027182842e098f60e3d576794a5bffb0777e025d381565b6000620002aa60405180602001620001169062000519565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f9091011660408190527f8948874900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015285917f00000000000000000000000027182842e098f60e3d576794a5bffb0777e025d3917f0000000000000000000000003520d5a913427e6f0d6a83e07ccd4a4da316e4d31690638948874990602401602060405180830381865afa158015620001f7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021d919062000574565b6040805173ffffffffffffffffffffffffffffffffffffffff9485166020820152928416908301529091166060820152608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526200028e9291602001620005c6565b6040516020818303038152906040528051906020012062000493565b92915050565b6040517f8948874900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015260009182917f0000000000000000000000003520d5a913427e6f0d6a83e07ccd4a4da316e4d31690638948874990602401602060405180830381865afa15801562000342573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000368919062000574565b905073ffffffffffffffffffffffffffffffffffffffff8116620003b8576040517f9c8b003300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b837f00000000000000000000000027182842e098f60e3d576794a5bffb0777e025d383604051620003ed9062000519565b73ffffffffffffffffffffffffffffffffffffffff9384168152918316602083015290911660408201526060018190604051809103906000f59050801580156200043b573d6000803e3d6000fd5b5060405173ffffffffffffffffffffffffffffffffffffffff8083168252919350908416907fcbd4e5d1362721c7fd10daaabb1a046344447d4798be55684b8a6b4fc1765d729060200160405180910390a250919050565b6040517fff0000000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660218201526000603582018190526055820183905290620002aa906075016040516020818303038152906040528051906020012090565b6124dc80620005e883390190565b73ffffffffffffffffffffffffffffffffffffffff811681146200054a57600080fd5b50565b6000602082840312156200056057600080fd5b81356200056d8162000527565b9392505050565b6000602082840312156200058757600080fd5b81516200056d8162000527565b6000815160005b81811015620005b757602081850181015186830152016200059b565b50600093019283525090919050565b6000620005df620005d8838662000594565b8462000594565b94935050505056fe6101406040523480156200001257600080fd5b50604051620024dc380380620024dc8339810160408190526200003591620002d4565b8262000041816200010f565b6200004c85620001a2565b8181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b3919062000328565b6000620000c18482620003f9565b506001620000d08382620003f9565b5060ff81166080524660a052620000e66200021f565b60c0525050506001600160a01b0392831660e05250509182166101005216610120525062000694565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000150573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200017a9190810190620004eb565b6040516020016200018c9190620005a3565b6040516020818303038152906040529050919050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200020d9190810190620004eb565b6040516020016200018c9190620005ea565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405162000253919062000616565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b0381168114620002d157600080fd5b50565b600080600060608486031215620002ea57600080fd5b8351620002f781620002bb565b60208501519093506200030a81620002bb565b60408501519092506200031d81620002bb565b809150509250925092565b6000602082840312156200033b57600080fd5b815160ff811681146200034d57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200037f57607f821691505b602082108103620003a057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003f457600081815260208120601f850160051c81016020861015620003cf5750805b601f850160051c820191505b81811015620003f057828155600101620003db565b5050505b505050565b81516001600160401b0381111562000415576200041562000354565b6200042d816200042684546200036a565b84620003a6565b602080601f8311600181146200046557600084156200044c5750858301515b600019600386901b1c1916600185901b178555620003f0565b600085815260208120601f198616915b82811015620004965788860151825594840194600190910190840162000475565b5085821015620004b55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60005b83811015620004e2578181015183820152602001620004c8565b50506000910152565b600060208284031215620004fe57600080fd5b81516001600160401b03808211156200051657600080fd5b818401915084601f8301126200052b57600080fd5b81518181111562000540576200054062000354565b604051601f8201601f19908116603f011681019083821181831017156200056b576200056b62000354565b816040528281528760208487010111156200058557600080fd5b62000598836020830160208801620004c5565b979650505050505050565b7f455243343632362d577261707065642045756c65722000000000000000000000815260008251620005dd816016850160208701620004c5565b9190910160160192915050565b61776560f01b81526000825162000609816002850160208701620004c5565b9190910160020192915050565b600080835462000626816200036a565b60018281168015620006415760018114620006575762000688565b60ff198416875282151583028701945062000688565b8760005260208060002060005b858110156200067f5781548a82015290840190820162000664565b50505082870194505b50929695505050505050565b60805160a05160c05160e0516101005161012051611d9d6200073f600039600081816103b20152818161050c015281816116a6015261175201526000818161047b01528181610eb8015281816112f8015261164b0152600081816102ba01528181610921015281816109d701528181610c5d01528181610e3401528181610ee50152818161132501526116290152600061085e0152600061082e015260006102790152611d9d6000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c806394bf804d11610104578063c63d75b6116100a2578063d905777e11610071578063d905777e14610463578063db661b7114610476578063dd62ed3e1461049d578063ef8b30f7146104c857600080fd5b8063c63d75b614610301578063c6e6f59214610428578063ce96cb771461043b578063d505accf1461044e57600080fd5b8063a9059cbb116100de578063a9059cbb146103dc578063b3d7f6b9146103ef578063b460af9414610402578063ba0876521461041557600080fd5b806394bf804d1461039a578063953d9cf1146103ad57806395d89b41146103d457600080fd5b8063313ce5671161017c5780634cdad5061161014b5780634cdad506146103345780636e553f651461034757806370a082311461035a5780637ecebe001461037a57600080fd5b8063313ce567146102745780633644e515146102ad57806338d52e0f146102b5578063402d267d1461030157600080fd5b8063095ea7b3116101b8578063095ea7b3146102225780630a28a4771461024557806318160ddd1461025857806323b872dd1461026157600080fd5b806301e1d114146101df57806306fdde03146101fa57806307a2d13a1461020f575b600080fd5b6101e76104db565b6040519081526020015b60405180910390f35b610202610591565b6040516101f1919061199c565b6101e761021d366004611a08565b61061f565b610235610230366004611a4a565b61064c565b60405190151581526020016101f1565b6101e7610253366004611a08565b6106c6565b6101e760025481565b61023561026f366004611a74565b6106e6565b61029b7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016101f1565b6101e761082a565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f1565b6101e761030f366004611ab0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b6101e7610342366004611a08565b610880565b6101e7610355366004611acb565b61088b565b6101e7610368366004611ab0565b60036020526000908152604090205481565b6101e7610388366004611ab0565b60056020526000908152604090205481565b6101e76103a8366004611acb565b6109b0565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b610202610a66565b6102356103ea366004611a4a565b610a73565b6101e76103fd366004611a08565b610af8565b6101e7610410366004611af7565b610b17565b6101e7610423366004611af7565b610c84565b6101e7610436366004611a08565b610e5b565b6101e7610449366004611ab0565b610e7b565b61046161045c366004611b33565b610f9c565b005b6101e7610471366004611ab0565b6112bb565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b6101e76104ab366004611ba6565b600460209081526000928352604080842090915290825290205481565b6101e76104d6366004611a08565b6113de565b6040517f3af9e6690000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690633af9e66990602401602060405180830381865afa158015610568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058c9190611bd0565b905090565b6000805461059e90611be9565b80601f01602080910402602001604051908101604052809291908181526020018280546105ca90611be9565b80156106175780601f106105ec57610100808354040283529160200191610617565b820191906000526020600020905b8154815290600101906020018083116105fa57829003601f168201915b505050505081565b60025460009080156106435761063e6106366104db565b8490836113e9565b610645565b825b9392505050565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106b49086815260200190565b60405180910390a35060015b92915050565b60025460009080156106435761063e816106de6104db565b859190611408565b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461077a576107488382611c6b565b73ffffffffffffffffffffffffffffffffffffffff861660009081526004602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff8516600090815260036020526040812080548592906107af908490611c6b565b909155505073ffffffffffffffffffffffffffffffffffffffff808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906108179087815260200190565b60405180910390a3506001949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461085b5761058c611436565b507f000000000000000000000000000000000000000000000000000000000000000090565b60006106c08261061f565b6000610896836113de565b905080600003610907576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a45524f5f53484152455300000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61094973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330866114d0565b6109538282611596565b604080518481526020810183905273ffffffffffffffffffffffffffffffffffffffff84169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a36106c0838261160f565b60006109bb83610af8565b90506109ff73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846114d0565b610a098284611596565b604080518281526020810185905273ffffffffffffffffffffffffffffffffffffffff84169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a36106c0818461160f565b6001805461059e90611be9565b33600090815260036020526040812080548391908390610a94908490611c6b565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906106b49086815260200190565b60025460009080156106435761063e610b0f6104db565b849083611408565b6000610b22846106c6565b90503373ffffffffffffffffffffffffffffffffffffffff831614610bd75773ffffffffffffffffffffffffffffffffffffffff821660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bd557610ba38282611c6b565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020555b505b610be1848261171c565b610beb8282611796565b604080518581526020810183905273ffffffffffffffffffffffffffffffffffffffff808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461064573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168486611824565b60003373ffffffffffffffffffffffffffffffffffffffff831614610d395773ffffffffffffffffffffffffffffffffffffffff821660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d3757610d058582611c6b565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020555b505b610d4284610880565b905080600003610dae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a45524f5f41535345545300000000000000000000000000000000000000000060448201526064016108fe565b610db8818561171c565b610dc28285611796565b604080518281526020810186905273ffffffffffffffffffffffffffffffffffffffff808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a461064573ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168483611824565b60025460009080156106435761063e81610e736104db565b8591906113e9565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610f2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f509190611bd0565b73ffffffffffffffffffffffffffffffffffffffff841660009081526003602052604081205491925090610f839061061f565b9050808210610f925780610f94565b815b949350505050565b42841015611006576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016108fe565b6000600161101261082a565b73ffffffffffffffffffffffffffffffffffffffff8a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611164573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116158015906111df57508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b611245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e455200000000000000000000000000000000000060448201526064016108fe565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116600483015260009182917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561136c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113909190611bd0565b9050600061139d82610e5b565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600360205260409020549091508082106113d357806113d5565b815b95945050505050565b60006106c082610e5b565b82820281151584158583048514171661140157600080fd5b0492915050565b82820281151584158583048514171661142057600080fd5b6001826001830304018115150290509392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516114689190611c7e565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061158f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064016108fe565b5050505050565b80600260008282546115a89190611d54565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b61167073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000846118e3565b6040517fe2bbb15800000000000000000000000000000000000000000000000000000000815260006004820152602481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e2bbb158906044015b600060405180830381600087803b15801561170057600080fd5b505af1158015611714573d6000803e3d6000fd5b505050505050565b6040517f441a3e7000000000000000000000000000000000000000000000000000000000815260006004820152602481018390527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063441a3e70906044016116e6565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080548392906117cb908490611c6b565b909155505060028054829003905560405181815260009073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001611603565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806118dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016108fe565b50505050565b60006040517f095ea7b3000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806118dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c454400000000000000000000000000000000000060448201526064016108fe565b600060208083528351808285015260005b818110156119c9578581018301518582016040015282016119ad565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600060208284031215611a1a57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a4557600080fd5b919050565b60008060408385031215611a5d57600080fd5b611a6683611a21565b946020939093013593505050565b600080600060608486031215611a8957600080fd5b611a9284611a21565b9250611aa060208501611a21565b9150604084013590509250925092565b600060208284031215611ac257600080fd5b61064582611a21565b60008060408385031215611ade57600080fd5b82359150611aee60208401611a21565b90509250929050565b600080600060608486031215611b0c57600080fd5b83359250611b1c60208501611a21565b9150611b2a60408501611a21565b90509250925092565b600080600080600080600060e0888a031215611b4e57600080fd5b611b5788611a21565b9650611b6560208901611a21565b95506040880135945060608801359350608088013560ff81168114611b8957600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611bb957600080fd5b611bc283611a21565b9150611aee60208401611a21565b600060208284031215611be257600080fd5b5051919050565b600181811c90821680611bfd57607f821691505b602082108103611c36577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106c0576106c0611c3c565b600080835481600182811c915080831680611c9a57607f831692505b60208084108203611cd2577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b818015611ce65760018114611d1957611d46565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952841515850289019650611d46565b60008a81526020902060005b86811015611d3e5781548b820152908501908301611d25565b505084890196505b509498975050505050505050565b808201808211156106c0576106c0611c3c56fea2646970667358221220e73f52cfbf7ad27baebb95b7efd129676c5a6a3278bab0624709f82e891c5bd264736f6c63430008100033a2646970667358221220959abefaab83efd6e7d611fba8301a2b8c4ef04e78b1c76f5a4222026e33ea1364736f6c63430008100033

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

00000000000000000000000027182842e098f60e3d576794a5bffb0777e025d30000000000000000000000003520d5a913427e6f0d6a83e07ccd4a4da316e4d3

-----Decoded View---------------
Arg [0] : euler_ (address): 0x27182842E098f60e3D576794A5bFFb0777E025d3
Arg [1] : markets_ (address): 0x3520d5a913427E6F0D6A83E07ccD4A4da316e4d3

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000027182842e098f60e3d576794a5bffb0777e025d3
Arg [1] : 0000000000000000000000003520d5a913427e6f0d6a83e07ccd4a4da316e4d3


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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