Contract 0x160CAed03795365F3A589f10C379FfA7d75d4E76

 
Txn Hash
Block
From
To
Value [Txn Fee]
0x1cf4c653ce53292799aceac273a66510985c36b72f1e8014b7d16db8c16624a884689702021-06-20 19:04:3520 mins ago0x72b223de2f773c814465c4a8f2ef9faae702cfb3 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000447325
0xb58e2d0f152089604aaf1cb9bb443b3c85a8dabd5b526552aa40bd6c4b0225ea84683822021-06-20 18:35:1150 mins ago0x42664ff369b16ab9b638b8e3030fed3192d68c5a IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000537595
0xb96a330ecaa18c7bcd9b52ddcd3c05d87a6d2f0d1085041faf5a39e2927892d184683402021-06-20 18:33:0552 mins ago0x3ed7950be7b1c56a235e218dfbfd204a979fbe68 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000451908
0x8fe56b6c10283ae4d24c9405628f0c889f068a487e88a0b0328b5afec81d218284681582021-06-20 18:23:591 hr 1 min ago0x2b18b809188e65133c88e60b86d3dee4c3f39c2f IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00060159
0xd0cbaca683b74835110064c0bb40ae30080b631978c80e05e7b751fe16f3d53a84680272021-06-20 18:17:261 hr 7 mins ago0xdc77c2c5f7aa4e45166042ba682e9f8f9137f41e IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000560775
0x9f65f0fd8e63e031fac8228e2cfb3bd43fc77fa14187825a178b52d17aa3109284679882021-06-20 18:15:291 hr 9 mins ago0xdc77c2c5f7aa4e45166042ba682e9f8f9137f41e IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000560775
0x29b1b8232fb081d997cf40427dd9b8f4ef9be89c01890be2bee054fcd6439b1884677372021-06-20 18:02:561 hr 22 mins ago0xd7d790e15ab37ceb124de88a207e826f5346c16a IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000626315
0xbe0c88757ba1e9e1d9b954edeb98ba98b6f6fe1dc8f417c181e219e5d505f43784677232021-06-20 18:02:141 hr 23 mins ago0x8c6778f77b22cead996a7bd73de2283e38d5aa4a IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00054442
0x5a1e5ab86a1f096ebe34624f769de37e5c5a2d985523743957dd69baeadf5ebf84674622021-06-20 17:49:111 hr 36 mins ago0x6bebbf542b5d45b0bf19229687288964bd7b014c IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000485955
0xa7ab442cc246d17b09aa903e404322bd2343665848bd7a4938889b27c2d7635c84668462021-06-20 17:18:232 hrs 6 mins ago0x8d3bea823f22fbfe058577ca01e9a88160e2dd3a IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000635835
0x9487813c83ac54c1e9ff3a90be005cbe935a48ad00fbc6d28ca964431c60aac084663832021-06-20 16:55:142 hrs 30 mins ago0x6bebbf542b5d45b0bf19229687288964bd7b014c IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00060147
0x3aa6a343ed30072f0b3e08e2db9e08841d0d037a568b80150c21b5a736c005ff84663382021-06-20 16:52:592 hrs 32 mins ago0x8d7229977ea35aec40ea9d4d7a138c0d7da3ca24 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000772275
0x8738ac9ada428e8d8e60089d256c4954e5cc8be70ba16f502a2438091db0971c84663092021-06-20 16:51:322 hrs 33 mins ago0x8d7229977ea35aec40ea9d4d7a138c0d7da3ca24 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00054019
0xb4eafa76b4984cd27ed846ce9606ecd448b908353215961a4719c5e1169af55c84662522021-06-20 16:48:412 hrs 36 mins ago0xe4c2993f65c487351eea82b4d24d1e6cb118cfc5 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000626255
0xe4ec369296f5706a2a5136b25f3c004ba7c0117323bd1cfff9d7f7ee18050e1b84662352021-06-20 16:47:502 hrs 37 mins ago0x3074e2c3222d10fb988a027e2bd7f8f753f5b0cb IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00054406
0x20447c8f993efc5e9797e21451f7f87450a5083e5c6f67a56bc383f47920846e84662202021-06-20 16:47:052 hrs 38 mins ago0x3074e2c3222d10fb988a027e2bd7f8f753f5b0cb IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00061924
0x0a0681bb4de7134597800fa3c9cc9d4f4263e9efa51a17cb1970ddb0dc25a54884659622021-06-20 16:34:112 hrs 51 mins ago0x7b3b5d817437053095d57228268ff445ede32535 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000772405
0xe52ac53812b83183ad434d70dabd593c5f0fb9a31c8d11c792812fbac20d947584658402021-06-20 16:28:052 hrs 57 mins ago0x3074e2c3222d10fb988a027e2bd7f8f753f5b0cb IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00054436
0xf07dda11725e073aedc751145bfdb42fd2648cb201f761bc8c703eac7cbb2b3184655192021-06-20 16:12:023 hrs 13 mins ago0x3ed7950be7b1c56a235e218dfbfd204a979fbe68 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000563376
0x2399825434753164e628e886ee61ff2d454012fc64b05c5277194c5b948b456f84654662021-06-20 16:09:233 hrs 15 mins ago0xf3bcd2e7cc95ac1c5824da5e372b9d6259dcf75c IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00060159
0xa89deeb12646686f3ab1b3b2c79e6f28ae25a3ae4c3ec9c73d39e62bd304e36984653302021-06-20 16:02:353 hrs 22 mins ago0x5fc5b2fc589967b5fe482e33ddce64881547a016 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00054454
0x01fb04011d879853f5f79204a5859af89900e45247d64a33dc7df4ef9017df8384653072021-06-20 16:01:263 hrs 23 mins ago0x5fc5b2fc589967b5fe482e33ddce64881547a016 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.00054047
0x850e02589de913abf03afd55adbfe170ca016a32057a32810d1cefe284aa390284652482021-06-20 15:58:293 hrs 26 mins ago0x651ad4d0001351ca8786dcb0b748d21f1e2d469a IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000701195
0x84008cb5fd01e8343d4ff5ec6ef778dcd9dbfc483f3ab1631ed008eedac6011484651552021-06-20 15:53:503 hrs 31 mins ago0xfc3b9fe7ae34a00d60b04472659ebb6f1b8dfd86 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000612655
0x9d733c6a9330cc237b28c6bb19357c1c992fa6bb51e2a51aac469a2bc0e6e08284650912021-06-20 15:50:383 hrs 34 mins ago0xb4989157aa07878c5066274e48660f80e5322129 IN  0x160caed03795365f3a589f10c379ffa7d75d4e760 BNB0.000575445
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Vyper_contract

Compiler Version
vyper:0.2.11

Optimization Enabled:
N/A

Other Settings:
, None license

Contract Source Code (Vyper language format)

# @version 0.2.11
# (c) Curve.Fi, 2020

from vyper.interfaces import ERC20

interface CurveToken:
    def totalSupply() -> uint256: view
    def mint(_to: address, _value: uint256) -> bool: nonpayable
    def burnFrom(_to: address, _value: uint256) -> bool: nonpayable


interface FeeConverter:
    def convertFees(i: uint256, j: uint256): nonpayable
    def notify(addr: address): nonpayable


# Events
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

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


# This can (and needs to) be changed at compile time
N_COINS: constant(int128) = 3  # <- change

FEE_DENOMINATOR: constant(uint256) = 10 ** 10
LENDING_PRECISION: constant(uint256) = 10 ** 18
PRECISION: constant(uint256) = 10 ** 18  # The precision to convert to
PRECISION_MUL: constant(uint256[N_COINS]) = [1, 1, 1]
RATES: constant(uint256[N_COINS]) = [1000000000000000000, 1000000000000000000, 1000000000000000000]
FEE_INDEX: constant(int128) = 2  # Which coin may potentially have fees (USDT)

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)
fee_converter: public(address)
token: CurveToken

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


@external
def __init__(
    _owner: address,
    _coins: address[N_COINS],
    _pool_token: address,
    _A: uint256,
    _fee: uint256,
    _admin_fee: uint256,
    _fee_converter: address,
):
    """
    @notice Contract constructor
    @param _owner Contract owner address
    @param _coins Addresses of ERC20 conracts of coins
    @param _pool_token Address of the token representing LP share
    @param _A Amplification coefficient multiplied by n * (n - 1)
    @param _fee Fee to charge for exchanges
    @param _admin_fee Admin fee
    """
    for i in range(N_COINS):
        assert _coins[i] != ZERO_ADDRESS
    self.coins = _coins
    self.initial_A = _A
    self.future_A = _A
    self.fee = _fee
    self.admin_fee = _admin_fee
    self.owner = _owner
    self.kill_deadline = block.timestamp + KILL_DEADLINE_DT
    self.token = CurveToken(_pool_token)
    self.fee_converter = _fee_converter


@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()


@view
@internal
def _xp() -> uint256[N_COINS]:
    result: uint256[N_COINS] = RATES
    for i in range(N_COINS):
        result[i] = result[i] * self.balances[i] / LENDING_PRECISION
    return result


@pure
@internal
def _xp_mem(_balances: uint256[N_COINS]) -> uint256[N_COINS]:
    result: uint256[N_COINS] = RATES
    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:
    S: uint256 = 0
    for _x in xp:
        S += _x
    if S == 0:
        return 0

    Dprev: uint256 = 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 + D_P * N_COINS) * D / ((Ann - 1) * D + (N_COINS + 1) * D_P)
        # Equality with the precision of 1
        if D > Dprev:
            if D - Dprev <= 1:
                break
        else:
            if Dprev - D <= 1:
                break
    return D


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


@view
@external
def get_virtual_price() -> uint256:
    """
    Returns portfolio virtual price (for calculating profit)
    scaled up by 1e18
    """
    D: uint256 = self.get_D(self._xp(), self._A())
    # 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
    token_supply: uint256 = self.token.totalSupply()
    return D * PRECISION / token_supply


@view
@external
def calc_token_amount(amounts: uint256[N_COINS], deposit: bool) -> uint256:
    """
    Simplified method to calculate addition or reduction in token supply at
    deposit or withdrawal without taking fees into account (but looking at
    slippage).
    Needed to prevent front-running, not for precise calculations!
    """
    _balances: uint256[N_COINS] = self.balances
    amp: uint256 = self._A()
    D0: uint256 = self.get_D_mem(_balances, amp)
    for i in range(N_COINS):
        if deposit:
            _balances[i] += amounts[i]
        else:
            _balances[i] -= amounts[i]
    D1: uint256 = self.get_D_mem(_balances, amp)
    token_amount: uint256 = self.token.totalSupply()
    diff: uint256 = 0
    if deposit:
        diff = D1 - D0
    else:
        diff = D0 - D1
    return diff * token_amount / D0


@external
@nonreentrant('lock')
def add_liquidity(amounts: uint256[N_COINS], min_mint_amount: uint256):
    assert not self.is_killed  # dev: is killed

    fees: uint256[N_COINS] = empty(uint256[N_COINS])
    _fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
    _admin_fee: uint256 = self.admin_fee
    amp: uint256 = self._A()

    token_supply: uint256 = self.token.totalSupply()
    # Initial invariant
    D0: uint256 = 0
    old_balances: uint256[N_COINS] = self.balances
    if token_supply > 0:
        D0 = self.get_D_mem(old_balances, amp)
    new_balances: uint256[N_COINS] = old_balances

    for i in range(N_COINS):
        in_amount: uint256 = amounts[i]
        if token_supply == 0:
            assert in_amount > 0  # dev: initial deposit requires all coins
        in_coin: address = self.coins[i]

        # Take coins from the sender
        if in_amount > 0:
            if i == FEE_INDEX:
                in_amount = ERC20(in_coin).balanceOf(self)

            # "safeTransferFrom" which works for ERC20s which return bool or not
            _response: Bytes[32] = raw_call(
                in_coin,
                concat(
                    method_id("transferFrom(address,address,uint256)"),
                    convert(msg.sender, bytes32),
                    convert(self, bytes32),
                    convert(amounts[i], bytes32),
                ),
                max_outsize=32,
            )  # dev: failed transfer
            if len(_response) > 0:
                assert convert(_response, bool)  # dev: failed transfer

            if i == FEE_INDEX:
                in_amount = ERC20(in_coin).balanceOf(self) - in_amount

        new_balances[i] = old_balances[i] + in_amount

    # 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
    D2: uint256 = D1
    if token_supply > 0:
        # Only account for fees if we are not the first to deposit
        for i in range(N_COINS):
            ideal_balance: uint256 = D1 * old_balances[i] / D0
            difference: uint256 = 0
            if ideal_balance > new_balances[i]:
                difference = ideal_balance - new_balances[i]
            else:
                difference = new_balances[i] - ideal_balance
            fees[i] = _fee * difference / FEE_DENOMINATOR
            self.balances[i] = new_balances[i] - (fees[i] * _admin_fee / FEE_DENOMINATOR)
            new_balances[i] -= fees[i]
        D2 = self.get_D_mem(new_balances, amp)
    else:
        self.balances = new_balances

    # Calculate, how much pool tokens to mint
    mint_amount: uint256 = 0
    if token_supply == 0:
        mint_amount = D1  # Take the dust if there was any
    else:
        mint_amount = token_supply * (D2 - D0) / D0

    assert mint_amount >= min_mint_amount, "Slippage screwed you"

    # Mint pool tokens
    self.token.mint(msg.sender, mint_amount)

    log AddLiquidity(msg.sender, amounts, fees, D1, token_supply + mint_amount)


@view
@internal
def get_y(i: int128, j: int128, x: uint256, xp_: uint256[N_COINS]) -> uint256:
    # 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)
    c: uint256 = D
    S_: uint256 = 0
    Ann: uint256 = amp * N_COINS

    _x: uint256 = 0
    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 / (Ann * N_COINS)
    b: uint256 = S_ + D / Ann  # - D
    y_prev: uint256 = 0
    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:
                break
        else:
            if y_prev - y <= 1:
                break
    return y


@view
@external
def get_dy(i: int128, j: int128, dx: uint256) -> uint256:
    # dx and dy in c-units
    rates: uint256[N_COINS] = RATES
    xp: uint256[N_COINS] = self._xp()

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


@view
@external
def get_dy_underlying(i: int128, j: int128, dx: uint256) -> uint256:
    # dx and dy in underlying units
    xp: uint256[N_COINS] = self._xp()
    precisions: uint256[N_COINS] = PRECISION_MUL

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



@external
@nonreentrant('lock')
def exchange(i: int128, j: int128, dx: uint256, min_dy: uint256):
    assert not self.is_killed  # dev: is killed
    rates: uint256[N_COINS] = RATES

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

    # Handling an unexpected charge of a fee on transfer (USDT, PAXG)
    dx_w_fee: uint256 = dx
    input_coin: address = self.coins[i]

    if i == FEE_INDEX:
        dx_w_fee = ERC20(input_coin).balanceOf(self)

    # "safeTransferFrom" which works for ERC20s which return bool or not
    _response: Bytes[32] = raw_call(
        input_coin,
        concat(
            method_id("transferFrom(address,address,uint256)"),
            convert(msg.sender, bytes32),
            convert(self, bytes32),
            convert(dx, bytes32),
        ),
        max_outsize=32,
    )  # dev: failed transfer
    if len(_response) > 0:
        assert convert(_response, bool)  # dev: failed transfer

    if i == FEE_INDEX:
        dx_w_fee = ERC20(input_coin).balanceOf(self) - dx_w_fee

    x: uint256 = xp[i] + dx_w_fee * 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_w_fee
    # When rounding errors happen, we undercharge admin fee in favor of LP
    self.balances[j] = old_balances[j] - dy - dy_admin_fee

    # "safeTransfer" which works for ERC20s which return bool or not
    _response = raw_call(
        self.coins[j],
        concat(
            method_id("transfer(address,uint256)"),
            convert(msg.sender, bytes32),
            convert(dy, bytes32),
        ),
        max_outsize=32,
    )  # dev: failed transfer
    if len(_response) > 0:
        assert convert(_response, bool)  # dev: failed transfer

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


@external
@nonreentrant('lock')
def remove_liquidity(_amount: uint256, min_amounts: uint256[N_COINS]):
    total_supply: uint256 = self.token.totalSupply()
    amounts: uint256[N_COINS] = empty(uint256[N_COINS])
    fees: uint256[N_COINS] = empty(uint256[N_COINS])  # Fees are unused but we've got them historically in event

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

        # "safeTransfer" which works for ERC20s which return bool or not
        _response: Bytes[32] = raw_call(
            self.coins[i],
            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)  # dev: failed transfer

    self.token.burnFrom(msg.sender, _amount)  # dev: insufficient funds

    log RemoveLiquidity(msg.sender, amounts, fees, total_supply - _amount)


@external
@nonreentrant('lock')
def remove_liquidity_imbalance(amounts: uint256[N_COINS], max_burn_amount: uint256):
    assert not self.is_killed  # dev: is killed

    token_supply: uint256 = self.token.totalSupply()
    assert token_supply != 0  # dev: zero total supply
    _fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
    _admin_fee: uint256 = self.admin_fee
    amp: uint256 = self._A()

    old_balances: uint256[N_COINS] = self.balances
    new_balances: uint256[N_COINS] = old_balances
    D0: uint256 = self.get_D_mem(old_balances, amp)
    for i in range(N_COINS):
        new_balances[i] -= amounts[i]
    D1: uint256 = self.get_D_mem(new_balances, amp)
    fees: uint256[N_COINS] = empty(uint256[N_COINS])
    for i in range(N_COINS):
        ideal_balance: uint256 = D1 * old_balances[i] / D0
        difference: uint256 = 0
        if ideal_balance > new_balances[i]:
            difference = ideal_balance - new_balances[i]
        else:
            difference = new_balances[i] - ideal_balance
        fees[i] = _fee * difference / FEE_DENOMINATOR
        self.balances[i] = new_balances[i] - (fees[i] * _admin_fee / FEE_DENOMINATOR)
        new_balances[i] -= fees[i]
    D2: uint256 = self.get_D_mem(new_balances, amp)

    token_amount: uint256 = (D0 - D2) * token_supply / D0
    assert token_amount != 0  # dev: zero tokens burned
    token_amount += 1  # In case of rounding errors - make it unfavorable for the "attacker"
    assert token_amount <= max_burn_amount, "Slippage screwed you"

    self.token.burnFrom(msg.sender, token_amount)  # dev: insufficient funds
    for i in range(N_COINS):
        if amounts[i] != 0:

            # "safeTransfer" which works for ERC20s which return bool or not
            _response: Bytes[32] = raw_call(
                self.coins[i],
                concat(
                    method_id("transfer(address,uint256)"),
                    convert(msg.sender, bytes32),
                    convert(amounts[i], bytes32),
                ),
                max_outsize=32,
            )  # dev: failed transfer
            if len(_response) > 0:
                assert convert(_response, bool)  # dev: failed transfer

    log RemoveLiquidityImbalance(msg.sender, amounts, fees, D1, token_supply - token_amount)


@view
@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 + x1 * (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

    c: uint256 = D
    S_: uint256 = 0
    Ann: uint256 = A_ * N_COINS

    _x: uint256 = 0
    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 / (Ann * N_COINS)
    b: uint256 = S_ + D / Ann
    y_prev: uint256 = 0
    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:
                break
        else:
            if y_prev - y <= 1:
                break
    return y


@view
@internal
def _calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> (uint256, uint256):
    # First, need to calculate
    # * Get current D
    # * Solve Eqn against y_i for D - _token_amount
    amp: uint256 = self._A()
    _fee: uint256 = self.fee * N_COINS / (4 * (N_COINS - 1))
    precisions: uint256[N_COINS] = PRECISION_MUL
    total_supply: uint256 = self.token.totalSupply()

    xp: uint256[N_COINS] = self._xp()

    D0: uint256 = self.get_D(xp, amp)
    D1: uint256 = D0 - _token_amount * D0 / total_supply
    xp_reduced: uint256[N_COINS] = xp

    new_y: uint256 = self.get_y_D(amp, i, xp, D1)
    dy_0: uint256 = (xp[i] - new_y) / precisions[i]  # w/o fees

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

    dy: uint256 = xp_reduced[i] - self.get_y_D(amp, i, xp_reduced, D1)
    dy = (dy - 1) / precisions[i]  # Withdraw less to account for rounding errors

    return dy, dy_0 - dy


@view
@external
def calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> uint256:
    return self._calc_withdraw_one_coin(_token_amount, i)[0]


@external
@nonreentrant('lock')
def remove_liquidity_one_coin(_token_amount: uint256, i: int128, min_amount: uint256):
    """
    Remove _amount of liquidity all in a form of coin i
    """
    assert not self.is_killed  # dev: is killed

    dy: uint256 = 0
    dy_fee: uint256 = 0
    dy, dy_fee = self._calc_withdraw_one_coin(_token_amount, i)
    assert dy >= min_amount, "Not enough coins removed"

    self.balances[i] -= (dy + dy_fee * self.admin_fee / FEE_DENOMINATOR)
    self.token.burnFrom(msg.sender, _token_amount)  # dev: insufficient funds

    # "safeTransfer" which works for ERC20s which return bool or not
    _response: Bytes[32] = raw_call(
        self.coins[i],
        concat(
            method_id("transfer(address,uint256)"),
            convert(msg.sender, bytes32),
            convert(dy, bytes32),
        ),
        max_outsize=32,
    )  # dev: failed transfer
    if len(_response) > 0:
        assert convert(_response, bool)  # dev: failed transfer

    log RemoveLiquidityOne(msg.sender, _token_amount, dy)


### Admin functions ###
@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()
    assert (_future_A > 0) and (_future_A < MAX_A)
    assert ((_future_A >= _initial_A) and (_future_A <= _initial_A * MAX_A_CHANGE)) or\
           ((_future_A < _initial_A) and (_future_A * MAX_A_CHANGE >= _initial_A))
    self.initial_A = _initial_A
    self.future_A = _future_A
    self.initial_A_time = block.timestamp
    self.future_A_time = _future_time

    log RampA(_initial_A, _future_A, 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():
    fee_converter: address = self.fee_converter
    for i in range(N_COINS):
        c: address = self.coins[i]
        value: uint256 = ERC20(c).balanceOf(self) - self.balances[i]
        if value > 0:
            # "safeTransfer" which works for ERC20s which return bool or not
            _response: Bytes[32] = raw_call(
                c,
                concat(
                    method_id("transfer(address,uint256)"),
                    convert(fee_converter, bytes32),
                    convert(value, bytes32),
                ),
                max_outsize=32,
            )  # dev: failed transfer
            if len(_response) > 0:
                assert convert(_response, bool)  # dev: failed transfer
            if i != 0:
                FeeConverter(fee_converter).convertFees(i, 0)
    FeeConverter(fee_converter).notify(self.coins[0])


@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 ABI

[{"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}],"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":"_owner","type":"address"},{"name":"_coins","type":"address[3]"},{"name":"_pool_token","type":"address"},{"name":"_A","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_admin_fee","type":"uint256"},{"name":"_fee_converter","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":5106},{"stateMutability":"view","type":"function","name":"get_virtual_price","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":1132771},{"stateMutability":"view","type":"function","name":"calc_token_amount","inputs":[{"name":"amounts","type":"uint256[3]"},{"name":"deposit","type":"bool"}],"outputs":[{"name":"","type":"uint256"}],"gas":4506209},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"amounts","type":"uint256[3]"},{"name":"min_mint_amount","type":"uint256"}],"outputs":[],"gas":6950840},{"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":2672568},{"stateMutability":"view","type":"function","name":"get_dy_underlying","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":2672270},{"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":[],"gas":2816580},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_amount","type":"uint256"},{"name":"min_amounts","type":"uint256[3]"}],"outputs":[],"gas":192419},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"amounts","type":"uint256[3]"},{"name":"max_burn_amount","type":"uint256"}],"outputs":[],"gas":6947760},{"stateMutability":"view","type":"function","name":"calc_withdraw_one_coin","inputs":[{"name":"_token_amount","type":"uint256"},{"name":"i","type":"int128"}],"outputs":[{"name":"","type":"uint256"}],"gas":1162},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_token_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"min_amount","type":"uint256"}],"outputs":[],"gas":4022793},{"stateMutability":"nonpayable","type":"function","name":"ramp_A","inputs":[{"name":"_future_A","type":"uint256"},{"name":"_future_time","type":"uint256"}],"outputs":[],"gas":151582},{"stateMutability":"nonpayable","type":"function","name":"stop_ramp_A","inputs":[],"outputs":[],"gas":148300},{"stateMutability":"nonpayable","type":"function","name":"commit_new_fee","inputs":[{"name":"new_fee","type":"uint256"},{"name":"new_admin_fee","type":"uint256"}],"outputs":[],"gas":110158},{"stateMutability":"nonpayable","type":"function","name":"apply_new_fee","inputs":[],"outputs":[],"gas":96939},{"stateMutability":"nonpayable","type":"function","name":"revert_new_parameters","inputs":[],"outputs":[],"gas":21592},{"stateMutability":"nonpayable","type":"function","name":"commit_transfer_ownership","inputs":[{"name":"_owner","type":"address"}],"outputs":[],"gas":74330},{"stateMutability":"nonpayable","type":"function","name":"apply_transfer_ownership","inputs":[],"outputs":[],"gas":60407},{"stateMutability":"nonpayable","type":"function","name":"revert_transfer_ownership","inputs":[],"outputs":[],"gas":21682},{"stateMutability":"view","type":"function","name":"admin_balances","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3178},{"stateMutability":"nonpayable","type":"function","name":"withdraw_admin_fees","inputs":[],"outputs":[],"gas":28794},{"stateMutability":"nonpayable","type":"function","name":"kill_me","inputs":[],"outputs":[],"gas":37665},{"stateMutability":"nonpayable","type":"function","name":"unkill_me","inputs":[],"outputs":[],"gas":21802},{"stateMutability":"view","type":"function","name":"coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":1887},{"stateMutability":"view","type":"function","name":"balances","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1917},{"stateMutability":"view","type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":1838},{"stateMutability":"view","type":"function","name":"admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":1868},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":1898},{"stateMutability":"view","type":"function","name":"fee_converter","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":1928},{"stateMutability":"view","type":"function","name":"initial_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":1958},{"stateMutability":"view","type":"function","name":"future_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":1988},{"stateMutability":"view","type":"function","name":"initial_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2018},{"stateMutability":"view","type":"function","name":"future_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2048},{"stateMutability":"view","type":"function","name":"admin_actions_deadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2078},{"stateMutability":"view","type":"function","name":"transfer_ownership_deadline","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2108},{"stateMutability":"view","type":"function","name":"future_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2138},{"stateMutability":"view","type":"function","name":"future_admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2168},{"stateMutability":"view","type":"function","name":"future_owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2198}]

610120614f7b610140396020614f7b60c03960c05160a01c1561002157600080fd5b60206020614f7b0160c03960c05160a01c1561003c57600080fd5b60206040614f7b0160c03960c05160a01c1561005757600080fd5b60206060614f7b0160c03960c05160a01c1561007257600080fd5b60206080614f7b0160c03960c05160a01c1561008d57600080fd5b6020610100614f7b0160c03960c05160a01c156100a957600080fd5b61026060006003818352015b600061016061026051600381106100cb57600080fd5b6020020151186100da57600080fd5b81516001018083528114156100b5575b5050600060c052602060c0206101605181556101805160018201556101a0516002820155506101e0516007556101e05160085561020051600255610220516003556101405160045542624f1a0081818301101561014657600080fd5b808201905090506011556101c05160065561024051600555614f6356600436101561000d57613821565b600035601c52600051341561002157600080fd5b63f446c1d08114156100475760065801613827565b610140526101405160005260206000f35b63bb7b8b808114156101e55761014051600658016139bf565b61016052610180526101a0526101405261016080516101c05280602001516101e052806040015161020052506101405161016051610180516101a0516101c0516101e0516102005160065801613827565b61022052610200526101e0526101c0526101a05261018052610160526101405261022051610240526101405161016051610180516101a0516101c0516101e0516102005161022051610240516101c051610260526101e05161028052610200516102a052610240516102c0526102c0516102a051610280516102605160065801613bc5565b610320526102405261022052610200526101e0526101c0526101a052610180526101605261014052610320516101405260206101e060046318160ddd6101805261019c6006545afa61018757600080fd5b601f3d1161019457600080fd5b6000506101e0516101605261014051670de0b6b3a764000080820282158284830414176101c057600080fd5b809050905090506101605180806101d657600080fd5b82049050905060005260206000f35b633883e1198114156104d95760643560011c1561020157600080fd5b60018060c052602060c020546101405260018160c052602060c02001546101605260028160c052602060c020015461018052506101405161016051610180516101a05160065801613827565b6101c0526101a0526101805261016052610140526101c0516101a0526101405161016051610180516101a0516101c051610140516101e052610160516102005261018051610220526101a051610240526102405161022051610200516101e05160065801613ea6565b6102a0526101c0526101a0526101805261016052610140526102a0516101c0526101e060006003818352015b6064351561033a576101406101e051600381106102fe57600080fd5b60200201805160046101e0516003811061031757600080fd5b602002013581818301101561032b57600080fd5b80820190509050815250610384565b6101406101e0516003811061034e57600080fd5b60200201805160046101e0516003811061036757600080fd5b60200201358082101561037957600080fd5b808203905090508152505b81516001018083528114156102e2575b50506101405161016051610180516101a0516101c0516101e0516101405161020052610160516102205261018051610240526101a051610260526102605161024051610220516102005160065801613ea6565b6102c0526101e0526101c0526101a0526101805261016052610140526102c0516101e052602061028060046318160ddd6102205261023c6006545afa61042c57600080fd5b601f3d1161043957600080fd5b600050610280516102005260006102205260643515610477576101e0516101c0518082101561046757600080fd5b8082039050905061022052610498565b6101c0516101e0518082101561048c57600080fd5b80820390509050610220525b610220516102005180820282158284830414176104b457600080fd5b809050905090506101c05180806104ca57600080fd5b82049050905060005260206000f35b634515cef3811415610f2657601254156104f257600080fd5b60016012556010541561050457600080fd5b606036610140376002546003808202821582848304141761052457600080fd5b809050905090506008808204905090506101a0526003546101c0526101405161016051610180516101a0516101c0516101e05160065801613827565b610200526101e0526101c0526101a052610180526101605261014052610200516101e052602061028060046318160ddd6102205261023c6006545afa6105a557600080fd5b601f3d116105b257600080fd5b600050610280516102005260006102205260018060c052602060c020546102405260018160c052602060c02001546102605260028160c052602060c0200154610280525060006102005111156106a0576101405161016051610180516101a0516101c0516101e0516102005161022051610240516102605161028051610240516102a052610260516102c052610280516102e0526101e05161030052610300516102e0516102c0516102a05160065801613ea6565b6103605261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261036051610220525b610240516102a052610260516102c052610280516102e05261030060006003818352015b600461030051600381106106d757600080fd5b6020020135610320526102005115156106fa57600061032051116106fa57600080fd5b610300516003811061070b57600080fd5b600060c052602060c020015461034052600061032051111561093a5760026103005114156107735760206103e060246370a0823161036052306103805261037c610340515afa61075a57600080fd5b601f3d1161076757600080fd5b6000506103e051610320525b600060046103c0527f23b872dd000000000000000000000000000000000000000000000000000000006103e0526103c060048060208461042001018260208501600060045af15050805182019150503360208261042001015260208101905030602082610420010152602081019050600461030051600381106107f557600080fd5b6020020135602082610420010152602081019050806104205261042090508051602001806104e08284600060045af161082d57600080fd5b505060206105c06104e0516105006000610340515af161084c57600080fd5b60203d8082111561085d578061085f565b815b905090506105a0526105a08051602001806103608284600060045af161088457600080fd5b505060006103605111156108d6576103608060200151600082518060209013156108ad57600080fd5b80919012156108bb57600080fd5b806020036101000a820490509050905015156108d657600080fd5b600261030051141561093a57602061044060246370a082316103c052306103e0526103dc610340515afa61090957600080fd5b601f3d1161091657600080fd5b60005061044051610320518082101561092e57600080fd5b80820390509050610320525b610240610300516003811061094e57600080fd5b60200201516103205181818301101561096657600080fd5b808201905090506102a0610300516003811061098157600080fd5b60200201525b81516001018083528114156106c4575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516102a051610320526102c051610340526102e051610360526101e051610380526103805161036051610340516103205160065801613ea6565b6103e052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103e05161030052610220516103005111610a6857600080fd5b61030051610320526000610200511115610d715761034060006003818352015b610300516102406103405160038110610aa057600080fd5b60200201518082028215828483041417610ab957600080fd5b80905090509050610220518080610acf57600080fd5b820490509050610360526000610380526102a06103405160038110610af357600080fd5b6020020151610360511115610b3c57610360516102a06103405160038110610b1a57600080fd5b602002015180821015610b2c57600080fd5b8082039050905061038052610b72565b6102a06103405160038110610b5057600080fd5b60200201516103605180821015610b6657600080fd5b80820390509050610380525b6101a051610380518082028215828483041417610b8e57600080fd5b809050905090506402540be400808204905090506101406103405160038110610bb657600080fd5b60200201526102a06103405160038110610bcf57600080fd5b60200201516101406103405160038110610be857600080fd5b60200201516101c0518082028215828483041417610c0557600080fd5b809050905090506402540be4008082049050905080821015610c2657600080fd5b808203905090506103405160038110610c3e57600080fd5b600160c052602060c02001556102a06103405160038110610c5e57600080fd5b6020020180516101406103405160038110610c7857600080fd5b602002015180821015610c8a57600080fd5b808203905090508152505b8151600101808352811415610a88575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516102a051610340526102c051610360526102e051610380526101e0516103a0526103a05161038051610360516103405160065801613ea6565b6104005261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526104005161032052610d95565b600160c052602060c0206102a05181556102c05160018201556102e0516002820155505b600061034052610200511515610db2576103005161034052610e07565b61020051610320516102205180821015610dcb57600080fd5b808203905090508082028215828483041417610de657600080fd5b80905090509050610220518080610dfc57600080fd5b820490509050610340525b6064356103405110151515610e5b576308c379a06103605260206103805260146103a0527f536c697070616765207363726577656420796f750000000000000000000000006103c0526103a050606461037cfd5b602061040060446340c10f19610360523361038052610340516103a05261037c60006006545af1610e8b57600080fd5b601f3d11610e9857600080fd5b6000506104005060043561036052602435610380526044356103a052610140516103c052610160516103e052610180516104005261030051610420526102005161034051818183011015610eeb57600080fd5b8082019050905061044052337f423f6495a08fc652425cf4ed0d1f9e37e571d9b9529b1c1c23cce780b2e7df0d610100610360a26000601255005b635e0d443f8114156111fc5760043580806000811215610f4257195b607f1c15610f4f57600080fd5b90505060243580806000811215610f6257195b607f1c15610f6f57600080fd5b905050670de0b6b3a764000061014052670de0b6b3a764000061016052670de0b6b3a7640000610180526101405161016051610180516101a0516101c0516101e051600658016139bf565b6102005261022052610240526101e0526101c0526101a05261018052610160526101405261020080516101a05280602001516101c05280604001516101e052506101a06004356003811061100d57600080fd5b60200201516044356101406004356003811061102857600080fd5b6020020151808202821582848304141761104157600080fd5b80905090509050670de0b6b3a76400008082049050905081818301101561106757600080fd5b80820190509050610200526101405161016051610180516101a0516101c0516101e0516102005161022051600435610240526024356102605261020051610280526101a0516102a0526101c0516102c0526101e0516102e0526102e0516102c0516102a05161028051610260516102405160065801614004565b6103405261022052610200526101e0526101c0526101a05261018052610160526101405261034051610220526101a06024356003811061112057600080fd5b6020020151610220518082101561113657600080fd5b8082039050905060018082101561114c57600080fd5b80820390509050670de0b6b3a7640000808202821582848304141761117057600080fd5b809050905090506101406024356003811061118a57600080fd5b6020020151808061119a57600080fd5b820490509050610240526002546102405180820282158284830414176111bf57600080fd5b809050905090506402540be40080820490509050610260526102405161026051808210156111ec57600080fd5b8082039050905060005260206000f35b6307211ef7811415611471576004358080600081121561121857195b607f1c1561122557600080fd5b9050506024358080600081121561123857195b607f1c1561124557600080fd5b905050610140516101605161018051600658016139bf565b6101a0526101c0526101e0526101805261016052610140526101a08051610140528060200151610160528060400151610180525060016101a05260016101c05260016101e052610140600435600381106112b657600080fd5b60200201516044356101a0600435600381106112d157600080fd5b602002015180820282158284830414176112ea57600080fd5b8090509050905081818301101561130057600080fd5b80820190509050610200526101405161016051610180516101a0516101c0516101e051610200516102205160043561024052602435610260526102005161028052610140516102a052610160516102c052610180516102e0526102e0516102c0516102a05161028051610260516102405160065801614004565b6103405261022052610200526101e0526101c0526101a0526101805261016052610140526103405161022052610140602435600381106113b957600080fd5b602002015161022051808210156113cf57600080fd5b808203905090506001808210156113e557600080fd5b808203905090506101a0602435600381106113ff57600080fd5b6020020151808061140f57600080fd5b8204905090506102405260025461024051808202821582848304141761143457600080fd5b809050905090506402540be400808204905090506102605261024051610260518082101561146157600080fd5b8082039050905060005260206000f35b633df02124811415611d8a576012541561148a57600080fd5b60016012556004358080600081121561149f57195b607f1c156114ac57600080fd5b905050602435808060008112156114bf57195b607f1c156114cc57600080fd5b905050601054156114dc57600080fd5b670de0b6b3a764000061014052670de0b6b3a764000061016052670de0b6b3a76400006101805260018060c052602060c020546101a05260018160c052602060c02001546101c05260028160c052602060c02001546101e052506101405161016051610180516101a0516101c0516101e0516102005161022051610240516101a051610260526101c051610280526101e0516102a0526102a051610280516102605160065801613abe565b6103005261032052610340526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103008051610200528060200151610220528060400151610240525060443561026052600435600381106115ea57600080fd5b600060c052602060c0200154610280526002600435141561164557602061032060246370a082316102a052306102c0526102bc610280515afa61162c57600080fd5b601f3d1161163957600080fd5b60005061032051610260525b60006004610300527f23b872dd000000000000000000000000000000000000000000000000000000006103205261030060048060208461036001018260208501600060045af15050805182019150503360208261036001015260208101905030602082610360010152602081019050604435602082610360010152602081019050806103605261036090508051602001806104208284600060045af16116ea57600080fd5b50506020610500610420516104406000610280515af161170957600080fd5b60203d8082111561171a578061171c565b815b905090506104e0526104e08051602001806102a08284600060045af161174157600080fd5b505060006102a0511115611793576102a080602001516000825180602090131561176a57600080fd5b809190121561177857600080fd5b806020036101000a8204905090509050151561179357600080fd5b600260043514156117f657602061038060246370a0823161030052306103205261031c610280515afa6117c557600080fd5b601f3d116117d257600080fd5b6000506103805161026051808210156117ea57600080fd5b80820390509050610260525b6102006004356003811061180957600080fd5b6020020151610260516101406004356003811061182557600080fd5b6020020151808202821582848304141761183e57600080fd5b80905090509050670de0b6b3a76400008082049050905081818301101561186457600080fd5b80820190509050610300526101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516103205160043561034052602435610360526103005161038052610200516103a052610220516103c052610240516103e0526103e0516103c0516103a05161038051610360516103405160065801614004565b6104405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261044051610320526102006024356003811061195d57600080fd5b6020020151610320518082101561197357600080fd5b8082039050905060018082101561198957600080fd5b80820390509050610340526103405160025480820282158284830414176119af57600080fd5b809050905090506402540be40080820490509050610360526103405161036051808210156119dc57600080fd5b80820390509050670de0b6b3a76400008082028215828483041417611a0057600080fd5b8090509050905061014060243560038110611a1a57600080fd5b60200201518080611a2a57600080fd5b820490509050610340526064356103405110151515611aad576308c379a06103805260206103a052602e6103c0527f45786368616e676520726573756c74656420696e20666577657220636f696e736103e0527f207468616e206578706563746564000000000000000000000000000000000000610400526103c050608461039cfd5b610360516003548082028215828483041417611ac857600080fd5b809050905090506402540be400808204905090506103805261038051670de0b6b3a76400008082028215828483041417611b0157600080fd5b8090509050905061014060243560038110611b1b57600080fd5b60200201518080611b2b57600080fd5b820490509050610380526101a060043560038110611b4857600080fd5b602002015161026051818183011015611b6057600080fd5b8082019050905060043560038110611b7757600080fd5b600160c052602060c02001556101a060243560038110611b9657600080fd5b60200201516103405180821015611bac57600080fd5b808203905090506103805180821015611bc457600080fd5b8082039050905060243560038110611bdb57600080fd5b600160c052602060c0200155600060046103a0527fa9059cbb000000000000000000000000000000000000000000000000000000006103c0526103a060048060208461040001018260208501600060045af15050805182019150503360208261040001015260208101905061034051602082610400010152602081019050806104005261040090508051602001806104a08284600060045af1611c7d57600080fd5b505060206105606104a0516104c0600060243560038110611c9d57600080fd5b600060c052602060c02001545af1611cb457600080fd5b60203d80821115611cc55780611cc7565b815b90509050610540526105408051602001806102a08284600060045af1611cec57600080fd5b505060006102a0511115611d3e576102a0806020015160008251806020901315611d1557600080fd5b8091901215611d2357600080fd5b806020036101000a82049050905090501515611d3e57600080fd5b6004356103a0526044356103c0526024356103e0526103405161040052337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd9714060806103a0a26000601255005b63ecb586a58114156121575760125415611da357600080fd5b600160125560206101c060046318160ddd6101605261017c6006545afa611dc957600080fd5b601f3d11611dd657600080fd5b6000506101c0516101405260c0366101603761022060006003818352015b6102205160038110611e0557600080fd5b600160c052602060c02001546004358082028215828483041417611e2857600080fd5b80905090509050610140518080611e3e57600080fd5b8204905090506102405260246102205160038110611e5b57600080fd5b60200201356102405110151515611ed6576308c379a06102605260206102805260306102a0527f5769746864726177616c20726573756c74656420696e20666577657220636f696102c0527f6e73207468616e206578706563746564000000000000000000000000000000006102e0526102a050608461027cfd5b6102205160038110611ee757600080fd5b600160c052602060c0200180546102405180821015611f0557600080fd5b80820390509050815550610240516101606102205160038110611f2757600080fd5b6020020152600060046102c0527fa9059cbb000000000000000000000000000000000000000000000000000000006102e0526102c060048060208461032001018260208501600060045af15050805182019150503360208261032001015260208101905061024051602082610320010152602081019050806103205261032090508051602001806103c08284600060045af1611fc257600080fd5b505060206104806103c0516103e060006102205160038110611fe357600080fd5b600060c052602060c02001545af1611ffa57600080fd5b60203d8082111561200b578061200d565b815b90509050610460526104608051602001806102608284600060045af161203257600080fd5b505060006102605111156120845761026080602001516000825180602090131561205b57600080fd5b809190121561206957600080fd5b806020036101000a8204905090509050151561208457600080fd5b8151600101808352811415611df4575b505060206102c060446379cc67906102205233610240526004356102605261023c60006006545af16120c557600080fd5b601f3d116120d257600080fd5b6000506102c050610160516102205261018051610240526101a051610260526101c051610280526101e0516102a052610200516102c052610140516004358082101561211d57600080fd5b808203905090506102e052337fa49d4cf02656aebf8c771f5a8585638a2a15ee6c97cf7205d4208ed7c1df252d60e0610220a26000601255005b639fdaea0c811415612a6b576012541561217057600080fd5b60016012556010541561218257600080fd5b60206101c060046318160ddd6101605261017c6006545afa6121a357600080fd5b601f3d116121b057600080fd5b6000506101c05161014052600061014051186121cb57600080fd5b600254600380820282158284830414176121e457600080fd5b8090509050905060088082049050905061016052600354610180526101405161016051610180516101a05160065801613827565b6101c0526101a0526101805261016052610140526101c0516101a05260018060c052602060c020546101c05260018160c052602060c02001546101e05260028160c052602060c020015461020052506101c051610220526101e0516102405261020051610260526101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516101c0516102a0526101e0516102c052610200516102e0526101a05161030052610300516102e0516102c0516102a05160065801613ea6565b6103605261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261036051610280526102a060006003818352015b6102206102a0516003811061233c57600080fd5b60200201805160046102a0516003811061235557600080fd5b60200201358082101561236757600080fd5b808203905090508152505b8151600101808352811415612328575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a051610220516102c052610240516102e05261026051610300526101a0516103205261032051610300516102e0516102c05160065801613ea6565b610380526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610380516102a0526060366102c03761032060006003818352015b6102a0516101c0610320516003811061245457600080fd5b6020020151808202821582848304141761246d57600080fd5b8090509050905061028051808061248357600080fd5b8204905090506103405260006103605261022061032051600381106124a757600080fd5b60200201516103405111156124f0576103405161022061032051600381106124ce57600080fd5b6020020151808210156124e057600080fd5b8082039050905061036052612526565b610220610320516003811061250457600080fd5b6020020151610340518082101561251a57600080fd5b80820390509050610360525b6101605161036051808202821582848304141761254257600080fd5b809050905090506402540be400808204905090506102c0610320516003811061256a57600080fd5b6020020152610220610320516003811061258357600080fd5b60200201516102c0610320516003811061259c57600080fd5b60200201516101805180820282158284830414176125b957600080fd5b809050905090506402540be40080820490509050808210156125da57600080fd5b8082039050905061032051600381106125f257600080fd5b600160c052602060c0200155610220610320516003811061261257600080fd5b6020020180516102c0610320516003811061262c57600080fd5b60200201518082101561263e57600080fd5b808203905090508152505b815160010180835281141561243c575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516102205161034052610240516103605261026051610380526101a0516103a0526103a05161038051610360516103405160065801613ea6565b6104005261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610400516103205261028051610320518082101561273557600080fd5b8082039050905061014051808202821582848304141761275457600080fd5b8090509050905061028051808061276a57600080fd5b820490509050610340526000610340511861278457600080fd5b6103408051600181818301101561279a57600080fd5b8082019050905081525060643561034051111515156127f8576308c379a06103605260206103805260146103a0527f536c697070616765207363726577656420796f750000000000000000000000006103c0526103a050606461037cfd5b602061040060446379cc6790610360523361038052610340516103a05261037c60006006545af161282857600080fd5b601f3d1161283557600080fd5b6000506104005061036060006003818352015b60006004610360516003811061285d57600080fd5b602002013518156129d457600060046103e0527fa9059cbb00000000000000000000000000000000000000000000000000000000610400526103e060048060208461044001018260208501600060045af150508051820191505033602082610440010152602081019050600461036051600381106128da57600080fd5b6020020135602082610440010152602081019050806104405261044090508051602001806104e08284600060045af161291257600080fd5b505060206105a06104e0516105006000610360516003811061293357600080fd5b600060c052602060c02001545af161294a57600080fd5b60203d8082111561295b578061295d565b815b90509050610580526105808051602001806103808284600060045af161298257600080fd5b505060006103805111156129d4576103808060200151600082518060209013156129ab57600080fd5b80919012156129b957600080fd5b806020036101000a820490509050905015156129d457600080fd5b8151600101808352811415612848575b505060043561036052602435610380526044356103a0526102c0516103c0526102e0516103e05261030051610400526102a05161042052610140516103405180821015612a3057600080fd5b8082039050905061044052337f173599dbf9c6ca6f7c3b590df07ae98a45d74ff54065505141e7de6c46a624c2610100610360a26000601255005b63cc2b27d7811415612aeb5760243580806000811215612a8757195b607f1c15612a9457600080fd5b905050600435610140526024356101605261016051610140516006580161477e565b6101c0526101e0526101c080808080516102005250506020810190508080805161022052505050506102005160005260206000f35b631a4d01d2811415612e505760125415612b0457600080fd5b600160125560243580806000811215612b1957195b607f1c15612b2657600080fd5b90505060105415612b3657600080fd5b604036610140376101405161016051600435610180526024356101a0526101a051610180516006580161477e565b610200526102205261016052610140526102008080808051610240525050602081019050808080516102605250505050610240805161014052806020015161016052506044356101405110151515612bfb576308c379a06101805260206101a05260186101c0527f4e6f7420656e6f75676820636f696e732072656d6f76656400000000000000006101e0526101c050606461019cfd5b60243560038110612c0b57600080fd5b600160c052602060c02001805461014051610160516003548082028215828483041417612c3757600080fd5b809050905090506402540be40080820490509050818183011015612c5a57600080fd5b8082019050905080821015612c6e57600080fd5b80820390509050815550602061022060446379cc679061018052336101a0526004356101c05261019c60006006545af1612ca757600080fd5b601f3d11612cb457600080fd5b60005061022050600060046101e0527fa9059cbb00000000000000000000000000000000000000000000000000000000610200526101e060048060208461024001018260208501600060045af15050805182019150503360208261024001015260208101905061014051602082610240010152602081019050806102405261024090508051602001806102e08284600060045af1612d5157600080fd5b505060206103a06102e051610300600060243560038110612d7157600080fd5b600060c052602060c02001545af1612d8857600080fd5b60203d80821115612d995780612d9b565b815b90509050610380526103808051602001806101808284600060045af1612dc057600080fd5b50506000610180511115612e1257610180806020015160008251806020901315612de957600080fd5b8091901215612df757600080fd5b806020036101000a82049050905090501515612e1257600080fd5b6004356101e0526101405161020052337f9e96dd3b997a2a257eec4df9bb6eaf626e206df5f543bd963682d143300be31060406101e0a26000601255005b633c157e64811415612fe4576004543314612e6a57600080fd5b60095462015180818183011015612e8057600080fd5b80820190509050421015612e9357600080fd5b4262015180818183011015612ea757600080fd5b808201905090506024351015612ebc57600080fd5b6101405160065801613827565b6101605261014052610160516101405260006004351115612ef157620f424060043510612ef4565b60005b612efd57600080fd5b61014051600435101515612f365761014051600a8082028215828483041417612f2557600080fd5b809050905090506004351115612f39565b60005b15612f45576001612f80565b610140516004351015612f7d5761014051600435600a8082028215828483041417612f6f57600080fd5b809050905090501015612f80565b60005b612f8957600080fd5b6101405160075560043560085542600955602435600a55610140516101605260043561018052426101a0526024356101c0527fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c2546080610160a1005b63551a6588811415613067576004543314612ffe57600080fd5b6101405160065801613827565b6101605261014052610160516101405261014051600755610140516008554260095542600a55610140516101605242610180527f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc2019386040610160a1005b635b5a146781141561312357600454331461308157600080fd5b600b541561308e57600080fd5b64012a05f20060043511156130a257600080fd5b6402540be40060243511156130b657600080fd5b426203f4808181830110156130ca57600080fd5b808201905090506101405261014051600b55600435600d55602435600e556004356101605260243561018052610140517f351fc5da2fbf480f2225debf3664a4bc90fa9923743aad58b4603f648e931fe06040610160a2005b634f12fe978114156131b557600454331461313d57600080fd5b600b5442101561314c57600080fd5b6000600b541861315b57600080fd5b6000600b55600d5461014052600e546101605261014051600255610160516003556101405161018052610160516101a0527fbe12859b636aed607d5230b2cc2711f68d70e51060e6cca1f575ef5d2fcc95d16040610180a1005b63226840fb8114156131d65760045433146131cf57600080fd5b6000600b55005b636b441a408114156132685760043560a01c156131f257600080fd5b600454331461320057600080fd5b600c541561320d57600080fd5b426203f48081818301101561322157600080fd5b808201905090506101405261014051600c55600435600f55600435610140517f181aa3aa17d4cbf99265dd4443eba009433d3cde79d60164fde1d1a192beb93560006000a3005b636a1c05ae8114156132df57600454331461328257600080fd5b600c5442101561329157600080fd5b6000600c54186132a057600080fd5b6000600c55600f546101405261014051600455610140517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c60006000a2005b6386fbf1938114156133005760045433146132f957600080fd5b6000600c55005b63e2e7d2648114156133985760206101c060246370a0823161014052306101605261015c6004356003811061333457600080fd5b600060c052602060c02001545afa61334b57600080fd5b601f3d1161335857600080fd5b6000506101c0516004356003811061336f57600080fd5b600160c052602060c02001548082101561338857600080fd5b8082039050905060005260206000f35b6330c54085811415613635576005546101405261016060006003818352015b61016051600381106133c857600080fd5b600060c052602060c020015461018052602061024060246370a082316101c052306101e0526101dc610180515afa6133ff57600080fd5b601f3d1161340c57600080fd5b60005061024051610160516003811061342457600080fd5b600160c052602060c02001548082101561343d57600080fd5b808203905090506101a05260006101a05111156135e15760006004610220527fa9059cbb000000000000000000000000000000000000000000000000000000006102405261022060048060208461028001018260208501600060045af1505080518201915050610140516020826102800101526020810190506101a051602082610280010152602081019050806102805261028090508051602001806103208284600060045af16134ed57600080fd5b505060206103e0610320516103406000610180515af161350c57600080fd5b60203d8082111561351d578061351f565b815b905090506103c0526103c08051602001806101c08284600060045af161354457600080fd5b505060006101c0511115613596576101c080602001516000825180602090131561356d57600080fd5b809190121561357b57600080fd5b806020036101000a8204905090509050151561359657600080fd5b60006101605118156135e157610140513b6135b057600080fd5b600060006044632047fcf561022052610160516102405260006102605261023c6000610140515af16135e157600080fd5b81516001018083528114156133b7575b5050610140513b61360157600080fd5b600060006024635fb9cf2061016052600060c052602060c020546101805261017c6000610140515af161363357600080fd5b005b63e369885381141561366457600454331461364f57600080fd5b426011541161365d57600080fd5b6001601055005b633046f97281141561368557600454331461367e57600080fd5b6000601055005b63c66106578114156136b657600435600381106136a157600080fd5b600060c052602060c020015460005260206000f35b634903b0d18114156136e757600435600381106136d257600080fd5b600160c052602060c020015460005260206000f35b63ddca3f438114156136ff5760025460005260206000f35b63fee3f7f98114156137175760035460005260206000f35b638da5cb5b81141561372f5760045460005260206000f35b63d90097f78114156137475760055460005260206000f35b635409491a81141561375f5760075460005260206000f35b63b4b577ad8114156137775760085460005260206000f35b632081066c81141561378f5760095460005260206000f35b63140522888114156137a757600a5460005260206000f35b63405e28f88114156137bf57600b5460005260206000f35b63e0a0b5868114156137d757600c5460005260206000f35b6358680d0b8114156137ef57600d5460005260206000f35b63e382446281141561380757600e5460005260206000f35b631ec0cdc181141561381f57600f5460005260206000f35b505b60006000fd5b61014052600a546101605260085461018052610160514210156139ad576007546101a0526009546101c0526101a051610180511115613907576101a051610180516101a0518082101561387957600080fd5b80820390509050426101c0518082101561389257600080fd5b8082039050905080820282158284830414176138ad57600080fd5b80905090509050610160516101c051808210156138c957600080fd5b8082039050905080806138db57600080fd5b8204905090508181830110156138f057600080fd5b8082019050905060005260005161014051566139a8565b6101a0516101a051610180518082101561392057600080fd5b80820390509050426101c0518082101561393957600080fd5b80820390509050808202821582848304141761395457600080fd5b80905090509050610160516101c0518082101561397057600080fd5b80820390509050808061398257600080fd5b8204905090508082101561399557600080fd5b8082039050905060005260005161014051565b6139bd565b6101805160005260005161014051565b005b61014052670de0b6b3a764000061016052670de0b6b3a764000061018052670de0b6b3a76400006101a0526101c060006003818352015b6101606101c05160038110613a0a57600080fd5b60200201516101c05160038110613a2057600080fd5b600160c052602060c02001548082028215828483041417613a4057600080fd5b80905090509050670de0b6b3a7640000808204905090506101606101c05160038110613a6b57600080fd5b60200201525b81516001018083528114156139f6575b505060606101c0525b60006101c051111515613a9c57613ab8565b60206101c05103610160015160206101c051036101c052613a8a565b61014051565b6101a052610140526101605261018052670de0b6b3a76400006101c052670de0b6b3a76400006101e052670de0b6b3a76400006102005261022060006003818352015b6101c06102205160038110613b1557600080fd5b60200201516101406102205160038110613b2e57600080fd5b60200201518082028215828483041417613b4757600080fd5b80905090509050670de0b6b3a7640000808204905090506101c06102205160038110613b7257600080fd5b60200201525b8151600101808352811415613b01575b50506060610220525b600061022051111515613ba357613bbf565b602061022051036101c001516020610220510361022052613b91565b6101a051565b6101c0526101405261016052610180526101a05260006101e05261022060006003818352015b602061022051026101400151610200526101e0805161020051818183011015613c1357600080fd5b808201905090508152505b8151600101808352811415613beb575b50506101e0511515613c485760006000526000516101c051565b6000610200526101e051610220526101a05160038082028215828483041417613c7057600080fd5b8090509050905061024052610260600060ff818352015b61022051610280526102c060006003818352015b60206102c0510261014001516102a05261028051610220518082028215828483041417613cc757600080fd5b809050905090506102a05160038082028215828483041417613ce857600080fd5b809050905090508080613cfa57600080fd5b820490509050610280525b8151600101808352811415613c9b575b50506102205161020052610240516101e0518082028215828483041417613d3b57600080fd5b809050905090506102805160038082028215828483041417613d5c57600080fd5b80905090509050818183011015613d7257600080fd5b80820190509050610220518082028215828483041417613d9157600080fd5b8090509050905061024051600180821015613dab57600080fd5b80820390509050610220518082028215828483041417613dca57600080fd5b809050905090506004610280518082028215828483041417613deb57600080fd5b80905090509050818183011015613e0157600080fd5b808201905090508080613e1357600080fd5b8204905090506102205261020051610220511115613e5a576001610220516102005180821015613e4257600080fd5b80820390509050111515613e5557613e94565b613e84565b6001610200516102205180821015613e7157600080fd5b80820390509050111515613e8457613e94565b8151600101808352811415613c87575b5050610220516000526000516101c051565b6101c0526101405261016052610180526101a0526101405161016051610180516101a0516101c051610140516101e0526101605161020052610180516102205261022051610200516101e05160065801613abe565b610280526102a0526102c0526101c0526101a05261018052610160526101405261028080516102e052806020015161030052806040015161032052506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516102e05161034052610300516103605261032051610380526101a0516103a0526103a05161038051610360516103405160065801613bc5565b6104005261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610400516000526000516101c051565b610200526101405261016052610180526101a0526101c0526101e05261016051610140511861403257600080fd5b600061016051121561404357600080fd5b6003610160511261405357600080fd5b600061014051121561406457600080fd5b6003610140511261407457600080fd5b6101405161016051610180516101a0516101c0516101e051610200516102205160065801613827565b6102405261022052610200526101e0526101c0526101a05261018052610160526101405261024051610220526101405161016051610180516101a0516101c0516101e0516102005161022051610240516101a051610260526101c051610280526101e0516102a052610220516102c0526102c0516102a051610280516102605160065801613bc5565b610320526102405261022052610200526101e0526101c0526101a05261018052610160526101405261032051610240526102405161026052600061028052610220516003808202821582848304141761417e57600080fd5b809050905090506102a05260006102c0526102e060006003818352015b610140516102e05114156141b657610180516102c0526141eb565b610160516102e05118156141e6576101a06102e051600381106141d857600080fd5b60200201516102c0526141eb565b614267565b61028080516102c05181818301101561420357600080fd5b808201905090508152506102605161024051808202821582848304141761422957600080fd5b809050905090506102c0516003808202821582848304141761424a57600080fd5b80905090509050808061425c57600080fd5b820490509050610260525b815160010180835281141561419b575b50506102605161024051808202821582848304141761429557600080fd5b809050905090506102a051600380820282158284830414176142b657600080fd5b8090509050905080806142c857600080fd5b8204905090506102605261028051610240516102a05180806142e957600080fd5b8204905090508181830110156142fe57600080fd5b808201905090506102e0526000610300526102405161032052610340600060ff818352015b61032051610300526103205161032051808202821582848304141761434757600080fd5b809050905090506102605181818301101561436157600080fd5b80820190509050600261032051808202821582848304141761438257600080fd5b809050905090506102e05181818301101561439c57600080fd5b8082019050905061024051808210156143b457600080fd5b8082039050905080806143c657600080fd5b820490509050610320526103005161032051111561440d5760016103205161030051808210156143f557600080fd5b8082039050905011151561440857614447565b614437565b600161030051610320518082101561442457600080fd5b8082039050905011151561443757614447565b8151600101808352811415614323575b50506103205160005260005161020051565b610200526101405261016052610180526101a0526101c0526101e052600061016051121561448657600080fd5b6003610160511261449657600080fd5b6101e0516102205260006102405261014051600380820282158284830414176144be57600080fd5b80905090509050610260526000610280526102a060006003818352015b610160516102a051181561450b576101806102a051600381106144fd57600080fd5b602002015161028052614510565b61458c565b61024080516102805181818301101561452857600080fd5b80820190509050815250610220516101e051808202821582848304141761454e57600080fd5b80905090509050610280516003808202821582848304141761456f57600080fd5b80905090509050808061458157600080fd5b820490509050610220525b81516001018083528114156144db575b5050610220516101e05180820282158284830414176145ba57600080fd5b8090509050905061026051600380820282158284830414176145db57600080fd5b8090509050905080806145ed57600080fd5b82049050905061022052610240516101e05161026051808061460e57600080fd5b82049050905081818301101561462357600080fd5b808201905090506102a05260006102c0526101e0516102e052610300600060ff818352015b6102e0516102c0526102e0516102e051808202821582848304141761466c57600080fd5b809050905090506102205181818301101561468657600080fd5b8082019050905060026102e05180820282158284830414176146a757600080fd5b809050905090506102a0518181830110156146c157600080fd5b808201905090506101e051808210156146d957600080fd5b8082039050905080806146eb57600080fd5b8204905090506102e0526102c0516102e05111156147325760016102e0516102c0518082101561471a57600080fd5b8082039050905011151561472d5761476c565b61475c565b60016102c0516102e0518082101561474957600080fd5b8082039050905011151561475c5761476c565b8151600101808352811415614648575b50506102e05160005260005161020051565b6101805261014052610160526101405161016051610180516101a05160065801613827565b6101c0526101a0526101805261016052610140526101c0516101a052600254600380820282158284830414176147d857600080fd5b809050905090506008808204905090506101c05260016101e05260016102005260016102205260206102c060046318160ddd6102605261027c6006545afa61481f57600080fd5b601f3d1161482c57600080fd5b6000506102c051610240526101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a051600658016139bf565b6102c0526102e052610300526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526102c080516102605280602001516102805280604001516102a052506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c051610260516102e05261028051610300526102a051610320526101a051610340526103405161032051610300516102e05160065801613bc5565b6103a0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103a0516102c0526102c051610140516102c051808202821582848304141761499557600080fd5b809050905090506102405180806149ab57600080fd5b820490509050808210156149be57600080fd5b808203905090506102e052610260516103005261028051610320526102a05161034052610140610380525b61038051516020610380510161038052610380610380511015614a0b576149e9565b6101a0516103a052610160516103c052610260516103e05261028051610400526102a051610420526102e051610440526104405161042051610400516103e0516103c0516103a05160065801614459565b6104a052610360610380525b6103805152602061038051036103805261014061038051101515614a8b57614a68565b6104a051610360526102606101605160038110614aa757600080fd5b60200201516103605180821015614abd57600080fd5b808203905090506101e06101605160038110614ad857600080fd5b60200201518080614ae857600080fd5b820490509050610380526103a060006003818352015b60006103c052610160516103a0511415614b80576102606103a05160038110614b2657600080fd5b60200201516102e0518082028215828483041417614b4357600080fd5b809050905090506102c0518080614b5957600080fd5b8204905090506103605180821015614b7057600080fd5b808203905090506103c052614bff565b6102606103a05160038110614b9457600080fd5b60200201516102606103a05160038110614bad57600080fd5b60200201516102e0518082028215828483041417614bca57600080fd5b809050905090506102c0518080614be057600080fd5b82049050905080821015614bf357600080fd5b808203905090506103c0525b6103006103a05160038110614c1357600080fd5b6020020180516101c0516103c0518082028215828483041417614c3557600080fd5b809050905090506402540be4008082049050905080821015614c5657600080fd5b808203905090508152505b8151600101808352811415614afe575b50506103006101605160038110614c8757600080fd5b60200201516101406103c0525b6103c0515160206103c051016103c0526103c06103c0511015614cb657614c94565b6101a0516103e05261016051610400526103005161042052610320516104405261034051610460526102e0516104805261048051610460516104405161042051610400516103e05160065801614459565b6104e0526103a06103c0525b6103c0515260206103c051036103c0526101406103c051101515614d3657614d13565b6104e05180821015614d4757600080fd5b808203905090506103a0526103a051600180821015614d6557600080fd5b808203905090506101e06101605160038110614d8057600080fd5b60200201518080614d9057600080fd5b8204905090506103a0526104006103a0518152610380516103a05180821015614db857600080fd5b808203905090508160200152506040610440525b600061044051111515614dde57614dfa565b6020610440510361040001516020610440510361044052614dcc565b61018051565b610163614f6303610163600039610163614f63036000f3000000000000000000000000abc00210a691ce0f3d7d0602d7d84aea4d91cdfd000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d00000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000af4de8e872131ae328ce21d909c74705d3aaf45200000000000000000000000000000000000000000000000000000000000005dc00000000000000000000000000000000000000000000000000000000003d0900000000000000000000000000000000000000000000000000000000012a05f200000000000000000000000000604348a7e98113e14c318605c458fbfb3b0dd3f6

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

000000000000000000000000abc00210a691ce0f3d7d0602d7d84aea4d91cdfd000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d00000000000000000000000055d398326f99059ff775485246999027b3197955000000000000000000000000af4de8e872131ae328ce21d909c74705d3aaf45200000000000000000000000000000000000000000000000000000000000005dc00000000000000000000000000000000000000000000000000000000003d0900000000000000000000000000000000000000000000000000000000012a05f200000000000000000000000000604348a7e98113e14c318605c458fbfb3b0dd3f6

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000abc00210a691ce0f3d7d0602d7d84aea4d91cdfd
Arg [1] : 000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56
Arg [2] : 0000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d
Arg [3] : 00000000000000000000000055d398326f99059ff775485246999027b3197955
Arg [4] : 000000000000000000000000af4de8e872131ae328ce21d909c74705d3aaf452
Arg [5] : 00000000000000000000000000000000000000000000000000000000000005dc
Arg [6] : 00000000000000000000000000000000000000000000000000000000003d0900
Arg [7] : 000000000000000000000000000000000000000000000000000000012a05f200
Arg [8] : 000000000000000000000000604348a7e98113e14c318605c458fbfb3b0dd3f6


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.