false
false

Contract Address Details

0xa71BbD3b9f5Ea4B30b1912828C9775a80F8A80C5

Contract Name
Vyper_contract
Creator
0x13f0b2–f18271 at 0x5b06b3–490277
Balance
0 KCS
Tokens
Fetching tokens...
Transactions
68 Transactions
Transfers
528 Transfers
Gas Used
24,137,213
Last Balance Update
50917009
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0x90f256f20e594d4039de03285e7cfe31dc083e1a.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
Contract name:
Vyper_contract




Optimization enabled
false
Compiler version
v0.2.8




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

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

Verify & Publish
0x60a06116ac6101403960206116ac60c03960c05160a01c1561002057600080fd5b602060206116ac0160c03960c05160a01c1561003b57600080fd5b602060406116ac0160c03960c05160a01c1561005657600080fd5b602060606116ac0160c03960c05160a01c1561007157600080fd5b602060806116ac0160c03960c05160a01c1561008c57600080fd5b6101405160005561016051600155600260c052602060c0206101805181556101a05160018201556101c05160028201555060028060c052602060c020546101e05260018160c052602060c02001546102005260028160c052602060c0200154610220525061026060006003818352015b602061026051026101e0015161024052610240513b61011a57600080fd5b60006000604463095ea7b3610280526000546102a0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102c05261029c6000610240515af161016957600080fd5b5b81516001018083528114156100fc575b505061169456341561000a57600080fd5b60043610156100185761150d565b600035601c5263384e03db600051141561003657336101405261006c565b63d0b951e860005114156100645760c43560a01c1561005457600080fd5b602060c46101403760005061006c565b6000156104e5575b60043560a01c1561007c57600080fd5b60c0366101603760028060c052602060c020546102205260018160c052602060c02001546102405260028160c052602060c02001546102605250600060243518156101f0576020610320602463c66106576102a05260006102c0526102bc6004355afa6100e857600080fd5b601f3d116100f557600080fd5b600050610320516102805260036102805160e05260c052604060c02060043560e05260c052604060c0205415156101a657610280513b61013457600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161018357600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b610280513b6101b457600080fd5b6000600060646323b872dd6102a052336102c052306102e052602435610300526102bc6000610280515af16101e857600080fd5b602435610160525b61028060016003818352015b6024610280516004811061020f57600080fd5b60200201356102a0526102a05115156102275761032f565b6001610200526102805160018082101561024057600080fd5b808203905090506102c0526102206102c0516003811061025f57600080fd5b60200201516102e0526102e0513b61027657600080fd5b6000600060646323b872dd61030052336103205230610340526102a0516103605261031c60006102e0515af16102ab57600080fd5b600361028051141561031057602061038060246370a0823161030052306103205261031c6102e0515afa6102de57600080fd5b601f3d116102eb57600080fd5b600050610380516101a06102c0516003811061030657600080fd5b602002015261032e565b6102a0516101a06102c0516003811061032857600080fd5b60200201525b5b81516001018083528114156101fc575b5050610200511561048457600154610280526000543b61035e57600080fd5b600060006084634515cef36102a0526101a0516102c0526101c0516102e0526101e051610300526000610320526102bc60006000545af161039e57600080fd5b602061032060246370a082316102a052306102c0526102bc610280515afa6103c557600080fd5b601f3d116103d257600080fd5b600050610320516101805260036102805160e05260c052604060c02060043560e05260c052604060c02054151561048357610280513b61041157600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161046057600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b5b60206103606084630c3e4b5461028052610160516102a052610180516102c05260a4356102e052610140516103005261029c60006004355af16104c657600080fd5b601f3d116104d357600080fd5b6000506103605160005260206000f350005b63ad5cc91860005114156104fd573361014052610533565b63cbc399e5600051141561052b5760c43560a01c1561051b57600080fd5b602060c461014037600050610533565b600015610876575b60043560a01c1561054357600080fd5b6004353b61055057600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161058357600080fd5b60e0366101603760406103406064635b36389c610280526024356102a0526044356102c05260006102e05261029c60006004355af16105c157600080fd5b603f3d116105ce57600080fd5b6000506103408051610240528060200151610260525061028060006003818352015b60446001610280518082018080600081121561060857195b607f1c1561061557600080fd5b9050905090506004811061062857600080fd5b6020020135610160610280516003811061064157600080fd5b60200201525b81516001018083528114156105f0575b50506000543b61066657600080fd5b60006000608463ecb586a561028052610260516102a052610160516102c052610180516102e0526101a0516103005261029c60006000545af16106a857600080fd5b6020610320602463c66106576102a05260006102c0526102bc6004355afa6106cf57600080fd5b601f3d116106dc57600080fd5b6000506103205161028052610280513b6106f557600080fd5b60006000604463a9059cbb6102a052610140516102c052610240516102e0526102bc6000610280515af161072857600080fd5b610240516101c05260028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060016003818352015b6102a06103005160018082038080600081121561078857195b607f1c1561079557600080fd5b905090509050600381106107a857600080fd5b60200201516102805260206103a060246370a0823161032052306103405261033c610280515afa6107d857600080fd5b601f3d116107e557600080fd5b6000506103a0516101c0610300516004811061080057600080fd5b6020020152610280513b61081357600080fd5b60006000604463a9059cbb6103205261014051610340526101c0610300516004811061083e57600080fd5b60200201516103605261033c6000610280515af161085b57600080fd5b5b815160010180835281141561076f575b505060806101c0f3005b6329ed2862600051141561088e5733610140526108c4565b631e700cbb60005114156108bc5760843560a01c156108ac57600080fd5b60206084610140376000506108c4565b600015610b61575b60043560a01c156108d457600080fd5b604435808060008112156108e457195b607f1c156108f157600080fd5b9050506004353b61090157600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161093457600080fd5b60006101605260443515156109a0576020610260608463081579a5610180526024356101a0526044356101c0526064356101e052610140516102005261019c60006004355af161098357600080fd5b601f3d1161099057600080fd5b6000506102605161016052610b52565b60028060c052602060c020546101805260018160c052602060c02001546101a05260028160c052602060c02001546101c052506101806044356001808203808060008112156109eb57195b607f1c156109f857600080fd5b90509050905060038110610a0b57600080fd5b60200201516101e05260206102e0608463081579a56102005260243561022052600161024052600061026052306102805261021c60006004355af1610a4f57600080fd5b601f3d11610a5c57600080fd5b6000506102e051610160526000543b610a7457600080fd5b600060006064631a4d01d2610200526101605161022052604435600180820380806000811215610aa057195b607f1c15610aad57600080fd5b905090509050610240526064356102605261021c60006000545af1610ad157600080fd5b602061028060246370a0823161020052306102205261021c6101e0515afa610af857600080fd5b601f3d11610b0557600080fd5b60005061028051610160526101e0513b610b1e57600080fd5b60006000604463a9059cbb610200526101405161022052610160516102405261021c60006101e0515af1610b5157600080fd5b5b6101605160005260206000f350005b63ac24f7716000511415610b79573361014052610baf565b634329c8cc6000511415610ba75760c43560a01c15610b9757600080fd5b602060c461014037600050610baf565b6000156111e2575b60043560a01c15610bbf57600080fd5b60206101e0600463ddca3f436101805261019c6000545afa610be057600080fd5b601f3d11610bed57600080fd5b6000506101e05160038082028215828483041417610c0a57600080fd5b80905090509050600880820490509050610160526101608051610160516402540be4008082028215828483041417610c4157600080fd5b809050905090506402540be40080820490509050818183011015610c6457600080fd5b808201905090508152506004353b610c7b57600080fd5b6000600060646323b872dd61018052336101a052306101c05260a4356101e05261019c60006004355af1610cae57600080fd5b60c0366101803761024060006003818352015b602460016102405180820180806000811215610cd957195b607f1c15610ce657600080fd5b90509050905060048110610cf957600080fd5b6020020135610260526000610260511815610d3257610260516101a06102405160038110610d2657600080fd5b60200201526001610180525b5b8151600101808352811415610cc1575b5050602435610200526101805115610e135760206103206084633883e119610240526101a051610260526101c051610280526101e0516102a05260006102c05261025c6000545afa610d9457600080fd5b601f3d11610da157600080fd5b6000506103205161022052610220805161022051610160518082028215828483041417610dcd57600080fd5b809050905090506402540be400808204905090506001818183011015610df257600080fd5b80820190509050818183011015610e0857600080fd5b808201905090508152505b6020610320606463e3103273610260526102005161028052610220516102a05260a4356102c05261027c60006004355af1610e4d57600080fd5b601f3d11610e5a57600080fd5b60005061032051610240526004353b610e7257600080fd5b60006000604463a9059cbb61026052336102805260a4356102405180821015610e9a57600080fd5b808203905090506102a05261027c60006004355af1610eb857600080fd5b6101805115611148576000543b610ece57600080fd5b600060006084639fdaea0c610260526101a051610280526101c0516102a0526101e0516102c052610220516102e05261027c60006000545af1610f1057600080fd5b60015461026052602061032060246370a082316102a052306102c0526102bc610260515afa610f3e57600080fd5b601f3d11610f4b57600080fd5b600050610320516102805260006102805111156110755760036102605160e05260c052604060c02060043560e05260c052604060c02054151561100857610260513b610f9657600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610260515af1610fe557600080fd5b600160036102605160e05260c052604060c02060043560e05260c052604060c020555b610240805160206103806084630c3e4b546102a05260006102c052610280516102e05260006103005233610320526102bc60006004355af161104957600080fd5b601f3d1161105657600080fd5b600050610380518082101561106a57600080fd5b808203905090508152505b60028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060006003818352015b6102a061030051600381106110c857600080fd5b60200201513b6110d757600080fd5b60006000604463a9059cbb6103205261014051610340526101a0610300516003811061110257600080fd5b60200201516103605261033c60006102a0610300516003811061112457600080fd5b60200201515af161113457600080fd5b5b81516001018083528114156110b4575b50505b600060243511156111d3576020610300602463c66106576102805260006102a05261029c6004355afa61117a57600080fd5b601f3d1161118757600080fd5b6000506103005161026052610260513b6111a057600080fd5b60006000604463a9059cbb61028052610140516102a0526024356102c05261029c6000610260515af16111d257600080fd5b5b6102405160005260206000f350005b6341b028f360005114156113375760043560a01c1561120057600080fd5b6044358080600081121561121057195b607f1c1561121d57600080fd5b9050506001604435121561127c5760206101e0604463cc2b27d761014052602435610160526044356101805261015c6004355afa61125a57600080fd5b601f3d1161126757600080fd5b6000506101e05160005260206000f350611335565b6020610200604463cc2b27d7610160526024356101805260016101a05261017c6004355afa6112aa57600080fd5b601f3d116112b757600080fd5b60005061020051610140526020610200604463cc2b27d76101605261014051610180526044356001808203808060008112156112ef57195b607f1c156112fc57600080fd5b9050905090506101a05261017c6000545afa61131757600080fd5b601f3d1161132457600080fd5b6000506102005160005260206000f3505b005b63861cdef0600051141561149f5760043560a01c1561135557600080fd5b60a43560011c1561136557600080fd5b60a03661014037602435610140526101e060006003818352015b60246101e05160018082018080600081121561139757195b607f1c156113a457600080fd5b905090509050600481106113b757600080fd5b60200201356101806101e051600381106113d057600080fd5b60200201525b815160010180835281141561137f575b505060206102e06084633883e1196102005261018051610220526101a051610240526101c0516102605260a4356102805261021c6000545afa61142857600080fd5b601f3d1161143557600080fd5b6000506102e0516101e0526101e0516101605260206102c0606463ed8e84f3610200526101405161022052610160516102405260a4356102605261021c6004355afa61148057600080fd5b601f3d1161148d57600080fd5b6000506102c05160005260206000f350005b635d6362bb60005114156114bb5760005460005260206000f350005b63d6716cb560005114156114d75760015460005260206000f350005b6387cb4f57600051141561150c57600435600381106114f557600080fd5b600260c052602060c020015460005260206000f350005b5b60006000fd5b61018161169403610181600039610181611694036000f3000000000000000000000000303006c7c6f54d51171d1577509d972b8790ab9e000000000000000000000000303006c7c6f54d51171d1577509d972b8790ab9e00000000000000000000000011cc35ceec84058a61705fe219496d67c0834a4d0000000000000000000000001153335a3c0f3c2036d239f3a378aa149101d5690000000000000000000000004b6a673b282442543f81d88c79f4754f42de4993

Deployed ByteCode

0x341561000a57600080fd5b60043610156100185761150d565b600035601c5263384e03db600051141561003657336101405261006c565b63d0b951e860005114156100645760c43560a01c1561005457600080fd5b602060c46101403760005061006c565b6000156104e5575b60043560a01c1561007c57600080fd5b60c0366101603760028060c052602060c020546102205260018160c052602060c02001546102405260028160c052602060c02001546102605250600060243518156101f0576020610320602463c66106576102a05260006102c0526102bc6004355afa6100e857600080fd5b601f3d116100f557600080fd5b600050610320516102805260036102805160e05260c052604060c02060043560e05260c052604060c0205415156101a657610280513b61013457600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161018357600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b610280513b6101b457600080fd5b6000600060646323b872dd6102a052336102c052306102e052602435610300526102bc6000610280515af16101e857600080fd5b602435610160525b61028060016003818352015b6024610280516004811061020f57600080fd5b60200201356102a0526102a05115156102275761032f565b6001610200526102805160018082101561024057600080fd5b808203905090506102c0526102206102c0516003811061025f57600080fd5b60200201516102e0526102e0513b61027657600080fd5b6000600060646323b872dd61030052336103205230610340526102a0516103605261031c60006102e0515af16102ab57600080fd5b600361028051141561031057602061038060246370a0823161030052306103205261031c6102e0515afa6102de57600080fd5b601f3d116102eb57600080fd5b600050610380516101a06102c0516003811061030657600080fd5b602002015261032e565b6102a0516101a06102c0516003811061032857600080fd5b60200201525b5b81516001018083528114156101fc575b5050610200511561048457600154610280526000543b61035e57600080fd5b600060006084634515cef36102a0526101a0516102c0526101c0516102e0526101e051610300526000610320526102bc60006000545af161039e57600080fd5b602061032060246370a082316102a052306102c0526102bc610280515afa6103c557600080fd5b601f3d116103d257600080fd5b600050610320516101805260036102805160e05260c052604060c02060043560e05260c052604060c02054151561048357610280513b61041157600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610280515af161046057600080fd5b600160036102805160e05260c052604060c02060043560e05260c052604060c020555b5b60206103606084630c3e4b5461028052610160516102a052610180516102c05260a4356102e052610140516103005261029c60006004355af16104c657600080fd5b601f3d116104d357600080fd5b6000506103605160005260206000f350005b63ad5cc91860005114156104fd573361014052610533565b63cbc399e5600051141561052b5760c43560a01c1561051b57600080fd5b602060c461014037600050610533565b600015610876575b60043560a01c1561054357600080fd5b6004353b61055057600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161058357600080fd5b60e0366101603760406103406064635b36389c610280526024356102a0526044356102c05260006102e05261029c60006004355af16105c157600080fd5b603f3d116105ce57600080fd5b6000506103408051610240528060200151610260525061028060006003818352015b60446001610280518082018080600081121561060857195b607f1c1561061557600080fd5b9050905090506004811061062857600080fd5b6020020135610160610280516003811061064157600080fd5b60200201525b81516001018083528114156105f0575b50506000543b61066657600080fd5b60006000608463ecb586a561028052610260516102a052610160516102c052610180516102e0526101a0516103005261029c60006000545af16106a857600080fd5b6020610320602463c66106576102a05260006102c0526102bc6004355afa6106cf57600080fd5b601f3d116106dc57600080fd5b6000506103205161028052610280513b6106f557600080fd5b60006000604463a9059cbb6102a052610140516102c052610240516102e0526102bc6000610280515af161072857600080fd5b610240516101c05260028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060016003818352015b6102a06103005160018082038080600081121561078857195b607f1c1561079557600080fd5b905090509050600381106107a857600080fd5b60200201516102805260206103a060246370a0823161032052306103405261033c610280515afa6107d857600080fd5b601f3d116107e557600080fd5b6000506103a0516101c0610300516004811061080057600080fd5b6020020152610280513b61081357600080fd5b60006000604463a9059cbb6103205261014051610340526101c0610300516004811061083e57600080fd5b60200201516103605261033c6000610280515af161085b57600080fd5b5b815160010180835281141561076f575b505060806101c0f3005b6329ed2862600051141561088e5733610140526108c4565b631e700cbb60005114156108bc5760843560a01c156108ac57600080fd5b60206084610140376000506108c4565b600015610b61575b60043560a01c156108d457600080fd5b604435808060008112156108e457195b607f1c156108f157600080fd5b9050506004353b61090157600080fd5b6000600060646323b872dd610160523361018052306101a0526024356101c05261017c60006004355af161093457600080fd5b60006101605260443515156109a0576020610260608463081579a5610180526024356101a0526044356101c0526064356101e052610140516102005261019c60006004355af161098357600080fd5b601f3d1161099057600080fd5b6000506102605161016052610b52565b60028060c052602060c020546101805260018160c052602060c02001546101a05260028160c052602060c02001546101c052506101806044356001808203808060008112156109eb57195b607f1c156109f857600080fd5b90509050905060038110610a0b57600080fd5b60200201516101e05260206102e0608463081579a56102005260243561022052600161024052600061026052306102805261021c60006004355af1610a4f57600080fd5b601f3d11610a5c57600080fd5b6000506102e051610160526000543b610a7457600080fd5b600060006064631a4d01d2610200526101605161022052604435600180820380806000811215610aa057195b607f1c15610aad57600080fd5b905090509050610240526064356102605261021c60006000545af1610ad157600080fd5b602061028060246370a0823161020052306102205261021c6101e0515afa610af857600080fd5b601f3d11610b0557600080fd5b60005061028051610160526101e0513b610b1e57600080fd5b60006000604463a9059cbb610200526101405161022052610160516102405261021c60006101e0515af1610b5157600080fd5b5b6101605160005260206000f350005b63ac24f7716000511415610b79573361014052610baf565b634329c8cc6000511415610ba75760c43560a01c15610b9757600080fd5b602060c461014037600050610baf565b6000156111e2575b60043560a01c15610bbf57600080fd5b60206101e0600463ddca3f436101805261019c6000545afa610be057600080fd5b601f3d11610bed57600080fd5b6000506101e05160038082028215828483041417610c0a57600080fd5b80905090509050600880820490509050610160526101608051610160516402540be4008082028215828483041417610c4157600080fd5b809050905090506402540be40080820490509050818183011015610c6457600080fd5b808201905090508152506004353b610c7b57600080fd5b6000600060646323b872dd61018052336101a052306101c05260a4356101e05261019c60006004355af1610cae57600080fd5b60c0366101803761024060006003818352015b602460016102405180820180806000811215610cd957195b607f1c15610ce657600080fd5b90509050905060048110610cf957600080fd5b6020020135610260526000610260511815610d3257610260516101a06102405160038110610d2657600080fd5b60200201526001610180525b5b8151600101808352811415610cc1575b5050602435610200526101805115610e135760206103206084633883e119610240526101a051610260526101c051610280526101e0516102a05260006102c05261025c6000545afa610d9457600080fd5b601f3d11610da157600080fd5b6000506103205161022052610220805161022051610160518082028215828483041417610dcd57600080fd5b809050905090506402540be400808204905090506001818183011015610df257600080fd5b80820190509050818183011015610e0857600080fd5b808201905090508152505b6020610320606463e3103273610260526102005161028052610220516102a05260a4356102c05261027c60006004355af1610e4d57600080fd5b601f3d11610e5a57600080fd5b60005061032051610240526004353b610e7257600080fd5b60006000604463a9059cbb61026052336102805260a4356102405180821015610e9a57600080fd5b808203905090506102a05261027c60006004355af1610eb857600080fd5b6101805115611148576000543b610ece57600080fd5b600060006084639fdaea0c610260526101a051610280526101c0516102a0526101e0516102c052610220516102e05261027c60006000545af1610f1057600080fd5b60015461026052602061032060246370a082316102a052306102c0526102bc610260515afa610f3e57600080fd5b601f3d11610f4b57600080fd5b600050610320516102805260006102805111156110755760036102605160e05260c052604060c02060043560e05260c052604060c02054151561100857610260513b610f9657600080fd5b60006000604463095ea7b36102a0526004356102c0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102e0526102bc6000610260515af1610fe557600080fd5b600160036102605160e05260c052604060c02060043560e05260c052604060c020555b610240805160206103806084630c3e4b546102a05260006102c052610280516102e05260006103005233610320526102bc60006004355af161104957600080fd5b601f3d1161105657600080fd5b600050610380518082101561106a57600080fd5b808203905090508152505b60028060c052602060c020546102a05260018160c052602060c02001546102c05260028160c052602060c02001546102e0525061030060006003818352015b6102a061030051600381106110c857600080fd5b60200201513b6110d757600080fd5b60006000604463a9059cbb6103205261014051610340526101a0610300516003811061110257600080fd5b60200201516103605261033c60006102a0610300516003811061112457600080fd5b60200201515af161113457600080fd5b5b81516001018083528114156110b4575b50505b600060243511156111d3576020610300602463c66106576102805260006102a05261029c6004355afa61117a57600080fd5b601f3d1161118757600080fd5b6000506103005161026052610260513b6111a057600080fd5b60006000604463a9059cbb61028052610140516102a0526024356102c05261029c6000610260515af16111d257600080fd5b5b6102405160005260206000f350005b6341b028f360005114156113375760043560a01c1561120057600080fd5b6044358080600081121561121057195b607f1c1561121d57600080fd5b9050506001604435121561127c5760206101e0604463cc2b27d761014052602435610160526044356101805261015c6004355afa61125a57600080fd5b601f3d1161126757600080fd5b6000506101e05160005260206000f350611335565b6020610200604463cc2b27d7610160526024356101805260016101a05261017c6004355afa6112aa57600080fd5b601f3d116112b757600080fd5b60005061020051610140526020610200604463cc2b27d76101605261014051610180526044356001808203808060008112156112ef57195b607f1c156112fc57600080fd5b9050905090506101a05261017c6000545afa61131757600080fd5b601f3d1161132457600080fd5b6000506102005160005260206000f3505b005b63861cdef0600051141561149f5760043560a01c1561135557600080fd5b60a43560011c1561136557600080fd5b60a03661014037602435610140526101e060006003818352015b60246101e05160018082018080600081121561139757195b607f1c156113a457600080fd5b905090509050600481106113b757600080fd5b60200201356101806101e051600381106113d057600080fd5b60200201525b815160010180835281141561137f575b505060206102e06084633883e1196102005261018051610220526101a051610240526101c0516102605260a4356102805261021c6000545afa61142857600080fd5b601f3d1161143557600080fd5b6000506102e0516101e0526101e0516101605260206102c0606463ed8e84f3610200526101405161022052610160516102405260a4356102605261021c6004355afa61148057600080fd5b601f3d1161148d57600080fd5b6000506102c05160005260206000f350005b635d6362bb60005114156114bb5760005460005260206000f350005b63d6716cb560005114156114d75760015460005260206000f350005b6387cb4f57600051141561150c57600435600381106114f557600080fd5b600260c052602060c020015460005260206000f350005b5b60006000fd