Contract 0x6852E7399C6cC73256Ca46A4921e1c7b2682D912

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x42794fbdc3064a61d1245aa5c688f01de7b230b0d3b47930cfdf42ba91e1e3d7Add_liquidity239523132022-01-20 16:11:372 days 17 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.0678964941 500.9
0x4d7ba919ea4b0bf402c9518a85e1ff6554701411e693f73340e0e07fe66fc242Exchange239519062022-01-20 15:56:412 days 17 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.0645344533 500.9
0x7b8e18d913623d1464b0a7283d9df6da44205d5c93da2d29b1e3a08876c190fdAdd_liquidity239360492022-01-20 6:31:483 days 3 hrs ago0x79d56b980baf8483a9899142f9f870a23afb56b3 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.0643157865 388.5
0xe84e797f8a2bcbaad0a4d47f550adda04f95a5d97e7e8a9e1bf9b00421c41629Remove_liquidity...238244792022-01-17 11:28:455 days 22 hrs ago0x2eac34dce8a6090133fce494e3ebc6badd3b7d9c IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.07852515550
0x5e18f4ae761b884ad2850de7490b67fd0533a754fb2cbac64608175be5cc7eb5Remove_liquidity237951972022-01-16 17:39:266 days 16 hrs ago0x075472d645f33ecae2fd78e560e65c489065b450 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.036026094221
0x0f24b6e534e98d7960518820c22cec90da1d0413ccc79836635e92d0f2a76dadAdd_liquidity237951212022-01-16 17:36:436 days 16 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.01160277393
0x9b3bfad3e6d3a8e7002798f15ab5af0ec9a80ecd835738e36809fb60c1243379Add_liquidity237930552022-01-16 16:21:276 days 17 hrs ago0x79d56b980baf8483a9899142f9f870a23afb56b3 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.007874301664.8
0x4ee5eec70a64629fd3e244e527164dd47dd3ea80cdb91d75a69e9ce6baec9ef0Remove_liquidity237904902022-01-16 14:42:356 days 19 hrs ago0x272c39c82ca9f10e5338a6ee75927cfe00c82e2c IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.056072688344
0x70f6253eeefc74da3156525359f62c2ada2568bc0695006b5cdbd9b8e1bd5422Exchange237617802022-01-15 21:29:287 days 12 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.004657222841.7
0x1f7f7a36132bfed68e96874c80adf2ec64fd44d7a100cd6e7e4763fa9360102fExchange237615982022-01-15 21:23:127 days 12 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.004657222841.7
0x94cf8f069b8e07c75b04717b03d4d09ef45198bd16c92b909f2e93d37a300078Exchange237615052022-01-15 21:20:027 days 12 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.004657222841.7
0xef4f0e2305fc7c32c08d5a48fa83ddb1577cae9bf3c1dcc1e3ba9b2a4ba13f87Exchange237487902022-01-15 13:39:107 days 20 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.00520497648
0x17677ba3340168aca705865fd127ab19cd4e9604b987134323dc7ebbcd07ddefExchange237485642022-01-15 13:29:367 days 20 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.003849568840.7
0xc1002fbf1a568e0776ddf0a2e06ef3e3e9542f0bb3d719e917fbd93645bb632aExchange237484172022-01-15 13:24:347 days 20 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.0034452330
0xe08e1393a81030c22f0109492a1477a47468920de2f20f7707b0bf340e6a3c19Remove_liquidity...237398702022-01-15 7:42:428 days 2 hrs ago0xb0e53390e4697e65d6c2ed5213e49b8390da9853 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.035243108164
0x3271c26e48a5bf04333494bfa06fc953daf9ca5f5bd4ce34f4261883daf722ffAdd_liquidity237398212022-01-15 7:39:588 days 2 hrs ago0xb0e53390e4697e65d6c2ed5213e49b8390da9853 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.03450964220
0x6bd2dfe47aa907f649b00bcf52ee6ce34b3eefd204981b4204ab069295240bcbExchange237376902022-01-15 6:13:568 days 3 hrs ago0xb0e53390e4697e65d6c2ed5213e49b8390da9853 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.02855974220
0x1227927d3242bee0255e6c89d0401cf98404766671ce34d72bbd42a8396e8d14Exchange237376792022-01-15 6:13:348 days 3 hrs ago0xb0e53390e4697e65d6c2ed5213e49b8390da9853 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.02856062220
0x123e0b8b51e9640341263e17acb1a7a40d0387e48f21d74e574bf9da7cbf587dRemove_liquidity236484292022-01-12 22:38:2610 days 11 hrs ago0x272c39c82ca9f10e5338a6ee75927cfe00c82e2c IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.014736102101
0x1d0ed4360f2a2af5351d4c4da2a7ecabbfa088928ad7d414cd7d881fe59ed364Remove_liquidity236418172022-01-12 18:32:4810 days 15 hrs ago0x272c39c82ca9f10e5338a6ee75927cfe00c82e2c IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.02261481155
0x6686d37369e687ee935245f7509c59620146442212eddc855b69b8f8735fa5b2Exchange236339532022-01-12 13:24:5310 days 20 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.00349472331
0x4ca5805e2eaea49c3fdef354de0897a1d696d28e4eed3f04b9dcea396d5f4870Add_liquidity236057952022-01-11 19:45:2211 days 14 hrs ago0x19c32602c50395220d8a52e684648fc22855a28f IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.00978530469
0xeaec4a167078470035161340f96ed4803e12bf9fc2110b8c40c49f1eb365b3dfRemove_liquidity...235460562022-01-10 5:45:5313 days 4 hrs ago0x10feb6f3111197336bc64ad3d0a123f22719d58a IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.006314447146.7
0x7a19cf28c4b0e58e5f5ceff2e1220033f8ecef5b23357b1ae862578948701aaeExchange235311502022-01-09 20:44:4413 days 13 hrs ago0x3c3e1450cd9ea5cf4a19a963f463951cbed1c4a0 IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.00417156537
0xede0b6175872ec216fa3725041273cb6ef9283addc6dd6ff0d7a4e3addeab930Remove_liquidity234481852022-01-07 17:15:5415 days 16 hrs ago0xe9920c2bdd13dfead70e4b4721d34f710cbb8cdb IN  0x6852e7399c6cc73256ca46a4921e1c7b2682d9120 MATIC0.1165365036798.6
[ 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.8

Optimization Enabled:
N/A

Other Settings:
, None license

Contract Source Code (Vyper language format)

# @version ^0.2.8
# Pool for DAI/USDC/USDT

from vyper.interfaces import ERC20

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

interface Whitelist:
    def isWhitelisted(_addr: address) -> bool: 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, 1000000000000, 1000000000000]
RATES: constant(uint256[N_COINS]) = [1000000000000000000, 1000000000000000000000000000000, 1000000000000000000000000000000]
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)
token: LPToken

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

whitelist: Whitelist


@external
def __init__(
    _owner: address,
    _coins: address[N_COINS],
    _pool_token: address,
    _A: uint256,
    _fee: uint256,
    _admin_fee: uint256,
    _whitelist: 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.token = LPToken(_pool_token)
    self.whitelist = Whitelist(_whitelist)


@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
    assert self.whitelist.isWhitelisted(msg.sender)

    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():
    assert msg.sender == self.owner  # dev: only owner

    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(msg.sender, bytes32),
                    convert(value, bytes32),
                ),
                max_outsize=32,
            )  # dev: failed transfer
            if len(_response) > 0:
                assert convert(_response, bool)  # dev: failed transfer


@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
    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":"TokenExchange","inputs":[{"type":"address","name":"buyer","indexed":true},{"type":"int128","name":"sold_id","indexed":false},{"type":"uint256","name":"tokens_sold","indexed":false},{"type":"int128","name":"bought_id","indexed":false},{"type":"uint256","name":"tokens_bought","indexed":false}],"anonymous":false,"type":"event"},{"name":"AddLiquidity","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256[3]","name":"token_amounts","indexed":false},{"type":"uint256[3]","name":"fees","indexed":false},{"type":"uint256","name":"invariant","indexed":false},{"type":"uint256","name":"token_supply","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidity","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256[3]","name":"token_amounts","indexed":false},{"type":"uint256[3]","name":"fees","indexed":false},{"type":"uint256","name":"token_supply","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityOne","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256","name":"token_amount","indexed":false},{"type":"uint256","name":"coin_amount","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityImbalance","inputs":[{"type":"address","name":"provider","indexed":true},{"type":"uint256[3]","name":"token_amounts","indexed":false},{"type":"uint256[3]","name":"fees","indexed":false},{"type":"uint256","name":"invariant","indexed":false},{"type":"uint256","name":"token_supply","indexed":false}],"anonymous":false,"type":"event"},{"name":"CommitNewAdmin","inputs":[{"type":"uint256","name":"deadline","indexed":true},{"type":"address","name":"admin","indexed":true}],"anonymous":false,"type":"event"},{"name":"NewAdmin","inputs":[{"type":"address","name":"admin","indexed":true}],"anonymous":false,"type":"event"},{"name":"CommitNewFee","inputs":[{"type":"uint256","name":"deadline","indexed":true},{"type":"uint256","name":"fee","indexed":false},{"type":"uint256","name":"admin_fee","indexed":false}],"anonymous":false,"type":"event"},{"name":"NewFee","inputs":[{"type":"uint256","name":"fee","indexed":false},{"type":"uint256","name":"admin_fee","indexed":false}],"anonymous":false,"type":"event"},{"name":"RampA","inputs":[{"type":"uint256","name":"old_A","indexed":false},{"type":"uint256","name":"new_A","indexed":false},{"type":"uint256","name":"initial_time","indexed":false},{"type":"uint256","name":"future_time","indexed":false}],"anonymous":false,"type":"event"},{"name":"StopRampA","inputs":[{"type":"uint256","name":"A","indexed":false},{"type":"uint256","name":"t","indexed":false}],"anonymous":false,"type":"event"},{"outputs":[],"inputs":[{"type":"address","name":"_owner"},{"type":"address[3]","name":"_coins"},{"type":"address","name":"_pool_token"},{"type":"uint256","name":"_A"},{"type":"uint256","name":"_fee"},{"type":"uint256","name":"_admin_fee"},{"type":"address","name":"_whitelist"}],"stateMutability":"nonpayable","type":"constructor"},{"name":"A","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":5131},{"name":"get_virtual_price","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":1133080},{"name":"calc_token_amount","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256[3]","name":"amounts"},{"type":"bool","name":"deposit"}],"stateMutability":"view","type":"function","gas":4507414},{"name":"add_liquidity","outputs":[],"inputs":[{"type":"uint256[3]","name":"amounts"},{"type":"uint256","name":"min_mint_amount"}],"stateMutability":"nonpayable","type":"function","gas":6954446},{"name":"get_dy","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"int128","name":"i"},{"type":"int128","name":"j"},{"type":"uint256","name":"dx"}],"stateMutability":"view","type":"function","gas":2673213},{"name":"get_dy_underlying","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"int128","name":"i"},{"type":"int128","name":"j"},{"type":"uint256","name":"dx"}],"stateMutability":"view","type":"function","gas":2672915},{"name":"exchange","outputs":[],"inputs":[{"type":"int128","name":"i"},{"type":"int128","name":"j"},{"type":"uint256","name":"dx"},{"type":"uint256","name":"min_dy"}],"stateMutability":"nonpayable","type":"function","gas":2817255},{"name":"remove_liquidity","outputs":[],"inputs":[{"type":"uint256","name":"_amount"},{"type":"uint256[3]","name":"min_amounts"}],"stateMutability":"nonpayable","type":"function","gas":192572},{"name":"remove_liquidity_imbalance","outputs":[],"inputs":[{"type":"uint256[3]","name":"amounts"},{"type":"uint256","name":"max_burn_amount"}],"stateMutability":"nonpayable","type":"function","gas":6949525},{"name":"calc_withdraw_one_coin","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"_token_amount"},{"type":"int128","name":"i"}],"stateMutability":"view","type":"function","gas":1375},{"name":"remove_liquidity_one_coin","outputs":[],"inputs":[{"type":"uint256","name":"_token_amount"},{"type":"int128","name":"i"},{"type":"uint256","name":"min_amount"}],"stateMutability":"nonpayable","type":"function","gas":4024585},{"name":"ramp_A","outputs":[],"inputs":[{"type":"uint256","name":"_future_A"},{"type":"uint256","name":"_future_time"}],"stateMutability":"nonpayable","type":"function","gas":151817},{"name":"stop_ramp_A","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":148535},{"name":"commit_new_fee","outputs":[],"inputs":[{"type":"uint256","name":"new_fee"},{"type":"uint256","name":"new_admin_fee"}],"stateMutability":"nonpayable","type":"function","gas":110371},{"name":"apply_new_fee","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":97152},{"name":"revert_new_parameters","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":21805},{"name":"commit_transfer_ownership","outputs":[],"inputs":[{"type":"address","name":"_owner"}],"stateMutability":"nonpayable","type":"function","gas":74543},{"name":"apply_transfer_ownership","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":60620},{"name":"revert_transfer_ownership","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":21895},{"name":"admin_balances","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"i"}],"stateMutability":"view","type":"function","gas":3391},{"name":"withdraw_admin_fees","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":21397},{"name":"donate_admin_fees","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":111299},{"name":"kill_me","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":37015},{"name":"unkill_me","outputs":[],"inputs":[],"stateMutability":"nonpayable","type":"function","gas":22045},{"name":"coins","outputs":[{"type":"address","name":""}],"inputs":[{"type":"uint256","name":"arg0"}],"stateMutability":"view","type":"function","gas":2130},{"name":"balances","outputs":[{"type":"uint256","name":""}],"inputs":[{"type":"uint256","name":"arg0"}],"stateMutability":"view","type":"function","gas":2160},{"name":"fee","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2081},{"name":"admin_fee","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2111},{"name":"owner","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2141},{"name":"initial_A","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2171},{"name":"future_A","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2201},{"name":"initial_A_time","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2231},{"name":"future_A_time","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2261},{"name":"admin_actions_deadline","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2291},{"name":"transfer_ownership_deadline","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2321},{"name":"future_fee","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2351},{"name":"future_admin_fee","outputs":[{"type":"uint256","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2381},{"name":"future_owner","outputs":[{"type":"address","name":""}],"inputs":[],"stateMutability":"view","type":"function","gas":2411}]

6101206150e76101403960206150e760c03960c05160a01c1561002157600080fd5b602060206150e70160c03960c05160a01c1561003c57600080fd5b602060406150e70160c03960c05160a01c1561005757600080fd5b602060606150e70160c03960c05160a01c1561007257600080fd5b602060806150e70160c03960c05160a01c1561008d57600080fd5b60206101006150e70160c03960c05160a01c156100a957600080fd5b61026060006003818352015b600061016061026051600381106100cb57600080fd5b6020020151186100da57600080fd5b5b81516001018083528114156100b5575b5050600060c052602060c0206101605181556101805160018201556101a0516002820155506101e0516006556101e0516007556102005160025561022051600355610140516004556101c051600555610240516010556150cf56341561000a57600080fd5b600436101561001857614f83565b600035601c526000156101c1575b610140526009546101605260075461018052610160514210156101ae576006546101a0526008546101c0526101a051610180511115610107576101a051610180516101a0518082101561007857600080fd5b80820390509050426101c0518082101561009157600080fd5b8082039050905080820282158284830414176100ac57600080fd5b80905090509050610160516101c051808210156100c857600080fd5b8082039050905080806100da57600080fd5b8204905090508181830110156100ef57600080fd5b808201905090506000526000516101405156506101a9565b6101a0516101a051610180518082101561012057600080fd5b80820390509050426101c0518082101561013957600080fd5b80820390509050808202821582848304141761015457600080fd5b80905090509050610160516101c0518082101561017057600080fd5b80820390509050808061018257600080fd5b8204905090508082101561019557600080fd5b808203905090506000526000516101405156505b6101bf565b610180516000526000516101405156505b005b63f446c1d060005114156101eb5760065801610026565b610140526101405160005260206000f350005b6000156102fd575b61014052670de0b6b3a7640000610160526c0c9f2c9cd04674edea40000000610180526c0c9f2c9cd04674edea400000006101a0526101c060006003818352015b6101606101c0516003811061024857600080fd5b60200201516101c0516003811061025e57600080fd5b600160c052602060c0200154808202821582848304141761027e57600080fd5b80905090509050670de0b6b3a7640000808204905090506101606101c051600381106102a957600080fd5b60200201525b8151600101808352811415610234575b505060606101c0525b60006101c0511115156102da576102f6565b60206101c05103610160015160206101c051036101c0526102c8565b6101405156005b600015610417575b6101a052610140526101605261018052670de0b6b3a76400006101c0526c0c9f2c9cd04674edea400000006101e0526c0c9f2c9cd04674edea400000006102005261022060006003818352015b6101c0610220516003811061036657600080fd5b6020020151610140610220516003811061037f57600080fd5b6020020151808202821582848304141761039857600080fd5b80905090509050670de0b6b3a7640000808204905090506101c061022051600381106103c357600080fd5b60200201525b8151600101808352811415610352575b50506060610220525b6000610220511115156103f457610410565b602061022051036101c0015160206102205103610220526103e2565b6101a05156005b600015610705575b6101c0526101405261016052610180526101a05260006101e05261022060006003818352015b602061022051026101400151610200526101e080516102005181818301101561046d57600080fd5b808201905090508152505b8151600101808352811415610445575b50506101e05115156104a35760006000526000516101c05156505b6000610200526101e051610220526101a051600380820282158284830414176104cb57600080fd5b8090509050905061024052610260600060ff818352015b61022051610280526102c060006003818352015b60206102c0510261014001516102a0526102805161022051808202821582848304141761052257600080fd5b809050905090506102a0516003808202821582848304141761054357600080fd5b80905090509050808061055557600080fd5b820490509050610280525b81516001018083528114156104f6575b50506102205161020052610240516101e051808202821582848304141761059657600080fd5b8090509050905061028051600380820282158284830414176105b757600080fd5b809050905090508181830110156105cd57600080fd5b808201905090506102205180820282158284830414176105ec57600080fd5b809050905090506102405160018082101561060657600080fd5b8082039050905061022051808202821582848304141761062557600080fd5b80905090509050600461028051808202821582848304141761064657600080fd5b8090509050905081818301101561065c57600080fd5b80820190509050808061066e57600080fd5b82049050905061022052610200516102205111156106b557600161022051610200518082101561069d57600080fd5b808203905090501115156106b0576106f1565b6106e0565b60016102005161022051808210156106cc57600080fd5b808203905090501115156106df576106f1565b5b5b81516001018083528114156104e2575b5050610220516000526000516101c0515650005b60001561086d575b6101c0526101405261016052610180526101a0526101405161016051610180516101a0516101c051610140516101e0526101605161020052610180516102205261022051610200516101e05160065801610305565b610280526102a0526102c0526101c0526101a05261018052610160526101405261028080516102e052806020015161030052806040015161032052506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516102e05161034052610300516103605261032051610380526101a0516103a0526103a0516103805161036051610340516006580161041f565b6104005261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610400516000526000516101c0515650005b63bb7b8b806000511415610a0f5761014051600658016101f3565b61016052610180526101a0526101405261016080516101c05280602001516101e052806040015161020052506101405161016051610180516101a0516101c0516101e0516102005160065801610026565b61022052610200526101e0526101c0526101a05261018052610160526101405261022051610240526101405161016051610180516101a0516101c0516101e0516102005161022051610240516101c051610260526101e05161028052610200516102a052610240516102c0526102c0516102a05161028051610260516006580161041f565b610320526102405261022052610200526101e0526101c0526101a052610180526101605261014052610320516101405260206101e060046318160ddd6101805261019c6005545afa6109af57600080fd5b601f3d116109bc57600080fd5b6000506101e0516101605261014051670de0b6b3a764000080820282158284830414176109e857600080fd5b809050905090506101605180806109fe57600080fd5b82049050905060005260206000f350005b633883e1196000511415610d085760643560011c15610a2d57600080fd5b60018060c052602060c020546101405260018160c052602060c02001546101605260028160c052602060c020015461018052506101405161016051610180516101a05160065801610026565b6101c0526101a0526101805261016052610140526101c0516101a0526101405161016051610180516101a0516101c051610140516101e052610160516102005261018051610220526101a051610240526102405161022051610200516101e0516006580161070d565b6102a0526101c0526101a0526101805261016052610140526102a0516101c0526101e060006003818352015b60643515610b66576101406101e05160038110610b2a57600080fd5b60200201805160046101e05160038110610b4357600080fd5b6020020135818183011015610b5757600080fd5b80820190509050815250610bb0565b6101406101e05160038110610b7a57600080fd5b60200201805160046101e05160038110610b9357600080fd5b602002013580821015610ba557600080fd5b808203905090508152505b5b8151600101808352811415610b0e575b50506101405161016051610180516101a0516101c0516101e0516101405161020052610160516102205261018051610240526101a05161026052610260516102405161022051610200516006580161070d565b6102c0526101e0526101c0526101a0526101805261016052610140526102c0516101e052602061028060046318160ddd6102205261023c6005545afa610c5957600080fd5b601f3d11610c6657600080fd5b600050610280516102005260006102205260643515610ca4576101e0516101c05180821015610c9457600080fd5b8082039050905061022052610cc5565b6101c0516101e05180821015610cb957600080fd5b80820390509050610220525b61022051610200518082028215828483041417610ce157600080fd5b809050905090506101c0518080610cf757600080fd5b82049050905060005260206000f350005b634515cef360005114156117a55762ffffff5415610d2557600080fd5b600162ffffff55600f5415610d3957600080fd5b60206101c06024633af32abf61014052336101605261015c60006010545af1610d6157600080fd5b601f3d11610d6e57600080fd5b6000506101c051610d7e57600080fd5b6060366101403760025460038082028215828483041417610d9e57600080fd5b809050905090506008808204905090506101a0526003546101c0526101405161016051610180516101a0516101c0516101e05160065801610026565b610200526101e0526101c0526101a052610180526101605261014052610200516101e052602061028060046318160ddd6102205261023c6005545afa610e1f57600080fd5b601f3d11610e2c57600080fd5b600050610280516102005260006102205260018060c052602060c020546102405260018160c052602060c02001546102605260028160c052602060c020015461028052506000610200511115610f1a576101405161016051610180516101a0516101c0516101e0516102005161022051610240516102605161028051610240516102a052610260516102c052610280516102e0526101e05161030052610300516102e0516102c0516102a0516006580161070d565b6103605261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261036051610220525b610240516102a052610260516102c052610280516102e05261030060006003818352015b60046103005160038110610f5157600080fd5b602002013561032052610200511515610f755760006103205111610f7457600080fd5b5b6103005160038110610f8657600080fd5b600060c052602060c02001546103405260006103205111156111b7576002610300511415610fee5760206103e060246370a0823161036052306103805261037c610340515afa610fd557600080fd5b601f3d11610fe257600080fd5b6000506103e051610320525b600060046103c0527f23b872dd000000000000000000000000000000000000000000000000000000006103e0526103c060048060208461042001018260208501600060045af150508051820191505033602082610420010152602081019050306020826104200101526020810190506004610300516003811061107057600080fd5b6020020135602082610420010152602081019050806104205261042090508051602001806104e08284600060045af16110a857600080fd5b505060206105c06104e0516105006000610340515af16110c757600080fd5b60203d808211156110d857806110da565b815b905090506105a0526105a08051602001806103608284600060045af16110ff57600080fd5b505060006103605111156111525761036080602001516000825180602090131561112857600080fd5b809190121561113657600080fd5b806020036101000a8204905090509050151561115157600080fd5b5b60026103005114156111b657602061044060246370a082316103c052306103e0526103dc610340515afa61118557600080fd5b601f3d1161119257600080fd5b6000506104405161032051808210156111aa57600080fd5b80820390509050610320525b5b61024061030051600381106111cb57600080fd5b6020020151610320518181830110156111e357600080fd5b808201905090506102a061030051600381106111fe57600080fd5b60200201525b8151600101808352811415610f3e575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516102a051610320526102c051610340526102e051610360526101e05161038052610380516103605161034051610320516006580161070d565b6103e052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103e051610300526102205161030051116112e557600080fd5b610300516103205260006102005111156115ee5761034060006003818352015b61030051610240610340516003811061131d57600080fd5b6020020151808202821582848304141761133657600080fd5b8090509050905061022051808061134c57600080fd5b820490509050610360526000610380526102a0610340516003811061137057600080fd5b60200201516103605111156113b957610360516102a0610340516003811061139757600080fd5b6020020151808210156113a957600080fd5b80820390509050610380526113ef565b6102a061034051600381106113cd57600080fd5b602002015161036051808210156113e357600080fd5b80820390509050610380525b6101a05161038051808202821582848304141761140b57600080fd5b809050905090506402540be40080820490509050610140610340516003811061143357600080fd5b60200201526102a0610340516003811061144c57600080fd5b6020020151610140610340516003811061146557600080fd5b60200201516101c051808202821582848304141761148257600080fd5b809050905090506402540be40080820490509050808210156114a357600080fd5b8082039050905061034051600381106114bb57600080fd5b600160c052602060c02001556102a061034051600381106114db57600080fd5b60200201805161014061034051600381106114f557600080fd5b60200201518082101561150757600080fd5b808203905090508152505b8151600101808352811415611305575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516102a051610340526102c051610360526102e051610380526101e0516103a0526103a0516103805161036051610340516006580161070d565b6104005261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526104005161032052611612565b600160c052602060c0206102a05181556102c05160018201556102e0516002820155505b60006103405261020051151561162f576103005161034052611684565b6102005161032051610220518082101561164857600080fd5b80820390509050808202821582848304141761166357600080fd5b8090509050905061022051808061167957600080fd5b820490509050610340525b60643561034051101515156116d8576308c379a06103605260206103805260146103a0527f536c697070616765207363726577656420796f750000000000000000000000006103c0526103a050606461037cfd5b602061040060446340c10f19610360523361038052610340516103a05261037c60006005545af161170857600080fd5b601f3d1161171557600080fd5b6000506104005060043561036052602435610380526044356103a052610140516103c052610160516103e05261018051610400526103005161042052610200516103405181818301101561176857600080fd5b8082019050905061044052337f423f6495a08fc652425cf4ed0d1f9e37e571d9b9529b1c1c23cce780b2e7df0d610100610360a2600062ffffff55005b600015611c07575b610200526101405261016052610180526101a0526101c0526101e0526101605161014051186117db57600080fd5b60006101605112156117ec57600080fd5b600361016051126117fc57600080fd5b600061014051121561180d57600080fd5b6003610140511261181d57600080fd5b6101405161016051610180516101a0516101c0516101e051610200516102205160065801610026565b6102405261022052610200526101e0526101c0526101a05261018052610160526101405261024051610220526101405161016051610180516101a0516101c0516101e0516102005161022051610240516101a051610260526101c051610280526101e0516102a052610220516102c0526102c0516102a05161028051610260516006580161041f565b610320526102405261022052610200526101e0526101c0526101a05261018052610160526101405261032051610240526102405161026052600061028052610220516003808202821582848304141761192757600080fd5b809050905090506102a05260006102c0526102e060006003818352015b610140516102e051141561195f57610180516102c052611995565b610160516102e051181561198f576101a06102e0516003811061198157600080fd5b60200201516102c052611994565b611a11565b5b61028080516102c0518181830110156119ad57600080fd5b80820190509050815250610260516102405180820282158284830414176119d357600080fd5b809050905090506102c051600380820282158284830414176119f457600080fd5b809050905090508080611a0657600080fd5b820490509050610260525b8151600101808352811415611944575b505061026051610240518082028215828483041417611a3f57600080fd5b809050905090506102a05160038082028215828483041417611a6057600080fd5b809050905090508080611a7257600080fd5b8204905090506102605261028051610240516102a0518080611a9357600080fd5b820490509050818183011015611aa857600080fd5b808201905090506102e0526000610300526102405161032052610340600060ff818352015b610320516103005261032051610320518082028215828483041417611af157600080fd5b8090509050905061026051818183011015611b0b57600080fd5b808201905090506002610320518082028215828483041417611b2c57600080fd5b809050905090506102e051818183011015611b4657600080fd5b808201905090506102405180821015611b5e57600080fd5b808203905090508080611b7057600080fd5b8204905090506103205261030051610320511115611bb7576001610320516103005180821015611b9f57600080fd5b80820390509050111515611bb257611bf3565b611be2565b6001610300516103205180821015611bce57600080fd5b80820390509050111515611be157611bf3565b5b5b8151600101808352811415611acd575b505061032051600052600051610200515650005b635e0d443f6000511415611eeb5760043580806000811215611c2557195b607f1c15611c3257600080fd5b90505060243580806000811215611c4557195b607f1c15611c5257600080fd5b905050670de0b6b3a7640000610140526c0c9f2c9cd04674edea40000000610160526c0c9f2c9cd04674edea40000000610180526101405161016051610180516101a0516101c0516101e051600658016101f3565b6102005261022052610240526101e0526101c0526101a05261018052610160526101405261020080516101a05280602001516101c05280604001516101e052506101a060043560038110611cfa57600080fd5b602002015160443561014060043560038110611d1557600080fd5b60200201518082028215828483041417611d2e57600080fd5b80905090509050670de0b6b3a764000080820490509050818183011015611d5457600080fd5b80820190509050610200526101405161016051610180516101a0516101c0516101e0516102005161022051600435610240526024356102605261020051610280526101a0516102a0526101c0516102c0526101e0516102e0526102e0516102c0516102a051610280516102605161024051600658016117ad565b6103405261022052610200526101e0526101c0526101a05261018052610160526101405261034051610220526101a060243560038110611e0d57600080fd5b60200201516102205180821015611e2357600080fd5b80820390509050600180821015611e3957600080fd5b80820390509050670de0b6b3a76400008082028215828483041417611e5d57600080fd5b8090509050905061014060243560038110611e7757600080fd5b60200201518080611e8757600080fd5b82049050905061024052600254610240518082028215828483041417611eac57600080fd5b809050905090506402540be4008082049050905061026052610240516102605180821015611ed957600080fd5b8082039050905060005260206000f350005b6307211ef7600051141561216c5760043580806000811215611f0957195b607f1c15611f1657600080fd5b90505060243580806000811215611f2957195b607f1c15611f3657600080fd5b905050610140516101605161018051600658016101f3565b6101a0526101c0526101e0526101805261016052610140526101a08051610140528060200151610160528060400151610180525060016101a05264e8d4a510006101c05264e8d4a510006101e05261014060043560038110611faf57600080fd5b60200201516044356101a060043560038110611fca57600080fd5b60200201518082028215828483041417611fe357600080fd5b80905090509050818183011015611ff957600080fd5b80820190509050610200526101405161016051610180516101a0516101c0516101e051610200516102205160043561024052602435610260526102005161028052610140516102a052610160516102c052610180516102e0526102e0516102c0516102a051610280516102605161024051600658016117ad565b6103405261022052610200526101e0526101c0526101a0526101805261016052610140526103405161022052610140602435600381106120b257600080fd5b602002015161022051808210156120c857600080fd5b808203905090506001808210156120de57600080fd5b808203905090506101a0602435600381106120f857600080fd5b6020020151808061210857600080fd5b8204905090506102405260025461024051808202821582848304141761212d57600080fd5b809050905090506402540be400808204905090506102605261024051610260518082101561215a57600080fd5b8082039050905060005260206000f350005b633df021246000511415612a995762ffffff541561218957600080fd5b600162ffffff55600435808060008112156121a057195b607f1c156121ad57600080fd5b905050602435808060008112156121c057195b607f1c156121cd57600080fd5b905050600f54156121dd57600080fd5b670de0b6b3a7640000610140526c0c9f2c9cd04674edea40000000610160526c0c9f2c9cd04674edea400000006101805260018060c052602060c020546101a05260018160c052602060c02001546101c05260028160c052602060c02001546101e052506101405161016051610180516101a0516101c0516101e0516102005161022051610240516101a051610260526101c051610280526101e0516102a0526102a051610280516102605160065801610305565b6103005261032052610340526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103008051610200528060200151610220528060400151610240525060443561026052600435600381106122f557600080fd5b600060c052602060c0200154610280526002600435141561235057602061032060246370a082316102a052306102c0526102bc610280515afa61233757600080fd5b601f3d1161234457600080fd5b60005061032051610260525b60006004610300527f23b872dd000000000000000000000000000000000000000000000000000000006103205261030060048060208461036001018260208501600060045af15050805182019150503360208261036001015260208101905030602082610360010152602081019050604435602082610360010152602081019050806103605261036090508051602001806104208284600060045af16123f557600080fd5b50506020610500610420516104406000610280515af161241457600080fd5b60203d808211156124255780612427565b815b905090506104e0526104e08051602001806102a08284600060045af161244c57600080fd5b505060006102a051111561249f576102a080602001516000825180602090131561247557600080fd5b809190121561248357600080fd5b806020036101000a8204905090509050151561249e57600080fd5b5b6002600435141561250257602061038060246370a0823161030052306103205261031c610280515afa6124d157600080fd5b601f3d116124de57600080fd5b6000506103805161026051808210156124f657600080fd5b80820390509050610260525b6102006004356003811061251557600080fd5b6020020151610260516101406004356003811061253157600080fd5b6020020151808202821582848304141761254a57600080fd5b80905090509050670de0b6b3a76400008082049050905081818301101561257057600080fd5b80820190509050610300526101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516103205160043561034052602435610360526103005161038052610200516103a052610220516103c052610240516103e0526103e0516103c0516103a051610380516103605161034051600658016117ad565b6104405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261044051610320526102006024356003811061266957600080fd5b6020020151610320518082101561267f57600080fd5b8082039050905060018082101561269557600080fd5b80820390509050610340526103405160025480820282158284830414176126bb57600080fd5b809050905090506402540be40080820490509050610360526103405161036051808210156126e857600080fd5b80820390509050670de0b6b3a7640000808202821582848304141761270c57600080fd5b809050905090506101406024356003811061272657600080fd5b6020020151808061273657600080fd5b8204905090506103405260643561034051101515156127b9576308c379a06103805260206103a052602e6103c0527f45786368616e676520726573756c74656420696e20666577657220636f696e736103e0527f207468616e206578706563746564000000000000000000000000000000000000610400526103c050608461039cfd5b6103605160035480820282158284830414176127d457600080fd5b809050905090506402540be400808204905090506103805261038051670de0b6b3a7640000808202821582848304141761280d57600080fd5b809050905090506101406024356003811061282757600080fd5b6020020151808061283757600080fd5b820490509050610380526101a06004356003811061285457600080fd5b60200201516102605181818301101561286c57600080fd5b808201905090506004356003811061288357600080fd5b600160c052602060c02001556101a0602435600381106128a257600080fd5b602002015161034051808210156128b857600080fd5b8082039050905061038051808210156128d057600080fd5b80820390509050602435600381106128e757600080fd5b600160c052602060c0200155600060046103a0527fa9059cbb000000000000000000000000000000000000000000000000000000006103c0526103a060048060208461040001018260208501600060045af15050805182019150503360208261040001015260208101905061034051602082610400010152602081019050806104005261040090508051602001806104a08284600060045af161298957600080fd5b505060206105606104a0516104c06000602435600381106129a957600080fd5b600060c052602060c02001545af16129c057600080fd5b60203d808211156129d157806129d3565b815b90509050610540526105408051602001806102a08284600060045af16129f857600080fd5b505060006102a0511115612a4b576102a0806020015160008251806020901315612a2157600080fd5b8091901215612a2f57600080fd5b806020036101000a82049050905090501515612a4a57600080fd5b5b6004356103a0526044356103c0526024356103e0526103405161040052337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd9714060806103a0a2600062ffffff55005b63ecb586a56000511415612e705762ffffff5415612ab657600080fd5b600162ffffff5560206101c060046318160ddd6101605261017c6005545afa612ade57600080fd5b601f3d11612aeb57600080fd5b6000506101c0516101405260c0366101603761022060006003818352015b6102205160038110612b1a57600080fd5b600160c052602060c02001546004358082028215828483041417612b3d57600080fd5b80905090509050610140518080612b5357600080fd5b8204905090506102405260246102205160038110612b7057600080fd5b60200201356102405110151515612beb576308c379a06102605260206102805260306102a0527f5769746864726177616c20726573756c74656420696e20666577657220636f696102c0527f6e73207468616e206578706563746564000000000000000000000000000000006102e0526102a050608461027cfd5b6102205160038110612bfc57600080fd5b600160c052602060c0200180546102405180821015612c1a57600080fd5b80820390509050815550610240516101606102205160038110612c3c57600080fd5b6020020152600060046102c0527fa9059cbb000000000000000000000000000000000000000000000000000000006102e0526102c060048060208461032001018260208501600060045af15050805182019150503360208261032001015260208101905061024051602082610320010152602081019050806103205261032090508051602001806103c08284600060045af1612cd757600080fd5b505060206104806103c0516103e060006102205160038110612cf857600080fd5b600060c052602060c02001545af1612d0f57600080fd5b60203d80821115612d205780612d22565b815b90509050610460526104608051602001806102608284600060045af1612d4757600080fd5b50506000610260511115612d9a57610260806020015160008251806020901315612d7057600080fd5b8091901215612d7e57600080fd5b806020036101000a82049050905090501515612d9957600080fd5b5b5b8151600101808352811415612b09575b505060206102c060446379cc67906102205233610240526004356102605261023c60006005545af1612ddc57600080fd5b601f3d11612de957600080fd5b6000506102c050610160516102205261018051610240526101a051610260526101c051610280526101e0516102a052610200516102c0526101405160043580821015612e3457600080fd5b808203905090506102e052337fa49d4cf02656aebf8c771f5a8585638a2a15ee6c97cf7205d4208ed7c1df252d60e0610220a2600062ffffff55005b639fdaea0c600051141561378f5762ffffff5415612e8d57600080fd5b600162ffffff55600f5415612ea157600080fd5b60206101c060046318160ddd6101605261017c6005545afa612ec257600080fd5b601f3d11612ecf57600080fd5b6000506101c0516101405260006101405118612eea57600080fd5b60025460038082028215828483041417612f0357600080fd5b8090509050905060088082049050905061016052600354610180526101405161016051610180516101a05160065801610026565b6101c0526101a0526101805261016052610140526101c0516101a05260018060c052602060c020546101c05260018160c052602060c02001546101e05260028160c052602060c020015461020052506101c051610220526101e0516102405261020051610260526101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516101c0516102a0526101e0516102c052610200516102e0526101a05161030052610300516102e0516102c0516102a0516006580161070d565b6103605261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261036051610280526102a060006003818352015b6102206102a0516003811061305b57600080fd5b60200201805160046102a0516003811061307457600080fd5b60200201358082101561308657600080fd5b808203905090508152505b8151600101808352811415613047575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a051610220516102c052610240516102e05261026051610300526101a0516103205261032051610300516102e0516102c0516006580161070d565b610380526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610380516102a0526060366102c03761032060006003818352015b6102a0516101c0610320516003811061317357600080fd5b6020020151808202821582848304141761318c57600080fd5b809050905090506102805180806131a257600080fd5b8204905090506103405260006103605261022061032051600381106131c657600080fd5b602002015161034051111561320f576103405161022061032051600381106131ed57600080fd5b6020020151808210156131ff57600080fd5b8082039050905061036052613245565b610220610320516003811061322357600080fd5b6020020151610340518082101561323957600080fd5b80820390509050610360525b6101605161036051808202821582848304141761326157600080fd5b809050905090506402540be400808204905090506102c0610320516003811061328957600080fd5b602002015261022061032051600381106132a257600080fd5b60200201516102c061032051600381106132bb57600080fd5b60200201516101805180820282158284830414176132d857600080fd5b809050905090506402540be40080820490509050808210156132f957600080fd5b80820390509050610320516003811061331157600080fd5b600160c052602060c0200155610220610320516003811061333157600080fd5b6020020180516102c0610320516003811061334b57600080fd5b60200201518082101561335d57600080fd5b808203905090508152505b815160010180835281141561315b575b50506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516102205161034052610240516103605261026051610380526101a0516103a0526103a0516103805161036051610340516006580161070d565b6104005261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610400516103205261028051610320518082101561345457600080fd5b8082039050905061014051808202821582848304141761347357600080fd5b8090509050905061028051808061348957600080fd5b82049050905061034052600061034051186134a357600080fd5b610340805160018181830110156134b957600080fd5b808201905090508152506064356103405111151515613517576308c379a06103605260206103805260146103a0527f536c697070616765207363726577656420796f750000000000000000000000006103c0526103a050606461037cfd5b602061040060446379cc6790610360523361038052610340516103a05261037c60006005545af161354757600080fd5b601f3d1161355457600080fd5b6000506104005061036060006003818352015b60006004610360516003811061357c57600080fd5b602002013518156136f557600060046103e0527fa9059cbb00000000000000000000000000000000000000000000000000000000610400526103e060048060208461044001018260208501600060045af150508051820191505033602082610440010152602081019050600461036051600381106135f957600080fd5b6020020135602082610440010152602081019050806104405261044090508051602001806104e08284600060045af161363157600080fd5b505060206105a06104e0516105006000610360516003811061365257600080fd5b600060c052602060c02001545af161366957600080fd5b60203d8082111561367a578061367c565b815b90509050610580526105808051602001806103808284600060045af16136a157600080fd5b505060006103805111156136f4576103808060200151600082518060209013156136ca57600080fd5b80919012156136d857600080fd5b806020036101000a820490509050905015156136f357600080fd5b5b5b5b8151600101808352811415613567575b505060043561036052602435610380526044356103a0526102c0516103c0526102e0516103e05261030051610400526102a0516104205261014051610340518082101561375257600080fd5b8082039050905061044052337f173599dbf9c6ca6f7c3b590df07ae98a45d74ff54065505141e7de6c46a624c2610100610360a2600062ffffff55005b600015613ac0575b610200526101405261016052610180526101a0526101c0526101e05260006101605112156137c457600080fd5b600361016051126137d457600080fd5b6101e0516102205260006102405261014051600380820282158284830414176137fc57600080fd5b80905090509050610260526000610280526102a060006003818352015b610160516102a0511815613849576101806102a0516003811061383b57600080fd5b60200201516102805261384e565b6138ca565b61024080516102805181818301101561386657600080fd5b80820190509050815250610220516101e051808202821582848304141761388c57600080fd5b8090509050905061028051600380820282158284830414176138ad57600080fd5b8090509050905080806138bf57600080fd5b820490509050610220525b8151600101808352811415613819575b5050610220516101e05180820282158284830414176138f857600080fd5b80905090509050610260516003808202821582848304141761391957600080fd5b80905090509050808061392b57600080fd5b82049050905061022052610240516101e05161026051808061394c57600080fd5b82049050905081818301101561396157600080fd5b808201905090506102a05260006102c0526101e0516102e052610300600060ff818352015b6102e0516102c0526102e0516102e05180820282158284830414176139aa57600080fd5b80905090509050610220518181830110156139c457600080fd5b8082019050905060026102e05180820282158284830414176139e557600080fd5b809050905090506102a0518181830110156139ff57600080fd5b808201905090506101e05180821015613a1757600080fd5b808203905090508080613a2957600080fd5b8204905090506102e0526102c0516102e0511115613a705760016102e0516102c05180821015613a5857600080fd5b80820390509050111515613a6b57613aac565b613a9b565b60016102c0516102e05180821015613a8757600080fd5b80820390509050111515613a9a57613aac565b5b5b8151600101808352811415613986575b50506102e051600052600051610200515650005b600015614169575b6101805261014052610160526101405161016051610180516101a05160065801610026565b6101c0526101a0526101805261016052610140526101c0516101a05260025460038082028215828483041417613b2257600080fd5b809050905090506008808204905090506101c05260016101e05264e8d4a510006102005264e8d4a510006102205260206102c060046318160ddd6102605261027c6005545afa613b7157600080fd5b601f3d11613b7e57600080fd5b6000506102c051610240526101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a051600658016101f3565b6102c0526102e052610300526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526102c080516102605280602001516102805280604001516102a052506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c051610260516102e05261028051610300526102a051610320526101a051610340526103405161032051610300516102e0516006580161041f565b6103a0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103a0516102c0526102c051610140516102c0518082028215828483041417613ce757600080fd5b80905090509050610240518080613cfd57600080fd5b82049050905080821015613d1057600080fd5b808203905090506102e052610260516103005261028051610320526102a05161034052610140610380525b61038051516020610380510161038052610380610380511015613d5d57613d3b565b6101a0516103a052610160516103c052610260516103e05261028051610400526102a051610420526102e051610440526104405161042051610400516103e0516103c0516103a05160065801613797565b6104a052610360610380525b6103805152602061038051036103805261014061038051101515613ddd57613dba565b6104a051610360526102606101605160038110613df957600080fd5b60200201516103605180821015613e0f57600080fd5b808203905090506101e06101605160038110613e2a57600080fd5b60200201518080613e3a57600080fd5b820490509050610380526103a060006003818352015b60006103c052610160516103a0511415613ed2576102606103a05160038110613e7857600080fd5b60200201516102e0518082028215828483041417613e9557600080fd5b809050905090506102c0518080613eab57600080fd5b8204905090506103605180821015613ec257600080fd5b808203905090506103c052613f51565b6102606103a05160038110613ee657600080fd5b60200201516102606103a05160038110613eff57600080fd5b60200201516102e0518082028215828483041417613f1c57600080fd5b809050905090506102c0518080613f3257600080fd5b82049050905080821015613f4557600080fd5b808203905090506103c0525b6103006103a05160038110613f6557600080fd5b6020020180516101c0516103c0518082028215828483041417613f8757600080fd5b809050905090506402540be4008082049050905080821015613fa857600080fd5b808203905090508152505b8151600101808352811415613e50575b50506103006101605160038110613fd957600080fd5b60200201516101406103c0525b6103c0515160206103c051016103c0526103c06103c051101561400857613fe6565b6101a0516103e05261016051610400526103005161042052610320516104405261034051610460526102e0516104805261048051610460516104405161042051610400516103e05160065801613797565b6104e0526103a06103c0525b6103c0515260206103c051036103c0526101406103c05110151561408857614065565b6104e0518082101561409957600080fd5b808203905090506103a0526103a0516001808210156140b757600080fd5b808203905090506101e061016051600381106140d257600080fd5b602002015180806140e257600080fd5b8204905090506103a0526103c08080806103a051815250506020810190508080610380516103a0518082101561411757600080fd5b808203905090508152505060409050905060c05260c051610400525b60006104005111151561414557614161565b602061040051036103c001516020610400510361040052614133565b610180515650005b63cc2b27d760005114156141ed576024358080600081121561418757195b607f1c1561419457600080fd5b9050506004356101405260243561016052610160516101405160065801613ac8565b6101c0526101e0526101c080808080516102005250506020810190508080805161022052505050506102005160005260206000f350005b631a4d01d2600051141561455b5762ffffff541561420a57600080fd5b600162ffffff556024358080600081121561422157195b607f1c1561422e57600080fd5b905050600f541561423e57600080fd5b604036610140376101405161016051600435610180526024356101a0526101a0516101805160065801613ac8565b610200526102205261016052610140526102008080808051610240525050602081019050808080516102605250505050610240805161014052806020015161016052506044356101405110151515614303576308c379a06101805260206101a05260186101c0527f4e6f7420656e6f75676820636f696e732072656d6f76656400000000000000006101e0526101c050606461019cfd5b6024356003811061431357600080fd5b600160c052602060c0200180546101405161016051600354808202821582848304141761433f57600080fd5b809050905090506402540be4008082049050905081818301101561436257600080fd5b808201905090508082101561437657600080fd5b80820390509050815550602061022060446379cc679061018052336101a0526004356101c05261019c60006005545af16143af57600080fd5b601f3d116143bc57600080fd5b60005061022050600060046101e0527fa9059cbb00000000000000000000000000000000000000000000000000000000610200526101e060048060208461024001018260208501600060045af15050805182019150503360208261024001015260208101905061014051602082610240010152602081019050806102405261024090508051602001806102e08284600060045af161445957600080fd5b505060206103a06102e05161030060006024356003811061447957600080fd5b600060c052602060c02001545af161449057600080fd5b60203d808211156144a157806144a3565b815b90509050610380526103808051602001806101808284600060045af16144c857600080fd5b5050600061018051111561451b576101808060200151600082518060209013156144f157600080fd5b80919012156144ff57600080fd5b806020036101000a8204905090509050151561451a57600080fd5b5b6004356101e0526101405161020052337f9e96dd3b997a2a257eec4df9bb6eaf626e206df5f543bd963682d143300be31060406101e0a2600062ffffff55005b633c157e6460005114156146f357600454331461457757600080fd5b6008546201518081818301101561458d57600080fd5b808201905090504210156145a057600080fd5b42620151808181830110156145b457600080fd5b8082019050905060243510156145c957600080fd5b6101405160065801610026565b61016052610140526101605161014052600060043511156145fe57620f424060043510614601565b60005b61460a57600080fd5b610140516004351015156146435761014051600a808202821582848304141761463257600080fd5b809050905090506004351115614646565b60005b1561465257600161468e565b61014051600435101561468a5761014051600435600a808202821582848304141761467c57600080fd5b80905090509050101561468d565b60005b5b5b61469857600080fd5b6101405160065560043560075542600855602435600955610140516101605260043561018052426101a0526024356101c0527fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c2546080610160a1005b63551a6588600051141561477857600454331461470f57600080fd5b6101405160065801610026565b6101605261014052610160516101405261014051600655610140516007554260085542600955610140516101605242610180527f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc2019386040610160a1005b635b5a1467600051141561483657600454331461479457600080fd5b600a54156147a157600080fd5b64012a05f20060043511156147b557600080fd5b6402540be40060243511156147c957600080fd5b426203f4808181830110156147dd57600080fd5b808201905090506101405261014051600a55600435600c55602435600d556004356101605260243561018052610140517f351fc5da2fbf480f2225debf3664a4bc90fa9923743aad58b4603f648e931fe06040610160a2005b634f12fe9760005114156148ca57600454331461485257600080fd5b600a5442101561486157600080fd5b6000600a541861487057600080fd5b6000600a55600c5461014052600d546101605261014051600255610160516003556101405161018052610160516101a0527fbe12859b636aed607d5230b2cc2711f68d70e51060e6cca1f575ef5d2fcc95d16040610180a1005b63226840fb60005114156148ed5760045433146148e657600080fd5b6000600a55005b636b441a4060005114156149815760043560a01c1561490b57600080fd5b600454331461491957600080fd5b600b541561492657600080fd5b426203f48081818301101561493a57600080fd5b808201905090506101405261014051600b55600435600e55600435610140517f181aa3aa17d4cbf99265dd4443eba009433d3cde79d60164fde1d1a192beb93560006000a3005b636a1c05ae60005114156149fa57600454331461499d57600080fd5b600b544210156149ac57600080fd5b6000600b54186149bb57600080fd5b6000600b55600e546101405261014051600455610140517f71614071b88dee5e0b2ae578a9dd7b2ebbe9ae832ba419dc0242cd065a290b6c60006000a2005b6386fbf1936000511415614a1d576004543314614a1657600080fd5b6000600b55005b63e2e7d2646000511415614ab95760206101c060246370a0823161014052306101605261015c60043560038110614a5357600080fd5b600060c052602060c02001545afa614a6a57600080fd5b601f3d11614a7757600080fd5b6000506101c05160043560038110614a8e57600080fd5b600160c052602060c020015480821015614aa757600080fd5b8082039050905060005260206000f350005b6330c540856000511415614cd4576004543314614ad557600080fd5b61014060006003818352015b6101405160038110614af257600080fd5b600060c052602060c020015461016052602061022060246370a082316101a052306101c0526101bc610160515afa614b2957600080fd5b601f3d11614b3657600080fd5b600050610220516101405160038110614b4e57600080fd5b600160c052602060c020015480821015614b6757600080fd5b80820390509050610180526000610180511115614cbf5760006004610200527fa9059cbb000000000000000000000000000000000000000000000000000000006102205261020060048060208461026001018260208501600060045af15050805182019150503360208261026001015260208101905061018051602082610260010152602081019050806102605261026090508051602001806103008284600060045af1614c1457600080fd5b505060206103c0610300516103206000610160515af1614c3357600080fd5b60203d80821115614c445780614c46565b815b905090506103a0526103a08051602001806101a08284600060045af1614c6b57600080fd5b505060006101a0511115614cbe576101a0806020015160008251806020901315614c9457600080fd5b8091901215614ca257600080fd5b806020036101000a82049050905090501515614cbd57600080fd5b5b5b5b8151600101808352811415614ae1575b5050005b63524c39016000511415614d82576004543314614cf057600080fd5b61014060006003818352015b60206101e060246370a0823161016052306101805261017c6101405160038110614d2557600080fd5b600060c052602060c02001545afa614d3c57600080fd5b601f3d11614d4957600080fd5b6000506101e0516101405160038110614d6157600080fd5b600160c052602060c02001555b8151600101808352811415614cfc575b5050005b63e36988536000511415614da5576004543314614d9e57600080fd5b6001600f55005b633046f9726000511415614dc8576004543314614dc157600080fd5b6000600f55005b63c66106576000511415614dfd5760043560038110614de657600080fd5b600060c052602060c020015460005260206000f350005b634903b0d16000511415614e325760043560038110614e1b57600080fd5b600160c052602060c020015460005260206000f350005b63ddca3f436000511415614e4e5760025460005260206000f350005b63fee3f7f96000511415614e6a5760035460005260206000f350005b638da5cb5b6000511415614e865760045460005260206000f350005b635409491a6000511415614ea25760065460005260206000f350005b63b4b577ad6000511415614ebe5760075460005260206000f350005b632081066c6000511415614eda5760085460005260206000f350005b63140522886000511415614ef65760095460005260206000f350005b63405e28f86000511415614f1257600a5460005260206000f350005b63e0a0b5866000511415614f2e57600b5460005260206000f350005b6358680d0b6000511415614f4a57600c5460005260206000f350005b63e38244626000511415614f6657600d5460005260206000f350005b631ec0cdc16000511415614f8257600e5460005260206000f350005b5b60006000fd5b6101466150cf036101466000396101466150cf036000f3000000000000000000000000f9589b4da15ffe6825df987e9651f7a4db8a296e0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0630000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f000000000000000000000000a16946c3c8196aac0bed8dd291cef2379663c258000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000003d0900000000000000000000000000000000000000000000000000000000012a05f200000000000000000000000000c4e6cfd5b251074786f167eeca0dbd6357ef39db

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

000000000000000000000000f9589b4da15ffe6825df987e9651f7a4db8a296e0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0630000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f000000000000000000000000a16946c3c8196aac0bed8dd291cef2379663c258000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000003d0900000000000000000000000000000000000000000000000000000000012a05f200000000000000000000000000c4e6cfd5b251074786f167eeca0dbd6357ef39db

-----Decoded View---------------
Arg [0] : _owner (address): 0xf9589b4da15ffe6825df987e9651f7a4db8a296e
Arg [1] : _coins (address[3]): 0x8f3cf7ad23cd3cadbd9735aff958023239c6a063,0x2791bca1f2de4661ed88a30c99a7a9449aa84174,0xc2132d05d31c914a87c6611c10748aeb04b58e8f
Arg [2] : _pool_token (address): 0xa16946c3c8196aac0bed8dd291cef2379663c258
Arg [3] : _A (uint256): 10
Arg [4] : _fee (uint256): 4000000
Arg [5] : _admin_fee (uint256): 5000000000
Arg [6] : _whitelist (address): 0xc4e6cfd5b251074786f167eeca0dbd6357ef39db

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000f9589b4da15ffe6825df987e9651f7a4db8a296e
Arg [1] : 0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063
Arg [2] : 0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [3] : 000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f
Arg [4] : 000000000000000000000000a16946c3c8196aac0bed8dd291cef2379663c258
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [6] : 00000000000000000000000000000000000000000000000000000000003d0900
Arg [7] : 000000000000000000000000000000000000000000000000000000012a05f200
Arg [8] : 000000000000000000000000c4e6cfd5b251074786f167eeca0dbd6357ef39db


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.