false
false

Contract Address Details

0x90F256F20E594d4039DE03285E7cfe31dC083E1A

Contract Name
Vyper_contract
Creator
0x13f0b2–f18271 at 0x6d51af–9291e2
Balance
0 KCS
Tokens
Fetching tokens...
Transactions
20 Transactions
Transfers
170 Transfers
Gas Used
7,334,185
Last Balance Update
51223042
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Vyper_contract




Optimization enabled
false
Compiler version
v0.2.8




Verified at
2022-07-13T09:39:45.181583Z

Constructor Arguments

000000000000000000000000217d950570b256774d3b824723f7570f5e1c6fbf000000000000000000000000217d950570b256774d3b824723f7570f5e1c6fbf0000000000000000000000001153335a3c0f3c2036d239f3a378aa149101d56900000000000000000000000011cc35ceec84058a61705fe219496d67c0834a4d0000000000000000000000004b6a673b282442543f81d88c79f4754f42de4993
              

Contract source code

# @version 0.2.8
"""
@title "Zap" Depositer for permissionless USD metapools
@author Curve.Fi
@license Copyright (c) Curve.Fi, 2021 - all rights reserved
"""

interface ERC20:
    def transfer(_receiver: address, _amount: uint256): nonpayable
    def transferFrom(_sender: address, _receiver: address, _amount: uint256): nonpayable
    def approve(_spender: address, _amount: uint256): nonpayable
    def decimals() -> uint256: view
    def balanceOf(_owner: address) -> uint256: view

interface CurveMeta:
    def add_liquidity(amounts: uint256[N_COINS], min_mint_amount: uint256, _receiver: address) -> uint256: nonpayable
    def remove_liquidity(_amount: uint256, min_amounts: uint256[N_COINS]) -> uint256[N_COINS]: nonpayable
    def remove_liquidity_one_coin(_token_amount: uint256, i: int128, min_amount: uint256, _receiver: address) -> uint256: nonpayable
    def remove_liquidity_imbalance(amounts: uint256[N_COINS], max_burn_amount: uint256) -> uint256: nonpayable
    def calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> uint256: view
    def calc_token_amount(amounts: uint256[N_COINS], deposit: bool) -> uint256: view
    def coins(i: uint256) -> address: view

interface CurveBase:
    def add_liquidity(amounts: uint256[BASE_N_COINS], min_mint_amount: uint256): nonpayable
    def remove_liquidity(_amount: uint256, min_amounts: uint256[BASE_N_COINS]): nonpayable
    def remove_liquidity_one_coin(_token_amount: uint256, i: int128, min_amount: uint256): nonpayable
    def remove_liquidity_imbalance(amounts: uint256[BASE_N_COINS], max_burn_amount: uint256): nonpayable
    def calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> uint256: view
    def calc_token_amount(amounts: uint256[BASE_N_COINS], deposit: bool) -> uint256: view
    def coins(i: uint256) -> address: view
    def fee() -> uint256: view


N_COINS: constant(int128) = 2
MAX_COIN: constant(int128) = N_COINS-1
BASE_N_COINS: constant(int128) = 3
N_ALL_COINS: constant(int128) = N_COINS + BASE_N_COINS - 1

FEE_DENOMINATOR: constant(uint256) = 10 ** 10
FEE_IMPRECISION: constant(uint256) = 100 * 10 ** 8  # % of the fee

base_pool: public(address)
base_lp_token: public(address)
base_coins: public(address[3])

# coin -> pool -> is approved to transfer?
is_approved: HashMap[address, HashMap[address, bool]]


@external
def __init__(_base_pool: address,_base_lp_token: address,_base_coins:address[3]):
    """
    @notice Contract constructor
    """
    self.base_pool = _base_pool
    self.base_lp_token = _base_lp_token
    self.base_coins = _base_coins
    base_coins: address[3] = self.base_coins
    for coin in base_coins:
        ERC20(coin).approve(self.base_pool, MAX_UINT256)


@external
def add_liquidity(
        _pool: address,
        _deposit_amounts: uint256[N_ALL_COINS],
        _min_mint_amount: uint256,
        _receiver: address = msg.sender,
) -> uint256:
    """
    @notice Wrap underlying coins and deposit them into `_pool`
    @param _pool Address of the pool to deposit into
    @param _deposit_amounts List of amounts of underlying coins to deposit
    @param _min_mint_amount Minimum amount of LP tokens to mint from the deposit
    @param _receiver Address that receives the LP tokens
    @return Amount of LP tokens received by depositing
    """
    meta_amounts: uint256[N_COINS] = empty(uint256[N_COINS])
    base_amounts: uint256[BASE_N_COINS] = empty(uint256[BASE_N_COINS])
    deposit_base: bool = False
    base_coins: address[3] = self.base_coins

    if _deposit_amounts[0] != 0:
        coin: address = CurveMeta(_pool).coins(0)
        if not self.is_approved[coin][_pool]:
            ERC20(coin).approve(_pool, MAX_UINT256)
            self.is_approved[coin][_pool] = True
        ERC20(coin).transferFrom(msg.sender, self, _deposit_amounts[0])
        meta_amounts[0] = _deposit_amounts[0]

    for i in range(1, N_ALL_COINS):
        amount: uint256 = _deposit_amounts[i]
        if amount == 0:
            continue
        deposit_base = True
        base_idx: uint256 = i - 1
        coin: address = base_coins[base_idx]

        ERC20(coin).transferFrom(msg.sender, self, amount)
        # Handle potential Tether fees
        if i == N_ALL_COINS - 1:
            base_amounts[base_idx] = ERC20(coin).balanceOf(self)
        else:
            base_amounts[base_idx] = amount

    # Deposit to the base pool
    if deposit_base:
        coin: address = self.base_lp_token
        CurveBase(self.base_pool).add_liquidity(base_amounts, 0)
        meta_amounts[MAX_COIN] = ERC20(coin).balanceOf(self)
        if not self.is_approved[coin][_pool]:
            ERC20(coin).approve(_pool, MAX_UINT256)
            self.is_approved[coin][_pool] = True

    # Deposit to the meta pool
    return CurveMeta(_pool).add_liquidity(meta_amounts, _min_mint_amount, _receiver)


@external
def remove_liquidity(
        _pool: address,
        _burn_amount: uint256,
        _min_amounts: uint256[N_ALL_COINS],
        _receiver: address = msg.sender
) -> uint256[N_ALL_COINS]:
    """
    @notice Withdraw and unwrap coins from the pool
    @dev Withdrawal amounts are based on current deposit ratios
    @param _pool Address of the pool to deposit into
    @param _burn_amount Quantity of LP tokens to burn in the withdrawal
    @param _min_amounts Minimum amounts of underlying coins to receive
    @param _receiver Address that receives the LP tokens
    @return List of amounts of underlying coins that were withdrawn
    """
    ERC20(_pool).transferFrom(msg.sender, self, _burn_amount)

    min_amounts_base: uint256[BASE_N_COINS] = empty(uint256[BASE_N_COINS])
    amounts: uint256[N_ALL_COINS] = empty(uint256[N_ALL_COINS])

    # Withdraw from meta
    meta_received: uint256[N_COINS] = CurveMeta(_pool).remove_liquidity(
        _burn_amount,
        [_min_amounts[0], convert(0, uint256)]
    )

    # Withdraw from base
    for i in range(BASE_N_COINS):
        min_amounts_base[i] = _min_amounts[MAX_COIN+i]
    CurveBase(self.base_pool).remove_liquidity(meta_received[1], min_amounts_base)

    # Transfer all coins out
    coin: address = CurveMeta(_pool).coins(0)
    ERC20(coin).transfer(_receiver, meta_received[0])
    amounts[0] = meta_received[0]

    base_coins: address[BASE_N_COINS] = self.base_coins
    for i in range(1, N_ALL_COINS):
        coin = base_coins[i-1]
        amounts[i] = ERC20(coin).balanceOf(self)
        ERC20(coin).transfer(_receiver, amounts[i])

    return amounts


@external
def remove_liquidity_one_coin(
        _pool: address,
        _burn_amount: uint256,
        i: int128,
        _min_amount: uint256,
        _receiver: address=msg.sender
) -> uint256:
    """
    @notice Withdraw and unwrap a single coin from the pool
    @param _pool Address of the pool to deposit into
    @param _burn_amount Amount of LP tokens to burn in the withdrawal
    @param i Index value of the coin to withdraw
    @param _min_amount Minimum amount of underlying coin to receive
    @param _receiver Address that receives the LP tokens
    @return Amount of underlying coin received
    """
    ERC20(_pool).transferFrom(msg.sender, self, _burn_amount)

    coin_amount: uint256 = 0
    if i == 0:
        coin_amount = CurveMeta(_pool).remove_liquidity_one_coin(_burn_amount, i, _min_amount, _receiver)
    else:
        base_coins: address[BASE_N_COINS] = self.base_coins
        coin: address = base_coins[i - MAX_COIN]
        # Withdraw a base pool coin
        coin_amount = CurveMeta(_pool).remove_liquidity_one_coin(_burn_amount, MAX_COIN, 0, self)
        CurveBase(self.base_pool).remove_liquidity_one_coin(coin_amount, i-MAX_COIN, _min_amount)
        coin_amount = ERC20(coin).balanceOf(self)
        ERC20(coin).transfer(_receiver, coin_amount)

    return coin_amount


@external
def remove_liquidity_imbalance(
        _pool: address,
        _amounts: uint256[N_ALL_COINS],
        _max_burn_amount: uint256,
        _receiver: address=msg.sender
) -> uint256:
    """
    @notice Withdraw coins from the pool in an imbalanced amount
    @param _pool Address of the pool to deposit into
    @param _amounts List of amounts of underlying coins to withdraw
    @param _max_burn_amount Maximum amount of LP token to burn in the withdrawal
    @param _receiver Address that receives the LP tokens
    @return Actual amount of the LP token burned in the withdrawal
    """
    fee: uint256 = CurveBase(self.base_pool).fee() * BASE_N_COINS / (4 * (BASE_N_COINS - 1))
    fee += fee * FEE_IMPRECISION / FEE_DENOMINATOR  # Overcharge to account for imprecision

    # Transfer the LP token in
    ERC20(_pool).transferFrom(msg.sender, self, _max_burn_amount)

    withdraw_base: bool = False
    amounts_base: uint256[BASE_N_COINS] = empty(uint256[BASE_N_COINS])
    amounts_meta: uint256[N_COINS] = empty(uint256[N_COINS])

    # determine amounts to withdraw from base pool
    for i in range(BASE_N_COINS):
        amount: uint256 = _amounts[MAX_COIN + i]
        if amount != 0:
            amounts_base[i] = amount
            withdraw_base = True

    # determine amounts to withdraw from metapool
    amounts_meta[0] = _amounts[0]
    if withdraw_base:
        amounts_meta[MAX_COIN] = CurveBase(self.base_pool).calc_token_amount(amounts_base, False)
        amounts_meta[MAX_COIN] += amounts_meta[MAX_COIN] * fee / FEE_DENOMINATOR + 1

    # withdraw from metapool and return the remaining LP tokens
    burn_amount: uint256 = CurveMeta(_pool).remove_liquidity_imbalance(amounts_meta, _max_burn_amount)
    ERC20(_pool).transfer(msg.sender, _max_burn_amount - burn_amount)

    # withdraw from base pool
    if withdraw_base:
        CurveBase(self.base_pool).remove_liquidity_imbalance(amounts_base, amounts_meta[MAX_COIN])
        coin: address = self.base_lp_token
        leftover: uint256 = ERC20(coin).balanceOf(self)

        if leftover > 0:
            # if some base pool LP tokens remain, re-deposit them for the caller
            if not self.is_approved[coin][_pool]:
                ERC20(coin).approve(_pool, MAX_UINT256)
                self.is_approved[coin][_pool] = True
            burn_amount -= CurveMeta(_pool).add_liquidity([convert(0, uint256), leftover], 0, msg.sender)

        # transfer withdrawn base pool tokens to caller
        base_coins: address[BASE_N_COINS] = self.base_coins
        for i in range(BASE_N_COINS):
            ERC20(base_coins[i]).transfer(_receiver, amounts_base[i])

    # transfer withdrawn metapool tokens to caller
    if _amounts[0] > 0:
        coin: address = CurveMeta(_pool).coins(0)
        ERC20(coin).transfer(_receiver, _amounts[0])

    return burn_amount


@view
@external
def calc_withdraw_one_coin(_pool: address, _token_amount: uint256, i: int128) -> uint256:
    """
    @notice Calculate the amount received when withdrawing and unwrapping a single coin
    @param _pool Address of the pool to deposit into
    @param _token_amount Amount of LP tokens to burn in the withdrawal
    @param i Index value of the underlying coin to withdraw
    @return Amount of coin received
    """
    if i < MAX_COIN:
        return CurveMeta(_pool).calc_withdraw_one_coin(_token_amount, i)
    else:
        _base_tokens: uint256 = CurveMeta(_pool).calc_withdraw_one_coin(_token_amount, MAX_COIN)
        return CurveBase(self.base_pool).calc_withdraw_one_coin(_base_tokens, i-MAX_COIN)


@view
@external
def calc_token_amount(_pool: address, _amounts: uint256[N_ALL_COINS], _is_deposit: bool) -> uint256:
    """
    @notice Calculate addition or reduction in token supply from a deposit or withdrawal
    @dev This calculation accounts for slippage, but not fees.
         Needed to prevent front-running, not for precise calculations!
    @param _pool Address of the pool to deposit into
    @param _amounts Amount of each underlying coin being deposited
    @param _is_deposit set True for deposits, False for withdrawals
    @return Expected amount of LP tokens received
    """
    meta_amounts: uint256[N_COINS] = empty(uint256[N_COINS])
    base_amounts: uint256[BASE_N_COINS] = empty(uint256[BASE_N_COINS])

    meta_amounts[0] = _amounts[0]
    for i in range(BASE_N_COINS):
        base_amounts[i] = _amounts[i + MAX_COIN]

    base_tokens: uint256 = CurveBase(self.base_pool).calc_token_amount(base_amounts, _is_deposit)
    meta_amounts[MAX_COIN] = base_tokens

    return CurveMeta(_pool).calc_token_amount(meta_amounts, _is_deposit)
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","outputs":[],"inputs":[{"type":"address","name":"_base_pool"},{"type":"address","name":"_base_lp_token"},{"type":"address[3]","name":"_base_coins"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"add_liquidity","inputs":[{"type":"address","name":"_pool"},{"type":"uint256[4]","name":"_deposit_amounts"},{"type":"uint256","name":"_min_mint_amount"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"add_liquidity","inputs":[{"type":"address","name":"_pool"},{"type":"uint256[4]","name":"_deposit_amounts"},{"type":"uint256","name":"_min_mint_amount"},{"type":"address","name":"_receiver"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[4]","name":""}],"name":"remove_liquidity","inputs":[{"type":"address","name":"_pool"},{"type":"uint256","name":"_burn_amount"},{"type":"uint256[4]","name":"_min_amounts"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[4]","name":""}],"name":"remove_liquidity","inputs":[{"type":"address","name":"_pool"},{"type":"uint256","name":"_burn_amount"},{"type":"uint256[4]","name":"_min_amounts"},{"type":"address","name":"_receiver"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"remove_liquidity_one_coin","inputs":[{"type":"address","name":"_pool"},{"type":"uint256","name":"_burn_amount"},{"type":"int128","name":"i"},{"type":"uint256","name":"_min_amount"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"remove_liquidity_one_coin","inputs":[{"type":"address","name":"_pool"},{"type":"uint256","name":"_burn_amount"},{"type":"int128","name":"i"},{"type":"uint256","name":"_min_amount"},{"type":"address","name":"_receiver"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"remove_liquidity_imbalance","inputs":[{"type":"address","name":"_pool"},{"type":"uint256[4]","name":"_amounts"},{"type":"uint256","name":"_max_burn_amount"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"remove_liquidity_imbalance","inputs":[{"type":"address","name":"_pool"},{"type":"uint256[4]","name":"_amounts"},{"type":"uint256","name":"_max_burn_amount"},{"type":"address","name":"_receiver"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"calc_withdraw_one_coin","inputs":[{"type":"address","name":"_pool"},{"type":"uint256","name":"_token_amount"},{"type":"int128","name":"i"}],"gas":2450},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"calc_token_amount","inputs":[{"type":"address","name":"_pool"},{"type":"uint256[4]","name":"_amounts"},{"type":"bool","name":"_is_deposit"}],"gas":3517},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"base_pool","inputs":[],"gas":1241},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"base_lp_token","inputs":[],"gas":1271},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"base_coins","inputs":[{"type":"uint256","name":"arg0"}],"gas":1410}]
              

Contract Creation Code

0x60a06116ac6101403960206116ac60c03960c05160a01c1561002057600080fd5b602060206116ac0160c03960c05160a01c1561003b57600080fd5b602060406116ac0160c03960c05160a01c1561005657600080fd5b602060606116ac0160c03960c05160a01c1561007157600080fd5b602060806116ac0160c03960c05160a01c1561008c57600080fd5b6101405160005561016051600155600260c052602060c0206101805181556101a05160018201556101c05160028201555060028060c052602060c020546101e05260018160c052602060c02001546102005260028160c052602060c0200154610220525061026060006003818352015b602061026051026101e0015161024052610240513b61011a57600080fd5b60006000604463095ea7b3610280526000546102a0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102c05261029c6000610240515af161016957600080fd5b5b81516001018083528114156100fc575b505061169456341561000a57600080fd5b60043610156100185761150d565b600035601c5263384e03db600051141561003657336101405261006c565b63d0b951e860005114156100645760c43560a01c1561005457600080fd5b602060c46101403760005061006c565b6000156104e5575b60043560a01c1561007c57600080fd5b60c0366101603760028060c052602060c020546102205260018160c052602060c02001546102405260028160c052602060c02001546102605250600060243518156101f0576020610320602463c66106576102a05260006102c0526102bc6004355afa6100e857600080fd5b601f3d116100f557600080fd5b600050610320516102805260036102805160e05260c052604060c02060043560e05260c052604060c0205415156101a657610280513b61013457600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161018357600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b610280513b6101b457600080fd5b6000600060646323b872dd6102a052336102c052306102e052602435610300526102bc6000610280515af16101e857600080fd5b602435610160525b61028060016003818352015b6024610280516004811061020f57600080fd5b60200201356102a0526102a05115156102275761032f565b6001610200526102805160018082101561024057600080fd5b808203905090506102c0526102206102c0516003811061025f57600080fd5b60200201516102e0526102e0513b61027657600080fd5b6000600060646323b872dd61030052336103205230610340526102a0516103605261031c60006102e0515af16102ab57600080fd5b600361028051141561031057602061038060246370a0823161030052306103205261031c6102e0515afa6102de57600080fd5b601f3d116102eb57600080fd5b600050610380516101a06102c0516003811061030657600080fd5b602002015261032e565b6102a0516101a06102c0516003811061032857600080fd5b60200201525b5b81516001018083528114156101fc575b5050610200511561048457600154610280526000543b61035e57600080fd5b600060006084634515cef36102a0526101a0516102c0526101c0516102e0526101e051610300526000610320526102bc60006000545af161039e57600080fd5b602061032060246370a082316102a052306102c0526102bc610280515afa6103c557600080fd5b601f3d116103d257600080fd5b600050610320516101805260036102805160e05260c052604060c02060043560e05260c052604060c02054151561048357610280513b61041157600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161046057600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b5b60206103606084630c3e4b5461028052610160516102a052610180516102c05260a4356102e052610140516103005261029c60006004355af16104c657600080fd5b601f3d116104d357600080fd5b6000506103605160005260206000f350005b63ad5cc91860005114156104fd573361014052610533565b63cbc399e5600051141561052b5760c43560a01c1561051b57600080fd5b602060c461014037600050610533565b600015610876575b60043560a01c1561054357600080fd5b6004353b61055057600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161058357600080fd5b60e0366101603760406103406064635b36389c610280526024356102a0526044356102c05260006102e05261029c60006004355af16105c157600080fd5b603f3d116105ce57600080fd5b6000506103408051610240528060200151610260525061028060006003818352015b60446001610280518082018080600081121561060857195b607f1c1561061557600080fd5b9050905090506004811061062857600080fd5b6020020135610160610280516003811061064157600080fd5b60200201525b81516001018083528114156105f0575b50506000543b61066657600080fd5b60006000608463ecb586a561028052610260516102a052610160516102c052610180516102e0526101a0516103005261029c60006000545af16106a857600080fd5b6020610320602463c66106576102a05260006102c0526102bc6004355afa6106cf57600080fd5b601f3d116106dc57600080fd5b6000506103205161028052610280513b6106f557600080fd5b60006000604463a9059cbb6102a052610140516102c052610240516102e0526102bc6000610280515af161072857600080fd5b610240516101c05260028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060016003818352015b6102a06103005160018082038080600081121561078857195b607f1c1561079557600080fd5b905090509050600381106107a857600080fd5b60200201516102805260206103a060246370a0823161032052306103405261033c610280515afa6107d857600080fd5b601f3d116107e557600080fd5b6000506103a0516101c0610300516004811061080057600080fd5b6020020152610280513b61081357600080fd5b60006000604463a9059cbb6103205261014051610340526101c0610300516004811061083e57600080fd5b60200201516103605261033c6000610280515af161085b57600080fd5b5b815160010180835281141561076f575b505060806101c0f3005b6329ed2862600051141561088e5733610140526108c4565b631e700cbb60005114156108bc5760843560a01c156108ac57600080fd5b60206084610140376000506108c4565b600015610b61575b60043560a01c156108d457600080fd5b604435808060008112156108e457195b607f1c156108f157600080fd5b9050506004353b61090157600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161093457600080fd5b60006101605260443515156109a0576020610260608463081579a5610180526024356101a0526044356101c0526064356101e052610140516102005261019c60006004355af161098357600080fd5b601f3d1161099057600080fd5b6000506102605161016052610b52565b60028060c052602060c020546101805260018160c052602060c02001546101a05260028160c052602060c02001546101c052506101806044356001808203808060008112156109eb57195b607f1c156109f857600080fd5b90509050905060038110610a0b57600080fd5b60200201516101e05260206102e0608463081579a56102005260243561022052600161024052600061026052306102805261021c60006004355af1610a4f57600080fd5b601f3d11610a5c57600080fd5b6000506102e051610160526000543b610a7457600080fd5b600060006064631a4d01d2610200526101605161022052604435600180820380806000811215610aa057195b607f1c15610aad57600080fd5b905090509050610240526064356102605261021c60006000545af1610ad157600080fd5b602061028060246370a0823161020052306102205261021c6101e0515afa610af857600080fd5b601f3d11610b0557600080fd5b60005061028051610160526101e0513b610b1e57600080fd5b60006000604463a9059cbb610200526101405161022052610160516102405261021c60006101e0515af1610b5157600080fd5b5b6101605160005260206000f350005b63ac24f7716000511415610b79573361014052610baf565b634329c8cc6000511415610ba75760c43560a01c15610b9757600080fd5b602060c461014037600050610baf565b6000156111e2575b60043560a01c15610bbf57600080fd5b60206101e0600463ddca3f436101805261019c6000545afa610be057600080fd5b601f3d11610bed57600080fd5b6000506101e05160038082028215828483041417610c0a57600080fd5b80905090509050600880820490509050610160526101608051610160516402540be4008082028215828483041417610c4157600080fd5b809050905090506402540be40080820490509050818183011015610c6457600080fd5b808201905090508152506004353b610c7b57600080fd5b6000600060646323b872dd61018052336101a052306101c05260a4356101e05261019c60006004355af1610cae57600080fd5b60c0366101803761024060006003818352015b602460016102405180820180806000811215610cd957195b607f1c15610ce657600080fd5b90509050905060048110610cf957600080fd5b6020020135610260526000610260511815610d3257610260516101a06102405160038110610d2657600080fd5b60200201526001610180525b5b8151600101808352811415610cc1575b5050602435610200526101805115610e135760206103206084633883e119610240526101a051610260526101c051610280526101e0516102a05260006102c05261025c6000545afa610d9457600080fd5b601f3d11610da157600080fd5b6000506103205161022052610220805161022051610160518082028215828483041417610dcd57600080fd5b809050905090506402540be400808204905090506001818183011015610df257600080fd5b80820190509050818183011015610e0857600080fd5b808201905090508152505b6020610320606463e3103273610260526102005161028052610220516102a05260a4356102c05261027c60006004355af1610e4d57600080fd5b601f3d11610e5a57600080fd5b60005061032051610240526004353b610e7257600080fd5b60006000604463a9059cbb61026052336102805260a4356102405180821015610e9a57600080fd5b808203905090506102a05261027c60006004355af1610eb857600080fd5b6101805115611148576000543b610ece57600080fd5b600060006084639fdaea0c610260526101a051610280526101c0516102a0526101e0516102c052610220516102e05261027c60006000545af1610f1057600080fd5b60015461026052602061032060246370a082316102a052306102c0526102bc610260515afa610f3e57600080fd5b601f3d11610f4b57600080fd5b600050610320516102805260006102805111156110755760036102605160e05260c052604060c02060043560e05260c052604060c02054151561100857610260513b610f9657600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610260515af1610fe557600080fd5b600160036102605160e05260c052604060c02060043560e05260c052604060c020555b610240805160206103806084630c3e4b546102a05260006102c052610280516102e05260006103005233610320526102bc60006004355af161104957600080fd5b601f3d1161105657600080fd5b600050610380518082101561106a57600080fd5b808203905090508152505b60028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060006003818352015b6102a061030051600381106110c857600080fd5b60200201513b6110d757600080fd5b60006000604463a9059cbb6103205261014051610340526101a0610300516003811061110257600080fd5b60200201516103605261033c60006102a0610300516003811061112457600080fd5b60200201515af161113457600080fd5b5b81516001018083528114156110b4575b50505b600060243511156111d3576020610300602463c66106576102805260006102a05261029c6004355afa61117a57600080fd5b601f3d1161118757600080fd5b6000506103005161026052610260513b6111a057600080fd5b60006000604463a9059cbb61028052610140516102a0526024356102c05261029c6000610260515af16111d257600080fd5b5b6102405160005260206000f350005b6341b028f360005114156113375760043560a01c1561120057600080fd5b6044358080600081121561121057195b607f1c1561121d57600080fd5b9050506001604435121561127c5760206101e0604463cc2b27d761014052602435610160526044356101805261015c6004355afa61125a57600080fd5b601f3d1161126757600080fd5b6000506101e05160005260206000f350611335565b6020610200604463cc2b27d7610160526024356101805260016101a05261017c6004355afa6112aa57600080fd5b601f3d116112b757600080fd5b60005061020051610140526020610200604463cc2b27d76101605261014051610180526044356001808203808060008112156112ef57195b607f1c156112fc57600080fd5b9050905090506101a05261017c6000545afa61131757600080fd5b601f3d1161132457600080fd5b6000506102005160005260206000f3505b005b63861cdef0600051141561149f5760043560a01c1561135557600080fd5b60a43560011c1561136557600080fd5b60a03661014037602435610140526101e060006003818352015b60246101e05160018082018080600081121561139757195b607f1c156113a457600080fd5b905090509050600481106113b757600080fd5b60200201356101806101e051600381106113d057600080fd5b60200201525b815160010180835281141561137f575b505060206102e06084633883e1196102005261018051610220526101a051610240526101c0516102605260a4356102805261021c6000545afa61142857600080fd5b601f3d1161143557600080fd5b6000506102e0516101e0526101e0516101605260206102c0606463ed8e84f3610200526101405161022052610160516102405260a4356102605261021c6004355afa61148057600080fd5b601f3d1161148d57600080fd5b6000506102c05160005260206000f350005b635d6362bb60005114156114bb5760005460005260206000f350005b63d6716cb560005114156114d75760015460005260206000f350005b6387cb4f57600051141561150c57600435600381106114f557600080fd5b600260c052602060c020015460005260206000f350005b5b60006000fd5b61018161169403610181600039610181611694036000f3000000000000000000000000217d950570b256774d3b824723f7570f5e1c6fbf000000000000000000000000217d950570b256774d3b824723f7570f5e1c6fbf0000000000000000000000001153335a3c0f3c2036d239f3a378aa149101d56900000000000000000000000011cc35ceec84058a61705fe219496d67c0834a4d0000000000000000000000004b6a673b282442543f81d88c79f4754f42de4993

Deployed ByteCode

0x341561000a57600080fd5b60043610156100185761150d565b600035601c5263384e03db600051141561003657336101405261006c565b63d0b951e860005114156100645760c43560a01c1561005457600080fd5b602060c46101403760005061006c565b6000156104e5575b60043560a01c1561007c57600080fd5b60c0366101603760028060c052602060c020546102205260018160c052602060c02001546102405260028160c052602060c02001546102605250600060243518156101f0576020610320602463c66106576102a05260006102c0526102bc6004355afa6100e857600080fd5b601f3d116100f557600080fd5b600050610320516102805260036102805160e05260c052604060c02060043560e05260c052604060c0205415156101a657610280513b61013457600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161018357600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b610280513b6101b457600080fd5b6000600060646323b872dd6102a052336102c052306102e052602435610300526102bc6000610280515af16101e857600080fd5b602435610160525b61028060016003818352015b6024610280516004811061020f57600080fd5b60200201356102a0526102a05115156102275761032f565b6001610200526102805160018082101561024057600080fd5b808203905090506102c0526102206102c0516003811061025f57600080fd5b60200201516102e0526102e0513b61027657600080fd5b6000600060646323b872dd61030052336103205230610340526102a0516103605261031c60006102e0515af16102ab57600080fd5b600361028051141561031057602061038060246370a0823161030052306103205261031c6102e0515afa6102de57600080fd5b601f3d116102eb57600080fd5b600050610380516101a06102c0516003811061030657600080fd5b602002015261032e565b6102a0516101a06102c0516003811061032857600080fd5b60200201525b5b81516001018083528114156101fc575b5050610200511561048457600154610280526000543b61035e57600080fd5b600060006084634515cef36102a0526101a0516102c0526101c0516102e0526101e051610300526000610320526102bc60006000545af161039e57600080fd5b602061032060246370a082316102a052306102c0526102bc610280515afa6103c557600080fd5b601f3d116103d257600080fd5b600050610320516101805260036102805160e05260c052604060c02060043560e05260c052604060c02054151561048357610280513b61041157600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161046057600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b5b60206103606084630c3e4b5461028052610160516102a052610180516102c05260a4356102e052610140516103005261029c60006004355af16104c657600080fd5b601f3d116104d357600080fd5b6000506103605160005260206000f350005b63ad5cc91860005114156104fd573361014052610533565b63cbc399e5600051141561052b5760c43560a01c1561051b57600080fd5b602060c461014037600050610533565b600015610876575b60043560a01c1561054357600080fd5b6004353b61055057600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161058357600080fd5b60e0366101603760406103406064635b36389c610280526024356102a0526044356102c05260006102e05261029c60006004355af16105c157600080fd5b603f3d116105ce57600080fd5b6000506103408051610240528060200151610260525061028060006003818352015b60446001610280518082018080600081121561060857195b607f1c1561061557600080fd5b9050905090506004811061062857600080fd5b6020020135610160610280516003811061064157600080fd5b60200201525b81516001018083528114156105f0575b50506000543b61066657600080fd5b60006000608463ecb586a561028052610260516102a052610160516102c052610180516102e0526101a0516103005261029c60006000545af16106a857600080fd5b6020610320602463c66106576102a05260006102c0526102bc6004355afa6106cf57600080fd5b601f3d116106dc57600080fd5b6000506103205161028052610280513b6106f557600080fd5b60006000604463a9059cbb6102a052610140516102c052610240516102e0526102bc6000610280515af161072857600080fd5b610240516101c05260028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060016003818352015b6102a06103005160018082038080600081121561078857195b607f1c1561079557600080fd5b905090509050600381106107a857600080fd5b60200201516102805260206103a060246370a0823161032052306103405261033c610280515afa6107d857600080fd5b601f3d116107e557600080fd5b6000506103a0516101c0610300516004811061080057600080fd5b6020020152610280513b61081357600080fd5b60006000604463a9059cbb6103205261014051610340526101c0610300516004811061083e57600080fd5b60200201516103605261033c6000610280515af161085b57600080fd5b5b815160010180835281141561076f575b505060806101c0f3005b6329ed2862600051141561088e5733610140526108c4565b631e700cbb60005114156108bc5760843560a01c156108ac57600080fd5b60206084610140376000506108c4565b600015610b61575b60043560a01c156108d457600080fd5b604435808060008112156108e457195b607f1c156108f157600080fd5b9050506004353b61090157600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161093457600080fd5b60006101605260443515156109a0576020610260608463081579a5610180526024356101a0526044356101c0526064356101e052610140516102005261019c60006004355af161098357600080fd5b601f3d1161099057600080fd5b6000506102605161016052610b52565b60028060c052602060c020546101805260018160c052602060c02001546101a05260028160c052602060c02001546101c052506101806044356001808203808060008112156109eb57195b607f1c156109f857600080fd5b90509050905060038110610a0b57600080fd5b60200201516101e05260206102e0608463081579a56102005260243561022052600161024052600061026052306102805261021c60006004355af1610a4f57600080fd5b601f3d11610a5c57600080fd5b6000506102e051610160526000543b610a7457600080fd5b600060006064631a4d01d2610200526101605161022052604435600180820380806000811215610aa057195b607f1c15610aad57600080fd5b905090509050610240526064356102605261021c60006000545af1610ad157600080fd5b602061028060246370a0823161020052306102205261021c6101e0515afa610af857600080fd5b601f3d11610b0557600080fd5b60005061028051610160526101e0513b610b1e57600080fd5b60006000604463a9059cbb610200526101405161022052610160516102405261021c60006101e0515af1610b5157600080fd5b5b6101605160005260206000f350005b63ac24f7716000511415610b79573361014052610baf565b634329c8cc6000511415610ba75760c43560a01c15610b9757600080fd5b602060c461014037600050610baf565b6000156111e2575b60043560a01c15610bbf57600080fd5b60206101e0600463ddca3f436101805261019c6000545afa610be057600080fd5b601f3d11610bed57600080fd5b6000506101e05160038082028215828483041417610c0a57600080fd5b80905090509050600880820490509050610160526101608051610160516402540be4008082028215828483041417610c4157600080fd5b809050905090506402540be40080820490509050818183011015610c6457600080fd5b808201905090508152506004353b610c7b57600080fd5b6000600060646323b872dd61018052336101a052306101c05260a4356101e05261019c60006004355af1610cae57600080fd5b60c0366101803761024060006003818352015b602460016102405180820180806000811215610cd957195b607f1c15610ce657600080fd5b90509050905060048110610cf957600080fd5b6020020135610260526000610260511815610d3257610260516101a06102405160038110610d2657600080fd5b60200201526001610180525b5b8151600101808352811415610cc1575b5050602435610200526101805115610e135760206103206084633883e119610240526101a051610260526101c051610280526101e0516102a05260006102c05261025c6000545afa610d9457600080fd5b601f3d11610da157600080fd5b6000506103205161022052610220805161022051610160518082028215828483041417610dcd57600080fd5b809050905090506402540be400808204905090506001818183011015610df257600080fd5b80820190509050818183011015610e0857600080fd5b808201905090508152505b6020610320606463e3103273610260526102005161028052610220516102a05260a4356102c05261027c60006004355af1610e4d57600080fd5b601f3d11610e5a57600080fd5b60005061032051610240526004353b610e7257600080fd5b60006000604463a9059cbb61026052336102805260a4356102405180821015610e9a57600080fd5b808203905090506102a05261027c60006004355af1610eb857600080fd5b6101805115611148576000543b610ece57600080fd5b600060006084639fdaea0c610260526101a051610280526101c0516102a0526101e0516102c052610220516102e05261027c60006000545af1610f1057600080fd5b60015461026052602061032060246370a082316102a052306102c0526102bc610260515afa610f3e57600080fd5b601f3d11610f4b57600080fd5b600050610320516102805260006102805111156110755760036102605160e05260c052604060c02060043560e05260c052604060c02054151561100857610260513b610f9657600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610260515af1610fe557600080fd5b600160036102605160e05260c052604060c02060043560e05260c052604060c020555b610240805160206103806084630c3e4b546102a05260006102c052610280516102e05260006103005233610320526102bc60006004355af161104957600080fd5b601f3d1161105657600080fd5b600050610380518082101561106a57600080fd5b808203905090508152505b60028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060006003818352015b6102a061030051600381106110c857600080fd5b60200201513b6110d757600080fd5b60006000604463a9059cbb6103205261014051610340526101a0610300516003811061110257600080fd5b60200201516103605261033c60006102a0610300516003811061112457600080fd5b60200201515af161113457600080fd5b5b81516001018083528114156110b4575b50505b600060243511156111d3576020610300602463c66106576102805260006102a05261029c6004355afa61117a57600080fd5b601f3d1161118757600080fd5b6000506103005161026052610260513b6111a057600080fd5b60006000604463a9059cbb61028052610140516102a0526024356102c05261029c6000610260515af16111d257600080fd5b5b6102405160005260206000f350005b6341b028f360005114156113375760043560a01c1561120057600080fd5b6044358080600081121561121057195b607f1c1561121d57600080fd5b9050506001604435121561127c5760206101e0604463cc2b27d761014052602435610160526044356101805261015c6004355afa61125a57600080fd5b601f3d1161126757600080fd5b6000506101e05160005260206000f350611335565b6020610200604463cc2b27d7610160526024356101805260016101a05261017c6004355afa6112aa57600080fd5b601f3d116112b757600080fd5b60005061020051610140526020610200604463cc2b27d76101605261014051610180526044356001808203808060008112156112ef57195b607f1c156112fc57600080fd5b9050905090506101a05261017c6000545afa61131757600080fd5b601f3d1161132457600080fd5b6000506102005160005260206000f3505b005b63861cdef0600051141561149f5760043560a01c1561135557600080fd5b60a43560011c1561136557600080fd5b60a03661014037602435610140526101e060006003818352015b60246101e05160018082018080600081121561139757195b607f1c156113a457600080fd5b905090509050600481106113b757600080fd5b60200201356101806101e051600381106113d057600080fd5b60200201525b815160010180835281141561137f575b505060206102e06084633883e1196102005261018051610220526101a051610240526101c0516102605260a4356102805261021c6000545afa61142857600080fd5b601f3d1161143557600080fd5b6000506102e0516101e0526101e0516101605260206102c0606463ed8e84f3610200526101405161022052610160516102405260a4356102605261021c6004355afa61148057600080fd5b601f3d1161148d57600080fd5b6000506102c05160005260206000f350005b635d6362bb60005114156114bb5760005460005260206000f350005b63d6716cb560005114156114d75760015460005260206000f350005b6387cb4f57600051141561150c57600435600381106114f557600080fd5b600260c052602060c020015460005260206000f350005b5b60006000fd