ETH Price: $3,696.69 (-1.81%)

Token

ERC20 ***

Overview

Max Total Supply

920,374.560065718865937815 ERC20 ***

Holders

19,231

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.147619354914739352 ERC20 ***

Value
$0.00
0x24d9Ad4603a20512D6Ac47a1404aDb130180062d
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
Vyper_contract

Compiler Version
vyper:0.3.1

Optimization Enabled:
N/A

Other Settings:
default evmVersion, None license

Contract Source Code (Vyper language format)

# @version 0.3.1
"""
@title StableSwap
@author Curve.Fi
@license Copyright (c) Curve.Fi, 2020-2021 - all rights reserved
@notice 3 coin pool implementation with no lending
@dev ERC20 support for return True/revert, return True/False, return None
"""

from vyper.interfaces import ERC20

event Transfer:
    sender: indexed(address)
    receiver: indexed(address)
    value: uint256

event Approval:
    owner: indexed(address)
    spender: indexed(address)
    value: uint256

event TokenExchange:
    buyer: indexed(address)
    sold_id: int128
    tokens_sold: uint256
    bought_id: int128
    tokens_bought: uint256

event AddLiquidity:
    provider: indexed(address)
    token_amounts: uint256[N_COINS]
    fees: uint256[N_COINS]
    invariant: uint256
    token_supply: uint256

event RemoveLiquidity:
    provider: indexed(address)
    token_amounts: uint256[N_COINS]
    fees: uint256[N_COINS]
    token_supply: uint256

event RemoveLiquidityOne:
    provider: indexed(address)
    token_amount: uint256
    coin_amount: uint256
    token_supply: uint256

event RemoveLiquidityImbalance:
    provider: indexed(address)
    token_amounts: uint256[N_COINS]
    fees: uint256[N_COINS]
    invariant: uint256
    token_supply: uint256

event CommitNewAdmin:
    deadline: indexed(uint256)
    admin: indexed(address)

event NewAdmin:
    admin: indexed(address)

event CommitNewFee:
    deadline: indexed(uint256)
    fee: uint256
    admin_fee: uint256

event NewFee:
    fee: uint256
    admin_fee: uint256

event RampA:
    old_A: uint256
    new_A: uint256
    initial_time: uint256
    future_time: uint256

event StopRampA:
    A: uint256
    t: uint256


N_COINS: constant(int128) = 3
RATE_MULTIPLIERS: constant(uint256[N_COINS]) = [1000000000000000000, 1000000000000000000000000000000, 1000000000000000000000000000000]

FEE_DENOMINATOR: constant(uint256) = 10 ** 10
PRECISION: constant(uint256) = 10 ** 18

A_PRECISION: constant(uint256) = 100
MAX_ADMIN_FEE: constant(uint256) = 10 * 10 ** 9
MAX_FEE: constant(uint256) = 5 * 10 ** 9
MAX_A: constant(uint256) = 10 ** 6
MAX_A_CHANGE: constant(uint256) = 10
ADMIN_ACTIONS_DELAY: constant(uint256) = 3 * 86400
MIN_RAMP_TIME: constant(uint256) = 86400

coins: public(address[N_COINS])
balances: public(uint256[N_COINS])
fee: public(uint256)  # fee * 1e10
admin_fee: public(uint256)  # admin_fee * 1e10

owner: public(address)

initial_A: public(uint256)
future_A: public(uint256)
initial_A_time: public(uint256)
future_A_time: public(uint256)

admin_actions_deadline: public(uint256)
transfer_ownership_deadline: public(uint256)
future_fee: public(uint256)
future_admin_fee: public(uint256)
future_owner: public(address)

is_killed: bool
kill_deadline: uint256
KILL_DEADLINE_DT: constant(uint256) = 2 * 30 * 86400

name: public(String[64])
symbol: public(String[32])

balanceOf: public(HashMap[address, uint256])
allowance: public(HashMap[address, HashMap[address, uint256]])
totalSupply: public(uint256)


@external
def __init__(
    _coins: address[N_COINS],
    _A: uint256,
    _fee: uint256,
    _admin_fee: uint256,
    _name: String[64],
    _symbol: String[32],
):
    """
    @notice Contract constructor
    @param _coins Addresses of ERC20 conracts of coins
    @param _A Amplification coefficient multiplied by n ** (n - 1)
    @param _fee Fee to charge for exchanges
    @param _admin_fee Admin fee
    @param _name Name of the new pool
    @param _symbol Token symbol
    """
    self.coins = _coins
    self.initial_A = _A * A_PRECISION
    self.future_A = _A * A_PRECISION
    self.fee = _fee
    self.admin_fee = _admin_fee
    self.owner = msg.sender
    self.kill_deadline = block.timestamp + KILL_DEADLINE_DT

    self.name = _name
    self.symbol = _symbol

    # fire a transfer event so block explorers identify the contract as an ERC20
    log Transfer(ZERO_ADDRESS, self, 0)


### ERC20 Functionality ###

@view
@external
def decimals() -> uint256:
    """
    @notice Get the number of decimals for this token
    @dev Implemented as a view method to reduce gas costs
    @return uint256 decimal places
    """
    return 18


@internal
def _transfer(_from: address, _to: address, _value: uint256):
    # # NOTE: vyper does not allow underflows
    # #       so the following subtraction would revert on insufficient balance
    self.balanceOf[_from] -= _value
    self.balanceOf[_to] += _value

    log Transfer(_from, _to, _value)


@external
def transfer(_to : address, _value : uint256) -> bool:
    """
    @dev Transfer token for a specified address
    @param _to The address to transfer to.
    @param _value The amount to be transferred.
    """
    self._transfer(msg.sender, _to, _value)
    return True


@external
def transferFrom(_from : address, _to : address, _value : uint256) -> bool:
    """
     @dev Transfer tokens from one address to another.
     @param _from address The address which you want to send tokens from
     @param _to address The address which you want to transfer to
     @param _value uint256 the amount of tokens to be transferred
    """
    self._transfer(_from, _to, _value)

    _allowance: uint256 = self.allowance[_from][msg.sender]
    if _allowance != MAX_UINT256:
        self.allowance[_from][msg.sender] = _allowance - _value

    return True


@external
def approve(_spender : address, _value : uint256) -> bool:
    """
    @notice Approve the passed address to transfer the specified amount of
            tokens on behalf of msg.sender
    @dev Beware that changing an allowance via this method brings the risk that
         someone may use both the old and new allowance by unfortunate transaction
         ordering: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    @param _spender The address which will transfer the funds
    @param _value The amount of tokens that may be transferred
    @return bool success
    """
    self.allowance[msg.sender][_spender] = _value

    log Approval(msg.sender, _spender, _value)
    return True


### StableSwap Functionality ###

@view
@external
def get_balances() -> uint256[N_COINS]:
    return self.balances


@view
@internal
def _A() -> uint256:
    """
    Handle ramping A up or down
    """
    t1: uint256 = self.future_A_time
    A1: uint256 = self.future_A

    if block.timestamp < t1:
        A0: uint256 = self.initial_A
        t0: uint256 = self.initial_A_time
        # Expressions in uint256 cannot have negative numbers, thus "if"
        if A1 > A0:
            return A0 + (A1 - A0) * (block.timestamp - t0) / (t1 - t0)
        else:
            return A0 - (A0 - A1) * (block.timestamp - t0) / (t1 - t0)

    else:  # when t1 == 0 or block.timestamp >= t1
        return A1


@view
@external
def A() -> uint256:
    return self._A() / A_PRECISION


@view
@external
def A_precise() -> uint256:
    return self._A()


@pure
@internal
def _xp_mem(_balances: uint256[N_COINS]) -> uint256[N_COINS]:
    result: uint256[N_COINS] = RATE_MULTIPLIERS
    for i in range(N_COINS):
        result[i] = result[i] * _balances[i] / PRECISION
    return result


@pure
@internal
def get_D(_xp: uint256[N_COINS], _amp: uint256) -> uint256:
    """
    D invariant calculation in non-overflowing integer operations
    iteratively

    A * sum(x_i) * n**n + D = A * D * n**n + D**(n+1) / (n**n * prod(x_i))

    Converging solution:
    D[j+1] = (A * n**n * sum(x_i) - D[j]**(n+1) / (n**n prod(x_i))) / (A * n**n - 1)
    """
    S: uint256 = 0
    Dprev: uint256 = 0
    for x in _xp:
        S += x
    if S == 0:
        return 0

    D: uint256 = S
    Ann: uint256 = _amp * N_COINS
    for i in range(255):
        D_P: uint256 = D
        for x in _xp:
            D_P = D_P * D / (x * N_COINS)  # If division by 0, this will be borked: only withdrawal will work. And that is good
        Dprev = D
        D = (Ann * S / A_PRECISION + D_P * N_COINS) * D / ((Ann - A_PRECISION) * D / A_PRECISION + (N_COINS + 1) * D_P)
        # Equality with the precision of 1
        if D > Dprev:
            if D - Dprev <= 1:
                return D
        else:
            if Dprev - D <= 1:
                return D
    # convergence typically occurs in 4 rounds or less, this should be unreachable!
    # if it does happen the pool is borked and LPs can withdraw via `remove_liquidity`
    raise


@view
@internal
def get_D_mem(_balances: uint256[N_COINS], _amp: uint256) -> uint256:
    xp: uint256[N_COINS] = self._xp_mem(_balances)
    return self.get_D(xp, _amp)


@view
@external
def get_virtual_price() -> uint256:
    """
    @notice The current virtual price of the pool LP token
    @dev Useful for calculating profits
    @return LP token virtual price normalized to 1e18
    """
    amp: uint256 = self._A()
    xp: uint256[N_COINS] = self._xp_mem(self.balances)
    D: uint256 = self.get_D(xp, amp)
    # D is in the units similar to DAI (e.g. converted to precision 1e18)
    # When balanced, D = n * x_u - total virtual value of the portfolio
    return D * PRECISION / self.totalSupply


@view
@external
def calc_token_amount(_amounts: uint256[N_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 _amounts Amount of each coin being deposited
    @param _is_deposit set True for deposits, False for withdrawals
    @return Expected amount of LP tokens received
    """
    amp: uint256 = self._A()
    balances: uint256[N_COINS] = self.balances
    D0: uint256 = self.get_D_mem(balances, amp)
    for i in range(N_COINS):
        amount: uint256 = _amounts[i]
        if _is_deposit:
            balances[i] += amount
        else:
            balances[i] -= amount
    D1: uint256 = self.get_D_mem(balances, amp)
    diff: uint256 = 0
    if _is_deposit:
        diff = D1 - D0
    else:
        diff = D0 - D1
    return diff * self.totalSupply / D0


@external
@nonreentrant('lock')
def add_liquidity(
    _amounts: uint256[N_COINS],
    _min_mint_amount: uint256,
    _receiver: address = msg.sender
) -> uint256:
    """
    @notice Deposit coins into the pool
    @param _amounts List of amounts of coins to deposit
    @param _min_mint_amount Minimum amount of LP tokens to mint from the deposit
    @param _receiver Address that owns the minted LP tokens
    @return Amount of LP tokens received by depositing
    """
    assert not self.is_killed  # dev: is killed
    amp: uint256 = self._A()
    old_balances: uint256[N_COINS] = self.balances

    # Initial invariant
    D0: uint256 = self.get_D_mem(old_balances, amp)

    total_supply: uint256 = self.totalSupply
    new_balances: uint256[N_COINS] = old_balances
    for i in range(N_COINS):
        amount: uint256 = _amounts[i]
        if amount > 0:
            response: Bytes[32] = raw_call(
                self.coins[i],
                concat(
                    method_id("transferFrom(address,address,uint256)"),
                    convert(msg.sender, bytes32),
                    convert(self, bytes32),
                    convert(amount, bytes32),
                ),
                max_outsize=32,
            )
            if len(response) > 0:
                assert convert(response, bool)  # dev: failed transfer
            new_balances[i] += amount
            # end "safeTransferFrom"
        else:
            assert total_supply != 0  # dev: initial deposit requires all coins

    # Invariant after change
    D1: uint256 = self.get_D_mem(new_balances, amp)
    assert D1 > D0

    # We need to recalculate the invariant accounting for fees
    # to calculate fair user's share
    fees: uint256[N_COINS] = empty(uint256[N_COINS])
    mint_amount: uint256 = 0
    if total_supply > 0:
        # Only account for fees if we are not the first to deposit
        base_fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
        for i in range(N_COINS):
            ideal_balance: uint256 = D1 * old_balances[i] / D0
            difference: uint256 = 0
            new_balance: uint256 = new_balances[i]
            if ideal_balance > new_balance:
                difference = ideal_balance - new_balance
            else:
                difference = new_balance - ideal_balance
            fees[i] = base_fee * difference / FEE_DENOMINATOR
            self.balances[i] = new_balance - (fees[i] * self.admin_fee / FEE_DENOMINATOR)
            new_balances[i] -= fees[i]
        D2: uint256 = self.get_D_mem(new_balances, amp)
        mint_amount = total_supply * (D2 - D0) / D0
    else:
        self.balances = new_balances
        mint_amount = D1  # Take the dust if there was any

    assert mint_amount >= _min_mint_amount, "Slippage screwed you"

    # Mint pool tokens
    total_supply += mint_amount
    self.balanceOf[_receiver] += mint_amount
    self.totalSupply = total_supply
    log Transfer(ZERO_ADDRESS, _receiver, mint_amount)

    log AddLiquidity(msg.sender, _amounts, fees, D1, total_supply)

    return mint_amount


@view
@internal
def get_y(i: int128, j: int128, x: uint256, xp: uint256[N_COINS]) -> uint256:
    """
    Calculate x[j] if one makes x[i] = x

    Done by solving quadratic equation iteratively.
    x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
    x_1**2 + b*x_1 = c

    x_1 = (x_1**2 + c) / (2*x_1 + b)
    """
    # x in the input is converted to the same price/precision

    assert i != j       # dev: same coin
    assert j >= 0       # dev: j below zero
    assert j < N_COINS  # dev: j above N_COINS

    # should be unreachable, but good for safety
    assert i >= 0
    assert i < N_COINS

    amp: uint256 = self._A()
    D: uint256 = self.get_D(xp, amp)
    S_: uint256 = 0
    _x: uint256 = 0
    y_prev: uint256 = 0
    c: uint256 = D
    Ann: uint256 = amp * N_COINS

    for _i in range(N_COINS):
        if _i == i:
            _x = x
        elif _i != j:
            _x = xp[_i]
        else:
            continue
        S_ += _x
        c = c * D / (_x * N_COINS)

    c = c * D * A_PRECISION / (Ann * N_COINS)
    b: uint256 = S_ + D * A_PRECISION / Ann  # - D
    y: uint256 = D

    for _i in range(255):
        y_prev = y
        y = (y*y + c) / (2 * y + b - D)
        # Equality with the precision of 1
        if y > y_prev:
            if y - y_prev <= 1:
                return y
        else:
            if y_prev - y <= 1:
                return y
    raise


@view
@external
def get_dy(i: int128, j: int128, dx: uint256) -> uint256:
    """
    @notice Calculate the current output dy given input dx
    @dev Index values can be found via the `coins` public getter method
    @param i Index value for the coin to send
    @param j Index valie of the coin to recieve
    @param dx Amount of `i` being exchanged
    @return Amount of `j` predicted
    """
    xp: uint256[N_COINS] = self._xp_mem(self.balances)
    rates: uint256[N_COINS] = RATE_MULTIPLIERS

    x: uint256 = xp[i] + (dx * rates[i] / PRECISION)
    y: uint256 = self.get_y(i, j, x, xp)
    dy: uint256 = xp[j] - y - 1
    fee: uint256 = self.fee * dy / FEE_DENOMINATOR
    return (dy - fee) * PRECISION / rates[j]


@external
@nonreentrant('lock')
def exchange(
    i: int128,
    j: int128,
    _dx: uint256,
    _min_dy: uint256,
    _receiver: address = msg.sender,
) -> uint256:
    """
    @notice Perform an exchange between two coins
    @dev Index values can be found via the `coins` public getter method
    @param i Index value for the coin to send
    @param j Index valie of the coin to recieve
    @param _dx Amount of `i` being exchanged
    @param _min_dy Minimum amount of `j` to receive
    @return Actual amount of `j` received
    """
    assert not self.is_killed  # dev: is killed

    old_balances: uint256[N_COINS] = self.balances
    xp: uint256[N_COINS] = self._xp_mem(old_balances)

    rates: uint256[N_COINS] = RATE_MULTIPLIERS
    x: uint256 = xp[i] + _dx * rates[i] / PRECISION
    y: uint256 = self.get_y(i, j, x, xp)

    dy: uint256 = xp[j] - y - 1  # -1 just in case there were some rounding errors
    dy_fee: uint256 = dy * self.fee / FEE_DENOMINATOR

    # Convert all to real units
    dy = (dy - dy_fee) * PRECISION / rates[j]
    assert dy >= _min_dy, "Exchange resulted in fewer coins than expected"

    dy_admin_fee: uint256 = dy_fee * self.admin_fee / FEE_DENOMINATOR
    dy_admin_fee = dy_admin_fee * PRECISION / rates[j]

    # Change balances exactly in same way as we change actual ERC20 coin amounts
    self.balances[i] = old_balances[i] + _dx
    # When rounding errors happen, we undercharge admin fee in favor of LP
    self.balances[j] = old_balances[j] - dy - dy_admin_fee

    response: Bytes[32] = raw_call(
        self.coins[i],
        concat(
            method_id("transferFrom(address,address,uint256)"),
            convert(msg.sender, bytes32),
            convert(self, bytes32),
            convert(_dx, bytes32),
        ),
        max_outsize=32,
    )
    if len(response) > 0:
        assert convert(response, bool)

    response = raw_call(
        self.coins[j],
        concat(
            method_id("transfer(address,uint256)"),
            convert(_receiver, bytes32),
            convert(dy, bytes32),
        ),
        max_outsize=32,
    )
    if len(response) > 0:
        assert convert(response, bool)

    log TokenExchange(msg.sender, i, _dx, j, dy)

    return dy


@external
@nonreentrant('lock')
def remove_liquidity(
    _burn_amount: uint256,
    _min_amounts: uint256[N_COINS],
    _receiver: address = msg.sender
) -> uint256[N_COINS]:
    """
    @notice Withdraw coins from the pool
    @dev Withdrawal amounts are based on current deposit ratios
    @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 withdrawn coins
    @return List of amounts of coins that were withdrawn
    """
    total_supply: uint256 = self.totalSupply
    amounts: uint256[N_COINS] = empty(uint256[N_COINS])

    for i in range(N_COINS):
        old_balance: uint256 = self.balances[i]
        value: uint256 = old_balance * _burn_amount / total_supply
        assert value >= _min_amounts[i], "Withdrawal resulted in fewer coins than expected"
        self.balances[i] = old_balance - value
        amounts[i] = value

        response: Bytes[32] = raw_call(
            self.coins[i],
            concat(
                method_id("transfer(address,uint256)"),
                convert(_receiver, bytes32),
                convert(value, bytes32),
            ),
            max_outsize=32,
        )
        if len(response) > 0:
            assert convert(response, bool)

    total_supply -= _burn_amount
    self.balanceOf[msg.sender] -= _burn_amount
    self.totalSupply = total_supply
    log Transfer(msg.sender, ZERO_ADDRESS, _burn_amount)

    log RemoveLiquidity(msg.sender, amounts, empty(uint256[N_COINS]), total_supply)

    return amounts


@external
@nonreentrant('lock')
def remove_liquidity_imbalance(
    _amounts: uint256[N_COINS],
    _max_burn_amount: uint256,
    _receiver: address = msg.sender
) -> uint256:
    """
    @notice Withdraw coins from the pool in an imbalanced amount
    @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 withdrawn coins
    @return Actual amount of the LP token burned in the withdrawal
    """
    assert not self.is_killed  # dev: is killed

    amp: uint256 = self._A()
    old_balances: uint256[N_COINS] = self.balances
    D0: uint256 = self.get_D_mem(old_balances, amp)

    new_balances: uint256[N_COINS] = old_balances
    for i in range(N_COINS):
        amount: uint256 = _amounts[i]
        if amount != 0:
            new_balances[i] -= amount
            response: Bytes[32] = raw_call(
                self.coins[i],
                concat(
                    method_id("transfer(address,uint256)"),
                    convert(_receiver, bytes32),
                    convert(amount, bytes32),
                ),
                max_outsize=32,
            )
            if len(response) > 0:
                assert convert(response, bool)
    D1: uint256 = self.get_D_mem(new_balances, amp)

    fees: uint256[N_COINS] = empty(uint256[N_COINS])
    base_fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
    for i in range(N_COINS):
        ideal_balance: uint256 = D1 * old_balances[i] / D0
        difference: uint256 = 0
        new_balance: uint256 = new_balances[i]
        if ideal_balance > new_balance:
            difference = ideal_balance - new_balance
        else:
            difference = new_balance - ideal_balance
        fees[i] = base_fee * difference / FEE_DENOMINATOR
        self.balances[i] = new_balance - (fees[i] * self.admin_fee / FEE_DENOMINATOR)
        new_balances[i] -= fees[i]
    D2: uint256 = self.get_D_mem(new_balances, amp)

    total_supply: uint256 = self.totalSupply
    burn_amount: uint256 = ((D0 - D2) * total_supply / D0) + 1
    assert burn_amount > 1  # dev: zero tokens burned
    assert burn_amount <= _max_burn_amount, "Slippage screwed you"

    total_supply -= burn_amount
    self.totalSupply = total_supply
    self.balanceOf[msg.sender] -= burn_amount
    log Transfer(msg.sender, ZERO_ADDRESS, burn_amount)
    log RemoveLiquidityImbalance(msg.sender, _amounts, fees, D1, total_supply)

    return burn_amount


@pure
@internal
def get_y_D(A: uint256, i: int128, xp: uint256[N_COINS], D: uint256) -> uint256:
    """
    Calculate x[i] if one reduces D from being calculated for xp to D

    Done by solving quadratic equation iteratively.
    x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
    x_1**2 + b*x_1 = c

    x_1 = (x_1**2 + c) / (2*x_1 + b)
    """
    # x in the input is converted to the same price/precision

    assert i >= 0  # dev: i below zero
    assert i < N_COINS  # dev: i above N_COINS

    S_: uint256 = 0
    _x: uint256 = 0
    y_prev: uint256 = 0
    c: uint256 = D
    Ann: uint256 = A * N_COINS

    for _i in range(N_COINS):
        if _i != i:
            _x = xp[_i]
        else:
            continue
        S_ += _x
        c = c * D / (_x * N_COINS)

    c = c * D * A_PRECISION / (Ann * N_COINS)
    b: uint256 = S_ + D * A_PRECISION / Ann
    y: uint256 = D

    for _i in range(255):
        y_prev = y
        y = (y*y + c) / (2 * y + b - D)
        # Equality with the precision of 1
        if y > y_prev:
            if y - y_prev <= 1:
                return y
        else:
            if y_prev - y <= 1:
                return y
    raise


@view
@internal
def _calc_withdraw_one_coin(_burn_amount: uint256, i: int128) -> uint256[2]:
    # First, need to calculate
    # * Get current D
    # * Solve Eqn against y_i for D - _token_amount
    amp: uint256 = self._A()
    rates: uint256[N_COINS] = RATE_MULTIPLIERS
    xp: uint256[N_COINS] = self._xp_mem(self.balances)
    D0: uint256 = self.get_D(xp, amp)

    total_supply: uint256 = self.totalSupply
    D1: uint256 = D0 - _burn_amount * D0 / total_supply
    new_y: uint256 = self.get_y_D(amp, i, xp, D1)

    base_fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
    xp_reduced: uint256[N_COINS] = empty(uint256[N_COINS])

    for j in range(N_COINS):
        dx_expected: uint256 = 0
        xp_j: uint256 = xp[j]
        if j == i:
            dx_expected = xp_j * D1 / D0 - new_y
        else:
            dx_expected = xp_j - xp_j * D1 / D0
        xp_reduced[j] = xp_j - base_fee * dx_expected / FEE_DENOMINATOR

    dy: uint256 = xp_reduced[i] - self.get_y_D(amp, i, xp_reduced, D1)
    dy_0: uint256 = (xp[i] - new_y) * PRECISION / rates[i]  # w/o fees
    dy = (dy - 1) * PRECISION / rates[i]  # Withdraw less to account for rounding errors

    return [dy, dy_0 - dy]


@view
@external
def calc_withdraw_one_coin(_burn_amount: uint256, i: int128) -> uint256:
    """
    @notice Calculate the amount received when withdrawing a single coin
    @param _burn_amount Amount of LP tokens to burn in the withdrawal
    @param i Index value of the coin to withdraw
    @return Amount of coin received
    """
    return self._calc_withdraw_one_coin(_burn_amount, i)[0]


@external
@nonreentrant('lock')
def remove_liquidity_one_coin(
    _burn_amount: uint256,
    i: int128,
    _min_received: uint256,
    _receiver: address = msg.sender,
) -> uint256:
    """
    @notice Withdraw a single coin from the pool
    @param _burn_amount Amount of LP tokens to burn in the withdrawal
    @param i Index value of the coin to withdraw
    @param _min_received Minimum amount of coin to receive
    @param _receiver Address that receives the withdrawn coins
    @return Amount of coin received
    """
    assert not self.is_killed  # dev: is killed

    dy: uint256[2] = self._calc_withdraw_one_coin(_burn_amount, i)
    assert dy[0] >= _min_received, "Not enough coins removed"

    self.balances[i] -= (dy[0] + dy[1] * self.admin_fee / FEE_DENOMINATOR)
    total_supply: uint256 = self.totalSupply - _burn_amount
    self.totalSupply = total_supply
    self.balanceOf[msg.sender] -= _burn_amount
    log Transfer(msg.sender, ZERO_ADDRESS, _burn_amount)

    response: Bytes[32] = raw_call(
        self.coins[i],
        concat(
            method_id("transfer(address,uint256)"),
            convert(_receiver, bytes32),
            convert(dy[0], bytes32),
        ),
        max_outsize=32,
    )
    if len(response) > 0:
        assert convert(response, bool)

    log RemoveLiquidityOne(msg.sender, _burn_amount, dy[0], total_supply)

    return dy[0]


@external
def ramp_A(_future_A: uint256, _future_time: uint256):
    assert msg.sender == self.owner  # dev: only owner
    assert block.timestamp >= self.initial_A_time + MIN_RAMP_TIME
    assert _future_time >= block.timestamp + MIN_RAMP_TIME  # dev: insufficient time

    initial_A: uint256 = self._A()
    future_A_p: uint256 = _future_A * A_PRECISION

    assert _future_A > 0 and _future_A < MAX_A
    if future_A_p < initial_A:
        assert future_A_p * MAX_A_CHANGE >= initial_A
    else:
        assert future_A_p <= initial_A * MAX_A_CHANGE

    self.initial_A = initial_A
    self.future_A = future_A_p
    self.initial_A_time = block.timestamp
    self.future_A_time = _future_time

    log RampA(initial_A, future_A_p, block.timestamp, _future_time)


@external
def stop_ramp_A():
    assert msg.sender == self.owner  # dev: only owner

    current_A: uint256 = self._A()
    self.initial_A = current_A
    self.future_A = current_A
    self.initial_A_time = block.timestamp
    self.future_A_time = block.timestamp
    # now (block.timestamp < t1) is always False, so we return saved A

    log StopRampA(current_A, block.timestamp)


@external
def commit_new_fee(_new_fee: uint256, _new_admin_fee: uint256):
    assert msg.sender == self.owner  # dev: only owner
    assert self.admin_actions_deadline == 0  # dev: active action
    assert _new_fee <= MAX_FEE  # dev: fee exceeds maximum
    assert _new_admin_fee <= MAX_ADMIN_FEE  # dev: admin fee exceeds maximum

    deadline: uint256 = block.timestamp + ADMIN_ACTIONS_DELAY
    self.admin_actions_deadline = deadline
    self.future_fee = _new_fee
    self.future_admin_fee = _new_admin_fee

    log CommitNewFee(deadline, _new_fee, _new_admin_fee)


@external
def apply_new_fee():
    assert msg.sender == self.owner  # dev: only owner
    assert block.timestamp >= self.admin_actions_deadline  # dev: insufficient time
    assert self.admin_actions_deadline != 0  # dev: no active action

    self.admin_actions_deadline = 0
    fee: uint256 = self.future_fee
    admin_fee: uint256 = self.future_admin_fee
    self.fee = fee
    self.admin_fee = admin_fee

    log NewFee(fee, admin_fee)


@external
def revert_new_parameters():
    assert msg.sender == self.owner  # dev: only owner

    self.admin_actions_deadline = 0


@external
def commit_transfer_ownership(_owner: address):
    assert msg.sender == self.owner  # dev: only owner
    assert self.transfer_ownership_deadline == 0  # dev: active transfer

    deadline: uint256 = block.timestamp + ADMIN_ACTIONS_DELAY
    self.transfer_ownership_deadline = deadline
    self.future_owner = _owner

    log CommitNewAdmin(deadline, _owner)


@external
def apply_transfer_ownership():
    assert msg.sender == self.owner  # dev: only owner
    assert block.timestamp >= self.transfer_ownership_deadline  # dev: insufficient time
    assert self.transfer_ownership_deadline != 0  # dev: no active transfer

    self.transfer_ownership_deadline = 0
    owner: address = self.future_owner
    self.owner = owner

    log NewAdmin(owner)


@external
def revert_transfer_ownership():
    assert msg.sender == self.owner  # dev: only owner

    self.transfer_ownership_deadline = 0


@view
@external
def admin_balances(i: uint256) -> uint256:
    return ERC20(self.coins[i]).balanceOf(self) - self.balances[i]


@external
def withdraw_admin_fees():
    assert msg.sender == self.owner  # dev: only owner

    for i in range(N_COINS):
        coin: address = self.coins[i]
        value: uint256 = ERC20(coin).balanceOf(self) - self.balances[i]
        if value > 0:
            response: Bytes[32] = raw_call(
                coin,
                concat(
                    method_id("transfer(address,uint256)"),
                    convert(msg.sender, bytes32),
                    convert(value, bytes32),
                ),
                max_outsize=32,
            )  # dev: failed transfer
            if len(response) > 0:
                assert convert(response, bool)


@external
def donate_admin_fees():
    assert msg.sender == self.owner  # dev: only owner
    for i in range(N_COINS):
        self.balances[i] = ERC20(self.coins[i]).balanceOf(self)


@external
def kill_me():
    assert msg.sender == self.owner  # dev: only owner
    assert self.kill_deadline > block.timestamp  # dev: deadline has passed
    self.is_killed = True


@external
def unkill_me():
    assert msg.sender == self.owner  # dev: only owner
    self.is_killed = False

Contract Security Audit

Contract ABI

[{"name":"Transfer","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true},{"name":"spender","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchange","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[3]","indexed":false},{"name":"fees","type":"uint256[3]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidity","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[3]","indexed":false},{"name":"fees","type":"uint256[3]","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityOne","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amount","type":"uint256","indexed":false},{"name":"coin_amount","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityImbalance","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[3]","indexed":false},{"name":"fees","type":"uint256[3]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CommitNewAdmin","inputs":[{"name":"deadline","type":"uint256","indexed":true},{"name":"admin","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"NewAdmin","inputs":[{"name":"admin","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"name":"CommitNewFee","inputs":[{"name":"deadline","type":"uint256","indexed":true},{"name":"fee","type":"uint256","indexed":false},{"name":"admin_fee","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"NewFee","inputs":[{"name":"fee","type":"uint256","indexed":false},{"name":"admin_fee","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RampA","inputs":[{"name":"old_A","type":"uint256","indexed":false},{"name":"new_A","type":"uint256","indexed":false},{"name":"initial_time","type":"uint256","indexed":false},{"name":"future_time","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"StopRampA","inputs":[{"name":"A","type":"uint256","indexed":false},{"name":"t","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_coins","type":"address[3]"},{"name":"_A","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_admin_fee","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":360},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":78945},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":116925},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":39181},{"stateMutability":"view","type":"function","name":"get_balances","inputs":[],"outputs":[{"name":"","type":"uint256[3]"}],"gas":6834},{"stateMutability":"view","type":"function","name":"A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":10358},{"stateMutability":"view","type":"function","name":"A_precise","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":10358},{"stateMutability":"view","type":"function","name":"get_virtual_price","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":947474},{"stateMutability":"view","type":"function","name":"calc_token_amount","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_is_deposit","type":"bool"}],"outputs":[{"name":"","type":"uint256"}],"gas":1879145},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_min_mint_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3098855},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_min_mint_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3098855},{"stateMutability":"view","type":"function","name":"get_dy","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1294964},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1453628},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1453628},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[3]"}],"outputs":[{"name":"","type":"uint256[3]"}],"gas":292198},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[3]"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256[3]"}],"gas":292198},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_max_burn_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3098883},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[3]"},{"name":"_max_burn_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3098883},{"stateMutability":"view","type":"function","name":"calc_withdraw_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"}],"outputs":[{"name":"","type":"uint256"}],"gas":1151},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1840077},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1840077},{"stateMutability":"nonpayable","type":"function","name":"ramp_A","inputs":[{"name":"_future_A","type":"uint256"},{"name":"_future_time","type":"uint256"}],"outputs":[],"gas":158694},{"stateMutability":"nonpayable","type":"function","name":"stop_ramp_A","inputs":[],"outputs":[],"gas":154917},{"stateMutability":"nonpayable","type":"function","name":"commit_new_fee","inputs":[{"name":"_new_fee","type":"uint256"},{"name":"_new_admin_fee","type":"uint256"}],"outputs":[],"gas":113448},{"stateMutability":"nonpayable","type":"function","name":"apply_new_fee","inputs":[],"outputs":[],"gas":103771},{"stateMutability":"nonpayable","type":"function","name":"revert_new_parameters","inputs":[],"outputs":[],"gas":23051},{"stateMutability":"nonpayable","type":"function","name":"commit_transfer_ownership","inputs":[{"name":"_owner","type":"address"}],"outputs":[],"gas":78686},{"stateMutability":"nonpayable","type":"function","name":"apply_transfer_ownership","inputs":[],"outputs":[],"gas":66954},{"stateMutability":"nonpayable","type":"function","name":"revert_transfer_ownership","inputs":[],"outputs":[],"gas":23141},{"stateMutability":"view","type":"function","name":"admin_balances","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":7919},{"stateMutability":"nonpayable","type":"function","name":"withdraw_admin_fees","inputs":[],"outputs":[],"gas":45837},{"stateMutability":"nonpayable","type":"function","name":"donate_admin_fees","inputs":[],"outputs":[],"gas":122256},{"stateMutability":"nonpayable","type":"function","name":"kill_me","inputs":[],"outputs":[],"gas":40454},{"stateMutability":"nonpayable","type":"function","name":"unkill_me","inputs":[],"outputs":[],"gas":23291},{"stateMutability":"view","type":"function","name":"coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":3375},{"stateMutability":"view","type":"function","name":"balances","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3405},{"stateMutability":"view","type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3390},{"stateMutability":"view","type":"function","name":"admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3420},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3450},{"stateMutability":"view","type":"function","name":"initial_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3480},{"stateMutability":"view","type":"function","name":"future_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3510},{"stateMutability":"view","type":"function","name":"initial_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3540},{"stateMutability":"view","type":"function","name":"future_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3570},{"stateMutability":"view","type":"function","name":"admin_actions_deadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3600},{"stateMutability":"view","type":"function","name":"transfer_ownership_deadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3630},{"stateMutability":"view","type":"function","name":"future_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3660},{"stateMutability":"view","type":"function","name":"future_admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3690},{"stateMutability":"view","type":"function","name":"future_owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3720},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":14039},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":11798},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":4076},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":4372},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3870}]

613c8b6020816080396080518060a01c613c865760e0526020602082016080396080518060a01c613c8657610100526020604082016080396080518060a01c613c86576101205250602060c0613c8b01608039608051613c8b01604060208260803960805111613c865780602081608039608051602001808261014039505050602060e0613c8b01608039608051613c8b01602060208260803960805111613c86578060208160803960805160200180826101a03950505060e051600155610100516002556101205160035560206060613c8b016080396080516064808202821582848304141715613c865790509050600a5560206060613c8b016080396080516064808202821582848304141715613c865790509050600b5560206080613c8b01608039608051600755602060a0613c8b016080396080516008553360095542624f1a008181830110613c865780820190509050601455610140806015602082510160c060006003818352015b8260c051602002111561017f5761019e565b60c05160200285015160c051850155815160010180835281141561016d575b5050505050506101a0806018602082510160c060006002818352015b8260c05160200211156101cc576101eb565b60c05160200285015160c05185015581516001018083528114156101ba575b5050505050503060007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006101e05260206101e0a3613c6e56600436101561000d57612b0f565b60046000601c3760005134613a435763313ce567811861003257601260e052602060e0f35b63a9059cbb8118610074576004358060a01c613a4357610160523360e052610160516101005260243561012052610067612b15565b6001610180526020610180f35b6323b872dd8118610148576004358060a01c613a4357610160526024358060a01c613a4357610180526101605160e0526101805161010052604435610120526100bb612b15565b601b6101605160a05260805260406080203360a0526080526040608020546101a0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101a0511461013b576101a051604435808210613a435780820390509050601b6101605160a05260805260406080203360a0526080526040608020555b60016101c05260206101c0f35b63095ea7b381186101c0576004358060a01c613a435760e052602435601b3360a052608052604060802060e05160a05260805260406080205560e051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925602435610100526020610100a36001610100526020610100f35b6314f0597981186101e55760045460e0526005546101005260065461012052606060e0f35b63f446c1d08118610213576101fb610160612b9e565b61016051606480820490509050610180526020610180f35b6376a2f0f0811861023857610229610160612b9e565b61016051610180526020610180f35b63bb7b8b8081186102ff5761024e610280612b9e565b610280516102605260045460e05260055461010052600654610120526102756102e0612cd9565b6102e080516102805280602001516102a05280604001516102c052506102805160e0526102a051610100526102c0516101205261026051610140526102bb610300612da4565b610300516102e0526102e051670de0b6b3a7640000808202821582848304141715613a435790509050601c54808015613a4357820490509050610300526020610300f35b633883e11981186104b8576064358060011c613a43576103a0526103246103e0612b9e565b6103e0516103c0526004546103e05260055461040052600654610420526103e051610260526104005161028052610420516102a0526103c0516102c05261036c610460613011565b610460516104405261046060006003818352015b6020610460510260040135610480526103a0516103c7576103e0610460516003811015613a435760200201805161048051808210613a4357808203905090508152506103f5565b6103e0610460516003811015613a4357602002018051610480518181830110613a4357808201905090508152505b81516001018083528114156103805750506103e051610260526104005161028052610420516102a0526103c0516102c052610431610480613011565b61048051610460526000610480526103a051610466576104405161046051808210613a43578082039050905061048052610481565b6104605161044051808210613a435780820390509050610480525b61048051601c54808202821582848304141715613a43579050905061044051808015613a43578204905090506104a05260206104a0f35b634515cef381186104cd57336103a0526104e8565b6375b96abc8118610b2c576084358060a01c613a43576103a0525b600054613a43576001600055601354613a43576105066103e0612b9e565b6103e0516103c0526004546103e05260055461040052600654610420526103e051610260526104005161028052610420516102a0526103c0516102c05261054e610460613011565b6104605161044052601c54610460526103e05161048052610400516104a052610420516104c0526104e060006003818352015b60206104e051026004013561050052600061050051116105ab5760006104605114613a43576106eb565b60006004610560527f23b872dd00000000000000000000000000000000000000000000000000000000610580526105606004806020846105a00101826020850160045afa505080518201915050336020826105a0010152602081019050306020826105a0010152602081019050610500516020826105a0010152602081019050806105a0526105a0505060206106606105a0516105c0600060016104e0516003811015613a435702600101545af1610668573d600060003e3d6000fd5b61064060203d80821161067b578161067d565b805b905090508152805160200180610520828460045afa9050505060006105205111156106bd57610540516105205181816020036008021c9050905015613a43575b6104806104e0516003811015613a4357602002018051610500518181830110613a4357808201905090508152505b815160010180835281141561058157505061048051610260526104a051610280526104c0516102a0526103c0516102c052610727610500613011565b610500516104e052610440516104e0511115613a4357608036610500376000610460511161077157610480516004556104a0516005556104c0516006556104e051610560526109ac565b6007546003808202821582848304141715613a435790509050600880820490509050610580526105a060006003818352015b6104e0516103e06105a0516003811015613a43576020020151808202821582848304141715613a43579050905061044051808015613a43578204905090506105c05260006105e0526104806105a0516003811015613a4357602002015161060052610600516105c0511161083057610600516105c051808210613a4357808203905090506105e05261084b565b6105c05161060051808210613a4357808203905090506105e0525b610580516105e051808202821582848304141715613a4357905090506402540be400808204905090506105006105a0516003811015613a43576020020152610600516105006105a0516003811015613a43576020020151600854808202821582848304141715613a4357905090506402540be40080820490509050808210613a43578082039050905060016105a0516003811015613a435702600401556104806105a0516003811015613a43576020020180516105006105a0516003811015613a43576020020151808210613a43578082039050905081525081516001018083528114156107a357505061048051610260526104a051610280526104c0516102a0526103c0516102c0526109606105c0613011565b6105c0516105a052610460516105a05161044051808210613a435780820390509050808202821582848304141715613a43579050905061044051808015613a4357820490509050610560525b606435610560511015610a30576014610580527f536c697070616765207363726577656420796f750000000000000000000000006105a0526105805061058051806105a001818260206001820306601f82010390500336823750506308c379a0610540526020610560526105805160206001820306601f820103905060440161055cfd5b6104608051610560518181830110613a435780820190509050815250601a6103a05160a05260805260406080208054610560518181830110613a43578082019050905081555061046051601c556103a05160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61056051610580526020610580a3337f423f6495a08fc652425cf4ed0d1f9e37e571d9b9529b1c1c23cce780b2e7df0d600435610580526024356105a0526044356105c052610500516105e052610520516106005261054051610620526104e051610640526104605161066052610100610580a2610560516105805260206105806000600055f35b635e0d443f8118610d3a576004358060801d81607f1d18613a4357610460526024358060801d81607f1d18613a43576104805260045460e0526005546101005260065461012052610b7e610500612cd9565b61050080516104a05280602001516104c05280604001516104e05250670de0b6b3a7640000610500526c0c9f2c9cd04674edea40000000610520526c0c9f2c9cd04674edea40000000610540526104a0610460516003811015613a43576020020151604435610500610460516003811015613a43576020020151808202821582848304141715613a435790509050670de0b6b3a7640000808204905090508181830110613a4357808201905090506105605261046051610260526104805161028052610560516102a0526104a0516102c0526104c0516102e0526104e05161030052610c6b6105a0613082565b6105a051610580526104a0610480516003811015613a4357602002015161058051808210613a4357808203905090506001808210613a4357808203905090506105a0526007546105a051808202821582848304141715613a4357905090506402540be400808204905090506105c0526105a0516105c051808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a435790509050610500610480516003811015613a43576020020151808015613a43578204905090506105e05260206105e0f35b633df021248118610d4f57336104a052610d6a565b63ddc1f59d81186113a7576084358060a01c613a43576104a0525b6004358060801d81607f1d18613a4357610460526024358060801d81607f1d18613a435761048052600054613a43576001600055601354613a43576004546104c0526005546104e052600654610500526104c05160e0526104e051610100526105005161012052610ddc610580612cd9565b61058080516105205280602001516105405280604001516105605250670de0b6b3a7640000610580526c0c9f2c9cd04674edea400000006105a0526c0c9f2c9cd04674edea400000006105c052610520610460516003811015613a43576020020151604435610580610460516003811015613a43576020020151808202821582848304141715613a435790509050670de0b6b3a7640000808204905090508181830110613a4357808201905090506105e052610460516102605261048051610280526105e0516102a052610520516102c052610540516102e0526105605161030052610ec9610620613082565b6106205161060052610520610480516003811015613a4357602002015161060051808210613a4357808203905090506001808210613a4357808203905090506106205261062051600754808202821582848304141715613a4357905090506402540be40080820490509050610640526106205161064051808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a435790509050610580610480516003811015613a43576020020151808015613a43578204905090506106205260643561062051101561103a57602e610660527f45786368616e676520726573756c74656420696e20666577657220636f696e73610680527f207468616e2065787065637465640000000000000000000000000000000000006106a05261066050610660518061068001818260206001820306601f82010390500336823750506308c379a0610620526020610640526106605160206001820306601f820103905060440161063cfd5b61064051600854808202821582848304141715613a4357905090506402540be400808204905090506106605261066051670de0b6b3a7640000808202821582848304141715613a435790509050610580610480516003811015613a43576020020151808015613a4357820490509050610660526104c0610460516003811015613a435760200201516044358181830110613a4357808201905090506001610460516003811015613a435702600401556104c0610480516003811015613a4357602002015161062051808210613a43578082039050905061066051808210613a4357808203905090506001610480516003811015613a43570260040155600060046106c0527f23b872dd000000000000000000000000000000000000000000000000000000006106e0526106c06004806020846107000101826020850160045afa50508051820191505033602082610700010152602081019050306020826107000101526020810190506044356020826107000101526020810190508061070052610700505060206107c06107005161072060006001610460516003811015613a435702600101545af16111f2573d600060003e3d6000fd5b6107a060203d8082116112055781611207565b805b905090508152805160200180610680828460045afa905050506000610680511115611247576106a0516106805181816020036008021c9050905015613a43575b600060046106c0527fa9059cbb000000000000000000000000000000000000000000000000000000006106e0526106c06004806020846107000101826020850160045afa5050805182019150506104a051602082610700010152602081019050610620516020826107000101526020810190508061070052610700505060206107a06107005161072060006001610480516003811015613a435702600101545af16112f7573d600060003e3d6000fd5b61078060203d80821161130a578161130c565b805b905090508152805160200180610680828460045afa90505050600061068051111561134c576106a0516106805181816020036008021c9050905015613a43575b337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd97140610460516106c0526044356106e0526104805161070052610620516107205260806106c0a2610620516106c05260206106c06000600055f35b63ecb586a581186113bb573360e0526113d5565b632da5dc218118611734576084358060a01c613a435760e0525b600054613a43576001600055601c54610100526060366101203761018060006003818352015b6001610180516003811015613a435702600401546101a0526101a051600435808202821582848304141715613a43579050905061010051808015613a43578204905090506101c05260206101805102602401356101c05110156114f45760306101e0527f5769746864726177616c20726573756c74656420696e20666577657220636f69610200527f6e73207468616e20657870656374656400000000000000000000000000000000610220526101e0506101e0518061020001818260206001820306601f82010390500336823750506308c379a06101a05260206101c0526101e05160206001820306601f82010390506044016101bcfd5b6101a0516101c051808210613a4357808203905090506001610180516003811015613a435702600401556101c051610120610180516003811015613a4357602002015260006004610220527fa9059cbb00000000000000000000000000000000000000000000000000000000610240526102206004806020846102600101826020850160045afa50508051820191505060e0516020826102600101526020810190506101c0516020826102600101526020810190508061026052610260505060206103006102605161028060006001610180516003811015613a435702600101545af16115e6573d600060003e3d6000fd5b6102e060203d8082116115f957816115fb565b805b9050905081528051602001806101e0828460045afa9050505060006101e051111561163b57610200516101e05181816020036008021c9050905015613a43575b81516001018083528114156113fb5750506101008051600435808210613a435780820390509050815250601a3360a05260805260406080208054600435808210613a43578082039050905081555061010051601c556000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600435610180526020610180a3337fa49d4cf02656aebf8c771f5a8585638a2a15ee6c97cf7205d4208ed7c1df252d6101205161018052610140516101a052610160516101c0526060366101e037610100516102405260e0610180a26101205161018052610140516101a052610160516101c05260606101806000600055f35b639fdaea0c811861174957336103a052611764565b639504fae88118611d60576084358060a01c613a43576103a0525b600054613a43576001600055601354613a43576117826103e0612b9e565b6103e0516103c0526004546103e05260055461040052600654610420526103e051610260526104005161028052610420516102a0526103c0516102c0526117ca610460613011565b61046051610440526103e051610460526104005161048052610420516104a0526104c060006003818352015b60206104c05102600401356104e05260006104e05114611940576104606104c0516003811015613a43576020020180516104e051808210613a43578082039050905081525060006004610540527fa9059cbb00000000000000000000000000000000000000000000000000000000610560526105406004806020846105800101826020850160045afa5050805182019150506103a0516020826105800101526020810190506104e051602082610580010152602081019050806105805261058050506020610620610580516105a0600060016104c0516003811015613a435702600101545af16118eb573d600060003e3d6000fd5b61060060203d8082116118fe5781611900565b805b905090508152805160200180610500828460045afa90505050600061050051111561194057610520516105005181816020036008021c9050905015613a43575b81516001018083528114156117f6575050610460516102605261048051610280526104a0516102a0526103c0516102c05261197c6104e0613011565b6104e0516104c0526060366104e0376007546003808202821582848304141715613a4357905090506008808204905090506105405261056060006003818352015b6104c0516103e0610560516003811015613a43576020020151808202821582848304141715613a43579050905061044051808015613a43578204905090506105805260006105a052610460610560516003811015613a435760200201516105c0526105c0516105805111611a4a576105c05161058051808210613a4357808203905090506105a052611a65565b610580516105c051808210613a4357808203905090506105a0525b610540516105a051808202821582848304141715613a4357905090506402540be400808204905090506104e0610560516003811015613a435760200201526105c0516104e0610560516003811015613a43576020020151600854808202821582848304141715613a4357905090506402540be40080820490509050808210613a4357808203905090506001610560516003811015613a43570260040155610460610560516003811015613a43576020020180516104e0610560516003811015613a43576020020151808210613a43578082039050905081525081516001018083528114156119bd575050610460516102605261048051610280526104a0516102a0526103c0516102c052611b7a610580613011565b6105805161056052601c54610580526104405161056051808210613a43578082039050905061058051808202821582848304141715613a43579050905061044051808015613a435782049050905060018181830110613a4357808201905090506105a05260016105a0511115613a43576064356105a0511115611c6e5760146105c0527f536c697070616765207363726577656420796f750000000000000000000000006105e0526105c0506105c051806105e001818260206001820306601f82010390500336823750506308c379a06105805260206105a0526105c05160206001820306601f820103905060440161059cfd5b61058080516105a051808210613a43578082039050905081525061058051601c55601a3360a052608052604060802080546105a051808210613a4357808203905090508155506000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6105a0516105c05260206105c0a3337f173599dbf9c6ca6f7c3b590df07ae98a45d74ff54065505141e7de6c46a624c26004356105c0526024356105e052604435610600526104e05161062052610500516106405261052051610660526104c05161068052610580516106a0526101006105c0a26105a0516105c05260206105c06000600055f35b63cc2b27d78118611da8576024358060801d81607f1d18613a4357610520526004356102a052610520516102c052611d9961054061366a565b61054051610580526020610580f35b631a4d01d28118611dbd573361054052611dd8565b63081579a581186120de576064358060a01c613a4357610540525b6024358060801d81607f1d18613a435761052052600054613a43576001600055601354613a43576004356102a052610520516102c052611e196105a061366a565b6105a080516105605280602001516105805250604435610560511015611eb05760186105a0527f4e6f7420656e6f75676820636f696e732072656d6f76656400000000000000006105c0526105a0506105a051806105c001818260206001820306601f82010390500336823750506308c379a0610560526020610580526105a05160206001820306601f820103905060440161057cfd5b6001610520516003811015613a43570260040180546105605161058051600854808202821582848304141715613a4357905090506402540be400808204905090508181830110613a435780820190509050808210613a435780820390509050815550601c54600435808210613a4357808203905090506105a0526105a051601c55601a3360a05260805260406080208054600435808210613a4357808203905090508155506000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6004356105c05260206105c0a360006004610600527fa9059cbb00000000000000000000000000000000000000000000000000000000610620526106006004806020846106400101826020850160045afa50508051820191505061054051602082610640010152602081019050610560516020826106400101526020810190508061064052610640505060206106e06106405161066060006001610520516003811015613a435702600101545af1612036573d600060003e3d6000fd5b6106c060203d808211612049578161204b565b805b9050905081528051602001806105c0828460045afa9050505060006105c051111561208b576105e0516105c05181816020036008021c9050905015613a43575b337f5ad056f2e28a8cec232015406b843668c1e36cda598127ec3b8c59b8c72773a06004356106005261056051610620526105a051610640526060610600a2610560516106005260206106006000600055f35b633c157e648118612231576009543318613a4357600c54620151808181830110613a4357808201905090504210613a435742620151808181830110613a43578082019050905060243510613a4357612137610180612b9e565b61018051610160526004356064808202821582848304141715613a4357905090506101805260006004351161216d576000612176565b620f4240600435105b15613a43576101605161018051106121b05761016051600a808202821582848304141715613a4357905090506101805111613a43576121d4565b6101605161018051600a808202821582848304141715613a43579050905010613a43575b61016051600a5561018051600b5542600c55602435600d557fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c254610160516101a052610180516101c052426101e0526024356102005260806101a0a1005b63551a658881186122a4576009543318613a4357612250610180612b9e565b610180516101605261016051600a5561016051600b5542600c5542600d557f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc2019386101605161018052426101a0526040610180a1005b635b5a1467811861233f576009543318613a4357600e54613a435764012a05f20060043511613a43576402540be40060243511613a4357426203f4808181830110613a43578082019050905060e05260e051600e5560043560105560243560115560e0517f351fc5da2fbf480f2225debf3664a4bc90fa9923743aad58b4603f648e931fe060043561010052602435610120526040610100a2005b634f12fe9781186123bd576009543318613a4357600e544210613a43576000600e5414613a43576000600e5560105460e0526011546101005260e051600755610100516008557fbe12859b636aed607d5230b2cc2711f68d70e51060e6cca1f575ef5d2fcc95d160e0516101205261010051610140526040610120a1005b63226840fb81186123d8576009543318613a43576000600e55005b636b441a408118612457576004358060a01c613a435760e0526009543318613a4357600f54613a4357426203f4808181830110613a4357808201905090506101005261010051600f5560e05160125560e051610100517f181aa3aa17d4cbf99265dd4443eba009433d3cde79d60164fde1d1a192beb9356000610120a3005b636a1c05ae81186124bb576009543318613a4357600f544210613a43576000600f5414613a43576000600f5560125460e05260e05160095560e0517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c6000610100a2005b6386fbf19381186124d6576009543318613a43576000600f55005b63e2e7d2648118612552576370a0823160e0523061010052602060e0602460fc60016004356003811015613a435702600101545afa61251a573d600060003e3d6000fd5b601f3d1115613a435760e05160016004356003811015613a43570260040154808210613a435780820390509050610120526020610120f35b6330c5408581186126f8576009543318613a435760e060006003818352015b600160e0516003811015613a43570260010154610100526370a082316101405230610160526020610140602461015c610100515afa6125b5573d600060003e3d6000fd5b601f3d1115613a435761014051600160e0516003811015613a43570260040154808210613a4357808203905090506101205260006101205111156126e55760006004610180527fa9059cbb000000000000000000000000000000000000000000000000000000006101a0526101806004806020846101c00101826020850160045afa505080518201915050336020826101c0010152602081019050610120516020826101c0010152602081019050806101c0526101c0505060206102606101c0516101e06000610100515af1612690573d600060003e3d6000fd5b61024060203d8082116126a357816126a5565b805b905090508152805160200180610140828460045afa9050505060006101405111156126e557610160516101405181816020036008021c9050905015613a43575b8151600101808352811415612571575050005b63524c39018118612786576009543318613a435760e060006003818352015b6370a082316101005230610120526020610100602461011c600160e0516003811015613a435702600101545afa612753573d600060003e3d6000fd5b601f3d1115613a435761010051600160e0516003811015613a435702600401558151600101808352811415612717575050005b63e369885381186127ab576009543318613a4357426014541115613a43576001601355005b633046f97281186127c6576009543318613a43576000601355005b63c661065781186127ed5760016004356003811015613a4357026001015460e052602060e0f35b634903b0d181186128145760016004356003811015613a4357026004015460e052602060e0f35b63ddca3f43811861282b5760075460e052602060e0f35b63fee3f7f981186128425760085460e052602060e0f35b638da5cb5b81186128595760095460e052602060e0f35b635409491a811861287057600a5460e052602060e0f35b63b4b577ad811861288757600b5460e052602060e0f35b632081066c811861289e57600c5460e052602060e0f35b631405228881186128b557600d5460e052602060e0f35b63405e28f881186128cc57600e5460e052602060e0f35b63e0a0b58681186128e357600f5460e052602060e0f35b6358680d0b81186128fa5760105460e052602060e0f35b63e382446281186129115760115460e052602060e0f35b631ec0cdc181186129285760125460e052602060e0f35b6306fdde0381186129cb5760e08060208082528083018060158082602082540160c060006003818352015b8260c051602002111561296557612984565b60c05185015460c0516020028501528151600101808352811415612953575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b6395d89b418118612a6e5760e08060208082528083018060188082602082540160c060006002818352015b8260c0516020021115612a0857612a27565b60c05185015460c05160200285015281516001018083528114156129f6575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b6370a082318118612aa3576004358060a01c613a435760e052601a60e05160a052608052604060802054610100526020610100f35b63dd62ed3e8118612af6576004358060a01c613a435760e0526024358060a01c613a435761010052601b60e05160a05260805260406080206101005160a052608052604060802054610120526020610120f35b6318160ddd8118612b0d57601c5460e052602060e0f35b505b60006000fd5b601a60e05160a0526080526040608020805461012051808210613a435780820390509050815550601a6101005160a05260805260406080208054610120518181830110613a4357808201905090508155506101005160e0517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61012051610140526020610140a3565b600d5460e052600b546101005260e0514210612bc45761010051815250612cd756612cd7565b600a5461012052600c5461014052610120516101005111612c5c57610120516101205161010051808210613a4357808203905090504261014051808210613a435780820390509050808202821582848304141715613a43579050905060e05161014051808210613a435780820390509050808015613a4357820490509050808210613a435780820390509050815250612cd756612cd7565b610120516101005161012051808210613a4357808203905090504261014051808210613a435780820390509050808202821582848304141715613a43579050905060e05161014051808210613a435780820390509050808015613a43578204905090508181830110613a435780820190509050815250612cd7565b565b670de0b6b3a7640000610140526c0c9f2c9cd04674edea40000000610160526c0c9f2c9cd04674edea40000000610180526101a060006003818352015b6101406101a0516003811015613a4357602002015160e06101a0516003811015613a43576020020151808202821582848304141715613a435790509050670de0b6b3a7640000808204905090506101406101a0516003811015613a435760200201528151600101808352811415612d1657505061014051815261016051816020015261018051816040015250565b604036610160376101c060006003818352015b60206101c0510260e001516101a05261016080516101a0518181830110613a4357808201905090508152508151600101808352811415612db757505061016051612e0557600081525061300f565b610160516101a052610140516003808202821582848304141715613a4357905090506101c0526101e0600060ff818352015b6101a0516102005261024060006003818352015b6020610240510260e0015161022052610200516101a051808202821582848304141715613a435790509050610220516003808202821582848304141715613a435790509050808015613a4357820490509050610200528151600101808352811415612e4b5750506101a051610180526101c05161016051808202821582848304141715613a435790509050606480820490509050610200516003808202821582848304141715613a4357905090508181830110613a4357808201905090506101a051808202821582848304141715613a4357905090506101c0516064808210613a4357808203905090506101a051808202821582848304141715613a435790509050606480820490509050600461020051808202821582848304141715613a4357905090508181830110613a435780820190509050808015613a43578204905090506101a052610180516101a05111612fcd576001610180516101a051808210613a43578082039050905011612ff85750506101a05181525061300f56612ff8565b60016101a05161018051808210613a43578082039050905011612ff85750506101a05181525061300f565b8151600101808352811415612e3757505060006000fd5b565b6102605160e05261028051610100526102a05161012052613033610340612cd9565b61034080516102e052806020015161030052806040015161032052506102e05160e052610300516101005261032051610120526102c05161014052613079610340612da4565b61034051815250565b610280516102605114613a435760006102805112613a43576003610280511215613a435760006102605112613a43576003610260511215613a43576130c8610340612b9e565b61034051610320526102c05160e0526102e05161010052610300516101205261032051610140526130fa610360612da4565b610360516103405260603661036037610340516103c052610320516003808202821582848304141715613a4357905090506103e05261040060006003818352015b610260516104005118613155576102a05161038052613186565b6102805161040051141561316c576131ea56613186565b6102c0610400516003811015613a43576020020151610380525b6103608051610380518181830110613a4357808201905090508152506103c05161034051808202821582848304141715613a435790509050610380516003808202821582848304141715613a435790509050808015613a43578204905090506103c0525b815160010180835281141561313b5750506103c05161034051808202821582848304141715613a4357905090506064808202821582848304141715613a4357905090506103e0516003808202821582848304141715613a435790509050808015613a43578204905090506103c05261036051610340516064808202821582848304141715613a4357905090506103e051808015613a43578204905090508181830110613a435780820190509050610400526103405161042052610440600060ff818352015b610420516103a0526104205161042051808202821582848304141715613a4357905090506103c0518181830110613a435780820190509050600261042051808202821582848304141715613a435790509050610400518181830110613a43578082019050905061034051808210613a435780820390509050808015613a4357820490509050610420526103a05161042051116133745760016103a05161042051808210613a4357808203905090501161339f575050610420518152506133b65661339f565b6001610420516103a051808210613a4357808203905090501161339f575050610420518152506133b6565b81516001018083528114156132af57505060006000fd5b565b60006101005112613a43576003610100511215613a43576060366101a037610180516102005260e0516003808202821582848304141715613a4357905090506102205261024060006003818352015b6101005161024051141561341e5761349c56613438565b610120610240516003811015613a435760200201516101c0525b6101a080516101c0518181830110613a4357808201905090508152506102005161018051808202821582848304141715613a4357905090506101c0516003808202821582848304141715613a435790509050808015613a4357820490509050610200525b81516001018083528114156134075750506102005161018051808202821582848304141715613a4357905090506064808202821582848304141715613a435790509050610220516003808202821582848304141715613a435790509050808015613a4357820490509050610200526101a051610180516064808202821582848304141715613a43579050905061022051808015613a43578204905090508181830110613a435780820190509050610240526101805161026052610280600060ff818352015b610260516101e0526102605161026051808202821582848304141715613a435790509050610200518181830110613a435780820190509050600261026051808202821582848304141715613a435790509050610240518181830110613a43578082019050905061018051808210613a435780820390509050808015613a4357820490509050610260526101e05161026051116136265760016101e05161026051808210613a435780820390509050116136515750506102605181525061366856613651565b6001610260516101e051808210613a4357808203905090501161365157505061026051815250613668565b815160010180835281141561356157505060006000fd5b565b613675610300612b9e565b610300516102e052670de0b6b3a7640000610300526c0c9f2c9cd04674edea40000000610320526c0c9f2c9cd04674edea400000006103405260045460e05260055461010052600654610120526136cd6103c0612cd9565b6103c080516103605280602001516103805280604001516103a052506103605160e05261038051610100526103a051610120526102e051610140526137136103e0612da4565b6103e0516103c052601c546103e0526103c0516102a0516103c051808202821582848304141715613a4357905090506103e051808015613a4357820490509050808210613a435780820390509050610400526102e05160e0526102c05161010052610360516101205261038051610140526103a05161016052610400516101805261379f6104406133b8565b61044051610420526007546003808202821582848304141715613a43579050905060088082049050905061044052606036610460376104c060006003818352015b60006104e0526103606104c0516003811015613a43576020020151610500526102c0516104c05118613854576105005161040051808202821582848304141715613a4357905090506103c051808015613a435782049050905061042051808210613a4357808203905090506104e052613898565b610500516105005161040051808202821582848304141715613a4357905090506103c051808015613a4357820490509050808210613a4357808203905090506104e0525b61050051610440516104e051808202821582848304141715613a4357905090506402540be40080820490509050808210613a4357808203905090506104606104c0516003811015613a4357602002015281516001018083528114156137e05750506104606102c0516003811015613a435760200201516102e05160e0526102c05161010052610460516101205261048051610140526104a0516101605261040051610180526139486104e06133b8565b6104e051808210613a4357808203905090506104c0526103606102c0516003811015613a4357602002015161042051808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a4357905090506103006102c0516003811015613a43576020020151808015613a43578204905090506104e0526104c0516001808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a4357905090506103006102c0516003811015613a43576020020151808015613a43578204905090506104c0526104c05181526104e0516104c051808210613a435780820390509050816020015250565b600080fd5b610226613c6e03610226600039610226613c6e036000f35b600080fd000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000003d0900000000000000000000000000000000000000000000000000000000012a05f20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000001643757276652e6669204441492f555344432f555344540000000000000000000000000000000000000000000000000000000000000000000000000000000000043343525600000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x600436101561000d57612b0f565b60046000601c3760005134613a435763313ce567811861003257601260e052602060e0f35b63a9059cbb8118610074576004358060a01c613a4357610160523360e052610160516101005260243561012052610067612b15565b6001610180526020610180f35b6323b872dd8118610148576004358060a01c613a4357610160526024358060a01c613a4357610180526101605160e0526101805161010052604435610120526100bb612b15565b601b6101605160a05260805260406080203360a0526080526040608020546101a0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101a0511461013b576101a051604435808210613a435780820390509050601b6101605160a05260805260406080203360a0526080526040608020555b60016101c05260206101c0f35b63095ea7b381186101c0576004358060a01c613a435760e052602435601b3360a052608052604060802060e05160a05260805260406080205560e051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925602435610100526020610100a36001610100526020610100f35b6314f0597981186101e55760045460e0526005546101005260065461012052606060e0f35b63f446c1d08118610213576101fb610160612b9e565b61016051606480820490509050610180526020610180f35b6376a2f0f0811861023857610229610160612b9e565b61016051610180526020610180f35b63bb7b8b8081186102ff5761024e610280612b9e565b610280516102605260045460e05260055461010052600654610120526102756102e0612cd9565b6102e080516102805280602001516102a05280604001516102c052506102805160e0526102a051610100526102c0516101205261026051610140526102bb610300612da4565b610300516102e0526102e051670de0b6b3a7640000808202821582848304141715613a435790509050601c54808015613a4357820490509050610300526020610300f35b633883e11981186104b8576064358060011c613a43576103a0526103246103e0612b9e565b6103e0516103c0526004546103e05260055461040052600654610420526103e051610260526104005161028052610420516102a0526103c0516102c05261036c610460613011565b610460516104405261046060006003818352015b6020610460510260040135610480526103a0516103c7576103e0610460516003811015613a435760200201805161048051808210613a4357808203905090508152506103f5565b6103e0610460516003811015613a4357602002018051610480518181830110613a4357808201905090508152505b81516001018083528114156103805750506103e051610260526104005161028052610420516102a0526103c0516102c052610431610480613011565b61048051610460526000610480526103a051610466576104405161046051808210613a43578082039050905061048052610481565b6104605161044051808210613a435780820390509050610480525b61048051601c54808202821582848304141715613a43579050905061044051808015613a43578204905090506104a05260206104a0f35b634515cef381186104cd57336103a0526104e8565b6375b96abc8118610b2c576084358060a01c613a43576103a0525b600054613a43576001600055601354613a43576105066103e0612b9e565b6103e0516103c0526004546103e05260055461040052600654610420526103e051610260526104005161028052610420516102a0526103c0516102c05261054e610460613011565b6104605161044052601c54610460526103e05161048052610400516104a052610420516104c0526104e060006003818352015b60206104e051026004013561050052600061050051116105ab5760006104605114613a43576106eb565b60006004610560527f23b872dd00000000000000000000000000000000000000000000000000000000610580526105606004806020846105a00101826020850160045afa505080518201915050336020826105a0010152602081019050306020826105a0010152602081019050610500516020826105a0010152602081019050806105a0526105a0505060206106606105a0516105c0600060016104e0516003811015613a435702600101545af1610668573d600060003e3d6000fd5b61064060203d80821161067b578161067d565b805b905090508152805160200180610520828460045afa9050505060006105205111156106bd57610540516105205181816020036008021c9050905015613a43575b6104806104e0516003811015613a4357602002018051610500518181830110613a4357808201905090508152505b815160010180835281141561058157505061048051610260526104a051610280526104c0516102a0526103c0516102c052610727610500613011565b610500516104e052610440516104e0511115613a4357608036610500376000610460511161077157610480516004556104a0516005556104c0516006556104e051610560526109ac565b6007546003808202821582848304141715613a435790509050600880820490509050610580526105a060006003818352015b6104e0516103e06105a0516003811015613a43576020020151808202821582848304141715613a43579050905061044051808015613a43578204905090506105c05260006105e0526104806105a0516003811015613a4357602002015161060052610600516105c0511161083057610600516105c051808210613a4357808203905090506105e05261084b565b6105c05161060051808210613a4357808203905090506105e0525b610580516105e051808202821582848304141715613a4357905090506402540be400808204905090506105006105a0516003811015613a43576020020152610600516105006105a0516003811015613a43576020020151600854808202821582848304141715613a4357905090506402540be40080820490509050808210613a43578082039050905060016105a0516003811015613a435702600401556104806105a0516003811015613a43576020020180516105006105a0516003811015613a43576020020151808210613a43578082039050905081525081516001018083528114156107a357505061048051610260526104a051610280526104c0516102a0526103c0516102c0526109606105c0613011565b6105c0516105a052610460516105a05161044051808210613a435780820390509050808202821582848304141715613a43579050905061044051808015613a4357820490509050610560525b606435610560511015610a30576014610580527f536c697070616765207363726577656420796f750000000000000000000000006105a0526105805061058051806105a001818260206001820306601f82010390500336823750506308c379a0610540526020610560526105805160206001820306601f820103905060440161055cfd5b6104608051610560518181830110613a435780820190509050815250601a6103a05160a05260805260406080208054610560518181830110613a43578082019050905081555061046051601c556103a05160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61056051610580526020610580a3337f423f6495a08fc652425cf4ed0d1f9e37e571d9b9529b1c1c23cce780b2e7df0d600435610580526024356105a0526044356105c052610500516105e052610520516106005261054051610620526104e051610640526104605161066052610100610580a2610560516105805260206105806000600055f35b635e0d443f8118610d3a576004358060801d81607f1d18613a4357610460526024358060801d81607f1d18613a43576104805260045460e0526005546101005260065461012052610b7e610500612cd9565b61050080516104a05280602001516104c05280604001516104e05250670de0b6b3a7640000610500526c0c9f2c9cd04674edea40000000610520526c0c9f2c9cd04674edea40000000610540526104a0610460516003811015613a43576020020151604435610500610460516003811015613a43576020020151808202821582848304141715613a435790509050670de0b6b3a7640000808204905090508181830110613a4357808201905090506105605261046051610260526104805161028052610560516102a0526104a0516102c0526104c0516102e0526104e05161030052610c6b6105a0613082565b6105a051610580526104a0610480516003811015613a4357602002015161058051808210613a4357808203905090506001808210613a4357808203905090506105a0526007546105a051808202821582848304141715613a4357905090506402540be400808204905090506105c0526105a0516105c051808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a435790509050610500610480516003811015613a43576020020151808015613a43578204905090506105e05260206105e0f35b633df021248118610d4f57336104a052610d6a565b63ddc1f59d81186113a7576084358060a01c613a43576104a0525b6004358060801d81607f1d18613a4357610460526024358060801d81607f1d18613a435761048052600054613a43576001600055601354613a43576004546104c0526005546104e052600654610500526104c05160e0526104e051610100526105005161012052610ddc610580612cd9565b61058080516105205280602001516105405280604001516105605250670de0b6b3a7640000610580526c0c9f2c9cd04674edea400000006105a0526c0c9f2c9cd04674edea400000006105c052610520610460516003811015613a43576020020151604435610580610460516003811015613a43576020020151808202821582848304141715613a435790509050670de0b6b3a7640000808204905090508181830110613a4357808201905090506105e052610460516102605261048051610280526105e0516102a052610520516102c052610540516102e0526105605161030052610ec9610620613082565b6106205161060052610520610480516003811015613a4357602002015161060051808210613a4357808203905090506001808210613a4357808203905090506106205261062051600754808202821582848304141715613a4357905090506402540be40080820490509050610640526106205161064051808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a435790509050610580610480516003811015613a43576020020151808015613a43578204905090506106205260643561062051101561103a57602e610660527f45786368616e676520726573756c74656420696e20666577657220636f696e73610680527f207468616e2065787065637465640000000000000000000000000000000000006106a05261066050610660518061068001818260206001820306601f82010390500336823750506308c379a0610620526020610640526106605160206001820306601f820103905060440161063cfd5b61064051600854808202821582848304141715613a4357905090506402540be400808204905090506106605261066051670de0b6b3a7640000808202821582848304141715613a435790509050610580610480516003811015613a43576020020151808015613a4357820490509050610660526104c0610460516003811015613a435760200201516044358181830110613a4357808201905090506001610460516003811015613a435702600401556104c0610480516003811015613a4357602002015161062051808210613a43578082039050905061066051808210613a4357808203905090506001610480516003811015613a43570260040155600060046106c0527f23b872dd000000000000000000000000000000000000000000000000000000006106e0526106c06004806020846107000101826020850160045afa50508051820191505033602082610700010152602081019050306020826107000101526020810190506044356020826107000101526020810190508061070052610700505060206107c06107005161072060006001610460516003811015613a435702600101545af16111f2573d600060003e3d6000fd5b6107a060203d8082116112055781611207565b805b905090508152805160200180610680828460045afa905050506000610680511115611247576106a0516106805181816020036008021c9050905015613a43575b600060046106c0527fa9059cbb000000000000000000000000000000000000000000000000000000006106e0526106c06004806020846107000101826020850160045afa5050805182019150506104a051602082610700010152602081019050610620516020826107000101526020810190508061070052610700505060206107a06107005161072060006001610480516003811015613a435702600101545af16112f7573d600060003e3d6000fd5b61078060203d80821161130a578161130c565b805b905090508152805160200180610680828460045afa90505050600061068051111561134c576106a0516106805181816020036008021c9050905015613a43575b337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd97140610460516106c0526044356106e0526104805161070052610620516107205260806106c0a2610620516106c05260206106c06000600055f35b63ecb586a581186113bb573360e0526113d5565b632da5dc218118611734576084358060a01c613a435760e0525b600054613a43576001600055601c54610100526060366101203761018060006003818352015b6001610180516003811015613a435702600401546101a0526101a051600435808202821582848304141715613a43579050905061010051808015613a43578204905090506101c05260206101805102602401356101c05110156114f45760306101e0527f5769746864726177616c20726573756c74656420696e20666577657220636f69610200527f6e73207468616e20657870656374656400000000000000000000000000000000610220526101e0506101e0518061020001818260206001820306601f82010390500336823750506308c379a06101a05260206101c0526101e05160206001820306601f82010390506044016101bcfd5b6101a0516101c051808210613a4357808203905090506001610180516003811015613a435702600401556101c051610120610180516003811015613a4357602002015260006004610220527fa9059cbb00000000000000000000000000000000000000000000000000000000610240526102206004806020846102600101826020850160045afa50508051820191505060e0516020826102600101526020810190506101c0516020826102600101526020810190508061026052610260505060206103006102605161028060006001610180516003811015613a435702600101545af16115e6573d600060003e3d6000fd5b6102e060203d8082116115f957816115fb565b805b9050905081528051602001806101e0828460045afa9050505060006101e051111561163b57610200516101e05181816020036008021c9050905015613a43575b81516001018083528114156113fb5750506101008051600435808210613a435780820390509050815250601a3360a05260805260406080208054600435808210613a43578082039050905081555061010051601c556000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600435610180526020610180a3337fa49d4cf02656aebf8c771f5a8585638a2a15ee6c97cf7205d4208ed7c1df252d6101205161018052610140516101a052610160516101c0526060366101e037610100516102405260e0610180a26101205161018052610140516101a052610160516101c05260606101806000600055f35b639fdaea0c811861174957336103a052611764565b639504fae88118611d60576084358060a01c613a43576103a0525b600054613a43576001600055601354613a43576117826103e0612b9e565b6103e0516103c0526004546103e05260055461040052600654610420526103e051610260526104005161028052610420516102a0526103c0516102c0526117ca610460613011565b61046051610440526103e051610460526104005161048052610420516104a0526104c060006003818352015b60206104c05102600401356104e05260006104e05114611940576104606104c0516003811015613a43576020020180516104e051808210613a43578082039050905081525060006004610540527fa9059cbb00000000000000000000000000000000000000000000000000000000610560526105406004806020846105800101826020850160045afa5050805182019150506103a0516020826105800101526020810190506104e051602082610580010152602081019050806105805261058050506020610620610580516105a0600060016104c0516003811015613a435702600101545af16118eb573d600060003e3d6000fd5b61060060203d8082116118fe5781611900565b805b905090508152805160200180610500828460045afa90505050600061050051111561194057610520516105005181816020036008021c9050905015613a43575b81516001018083528114156117f6575050610460516102605261048051610280526104a0516102a0526103c0516102c05261197c6104e0613011565b6104e0516104c0526060366104e0376007546003808202821582848304141715613a4357905090506008808204905090506105405261056060006003818352015b6104c0516103e0610560516003811015613a43576020020151808202821582848304141715613a43579050905061044051808015613a43578204905090506105805260006105a052610460610560516003811015613a435760200201516105c0526105c0516105805111611a4a576105c05161058051808210613a4357808203905090506105a052611a65565b610580516105c051808210613a4357808203905090506105a0525b610540516105a051808202821582848304141715613a4357905090506402540be400808204905090506104e0610560516003811015613a435760200201526105c0516104e0610560516003811015613a43576020020151600854808202821582848304141715613a4357905090506402540be40080820490509050808210613a4357808203905090506001610560516003811015613a43570260040155610460610560516003811015613a43576020020180516104e0610560516003811015613a43576020020151808210613a43578082039050905081525081516001018083528114156119bd575050610460516102605261048051610280526104a0516102a0526103c0516102c052611b7a610580613011565b6105805161056052601c54610580526104405161056051808210613a43578082039050905061058051808202821582848304141715613a43579050905061044051808015613a435782049050905060018181830110613a4357808201905090506105a05260016105a0511115613a43576064356105a0511115611c6e5760146105c0527f536c697070616765207363726577656420796f750000000000000000000000006105e0526105c0506105c051806105e001818260206001820306601f82010390500336823750506308c379a06105805260206105a0526105c05160206001820306601f820103905060440161059cfd5b61058080516105a051808210613a43578082039050905081525061058051601c55601a3360a052608052604060802080546105a051808210613a4357808203905090508155506000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6105a0516105c05260206105c0a3337f173599dbf9c6ca6f7c3b590df07ae98a45d74ff54065505141e7de6c46a624c26004356105c0526024356105e052604435610600526104e05161062052610500516106405261052051610660526104c05161068052610580516106a0526101006105c0a26105a0516105c05260206105c06000600055f35b63cc2b27d78118611da8576024358060801d81607f1d18613a4357610520526004356102a052610520516102c052611d9961054061366a565b61054051610580526020610580f35b631a4d01d28118611dbd573361054052611dd8565b63081579a581186120de576064358060a01c613a4357610540525b6024358060801d81607f1d18613a435761052052600054613a43576001600055601354613a43576004356102a052610520516102c052611e196105a061366a565b6105a080516105605280602001516105805250604435610560511015611eb05760186105a0527f4e6f7420656e6f75676820636f696e732072656d6f76656400000000000000006105c0526105a0506105a051806105c001818260206001820306601f82010390500336823750506308c379a0610560526020610580526105a05160206001820306601f820103905060440161057cfd5b6001610520516003811015613a43570260040180546105605161058051600854808202821582848304141715613a4357905090506402540be400808204905090508181830110613a435780820190509050808210613a435780820390509050815550601c54600435808210613a4357808203905090506105a0526105a051601c55601a3360a05260805260406080208054600435808210613a4357808203905090508155506000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6004356105c05260206105c0a360006004610600527fa9059cbb00000000000000000000000000000000000000000000000000000000610620526106006004806020846106400101826020850160045afa50508051820191505061054051602082610640010152602081019050610560516020826106400101526020810190508061064052610640505060206106e06106405161066060006001610520516003811015613a435702600101545af1612036573d600060003e3d6000fd5b6106c060203d808211612049578161204b565b805b9050905081528051602001806105c0828460045afa9050505060006105c051111561208b576105e0516105c05181816020036008021c9050905015613a43575b337f5ad056f2e28a8cec232015406b843668c1e36cda598127ec3b8c59b8c72773a06004356106005261056051610620526105a051610640526060610600a2610560516106005260206106006000600055f35b633c157e648118612231576009543318613a4357600c54620151808181830110613a4357808201905090504210613a435742620151808181830110613a43578082019050905060243510613a4357612137610180612b9e565b61018051610160526004356064808202821582848304141715613a4357905090506101805260006004351161216d576000612176565b620f4240600435105b15613a43576101605161018051106121b05761016051600a808202821582848304141715613a4357905090506101805111613a43576121d4565b6101605161018051600a808202821582848304141715613a43579050905010613a43575b61016051600a5561018051600b5542600c55602435600d557fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c254610160516101a052610180516101c052426101e0526024356102005260806101a0a1005b63551a658881186122a4576009543318613a4357612250610180612b9e565b610180516101605261016051600a5561016051600b5542600c5542600d557f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc2019386101605161018052426101a0526040610180a1005b635b5a1467811861233f576009543318613a4357600e54613a435764012a05f20060043511613a43576402540be40060243511613a4357426203f4808181830110613a43578082019050905060e05260e051600e5560043560105560243560115560e0517f351fc5da2fbf480f2225debf3664a4bc90fa9923743aad58b4603f648e931fe060043561010052602435610120526040610100a2005b634f12fe9781186123bd576009543318613a4357600e544210613a43576000600e5414613a43576000600e5560105460e0526011546101005260e051600755610100516008557fbe12859b636aed607d5230b2cc2711f68d70e51060e6cca1f575ef5d2fcc95d160e0516101205261010051610140526040610120a1005b63226840fb81186123d8576009543318613a43576000600e55005b636b441a408118612457576004358060a01c613a435760e0526009543318613a4357600f54613a4357426203f4808181830110613a4357808201905090506101005261010051600f5560e05160125560e051610100517f181aa3aa17d4cbf99265dd4443eba009433d3cde79d60164fde1d1a192beb9356000610120a3005b636a1c05ae81186124bb576009543318613a4357600f544210613a43576000600f5414613a43576000600f5560125460e05260e05160095560e0517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c6000610100a2005b6386fbf19381186124d6576009543318613a43576000600f55005b63e2e7d2648118612552576370a0823160e0523061010052602060e0602460fc60016004356003811015613a435702600101545afa61251a573d600060003e3d6000fd5b601f3d1115613a435760e05160016004356003811015613a43570260040154808210613a435780820390509050610120526020610120f35b6330c5408581186126f8576009543318613a435760e060006003818352015b600160e0516003811015613a43570260010154610100526370a082316101405230610160526020610140602461015c610100515afa6125b5573d600060003e3d6000fd5b601f3d1115613a435761014051600160e0516003811015613a43570260040154808210613a4357808203905090506101205260006101205111156126e55760006004610180527fa9059cbb000000000000000000000000000000000000000000000000000000006101a0526101806004806020846101c00101826020850160045afa505080518201915050336020826101c0010152602081019050610120516020826101c0010152602081019050806101c0526101c0505060206102606101c0516101e06000610100515af1612690573d600060003e3d6000fd5b61024060203d8082116126a357816126a5565b805b905090508152805160200180610140828460045afa9050505060006101405111156126e557610160516101405181816020036008021c9050905015613a43575b8151600101808352811415612571575050005b63524c39018118612786576009543318613a435760e060006003818352015b6370a082316101005230610120526020610100602461011c600160e0516003811015613a435702600101545afa612753573d600060003e3d6000fd5b601f3d1115613a435761010051600160e0516003811015613a435702600401558151600101808352811415612717575050005b63e369885381186127ab576009543318613a4357426014541115613a43576001601355005b633046f97281186127c6576009543318613a43576000601355005b63c661065781186127ed5760016004356003811015613a4357026001015460e052602060e0f35b634903b0d181186128145760016004356003811015613a4357026004015460e052602060e0f35b63ddca3f43811861282b5760075460e052602060e0f35b63fee3f7f981186128425760085460e052602060e0f35b638da5cb5b81186128595760095460e052602060e0f35b635409491a811861287057600a5460e052602060e0f35b63b4b577ad811861288757600b5460e052602060e0f35b632081066c811861289e57600c5460e052602060e0f35b631405228881186128b557600d5460e052602060e0f35b63405e28f881186128cc57600e5460e052602060e0f35b63e0a0b58681186128e357600f5460e052602060e0f35b6358680d0b81186128fa5760105460e052602060e0f35b63e382446281186129115760115460e052602060e0f35b631ec0cdc181186129285760125460e052602060e0f35b6306fdde0381186129cb5760e08060208082528083018060158082602082540160c060006003818352015b8260c051602002111561296557612984565b60c05185015460c0516020028501528151600101808352811415612953575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b6395d89b418118612a6e5760e08060208082528083018060188082602082540160c060006002818352015b8260c0516020021115612a0857612a27565b60c05185015460c05160200285015281516001018083528114156129f6575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b6370a082318118612aa3576004358060a01c613a435760e052601a60e05160a052608052604060802054610100526020610100f35b63dd62ed3e8118612af6576004358060a01c613a435760e0526024358060a01c613a435761010052601b60e05160a05260805260406080206101005160a052608052604060802054610120526020610120f35b6318160ddd8118612b0d57601c5460e052602060e0f35b505b60006000fd5b601a60e05160a0526080526040608020805461012051808210613a435780820390509050815550601a6101005160a05260805260406080208054610120518181830110613a4357808201905090508155506101005160e0517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61012051610140526020610140a3565b600d5460e052600b546101005260e0514210612bc45761010051815250612cd756612cd7565b600a5461012052600c5461014052610120516101005111612c5c57610120516101205161010051808210613a4357808203905090504261014051808210613a435780820390509050808202821582848304141715613a43579050905060e05161014051808210613a435780820390509050808015613a4357820490509050808210613a435780820390509050815250612cd756612cd7565b610120516101005161012051808210613a4357808203905090504261014051808210613a435780820390509050808202821582848304141715613a43579050905060e05161014051808210613a435780820390509050808015613a43578204905090508181830110613a435780820190509050815250612cd7565b565b670de0b6b3a7640000610140526c0c9f2c9cd04674edea40000000610160526c0c9f2c9cd04674edea40000000610180526101a060006003818352015b6101406101a0516003811015613a4357602002015160e06101a0516003811015613a43576020020151808202821582848304141715613a435790509050670de0b6b3a7640000808204905090506101406101a0516003811015613a435760200201528151600101808352811415612d1657505061014051815261016051816020015261018051816040015250565b604036610160376101c060006003818352015b60206101c0510260e001516101a05261016080516101a0518181830110613a4357808201905090508152508151600101808352811415612db757505061016051612e0557600081525061300f565b610160516101a052610140516003808202821582848304141715613a4357905090506101c0526101e0600060ff818352015b6101a0516102005261024060006003818352015b6020610240510260e0015161022052610200516101a051808202821582848304141715613a435790509050610220516003808202821582848304141715613a435790509050808015613a4357820490509050610200528151600101808352811415612e4b5750506101a051610180526101c05161016051808202821582848304141715613a435790509050606480820490509050610200516003808202821582848304141715613a4357905090508181830110613a4357808201905090506101a051808202821582848304141715613a4357905090506101c0516064808210613a4357808203905090506101a051808202821582848304141715613a435790509050606480820490509050600461020051808202821582848304141715613a4357905090508181830110613a435780820190509050808015613a43578204905090506101a052610180516101a05111612fcd576001610180516101a051808210613a43578082039050905011612ff85750506101a05181525061300f56612ff8565b60016101a05161018051808210613a43578082039050905011612ff85750506101a05181525061300f565b8151600101808352811415612e3757505060006000fd5b565b6102605160e05261028051610100526102a05161012052613033610340612cd9565b61034080516102e052806020015161030052806040015161032052506102e05160e052610300516101005261032051610120526102c05161014052613079610340612da4565b61034051815250565b610280516102605114613a435760006102805112613a43576003610280511215613a435760006102605112613a43576003610260511215613a43576130c8610340612b9e565b61034051610320526102c05160e0526102e05161010052610300516101205261032051610140526130fa610360612da4565b610360516103405260603661036037610340516103c052610320516003808202821582848304141715613a4357905090506103e05261040060006003818352015b610260516104005118613155576102a05161038052613186565b6102805161040051141561316c576131ea56613186565b6102c0610400516003811015613a43576020020151610380525b6103608051610380518181830110613a4357808201905090508152506103c05161034051808202821582848304141715613a435790509050610380516003808202821582848304141715613a435790509050808015613a43578204905090506103c0525b815160010180835281141561313b5750506103c05161034051808202821582848304141715613a4357905090506064808202821582848304141715613a4357905090506103e0516003808202821582848304141715613a435790509050808015613a43578204905090506103c05261036051610340516064808202821582848304141715613a4357905090506103e051808015613a43578204905090508181830110613a435780820190509050610400526103405161042052610440600060ff818352015b610420516103a0526104205161042051808202821582848304141715613a4357905090506103c0518181830110613a435780820190509050600261042051808202821582848304141715613a435790509050610400518181830110613a43578082019050905061034051808210613a435780820390509050808015613a4357820490509050610420526103a05161042051116133745760016103a05161042051808210613a4357808203905090501161339f575050610420518152506133b65661339f565b6001610420516103a051808210613a4357808203905090501161339f575050610420518152506133b6565b81516001018083528114156132af57505060006000fd5b565b60006101005112613a43576003610100511215613a43576060366101a037610180516102005260e0516003808202821582848304141715613a4357905090506102205261024060006003818352015b6101005161024051141561341e5761349c56613438565b610120610240516003811015613a435760200201516101c0525b6101a080516101c0518181830110613a4357808201905090508152506102005161018051808202821582848304141715613a4357905090506101c0516003808202821582848304141715613a435790509050808015613a4357820490509050610200525b81516001018083528114156134075750506102005161018051808202821582848304141715613a4357905090506064808202821582848304141715613a435790509050610220516003808202821582848304141715613a435790509050808015613a4357820490509050610200526101a051610180516064808202821582848304141715613a43579050905061022051808015613a43578204905090508181830110613a435780820190509050610240526101805161026052610280600060ff818352015b610260516101e0526102605161026051808202821582848304141715613a435790509050610200518181830110613a435780820190509050600261026051808202821582848304141715613a435790509050610240518181830110613a43578082019050905061018051808210613a435780820390509050808015613a4357820490509050610260526101e05161026051116136265760016101e05161026051808210613a435780820390509050116136515750506102605181525061366856613651565b6001610260516101e051808210613a4357808203905090501161365157505061026051815250613668565b815160010180835281141561356157505060006000fd5b565b613675610300612b9e565b610300516102e052670de0b6b3a7640000610300526c0c9f2c9cd04674edea40000000610320526c0c9f2c9cd04674edea400000006103405260045460e05260055461010052600654610120526136cd6103c0612cd9565b6103c080516103605280602001516103805280604001516103a052506103605160e05261038051610100526103a051610120526102e051610140526137136103e0612da4565b6103e0516103c052601c546103e0526103c0516102a0516103c051808202821582848304141715613a4357905090506103e051808015613a4357820490509050808210613a435780820390509050610400526102e05160e0526102c05161010052610360516101205261038051610140526103a05161016052610400516101805261379f6104406133b8565b61044051610420526007546003808202821582848304141715613a43579050905060088082049050905061044052606036610460376104c060006003818352015b60006104e0526103606104c0516003811015613a43576020020151610500526102c0516104c05118613854576105005161040051808202821582848304141715613a4357905090506103c051808015613a435782049050905061042051808210613a4357808203905090506104e052613898565b610500516105005161040051808202821582848304141715613a4357905090506103c051808015613a4357820490509050808210613a4357808203905090506104e0525b61050051610440516104e051808202821582848304141715613a4357905090506402540be40080820490509050808210613a4357808203905090506104606104c0516003811015613a4357602002015281516001018083528114156137e05750506104606102c0516003811015613a435760200201516102e05160e0526102c05161010052610460516101205261048051610140526104a0516101605261040051610180526139486104e06133b8565b6104e051808210613a4357808203905090506104c0526103606102c0516003811015613a4357602002015161042051808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a4357905090506103006102c0516003811015613a43576020020151808015613a43578204905090506104e0526104c0516001808210613a435780820390509050670de0b6b3a7640000808202821582848304141715613a4357905090506103006102c0516003811015613a43576020020151808015613a43578204905090506104c0526104c05181526104e0516104c051808210613a435780820390509050816020015250565b600080fd

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

000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da10000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e5800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000003d0900000000000000000000000000000000000000000000000000000000012a05f20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000001643757276652e6669204441492f555344432f555344540000000000000000000000000000000000000000000000000000000000000000000000000000000000043343525600000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _coins (address[3]): 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1,0x7F5c764cBc14f9669B88837ca1490cCa17c31607,0x94b008aA00579c1307B0EF2c499aD98a8ce58e58
Arg [1] : _A (uint256): 1000
Arg [2] : _fee (uint256): 4000000
Arg [3] : _admin_fee (uint256): 5000000000
Arg [4] : _name (string): Curve.fi DAI/USDC/USDT
Arg [5] : _symbol (string): 3CRV

-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1
Arg [1] : 0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607
Arg [2] : 00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58
Arg [3] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [4] : 00000000000000000000000000000000000000000000000000000000003d0900
Arg [5] : 000000000000000000000000000000000000000000000000000000012a05f200
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [9] : 43757276652e6669204441492f555344432f5553445400000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [11] : 3343525600000000000000000000000000000000000000000000000000000000


[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.