Contract 0x8DEb66a4A40E370355bEe35f12E55Fe9c755d686

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x78989c4d057035ff728f24c70c07bf4592a5687ab49547cf929e310ae5c9aece0x617a6960190700462022-07-31 22:06:0864 days 11 hrs ago0x745748bcfd8f9c2de519a71d789be8a63dd7d66c IN  Create: Vyper_contract0 ETH0.007184623532 ETH
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xe39ff5c514f639c417f5d3495562fe2325344efc8b61514fe9aadc9576d81c47278042242022-10-01 15:10:092 days 18 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x60a8758382c00eba8b5932f8665988424a9be7936e8167a4f11430b0c4ea7f4a272154792022-09-28 12:58:455 days 21 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x60a8758382c00eba8b5932f8665988424a9be7936e8167a4f11430b0c4ea7f4a272154792022-09-28 12:58:455 days 21 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x33895bc63492f826580da99a1cd9c0451ee662f1672e329811aeb6675ff982a5266520452022-09-25 19:47:138 days 14 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x3b44398334159d016ee90d304b67c2ef5876a03cd4bc0f2a4e73880bc34fd7f1266434332022-09-25 18:33:368 days 15 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x325d9874d5f06c460997a5a1004dbe968a68d7cfcc9704589a7120ec6a75362e266432452022-09-25 18:31:318 days 15 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xd2a747360483c57f1bb3d61b32a8d745c3111dcf03636104bbfaeefd88190a17264415502022-09-24 18:38:509 days 15 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xaeccdcb8355d1ac6860535cd8892f00fdf5f8bebbd1367ffe7ad4953c1b7b487264399622022-09-24 18:24:109 days 15 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x5b2b89991028dada8a563740043fe329620eaab151ed180c6aa61ac232a5a553264395732022-09-24 18:20:549 days 15 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x2d9de294dd614855350f3a3fc78dd13058dc3af79c5f41e0b587e83def2543c1263370762022-09-24 7:09:3110 days 2 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x1280076789688fa521853bcfb3b87be11c045545837d8baf2dd231540b33d241263370442022-09-24 7:09:2010 days 2 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xa0a987a1aed70c76e91c5a6b483418cec45f6149365adc5d80d0f958d3ad30ad256856832022-09-21 11:25:1412 days 22 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xa0a987a1aed70c76e91c5a6b483418cec45f6149365adc5d80d0f958d3ad30ad256856832022-09-21 11:25:1412 days 22 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xe9a0bb83f9633491a8d91e5921153893d632d206ddc40d3129a28108d594ff37254627712022-09-20 11:44:5613 days 22 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x09b787d2f6a692c4fd815a8eac70c58ee9ad6d280f6430606bd1d78ea8ab8ec9245895612022-09-14 11:13:5019 days 22 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x7411d0bb1d24949f578ffd4ed6223580db4b275e4811bff293229bf9febfcfcd242138992022-09-12 8:17:1322 days 1 hr ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x0de3474e098baeda0c13fcf6695d6cd04052e398f586c649ac211456b9db89e6237834422022-09-09 14:30:3524 days 19 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x32db7b91499446385438dd05e1ed04c62ceee6afb92a55a1897d88418ff8a3af237833792022-09-09 14:30:0824 days 19 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x82283b070599584f4b86b449f6783e5f5e04b00c651961ae3125dc3688949a02233720592022-09-07 12:50:0126 days 21 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x09a31c153e9f43a9c2ebd600403daa062c6001de3723fbf8206b7a9359824b5b233706892022-09-07 12:41:1426 days 21 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xdd5d1eb7b7f69f85ff8153dd1a7f6ef1f2e9700dc2c3388ee12bb2fe7bf8e5bf226524202022-09-03 13:39:1130 days 20 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x568f97d3206a938fdd5a83bc6619d3e2e0efbd48375929a657b0a4743f4066c7224962992022-09-02 13:41:0131 days 20 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0xd80d54aafdd1cf28d14ac398c9cb171edf95179c0986d56b5adcacc6b2cefecd221872532022-08-31 12:28:2233 days 21 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x42bfefbc35879b8ffb178d32e02454a32dc1d0eb11f3ba59278eca726aefe74a211540122022-08-24 13:18:0340 days 20 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
0x9efb9854b51142efed2818e921ad973f2a9b6d8c4c50f7b00bc2567d663e9ace205127042022-08-17 14:13:4647 days 19 hrs ago 0x4b043cdd981dbd9a0c229d23b80cc1eb3c50b05b 0x8deb66a4a40e370355bee35f12e55fe9c755d6860 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Vyper_contract

Compiler Version
vyper:0.3.1

Optimization Enabled:
N/A

Other Settings:
, None license

Contract Source Code (Vyper language format)

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

interface ERC20:
    def approve(_spender: address, _amount: uint256): nonpayable
    def balanceOf(_owner: address) -> uint256: view

interface Curve:
    def coins(i: uint256) -> address: view
    def get_virtual_price() -> uint256: view
    def calc_token_amount(amounts: uint256[BASE_N_COINS], deposit: bool) -> uint256: view
    def calc_withdraw_one_coin(_token_amount: uint256, i: int128) -> uint256: view
    def fee() -> uint256: view
    def get_dy(i: int128, j: int128, dx: uint256) -> uint256: view
    def exchange(i: int128, j: int128, dx: uint256, min_dy: uint256): nonpayable
    def add_liquidity(amounts: uint256[BASE_N_COINS], min_mint_amount: uint256): nonpayable
    def remove_liquidity_one_coin(_token_amount: uint256, i: int128, min_amount: uint256): nonpayable

interface Factory:
    def convert_metapool_fees() -> bool: nonpayable
    def get_fee_receiver(_pool: address) -> address: view
    def admin() -> address: view

interface ERC1271:
    def isValidSignature(_hash: bytes32, _signature: Bytes[65]) -> bytes32: view


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

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

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

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

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

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

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

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

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

event StopRampA:
    A: uint256
    t: uint256


BASE_POOL: constant(address) = 0xC9B8a3FDECB9D5b218d02555a8Baf332E5B740d5
BASE_N_COINS: constant(int128) = 2
BASE_COINS: constant(address[BASE_N_COINS]) = [0x17FC002b466eEc40DaE837Fc4bE5c67993ddBd6F, 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8]

BASE_LP_TOKEN: constant(address) = 0xC9B8a3FDECB9D5b218d02555a8Baf332E5B740d5

N_COINS: constant(int128) = 2
MAX_COIN: constant(int128) = N_COINS - 1
PRECISION: constant(uint256) = 10 ** 18

FEE_DENOMINATOR: constant(uint256) = 10 ** 10
ADMIN_FEE: constant(uint256) = 5000000000

A_PRECISION: constant(uint256) = 100
MAX_A: constant(uint256) = 10 ** 6
MAX_A_CHANGE: constant(uint256) = 10
MIN_RAMP_TIME: constant(uint256) = 86400

EIP712_TYPEHASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
PERMIT_TYPEHASH: constant(bytes32) = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")

# keccak256("isValidSignature(bytes32,bytes)")[:4] << 224
ERC1271_MAGIC_VAL: constant(bytes32) = 0x1626ba7e00000000000000000000000000000000000000000000000000000000
VERSION: constant(String[8]) = "v5.0.0"


factory: address

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

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

rate_multiplier: uint256

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

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

DOMAIN_SEPARATOR: public(bytes32)
nonces: public(HashMap[address, uint256])


@external
def __init__():
    # we do this to prevent the implementation contract from being used as a pool
    self.fee = 31337


@external
def initialize(
    _name: String[32],
    _symbol: String[10],
    _coin: address,
    _rate_multiplier: uint256,
    _A: uint256,
    _fee: uint256
):
    """
    @notice Contract initializer
    @param _name Name of the new pool
    @param _symbol Token symbol
    @param _coin Addresses of ERC20 conracts of coins
    @param _rate_multiplier Rate multiplier for `_coin` (10 ** (36 - decimals))
    @param _A Amplification coefficient multiplied by n ** (n - 1)
    @param _fee Fee to charge for exchanges
    """
    # check if fee was already set to prevent initializing contract twice
    assert self.fee == 0

    A: uint256 = _A * A_PRECISION
    self.coins = [_coin, BASE_LP_TOKEN]
    self.rate_multiplier = _rate_multiplier
    self.initial_A = A
    self.future_A = A
    self.fee = _fee
    self.factory = msg.sender

    name: String[64] = concat("Curve.fi Factory USD Metapool: ", _name)
    self.name = name
    self.symbol = concat(_symbol, "3CRV-f")

    for coin in BASE_COINS:
        ERC20(coin).approve(BASE_POOL, MAX_UINT256)

    self.DOMAIN_SEPARATOR = keccak256(
        _abi_encode(EIP712_TYPEHASH, keccak256(name), keccak256(VERSION), chain.id, self)
    )

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


### ERC20 Functionality ###

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


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

    log Transfer(_from, _to, _value)


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


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

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

    return True


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

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


@external
def permit(
    _owner: address,
    _spender: address,
    _value: uint256,
    _deadline: uint256,
    _v: uint8,
    _r: bytes32,
    _s: bytes32
) -> bool:
    """
    @notice Approves spender by owner's signature to expend owner's tokens.
        See https://eips.ethereum.org/EIPS/eip-2612.
    @dev Inspired by https://github.com/yearn/yearn-vaults/blob/main/contracts/Vault.vy#L753-L793
    @dev Supports smart contract wallets which implement ERC1271
        https://eips.ethereum.org/EIPS/eip-1271
    @param _owner The address which is a source of funds and has signed the Permit.
    @param _spender The address which is allowed to spend the funds.
    @param _value The amount of tokens to be spent.
    @param _deadline The timestamp after which the Permit is no longer valid.
    @param _v The bytes[64] of the valid secp256k1 signature of permit by owner
    @param _r The bytes[0:32] of the valid secp256k1 signature of permit by owner
    @param _s The bytes[32:64] of the valid secp256k1 signature of permit by owner
    @return True, if transaction completes successfully
    """
    assert _owner != ZERO_ADDRESS
    assert block.timestamp <= _deadline

    nonce: uint256 = self.nonces[_owner]
    digest: bytes32 = keccak256(
        concat(
            b"\x19\x01",
            self.DOMAIN_SEPARATOR,
            keccak256(_abi_encode(PERMIT_TYPEHASH, _owner, _spender, _value, nonce, _deadline))
        )
    )

    if _owner.is_contract:
        sig: Bytes[65] = concat(_abi_encode(_r, _s), slice(convert(_v, bytes32), 31, 1))
        # reentrancy not a concern since this is a staticcall
        assert ERC1271(_owner).isValidSignature(digest, sig) == ERC1271_MAGIC_VAL
    else:
        assert ecrecover(digest, convert(_v, uint256), convert(_r, uint256), convert(_s, uint256)) == _owner

    self.allowance[_owner][_spender] = _value
    self.nonces[_owner] = nonce + 1

    log Approval(_owner, _spender, _value)
    return True


### StableSwap Functionality ###

@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 admin_fee() -> uint256:
    return ADMIN_FEE


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


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


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


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

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

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

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


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


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


@view
@external
def calc_token_amount(_amounts: uint256[N_COINS], _is_deposit: bool) -> uint256:
    """
    @notice Calculate addition or reduction in token supply from a deposit or withdrawal
    @dev This calculation accounts for slippage, but not fees.
         Needed to prevent front-running, not for precise calculations!
    @param _amounts Amount of each coin being deposited
    @param _is_deposit set True for deposits, False for withdrawals
    @return Expected amount of LP tokens received
    """
    amp: uint256 = self._A()
    rates: uint256[N_COINS] = [self.rate_multiplier, Curve(BASE_POOL).get_virtual_price()]
    balances: uint256[N_COINS] = self.balances

    D0: uint256 = self.get_D_mem(rates, balances, amp)
    for i in range(N_COINS):
        amount: uint256 = _amounts[i]
        if _is_deposit:
            balances[i] += amount
        else:
            balances[i] -= amount
    D1: uint256 = self.get_D_mem(rates, balances, amp)
    diff: uint256 = 0
    if _is_deposit:
        diff = D1 - D0
    else:
        diff = D0 - D1
    return diff * self.totalSupply / D0


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

    # Initial invariant
    old_balances: uint256[N_COINS] = self.balances
    D0: uint256 = self.get_D_mem(rates, old_balances, amp)
    new_balances: uint256[N_COINS] = old_balances

    total_supply: uint256 = self.totalSupply
    for i in range(N_COINS):
        amount: uint256 = _amounts[i]
        if amount == 0:
            assert total_supply > 0
        else:
            response: Bytes[32] = raw_call(
                self.coins[i],
                _abi_encode(
                    msg.sender,
                    self,
                    amount,
                    method_id=method_id("transferFrom(address,address,uint256)")
                ),
                max_outsize=32,
            )
            if len(response) > 0:
                assert convert(response, bool)
            new_balances[i] += amount

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

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

    assert mint_amount >= _min_mint_amount

    # Mint pool tokens
    total_supply += mint_amount
    self.balanceOf[_receiver] += mint_amount
    self.totalSupply = total_supply
    log Transfer(ZERO_ADDRESS, _receiver, mint_amount)
    log AddLiquidity(msg.sender, _amounts, fees, D1, total_supply)

    return mint_amount


@view
@internal
def get_y(i: int128, j: int128, x: uint256, xp: uint256[N_COINS]) -> uint256:
    # x in the input is converted to the same price/precision

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

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

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

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

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

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


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

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


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

    x: uint256 = 0
    base_i: int128 = 0
    base_j: int128 = 0
    meta_i: int128 = 0
    meta_j: int128 = 0

    if i != 0:
        base_i = i - MAX_COIN
        meta_i = 1
    if j != 0:
        base_j = j - MAX_COIN
        meta_j = 1

    if i == 0:
        x = xp[i] + dx * (rates[0] / 10**18)
    else:
        if j == 0:
            # i is from BasePool
            # At first, get the amount of pool tokens
            base_inputs: uint256[BASE_N_COINS] = empty(uint256[BASE_N_COINS])
            base_inputs[base_i] = dx
            # Token amount transformed to underlying "dollars"
            x = Curve(BASE_POOL).calc_token_amount(base_inputs, True) * rates[1] / PRECISION
            # Accounting for deposit/withdraw fees approximately
            x -= x * Curve(BASE_POOL).fee() / (2 * FEE_DENOMINATOR)
            # Adding number of pool tokens
            x += xp[MAX_COIN]
        else:
            # If both are from the base pool
            return Curve(BASE_POOL).get_dy(base_i, base_j, dx)

    # This pool is involved only when in-pool assets are used
    y: uint256 = self.get_y(meta_i, meta_j, x, xp)
    dy: uint256 = xp[meta_j] - y - 1
    dy = (dy - self.fee * dy / FEE_DENOMINATOR)

    # If output is going via the metapool
    if j == 0:
        dy /= (rates[0] / 10**18)
    else:
        # j is from BasePool
        # The fee is already accounted for
        dy = Curve(BASE_POOL).calc_withdraw_one_coin(dy * PRECISION / rates[1], base_j)

    return dy


@external
@nonreentrant('lock')
def exchange(
    i: int128,
    j: int128,
    _dx: uint256,
    _min_dy: uint256,
    _receiver: address = msg.sender,
) -> uint256:
    """
    @notice Perform an exchange between two coins
    @dev Index values can be found via the `coins` public getter method
    @param i Index value for the coin to send
    @param j Index valie of the coin to recieve
    @param _dx Amount of `i` being exchanged
    @param _min_dy Minimum amount of `j` to receive
    @param _receiver Address that receives `j`
    @return Actual amount of `j` received
    """
    rates: uint256[N_COINS] = [self.rate_multiplier, Curve(BASE_POOL).get_virtual_price()]

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

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

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

    # Convert all to real units
    dy = (dy - dy_fee) * PRECISION / rates[j]
    assert dy >= _min_dy

    dy_admin_fee: uint256 = dy_fee * ADMIN_FEE / FEE_DENOMINATOR
    dy_admin_fee = dy_admin_fee * PRECISION / rates[j]

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

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

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

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

    return dy


@external
@nonreentrant('lock')
def exchange_underlying(
    i: int128,
    j: int128,
    _dx: uint256,
    _min_dy: uint256,
    _receiver: address = msg.sender,
) -> uint256:
    """
    @notice Perform an exchange between two underlying coins
    @param i Index value for the underlying coin to send
    @param j Index valie of the underlying coin to receive
    @param _dx Amount of `i` being exchanged
    @param _min_dy Minimum amount of `j` to receive
    @param _receiver Address that receives `j`
    @return Actual amount of `j` received
    """
    rates: uint256[N_COINS] = [self.rate_multiplier, Curve(BASE_POOL).get_virtual_price()]
    old_balances: uint256[N_COINS] = self.balances
    xp: uint256[N_COINS] = self._xp_mem(rates, old_balances)

    base_coins: address[BASE_N_COINS] = BASE_COINS

    dy: uint256 = 0
    base_i: int128 = 0
    base_j: int128 = 0
    meta_i: int128 = 0
    meta_j: int128 = 0
    x: uint256 = 0
    input_coin: address = ZERO_ADDRESS
    output_coin: address = ZERO_ADDRESS

    if i == 0:
        input_coin = self.coins[0]
    else:
        base_i = i - MAX_COIN
        meta_i = 1
        input_coin = base_coins[base_i]
    if j == 0:
        output_coin = self.coins[0]
    else:
        base_j = j - MAX_COIN
        meta_j = 1
        output_coin = base_coins[base_j]

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

    dx: uint256 = _dx
    if i == 0 or j == 0:
        if i == 0:
            x = xp[i] + dx * rates[i] / PRECISION
        else:
            # i is from BasePool
            # At first, get the amount of pool tokens
            base_inputs: uint256[BASE_N_COINS] = empty(uint256[BASE_N_COINS])
            base_inputs[base_i] = dx
            coin_i: address = self.coins[MAX_COIN]
            # Deposit and measure delta
            x = ERC20(coin_i).balanceOf(self)
            Curve(BASE_POOL).add_liquidity(base_inputs, 0)
            # Need to convert pool token to "virtual" units using rates
            # dx is also different now
            dx = ERC20(coin_i).balanceOf(self) - x
            x = dx * rates[MAX_COIN] / PRECISION
            # Adding number of pool tokens
            x += xp[MAX_COIN]

        y: uint256 = self.get_y(meta_i, meta_j, x, xp)

        # Either a real coin or token
        dy = xp[meta_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
        # Works for both pool coins and real coins
        dy = (dy - dy_fee) * PRECISION / rates[meta_j]

        dy_admin_fee: uint256 = dy_fee * ADMIN_FEE / FEE_DENOMINATOR
        dy_admin_fee = dy_admin_fee * PRECISION / rates[meta_j]

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

        # Withdraw from the base pool if needed
        if j > 0:
            out_amount: uint256 = ERC20(output_coin).balanceOf(self)
            Curve(BASE_POOL).remove_liquidity_one_coin(dy, base_j, 0)
            dy = ERC20(output_coin).balanceOf(self) - out_amount

        assert dy >= _min_dy

    else:
        # If both are from the base pool
        dy = ERC20(output_coin).balanceOf(self)
        Curve(BASE_POOL).exchange(base_i, base_j, dx, _min_dy)
        dy = ERC20(output_coin).balanceOf(self) - dy

    response = raw_call(
        output_coin,
        _abi_encode(_receiver, dy, method_id=method_id("transfer(address,uint256)")),
        max_outsize=32,
    )
    if len(response) > 0:
        assert convert(response, bool)

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

    return dy


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

    for i in range(N_COINS):
        old_balance: uint256 = self.balances[i]
        value: uint256 = old_balance * _burn_amount / total_supply
        assert value >= _min_amounts[i]
        self.balances[i] = old_balance - value
        amounts[i] = value
        response: Bytes[32] = raw_call(
            self.coins[i],
            _abi_encode(_receiver, value, method_id=method_id("transfer(address,uint256)")),
            max_outsize=32,
        )
        if len(response) > 0:
            assert convert(response, bool)

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

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

    return amounts


@external
@nonreentrant('lock')
def remove_liquidity_imbalance(
    _amounts: uint256[N_COINS],
    _max_burn_amount: uint256,
    _receiver: address = msg.sender
) -> uint256:
    """
    @notice Withdraw coins from the pool in an imbalanced amount
    @param _amounts List of amounts of underlying coins to withdraw
    @param _max_burn_amount Maximum amount of LP token to burn in the withdrawal
    @param _receiver Address that receives the withdrawn coins
    @return Actual amount of the LP token burned in the withdrawal
    """
    amp: uint256 = self._A()
    rates: uint256[N_COINS] = [self.rate_multiplier, Curve(BASE_POOL).get_virtual_price()]
    old_balances: uint256[N_COINS] = self.balances
    D0: uint256 = self.get_D_mem(rates, old_balances, amp)

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

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

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

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

    return burn_amount


@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

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

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

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

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


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

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

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

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

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

    return [dy, dy_0 - dy]


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


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

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

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

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

    return dy[0]


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

    _initial_A: uint256 = self._A()
    _future_A_p: uint256 = _future_A * A_PRECISION

    assert _future_A > 0 and _future_A < MAX_A
    if _future_A_p < _initial_A:
        assert _future_A_p * MAX_A_CHANGE >= _initial_A
    else:
        assert _future_A_p <= _initial_A * MAX_A_CHANGE

    self.initial_A = _initial_A
    self.future_A = _future_A_p
    self.initial_A_time = block.timestamp
    self.future_A_time = _future_time

    log RampA(_initial_A, _future_A_p, block.timestamp, _future_time)


@external
def stop_ramp_A():
    assert msg.sender == Factory(self.factory).admin()  # 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)


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


@external
def withdraw_admin_fees():
    # transfer coin 0 to Factory and call `convert_fees` to swap it for coin 1
    factory: address = self.factory
    coin: address = self.coins[0]
    amount: uint256 = ERC20(coin).balanceOf(self) - self.balances[0]
    if amount > 0:
        response: Bytes[32] = raw_call(
            coin,
            _abi_encode(factory, amount, method_id=method_id("transfer(address,uint256)")),
            max_outsize=32,
        )
        if len(response) > 0:
            assert convert(response, bool)
        Factory(factory).convert_metapool_fees()

    # transfer coin 1 to the receiver
    coin = self.coins[1]
    amount = ERC20(coin).balanceOf(self) - self.balances[1]
    if amount > 0:
        receiver: address = Factory(factory).get_fee_receiver(self)
        response: Bytes[32] = raw_call(
            coin,
            _abi_encode(receiver, amount, method_id=method_id("transfer(address,uint256)")),
            max_outsize=32,
        )
        if len(response) > 0:
            assert convert(response, bool)


@view
@external
def version() -> String[8]:
    """
    @notice Get the version of this token contract
    """
    return VERSION

Contract ABI

[{"name":"Transfer","inputs":[{"name":"sender","type":"address","indexed":true},{"name":"receiver","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true},{"name":"spender","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchange","inputs":[{"name":"buyer","type":"address","indexed":true},{"name":"sold_id","type":"int128","indexed":false},{"name":"tokens_sold","type":"uint256","indexed":false},{"name":"bought_id","type":"int128","indexed":false},{"name":"tokens_bought","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"TokenExchangeUnderlying","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[2]","indexed":false},{"name":"fees","type":"uint256[2]","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[2]","indexed":false},{"name":"fees","type":"uint256[2]","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityOne","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amount","type":"uint256","indexed":false},{"name":"coin_amount","type":"uint256","indexed":false},{"name":"token_supply","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"RemoveLiquidityImbalance","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"token_amounts","type":"uint256[2]","indexed":false},{"name":"fees","type":"uint256[2]","indexed":false},{"name":"invariant","type":"uint256","indexed":false},{"name":"token_supply","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":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"initialize","inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_coin","type":"address"},{"name":"_rate_multiplier","type":"uint256"},{"name":"_A","type":"uint256"},{"name":"_fee","type":"uint256"}],"outputs":[],"gas":491073},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":390},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":79005},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":116985},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"gas":39211},{"stateMutability":"nonpayable","type":"function","name":"permit","inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_deadline","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"outputs":[{"name":"","type":"bool"}],"gas":102281},{"stateMutability":"view","type":"function","name":"admin_fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":540},{"stateMutability":"view","type":"function","name":"A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":10448},{"stateMutability":"view","type":"function","name":"A_precise","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":10448},{"stateMutability":"view","type":"function","name":"get_virtual_price","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":807920},{"stateMutability":"view","type":"function","name":"calc_token_amount","inputs":[{"name":"_amounts","type":"uint256[2]"},{"name":"_is_deposit","type":"bool"}],"outputs":[{"name":"","type":"uint256"}],"gas":1597346},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[2]"},{"name":"_min_mint_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":2611832},{"stateMutability":"nonpayable","type":"function","name":"add_liquidity","inputs":[{"name":"_amounts","type":"uint256[2]"},{"name":"_min_mint_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":2611832},{"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":1154525},{"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":1162775},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1300799},{"stateMutability":"nonpayable","type":"function","name":"exchange","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1300799},{"stateMutability":"nonpayable","type":"function","name":"exchange_underlying","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1323223},{"stateMutability":"nonpayable","type":"function","name":"exchange_underlying","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"_dx","type":"uint256"},{"name":"_min_dy","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1323223},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[2]"}],"outputs":[{"name":"","type":"uint256[2]"}],"gas":229848},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"_min_amounts","type":"uint256[2]"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256[2]"}],"gas":229848},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[2]"},{"name":"_max_burn_amount","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":2612120},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_imbalance","inputs":[{"name":"_amounts","type":"uint256[2]"},{"name":"_max_burn_amount","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":2612120},{"stateMutability":"view","type":"function","name":"calc_withdraw_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"}],"outputs":[{"name":"","type":"uint256"}],"gas":1259},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":1688189},{"stateMutability":"nonpayable","type":"function","name":"remove_liquidity_one_coin","inputs":[{"name":"_burn_amount","type":"uint256"},{"name":"i","type":"int128"},{"name":"_min_received","type":"uint256"},{"name":"_receiver","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1688189},{"stateMutability":"nonpayable","type":"function","name":"ramp_A","inputs":[{"name":"_future_A","type":"uint256"},{"name":"_future_time","type":"uint256"}],"outputs":[],"gas":161164},{"stateMutability":"nonpayable","type":"function","name":"stop_ramp_A","inputs":[],"outputs":[],"gas":157387},{"stateMutability":"view","type":"function","name":"admin_balances","inputs":[{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":7859},{"stateMutability":"nonpayable","type":"function","name":"withdraw_admin_fees","inputs":[],"outputs":[],"gas":31294},{"stateMutability":"view","type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":6707},{"stateMutability":"view","type":"function","name":"coins","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":3255},{"stateMutability":"view","type":"function","name":"balances","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}],"gas":3285},{"stateMutability":"view","type":"function","name":"fee","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3270},{"stateMutability":"view","type":"function","name":"initial_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3300},{"stateMutability":"view","type":"function","name":"future_A","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3330},{"stateMutability":"view","type":"function","name":"initial_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3360},{"stateMutability":"view","type":"function","name":"future_A_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3390},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":13709},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}],"gas":11468},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3746},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":4042},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":3540},{"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32"}],"gas":3570},{"stateMutability":"view","type":"function","name":"nonces","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3866}]

617a69600655614a9d56600436101561000d57613b96565b60046000601c3760005134614a8e576398094be081186103e4576004356004016020813511614a8e57808035602001808260e037505050602435600401600a813511614a8e578080356020018082610120375050506044358060a01c614a8e5761016052600654614a8e576084356064808202821582848304141715614a8e5790509050610180526101605160025573c9b8a3fdecb9d5b218d02555a8baf332e5b740d5600355606435600b55610180516007556101805160085560a435600655336001556000601f610200527f43757276652e666920466163746f727920555344204d657461706f6f6c3a200061022052610200601f806020846102400101826020850160045afa50508051820191505060e06020806020846102400101826020850160045afa505080518201915050806102405261024090508051602001806101a0828460045afa905050506101a080600c602082510160c060006003818352015b8260c0516020021115610183576101a2565b60c05160200285015160c0518501558151600101808352811415610171575b5050505050506000610120600a806020846102400101826020850160045afa5050805182019150506006610200527f334352562d660000000000000000000000000000000000000000000000000000610220526102006006806020846102400101826020850160045afa5050805182019150508061024052610240905080600f602082510160c060006002818352015b8260c051602002111561024457610263565b60c05160200285015160c0518501558151600101808352811415610232575b5050505050507317fc002b466eec40dae837fc4be5c67993ddbd6f6102405273ff970a61a04b1ca14834a43f5de4533ebddb5cc86102605261022060006002818352015b6020610220510261024001516102005263095ea7b36102805273c9b8a3fdecb9d5b218d02555a8baf332e5b740d56102a0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6102c052610200513b15614a8e5760006000604461029c6000610200515af1610328573d600060003e3d6000fd5b81516001018083528114156102a75750507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6102e0526101a0805160208201209050610300527f572f01d824885a118d5d21c74542f263b131d2897955c62a721594f1d7c3b2e2610320524661034052306103605260a06102c0526102c08051602082012090506014553060007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6000610200526020610200a3005b63313ce56781186103fa57601260e052602060e0f35b63a9059cbb811861043c576004358060a01c614a8e57610160523360e05261016051610100526024356101205261042f613b9c565b6001610180526020610180f35b6323b872dd8118610510576004358060a01c614a8e57610160526024358060a01c614a8e57610180526101605160e052610180516101005260443561012052610483613b9c565b60126101605160a05260805260406080203360a0526080526040608020546101a0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101a05114610503576101a051604435808210614a8e578082039050905060126101605160a05260805260406080203360a0526080526040608020555b60016101c05260206101c0f35b63095ea7b38118610588576004358060a01c614a8e5760e05260243560123360a052608052604060802060e05160a05260805260406080205560e051337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925602435610100526020610100a36001610100526020610100f35b63d505accf81186108f5576004358060a01c614a8e5760e0526024358060a01c614a8e57610100526084358060081c614a8e5761012052600060e05114614a8e576064354211614a8e57601560e05160a0526080526040608020546101405260006002610400527f1901000000000000000000000000000000000000000000000000000000000000610420526104006002806020846106000101826020850160045afa5050805182019150506014546020826106000101526020810190507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c96105405260e0516105605261010051610580526044356105a052610140516105c0526064356105e05260c0610520526105208051602082012090506020826106000101526020810190508061060052610600905080516020820120905061016052600060e0513b116107095760e0516101605161018052610120516101a052604060a46101c03760206080608061018060015afa5060805118614a8e57610869565b600060a4356102205260c435610240526040610200526102006040806020846102c00101826020850160045afa505080518201915050601f60016020820661026001602082840111614a8e576020806102808261012060045afa5050818152905090506001806020846102c00101826020850160045afa505080518201915050806102c0526102c09050805160200180610180828460045afa905050507f1626ba7e00000000000000000000000000000000000000000000000000000000631626ba7e610200526102208060406101605182526020820191508082528083018061018080516020018083828460045afa905050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810150505050602061020060c461021c60e0515afa610856573d600060003e3d6000fd5b601f3d1115614a8e576102005118614a8e575b604435601260e05160a05260805260406080206101005160a0526080526040608020556101405160018181830110614a8e5780820190509050601560e05160a0526080526040608020556101005160e0517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925604435610180526020610180a36001610180526020610180f35b63fee3f7f9811861090f5764012a05f20060e052602060e0f35b63f446c1d0811861093d57610925610160613c25565b61016051606480820490509050610180526020610180f35b6376a2f0f0811861096257610953610160613c25565b61016051610180526020610180f35b63bb7b8b808118610a7257610978610260613c25565b6102605161024052600b546102605263bb7b8b806102a05260206102a060046102bc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa6109c0573d600060003e3d6000fd5b601f3d1115614a8e576102a051610280526102605160e052610280516101005260045461012052600554610140526109f96102e0613d60565b6102e080516102a05280602001516102c052506102a05160e0526102c051610100526102405161012052610a2e610300613df8565b610300516102e0526102e051670de0b6b3a7640000808202821582848304141715614a8e5790509050601354808015614a8e57820490509050610300526020610300f35b63ed8e84f38118610c85576044358060011c614a8e5761036052610a976103a0613c25565b6103a05161038052600b546103a05263bb7b8b806103e05260206103e060046103fc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa610adf573d600060003e3d6000fd5b601f3d1115614a8e576103e0516103c0526004546103e052600554610400526103a051610240526103c051610260526103e05161028052610400516102a052610380516102c052610b31610440614065565b610440516104205261044060006002818352015b60206104405102600401356104605261036051610b8c576103e0610440516002811015614a8e5760200201805161046051808210614a8e5780820390509050815250610bba565b6103e0610440516002811015614a8e57602002018051610460518181830110614a8e57808201905090508152505b8151600101808352811415610b455750506103a051610240526103c051610260526103e05161028052610400516102a052610380516102c052610bfe610460614065565b610460516104405260006104605261036051610c33576104205161044051808210614a8e578082039050905061046052610c4e565b6104405161042051808210614a8e5780820390509050610460525b61046051601354808202821582848304141715614a8e579050905061042051808015614a8e57820490509050610480526020610480f35b630b4c7e4d8118610c9a573361036052610cb5565b630c3e4b54811861125d576064358060a01c614a8e57610360525b600054614a8e576001600055610ccc6103a0613c25565b6103a05161038052600b546103a05263bb7b8b806103e05260206103e060046103fc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa610d14573d600060003e3d6000fd5b601f3d1115614a8e576103e0516103c0526004546103e052600554610400526103a051610240526103c051610260526103e05161028052610400516102a052610380516102c052610d66610440614065565b61044051610420526103e051610440526104005161046052601354610480526104a060006002818352015b60206104a05102600401356104c0526104c05115610e8b576323b872dd610524526004336105445230610564526104c05161058452606001610520526105205060206105e061052051610540600060016104a0516002811015614a8e5702600201545af1610e04573d600060003e3d6000fd5b6105c060203d808211610e175781610e19565b805b9050905081528051602001806104e0828460045afa9050505060006104e0511115610e5957610500516104e05181816020036008021c9050905015614a8e575b6104406104a0516002811015614a8e576020020180516104c0518181830110614a8e5780820190509050815250610e98565b6000610480511115614a8e575b8151600101808352811415610d915750506103a051610240526103c051610260526104405161028052610460516102a052610380516102c052610edc6104c0614065565b6104c0516104a052610420516104a0511115614a8e576060366104c03760006104805111610f1f5761044051600455610460516005556104a05161050052611165565b6006546002808202821582848304141715614a8e57905090506004808204905090506105205261054060006002818352015b6104a0516103e0610540516002811015614a8e576020020151808202821582848304141715614a8e579050905061042051808015614a8e5782049050905061056052600061058052610440610540516002811015614a8e5760200201516105a0526105a0516105605111610fde576105a05161056051808210614a8e578082039050905061058052610ff9565b610560516105a051808210614a8e5780820390509050610580525b6105205161058051808202821582848304141715614a8e57905090506402540be400808204905090506104c0610540516002811015614a8e5760200201526105a0516104c0610540516002811015614a8e57602002015164012a05f200808202821582848304141715614a8e57905090506402540be40080820490509050808210614a8e57808203905090506001610540516002811015614a8e570260040155610440610540516002811015614a8e576020020180516104c0610540516002811015614a8e576020020151808210614a8e57808203905090508152508151600101808352811415610f515750506103a051610240526103c051610260526104405161028052610460516102a052610380516102c052611119610560614065565b6105605161054052610480516105405161042051808210614a8e5780820390509050808202821582848304141715614a8e579050905061042051808015614a8e57820490509050610500525b6044356105005110614a8e576104808051610500518181830110614a8e578082019050905081525060116103605160a05260805260406080208054610500518181830110614a8e5780820190509050815550610480516013556103605160007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61050051610520526020610520a3337f26f55a85081d24974e85c6c00045d0f0453991e95873f52bff0d21af4079a76860043561052052602435610540526104c051610560526104e051610580526104a0516105a052610480516105c05260c0610520a2610500516105205260206105206000600055f35b635e0d443f8118611483576004358060801d81607f1d18614a8e57610420526024358060801d81607f1d18614a8e5761044052600b546104605263bb7b8b806104a05260206104a060046104bc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa6112d0573d600060003e3d6000fd5b601f3d1115614a8e576104a051610480526104605160e052610480516101005260045461012052600554610140526113096104e0613d60565b6104e080516104a05280602001516104c052506104a0610420516002811015614a8e576020020151604435610460610420516002811015614a8e576020020151808202821582848304141715614a8e5790509050670de0b6b3a7640000808204905090508181830110614a8e57808201905090506104e052610420516102405261044051610260526104e051610280526104a0516102a0526104c0516102c0526113b46105206140cd565b61052051610500526104a0610440516002811015614a8e57602002015161050051808210614a8e57808203905090506001808210614a8e57808203905090506105205260065461052051808202821582848304141715614a8e57905090506402540be40080820490509050610540526105205161054051808210614a8e5780820390509050670de0b6b3a7640000808202821582848304141715614a8e5790509050610460610440516002811015614a8e576020020151808015614a8e57820490509050610560526020610560f35b6307211ef7811861194c576004358060801d81607f1d18614a8e57610420526024358060801d81607f1d18614a8e5761044052600b546104605263bb7b8b806104a05260206104a060046104bc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa6114f6573d600060003e3d6000fd5b601f3d1115614a8e576104a051610480526104605160e0526104805161010052600454610120526005546101405261152f6104e0613d60565b6104e080516104a05280602001516104c0525060a0366104e03760006104205114611579576104205160018082038060801d81607f1d18614a8e5790509050610500526001610540525b600061044051146115a9576104405160018082038060801d81607f1d18614a8e5790509050610520526001610560525b610420511561177357610440511561162a57635e0d443f61058052610500516105a052610520516105c0526044356105e0526020610580606461059c73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa61160b573d600060003e3d6000fd5b601f3d1115614a8e576105805161060052602061060061194a566117c8565b60403661058037604435610580610500516002811015614a8e57602002015263ed8e84f36105c052610580516105e0526105a0516106005260016106205260206105c060646105dc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa611698573d600060003e3d6000fd5b601f3d1115614a8e576105c05161048051808202821582848304141715614a8e5790509050670de0b6b3a7640000808204905090506104e0526104e080516104e05163ddca3f436105c05260206105c060046105dc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa611713573d600060003e3d6000fd5b601f3d1115614a8e576105c051808202821582848304141715614a8e57905090506404a817c80080820490509050808210614a8e57808203905090508152506104e080516104c0518181830110614a8e57808201905090508152506117c8565b6104a0610420516002811015614a8e57602002015160443561046051670de0b6b3a764000080820490509050808202821582848304141715614a8e57905090508181830110614a8e57808201905090506104e0525b610540516102405261056051610260526104e051610280526104a0516102a0526104c0516102c0526117fb6105a06140cd565b6105a051610580526104a0610560516002811015614a8e57602002015161058051808210614a8e57808203905090506001808210614a8e57808203905090506105a0526105a0516006546105a051808202821582848304141715614a8e57905090506402540be40080820490509050808210614a8e57808203905090506105a05261044051156119125763cc2b27d76105c0526105a051670de0b6b3a7640000808202821582848304141715614a8e579050905061048051808015614a8e578204905090506105e052610520516106005260206105c060446105dc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa6118fc573d600060003e3d6000fd5b601f3d1115614a8e576105c0516105a05261193c565b6105a0805161046051670de0b6b3a764000080820490509050808015614a8e578204905090508152505b6105a0516105c05260206105c05bf35b633df02124811861196157336104605261197c565b63ddc1f59d8118611e6f576084358060a01c614a8e57610460525b6004358060801d81607f1d18614a8e57610420526024358060801d81607f1d18614a8e5761044052600054614a8e576001600055600b546104805263bb7b8b806104c05260206104c060046104dc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa6119f0573d600060003e3d6000fd5b601f3d1115614a8e576104c0516104a0526004546104c0526005546104e0526104805160e0526104a051610100526104c051610120526104e05161014052611a39610540613d60565b61054080516105005280602001516105205250610500610420516002811015614a8e576020020151604435610480610420516002811015614a8e576020020151808202821582848304141715614a8e5790509050670de0b6b3a7640000808204905090508181830110614a8e578082019050905061054052610420516102405261044051610260526105405161028052610500516102a052610520516102c052611ae46105806140cd565b6105805161056052610500610440516002811015614a8e57602002015161056051808210614a8e57808203905090506001808210614a8e57808203905090506105805261058051600654808202821582848304141715614a8e57905090506402540be400808204905090506105a052610580516105a051808210614a8e5780820390509050670de0b6b3a7640000808202821582848304141715614a8e5790509050610480610440516002811015614a8e576020020151808015614a8e57820490509050610580526064356105805110614a8e576105a05164012a05f200808202821582848304141715614a8e57905090506402540be400808204905090506105c0526105c051670de0b6b3a7640000808202821582848304141715614a8e5790509050610480610440516002811015614a8e576020020151808015614a8e578204905090506105c0526104c0610420516002811015614a8e5760200201516044358181830110614a8e57808201905090506001610420516002811015614a8e5702600401556104c0610440516002811015614a8e57602002015161058051808210614a8e57808203905090506105c051808210614a8e57808203905090506001610440516002811015614a8e5702600401556323b872dd6106245260043361064452306106645260443561068452606001610620526106205060206106e06106205161064060006001610420516002811015614a8e5702600201545af1611d11573d600060003e3d6000fd5b6106c060203d808211611d245781611d26565b805b9050905081528051602001806105e0828460045afa9050505060006105e0511115611d6657610600516105e05181816020036008021c9050905015614a8e575b63a9059cbb61062452600461046051610644526105805161066452604001610620526106205060206106c06106205161064060006001610440516002811015614a8e5702600201545af1611dbf573d600060003e3d6000fd5b6106a060203d808211611dd25781611dd4565b805b9050905081528051602001806105e0828460045afa9050505060006105e0511115611e1457610600516105e05181816020036008021c9050905015614a8e575b337f8b3e96f2b889fa771c53c981b40daf005f63f637f1869f707052d15a3dd97140610420516106205260443561064052610440516106605261058051610680526080610620a2610580516106205260206106206000600055f35b63a6417ed68118611e84573361046052611e9f565b6344ee198681186127ff576084358060a01c614a8e57610460525b6004358060801d81607f1d18614a8e57610420526024358060801d81607f1d18614a8e5761044052600054614a8e576001600055600b546104805263bb7b8b806104c05260206104c060046104dc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa611f13573d600060003e3d6000fd5b601f3d1115614a8e576104c0516104a0526004546104c0526005546104e0526104805160e0526104a051610100526104c051610120526104e05161014052611f5c610540613d60565b610540805161050052806020015161052052507317fc002b466eec40dae837fc4be5c67993ddbd6f6105405273ff970a61a04b1ca14834a43f5de4533ebddb5cc86105605261010036610580376104205115611ff4576104205160018082038060801d81607f1d18614a8e57905090506105a05260016105e0526105406105a0516002811015614a8e57602002015161064052611ffc565b600254610640525b6104405115612047576104405160018082038060801d81607f1d18614a8e57905090506105c0526001610600526105406105c0516002811015614a8e5760200201516106605261204f565b600254610660525b6323b872dd6106c4526004336106e4523061070452604435610724526060016106c0526106c05060206107806106c0516106e06000610640515af1612099573d600060003e3d6000fd5b61076060203d8082116120ac57816120ae565b805b905090508152805160200180610680828460045afa9050505060006106805111156120ee576106a0516106805181816020036008021c9050905015614a8e575b6044356106c052610420511561210857610440511561210b565b60015b612216576370a082316106e052306107005260206106e060246106fc610660515afa61213c573d600060003e3d6000fd5b601f3d1115614a8e576106e05161058052633df021246106e0526105a051610700526105c051610720526106c051610740526064356107605273c9b8a3fdecb9d5b218d02555a8baf332e5b740d53b15614a8e576000600060846106fc600073c9b8a3fdecb9d5b218d02555a8baf332e5b740d55af16121c1573d600060003e3d6000fd5b6370a082316106e052306107005260206106e060246106fc610660515afa6121ee573d600060003e3d6000fd5b601f3d1115614a8e576106e05161058051808210614a8e578082039050905061058052612705565b6104205115612390576040366106e0376106c0516106e06105a0516002811015614a8e576020020152600354610720526370a082316107405230610760526020610740602461075c610720515afa612273573d600060003e3d6000fd5b601f3d1115614a8e576107405161062052630b4c7e4d610740526106e05161076052610700516107805260006107a05273c9b8a3fdecb9d5b218d02555a8baf332e5b740d53b15614a8e5760006000606461075c600073c9b8a3fdecb9d5b218d02555a8baf332e5b740d55af16122ef573d600060003e3d6000fd5b6370a082316107405230610760526020610740602461075c610720515afa61231c573d600060003e3d6000fd5b601f3d1115614a8e576107405161062051808210614a8e57808203905090506106c0526106c0516104a051808202821582848304141715614a8e5790509050670de0b6b3a764000080820490509050610620526106208051610520518181830110614a8e57808201905090508152506123f7565b610500610420516002811015614a8e5760200201516106c051610480610420516002811015614a8e576020020151808202821582848304141715614a8e5790509050670de0b6b3a7640000808204905090508181830110614a8e5780820190509050610620525b6105e0516102405261060051610260526106205161028052610500516102a052610520516102c05261242a6107006140cd565b610700516106e052610500610600516002811015614a8e5760200201516106e051808210614a8e57808203905090506001808210614a8e57808203905090506105805261058051600654808202821582848304141715614a8e57905090506402540be40080820490509050610700526105805161070051808210614a8e5780820390509050670de0b6b3a7640000808202821582848304141715614a8e5790509050610480610600516002811015614a8e576020020151808015614a8e57820490509050610580526107005164012a05f200808202821582848304141715614a8e57905090506402540be400808204905090506107205261072051670de0b6b3a7640000808202821582848304141715614a8e5790509050610480610600516002811015614a8e576020020151808015614a8e57820490509050610720526104c06105e0516002811015614a8e5760200201516106c0518181830110614a8e578082019050905060016105e0516002811015614a8e5702600401556104c0610600516002811015614a8e57602002015161058051808210614a8e578082039050905061072051808210614a8e57808203905090506001610600516002811015614a8e57026004015560006104405113156126f8576370a082316107605230610780526020610760602461077c610660515afa61262b573d600060003e3d6000fd5b601f3d1115614a8e576107605161074052631a4d01d26107605261058051610780526105c0516107a05260006107c05273c9b8a3fdecb9d5b218d02555a8baf332e5b740d53b15614a8e5760006000606461077c600073c9b8a3fdecb9d5b218d02555a8baf332e5b740d55af16126a7573d600060003e3d6000fd5b6370a082316107605230610780526020610760602461077c610660515afa6126d4573d600060003e3d6000fd5b601f3d1115614a8e576107605161074051808210614a8e5780820390509050610580525b6064356105805110614a8e575b63a9059cbb6106e4526004610460516107045261058051610724526040016106e0526106e05060206107806106e0516107006000610660515af161274e573d600060003e3d6000fd5b61076060203d8082116127615781612763565b805b905090508152805160200180610680828460045afa9050505060006106805111156127a3576106a0516106805181816020036008021c9050905015614a8e575b337fd013ca23e77a65003c2c659c5442c00c805371b7fc1ebd4c206c41d1536bd90b610420516106e0526106c051610700526104405161072052610580516107405260806106e0a2610580516106e05260206106e06000600055f35b635b36389c8118612813573360e05261282d565b633eb1719f8118612a88576064358060a01c614a8e5760e0525b600054614a8e576001600055601354610100526040366101203761016060006002818352015b6001610160516002811015614a8e5702600401546101805261018051600435808202821582848304141715614a8e579050905061010051808015614a8e578204905090506101a05260206101605102602401356101a05110614a8e57610180516101a051808210614a8e57808203905090506001610160516002811015614a8e5702600401556101a051610120610160516002811015614a8e57602002015263a9059cbb61020452600460e051610224526101a05161024452604001610200526102005060206102a06102005161022060006001610160516002811015614a8e5702600201545af161294a573d600060003e3d6000fd5b61028060203d80821161295d578161295f565b805b9050905081528051602001806101c0828460045afa9050505060006101c051111561299f576101e0516101c05181816020036008021c9050905015614a8e575b81516001018083528114156128535750506101008051600435808210614a8e578082039050905081525060113360a05260805260406080208054600435808210614a8e5780820390509050815550610100516013556000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600435610160526020610160a3337f7c363854ccf79623411f8995b362bce5eddff18c927edc6f5dbbb5e05819a82c610120516101605261014051610180526040366101a037610100516101e05260a0610160a26101205161016052610140516101805260406101606000600055f35b63e31032738118612a9d573361036052612ab8565b6352d2cfdd811861302b576064358060a01c614a8e57610360525b600054614a8e576001600055612acf6103a0613c25565b6103a05161038052600b546103a05263bb7b8b806103e05260206103e060046103fc73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa612b17573d600060003e3d6000fd5b601f3d1115614a8e576103e0516103c0526004546103e052600554610400526103a051610240526103c051610260526103e05161028052610400516102a052610380516102c052612b69610440614065565b61044051610420526103e05161044052610400516104605261048060006002818352015b60206104805102600401356104a05260006104a05114612c8057610440610480516002811015614a8e576020020180516104a051808210614a8e578082039050905081525063a9059cbb61050452600461036051610524526104a05161054452604001610500526105005060206105a06105005161052060006001610480516002811015614a8e5702600201545af1612c2b573d600060003e3d6000fd5b61058060203d808211612c3e5781612c40565b805b9050905081528051602001806104c0828460045afa9050505060006104c0511115612c80576104e0516104c05181816020036008021c9050905015614a8e575b8151600101808352811415612b8d5750506103a051610240526103c051610260526104405161028052610460516102a052610380516102c052612cc46104a0614065565b6104a051610480526040366104a0376006546002808202821582848304141715614a8e57905090506004808204905090506104e05261050060006002818352015b610480516103e0610500516002811015614a8e576020020151808202821582848304141715614a8e579050905061042051808015614a8e5782049050905061052052600061054052610440610500516002811015614a8e57602002015161056052610560516105205111612d92576105605161052051808210614a8e578082039050905061054052612dad565b6105205161056051808210614a8e5780820390509050610540525b6104e05161054051808202821582848304141715614a8e57905090506402540be400808204905090506104a0610500516002811015614a8e576020020152610560516104a0610500516002811015614a8e57602002015164012a05f200808202821582848304141715614a8e57905090506402540be40080820490509050808210614a8e57808203905090506001610500516002811015614a8e570260040155610440610500516002811015614a8e576020020180516104a0610500516002811015614a8e576020020151808210614a8e57808203905090508152508151600101808352811415612d055750506103a051610240526103c051610260526104405161028052610460516102a052610380516102c052612ecd610520614065565b6105205161050052601354610520526104205161050051808210614a8e578082039050905061052051808202821582848304141715614a8e579050905061042051808015614a8e5782049050905060018181830110614a8e5780820190509050610540526001610540511115614a8e576044356105405111614a8e57610520805161054051808210614a8e57808203905090508152506105205160135560113360a0526080526040608020805461054051808210614a8e57808203905090508155506000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61054051610560526020610560a3337f2b5508378d7e19e0d5fa338419034731416c4f5b219a10379956f764317fd47e60043561056052602435610580526104a0516105a0526104c0516105c052610480516105e052610520516106005260c0610560a2610540516105605260206105606000600055f35b63cc2b27d78118613073576024358060801d81607f1d18614a8e576104a052600435610280526104a0516102a0526130646104c06146ad565b6104c051610500526020610500f35b631a4d01d2811861308857336104c0526130a3565b63081579a581186132d6576064358060a01c614a8e576104c0525b6024358060801d81607f1d18614a8e576104a052600054614a8e576001600055600435610280526104a0516102a0526130dd6105206146ad565b61052080516104e052806020015161050052506044356104e05110614a8e5760016104a0516002811015614a8e570260040180546104e0516105005164012a05f200808202821582848304141715614a8e57905090506402540be400808204905090508181830110614a8e5780820190509050808210614a8e5780820390509050815550601354600435808210614a8e5780820390509050610520526105205160135560113360a05260805260406080208054600435808210614a8e57808203905090508155506000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600435610540526020610540a363a9059cbb6105845260046104c0516105a4526104e0516105c45260400161058052610580506020610620610580516105a0600060016104a0516002811015614a8e5702600201545af161322e573d600060003e3d6000fd5b61060060203d8082116132415781613243565b805b905090508152805160200180610540828460045afa90505050600061054051111561328357610560516105405181816020036008021c9050905015614a8e575b337f5ad056f2e28a8cec232015406b843668c1e36cda598127ec3b8c59b8c72773a0600435610580526104e0516105a052610520516105c0526060610580a26104e0516105805260206105806000600055f35b633c157e64811861345a5763f851a440610160526020610160600461017c6001545afa613308573d600060003e3d6000fd5b601f3d1115614a8e57610160513318614a8e57600954620151808181830110614a8e57808201905090504210614a8e5742620151808181830110614a8e578082019050905060243510614a8e57613360610180613c25565b61018051610160526004356064808202821582848304141715614a8e57905090506101805260006004351161339657600061339f565b620f4240600435105b15614a8e576101605161018051106133d95761016051600a808202821582848304141715614a8e57905090506101805111614a8e576133fd565b6101605161018051600a808202821582848304141715614a8e579050905010614a8e575b610160516007556101805160085542600955602435600a557fa2b71ec6df949300b59aab36b55e189697b750119dd349fcfa8c0f779e83c254610160516101a052610180516101c052426101e0526024356102005260806101a0a1005b63551a658881186134fe5763f851a440610160526020610160600461017c6001545afa61348c573d600060003e3d6000fd5b601f3d1115614a8e57610160513318614a8e576134aa610180613c25565b610180516101605261016051600755610160516008554260095542600a557f46e22fb3709ad289f62ce63d469248536dbc78d82b84a3d7e74ad606dc2019386101605161018052426101a0526040610180a1005b63e2e7d264811861357a576370a0823160e0523061010052602060e0602460fc60016004356002811015614a8e5702600201545afa613542573d600060003e3d6000fd5b601f3d1115614a8e5760e05160016004356002811015614a8e570260040154808210614a8e5780820390509050610120526020610120f35b6330c5408581186138085760015460e052600254610100526370a082316101405230610160526020610140602461015c610100515afa6135bf573d600060003e3d6000fd5b601f3d1115614a8e5761014051600454808210614a8e57808203905090506101205260006101205111156136c15763a9059cbb61018452600460e0516101a452610120516101c45260400161018052610180506020610220610180516101a06000610100515af1613635573d600060003e3d6000fd5b61020060203d808211613648578161364a565b805b905090508152805160200180610140828460045afa90505050600061014051111561368a57610160516101405181816020036008021c9050905015614a8e575b63bcc981d2610180526020610180600461019c600060e0515af16136b3573d600060003e3d6000fd5b601f3d1115614a8e57610180505b600354610100526370a082316101405230610160526020610140602461015c610100515afa6136f5573d600060003e3d6000fd5b601f3d1115614a8e5761014051600554808210614a8e57808203905090506101205260006101205111156138065763154aa8f56101605230610180526020610160602461017c60e0515afa61374f573d600060003e3d6000fd5b601f3d1115614a8e57610160518060a01c614a8e576101405263a9059cbb6101a4526004610140516101c452610120516101e4526040016101a0526101a05060206102406101a0516101c06000610100515af16137b1573d600060003e3d6000fd5b61022060203d8082116137c457816137c6565b805b905090508152805160200180610160828460045afa90505050600061016051111561380657610180516101605181816020036008021c9050905015614a8e575b005b6354fd4d5081186138a257610120806020808252600660e0527f76352e302e3000000000000000000000000000000000000000000000000000006101005260e0818401808280516020018083828460045afa905050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f82010390509050905090508101905090509050610120f35b63c661065781186138c95760016004356002811015614a8e57026002015460e052602060e0f35b634903b0d181186138f05760016004356002811015614a8e57026004015460e052602060e0f35b63ddca3f4381186139075760065460e052602060e0f35b635409491a811861391e5760075460e052602060e0f35b63b4b577ad81186139355760085460e052602060e0f35b632081066c811861394c5760095460e052602060e0f35b6314052288811861396357600a5460e052602060e0f35b6306fdde038118613a065760e080602080825280830180600c8082602082540160c060006003818352015b8260c05160200211156139a0576139bf565b60c05185015460c051602002850152815160010180835281141561398e575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b6395d89b418118613aa95760e080602080825280830180600f8082602082540160c060006002818352015b8260c0516020021115613a4357613a62565b60c05185015460c0516020028501528151600101808352811415613a31575b5050505050508051806020830101818260206001820306601f8201039050033682375050805160200160206001820306601f820103905090509050810190509050905060e0f35b6370a082318118613ade576004358060a01c614a8e5760e052601160e05160a052608052604060802054610100526020610100f35b63dd62ed3e8118613b31576004358060a01c614a8e5760e0526024358060a01c614a8e5761010052601260e05160a05260805260406080206101005160a052608052604060802054610120526020610120f35b6318160ddd8118613b485760135460e052602060e0f35b633644e5158118613b5f5760145460e052602060e0f35b637ecebe008118613b94576004358060a01c614a8e5760e052601560e05160a052608052604060802054610100526020610100f35b505b60006000fd5b601160e05160a0526080526040608020805461012051808210614a8e578082039050905081555060116101005160a05260805260406080208054610120518181830110614a8e57808201905090508155506101005160e0517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef61012051610140526020610140a3565b600a5460e0526008546101005260e0514210613c4b5761010051815250613d5e56613d5e565b6007546101205260095461014052610120516101005111613ce357610120516101205161010051808210614a8e57808203905090504261014051808210614a8e5780820390509050808202821582848304141715614a8e579050905060e05161014051808210614a8e5780820390509050808015614a8e57820490509050808210614a8e5780820390509050815250613d5e56613d5e565b610120516101005161012051808210614a8e57808203905090504261014051808210614a8e5780820390509050808202821582848304141715614a8e579050905060e05161014051808210614a8e5780820390509050808015614a8e578204905090508181830110614a8e5780820190509050815250613d5e565b565b604036610160376101a060006002818352015b60e06101a0516002811015614a8e5760200201516101206101a0516002811015614a8e576020020151808202821582848304141715614a8e5790509050670de0b6b3a7640000808204905090506101606101a0516002811015614a8e5760200201528151600101808352811415613d7357505061016051815261018051816020015250565b604036610140376101a060006002818352015b60206101a0510260e00151610180526101408051610180518181830110614a8e57808201905090508152508151600101808352811415613e0b57505061014051613e59576000815250614063565b6101405161018052610120516002808202821582848304141715614a8e57905090506101a0526101c0600060ff818352015b610180516101e05261022060006002818352015b6020610220510260e00151610200526101e05161018051808202821582848304141715614a8e5790509050610200516002808202821582848304141715614a8e5790509050808015614a8e578204905090506101e0528151600101808352811415613e9f57505061018051610160526101a05161014051808202821582848304141715614a8e57905090506064808204905090506101e0516002808202821582848304141715614a8e57905090508181830110614a8e578082019050905061018051808202821582848304141715614a8e57905090506101a0516064808210614a8e578082039050905061018051808202821582848304141715614a8e579050905060648082049050905060036101e051808202821582848304141715614a8e57905090508181830110614a8e5780820190509050808015614a8e57820490509050610180526101605161018051116140215760016101605161018051808210614a8e57808203905090501161404c575050610180518152506140635661404c565b60016101805161016051808210614a8e57808203905090501161404c57505061018051815250614063565b8151600101808352811415613e8b57505060006000fd5b565b6102405160e052610260516101005261028051610120526102a0516101405261408f610320613d60565b61032080516102e052806020015161030052506102e05160e05261030051610100526102c051610120526140c4610320613df8565b61032051815250565b610260516102405114614a8e5760006102605112614a8e576002610260511215614a8e5760006102405112614a8e576002610240511215614a8e57614113610300613c25565b610300516102e0526102a05160e0526102c051610100526102e0516101205261413d610320613df8565b61032051610300526060366103203761030051610380526102e0516002808202821582848304141715614a8e57905090506103a0526103c060006002818352015b610240516103c051186141985761028051610340526141c9565b610260516103c05114156141af5761422d566141c9565b6102a06103c0516002811015614a8e576020020151610340525b6103208051610340518181830110614a8e57808201905090508152506103805161030051808202821582848304141715614a8e5790509050610340516002808202821582848304141715614a8e5790509050808015614a8e57820490509050610380525b815160010180835281141561417e5750506103805161030051808202821582848304141715614a8e57905090506064808202821582848304141715614a8e57905090506103a0516002808202821582848304141715614a8e5790509050808015614a8e578204905090506103805261032051610300516064808202821582848304141715614a8e57905090506103a051808015614a8e578204905090508181830110614a8e57808201905090506103c052610300516103e052610400600060ff818352015b6103e051610360526103e0516103e051808202821582848304141715614a8e5790509050610380518181830110614a8e578082019050905060026103e051808202821582848304141715614a8e57905090506103c0518181830110614a8e578082019050905061030051808210614a8e5780820390509050808015614a8e578204905090506103e052610360516103e051116143b7576001610360516103e051808210614a8e5780820390509050116143e25750506103e0518152506143f9566143e2565b60016103e05161036051808210614a8e5780820390509050116143e25750506103e0518152506143f9565b81516001018083528114156142f257505060006000fd5b565b60006101005112614a8e576002610100511215614a8e5760603661018037610160516101e05260e0516002808202821582848304141715614a8e57905090506102005261022060006002818352015b61010051610220511415614461576144df5661447b565b610120610220516002811015614a8e5760200201516101a0525b61018080516101a0518181830110614a8e57808201905090508152506101e05161016051808202821582848304141715614a8e57905090506101a0516002808202821582848304141715614a8e5790509050808015614a8e578204905090506101e0525b815160010180835281141561444a5750506101e05161016051808202821582848304141715614a8e57905090506064808202821582848304141715614a8e5790509050610200516002808202821582848304141715614a8e5790509050808015614a8e578204905090506101e05261018051610160516064808202821582848304141715614a8e579050905061020051808015614a8e578204905090508181830110614a8e5780820190509050610220526101605161024052610260600060ff818352015b610240516101c0526102405161024051808202821582848304141715614a8e57905090506101e0518181830110614a8e5780820190509050600261024051808202821582848304141715614a8e5790509050610220518181830110614a8e578082019050905061016051808210614a8e5780820390509050808015614a8e57820490509050610240526101c05161024051116146695760016101c05161024051808210614a8e578082039050905011614694575050610240518152506146ab56614694565b6001610240516101c051808210614a8e578082039050905011614694575050610240518152506146ab565b81516001018083528114156145a457505060006000fd5b565b6146b86102e0613c25565b6102e0516102c052600b546102e05263bb7b8b80610320526020610320600461033c73c9b8a3fdecb9d5b218d02555a8baf332e5b740d55afa614700573d600060003e3d6000fd5b601f3d1115614a8e5761032051610300526102e05160e05261030051610100526004546101205260055461014052614739610360613d60565b610360805161032052806020015161034052506103205160e05261034051610100526102c0516101205261476e610380613df8565b610380516103605260135461038052610360516102805161036051808202821582848304141715614a8e579050905061038051808015614a8e57820490509050808210614a8e57808203905090506103a0526102c05160e0526102a05161010052610320516101205261034051610140526103a051610160526147f26103e06143fb565b6103e0516103c0526006546002808202821582848304141715614a8e57905090506004808204905090506103e0526040366104003761044060006002818352015b600061046052610320610440516002811015614a8e576020020151610480526102a05161044051186148a757610480516103a051808202821582848304141715614a8e579050905061036051808015614a8e578204905090506103c051808210614a8e5780820390509050610460526148eb565b61048051610480516103a051808202821582848304141715614a8e579050905061036051808015614a8e57820490509050808210614a8e5780820390509050610460525b610480516103e05161046051808202821582848304141715614a8e57905090506402540be40080820490509050808210614a8e5780820390509050610400610440516002811015614a8e57602002015281516001018083528114156148335750506104006102a0516002811015614a8e5760200201516102c05160e0526102a05161010052610400516101205261042051610140526103a051610160526149936104606143fb565b61046051808210614a8e5780820390509050610440526103206102a0516002811015614a8e5760200201516103c051808210614a8e5780820390509050670de0b6b3a7640000808202821582848304141715614a8e57905090506102e06102a0516002811015614a8e576020020151808015614a8e5782049050905061046052610440516001808210614a8e5780820390509050670de0b6b3a7640000808202821582848304141715614a8e57905090506102e06102a0516002811015614a8e576020020151808015614a8e57820490509050610440526104405181526104605161044051808210614a8e5780820390509050816020015250565b600080fd5b61000a614a9d0361000a60003961000a614a9d036000f3

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