More Info
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
View more zero value Internal Transactions in Advanced View mode
Contract Source Code Verified (Exact Match)
Contract Name:
Vyper_contract
Compiler Version
vyper:0.2.11
Contract Source Code (Vyper language format)
# @version 0.2.11 """ @title Curve Registry @license MIT @author Curve.Fi """ MAX_COINS: constant(int128) = 8 CALC_INPUT_SIZE: constant(int128) = 100 struct CoinInfo: index: uint256 register_count: uint256 swap_count: uint256 swap_for: address[MAX_INT128] struct PoolArray: location: uint256 decimals: uint256 underlying_decimals: uint256 rate_info: bytes32 base_pool: address coins: address[MAX_COINS] ul_coins: address[MAX_COINS] n_coins: uint256 # [coins, underlying coins] tightly packed as uint128[2] has_initial_A: bool is_v1: bool name: String[64] asset_type: uint256 struct PoolParams: A: uint256 future_A: uint256 fee: uint256 admin_fee: uint256 future_fee: uint256 future_admin_fee: uint256 future_owner: address initial_A: uint256 initial_A_time: uint256 future_A_time: uint256 interface AddressProvider: def admin() -> address: view def get_address(_id: uint256) -> address: view interface ERC20: def balanceOf(_addr: address) -> uint256: view def decimals() -> uint256: view def totalSupply() -> uint256: view interface CurvePool: def A() -> uint256: view def future_A() -> uint256: view def fee() -> uint256: view def admin_fee() -> uint256: view def future_fee() -> uint256: view def future_admin_fee() -> uint256: view def future_owner() -> address: view def initial_A() -> uint256: view def initial_A_time() -> uint256: view def future_A_time() -> uint256: view def coins(i: uint256) -> address: view def underlying_coins(i: uint256) -> address: view def balances(i: uint256) -> uint256: view def get_virtual_price() -> uint256: view interface CurvePoolV1: def coins(i: int128) -> address: view def underlying_coins(i: int128) -> address: view def balances(i: int128) -> uint256: view interface CurveMetapool: def base_pool() -> address: view interface GasEstimator: def estimate_gas_used(_pool: address, _from: address, _to: address) -> uint256: view interface LiquidityGauge: def lp_token() -> address: view interface GaugeController: def gauge_types(gauge: address) -> int128: view interface RateCalc: def get_rate(_coin: address) -> uint256: view event PoolAdded: pool: indexed(address) rate_method_id: Bytes[4] event PoolRemoved: pool: indexed(address) address_provider: public(AddressProvider) gauge_controller: public(address) pool_list: public(address[65536]) # master list of pools pool_count: public(uint256) # actual length of pool_list pool_data: HashMap[address, PoolArray] coin_count: public(uint256) # total unique coins registered coins: HashMap[address, CoinInfo] get_coin: public(address[65536]) # unique list of registered coins # bitwise_xor(coina, coinb) -> (coina_pos, coinb_pos) sorted # stored as uint128[2] coin_swap_indexes: HashMap[uint256, uint256] # lp token -> pool get_pool_from_lp_token: public(HashMap[address, address]) # pool -> lp token get_lp_token: public(HashMap[address, address]) # mapping of estimated gas costs for pools and coins # for a pool the values are [wrapped exchange, underlying exchange] # for a coin the values are [transfer cost, 0] gas_estimate_values: HashMap[address, uint256[2]] # pool -> gas estimation contract # used when gas costs for a pool are too complex to be handled by summing # values in `gas_estimate_values` gas_estimate_contracts: HashMap[address, address] # mapping of coins -> pools for trading # a mapping key is generated for each pair of addresses via # `bitwise_xor(convert(a, uint256), convert(b, uint256))` markets: HashMap[uint256, address[65536]] market_counts: HashMap[uint256, uint256] liquidity_gauges: HashMap[address, address[10]] last_updated: public(uint256) @external def __init__(_address_provider: address, _gauge_controller: address): """ @notice Constructor function """ self.address_provider = AddressProvider(_address_provider) self.gauge_controller = _gauge_controller # internal functionality for getters @view @internal def _unpack_decimals(_packed: uint256, _n_coins: uint256) -> uint256[MAX_COINS]: # decimals are tightly packed as a series of uint8 within a little-endian bytes32 # the packed value is stored as uint256 to simplify unpacking via shift and modulo decimals: uint256[MAX_COINS] = empty(uint256[MAX_COINS]) n_coins: int128 = convert(_n_coins, int128) for i in range(MAX_COINS): if i == n_coins: break decimals[i] = shift(_packed, -8 * i) % 256 return decimals @view @internal def _get_rates(_pool: address) -> uint256[MAX_COINS]: rates: uint256[MAX_COINS] = empty(uint256[MAX_COINS]) base_pool: address = self.pool_data[_pool].base_pool if base_pool == ZERO_ADDRESS: rate_info: bytes32 = self.pool_data[_pool].rate_info rate_calc_addr: uint256 = convert(slice(rate_info, 8, 20), uint256) rate_method_id: Bytes[4] = slice(rate_info, 28, 4) for i in range(MAX_COINS): coin: address = self.pool_data[_pool].coins[i] if coin == ZERO_ADDRESS: break if rate_info == EMPTY_BYTES32 or coin == self.pool_data[_pool].ul_coins[i]: rates[i] = 10 ** 18 elif rate_calc_addr != 0: rates[i] = RateCalc(convert(rate_calc_addr, address)).get_rate(coin) else: rates[i] = convert( raw_call(coin, rate_method_id, max_outsize=32, is_static_call=True), # dev: bad response uint256 ) else: base_coin_idx: uint256 = shift(self.pool_data[_pool].n_coins, -128) - 1 rates[base_coin_idx] = CurvePool(base_pool).get_virtual_price() for i in range(MAX_COINS): if i == base_coin_idx: break rates[i] = 10 ** 18 return rates @view @internal def _get_balances(_pool: address) -> uint256[MAX_COINS]: is_v1: bool = self.pool_data[_pool].is_v1 balances: uint256[MAX_COINS] = empty(uint256[MAX_COINS]) for i in range(MAX_COINS): if self.pool_data[_pool].coins[i] == ZERO_ADDRESS: assert i != 0 break if is_v1: balances[i] = CurvePoolV1(_pool).balances(i) else: balances[i] = CurvePool(_pool).balances(convert(i, uint256)) return balances @view @internal def _get_underlying_balances(_pool: address) -> uint256[MAX_COINS]: balances: uint256[MAX_COINS] = self._get_balances(_pool) rates: uint256[MAX_COINS] = self._get_rates(_pool) decimals: uint256 = self.pool_data[_pool].underlying_decimals underlying_balances: uint256[MAX_COINS] = balances for i in range(MAX_COINS): coin: address = self.pool_data[_pool].coins[i] if coin == ZERO_ADDRESS: break ucoin: address = self.pool_data[_pool].ul_coins[i] if ucoin == ZERO_ADDRESS: continue if ucoin != coin: underlying_balances[i] = balances[i] * rates[i] / 10**(shift(decimals, -8 * i) % 256) return underlying_balances @view @internal def _get_meta_underlying_balances(_pool: address, _base_pool: address) -> uint256[MAX_COINS]: base_coin_idx: uint256 = shift(self.pool_data[_pool].n_coins, -128) - 1 is_v1: bool = self.pool_data[_base_pool].is_v1 base_total_supply: uint256 = ERC20(self.get_lp_token[_base_pool]).totalSupply() underlying_balances: uint256[MAX_COINS] = empty(uint256[MAX_COINS]) ul_balance: uint256 = 0 underlying_pct: uint256 = 0 if base_total_supply > 0: underlying_pct = CurvePool(_pool).balances(base_coin_idx) * 10**36 / base_total_supply for i in range(MAX_COINS): if self.pool_data[_pool].ul_coins[i] == ZERO_ADDRESS: break if i < base_coin_idx: ul_balance = CurvePool(_pool).balances(i) else: if is_v1: ul_balance = CurvePoolV1(_base_pool).balances(convert(i - base_coin_idx, int128)) else: ul_balance = CurvePool(_base_pool).balances(i-base_coin_idx) ul_balance = ul_balance * underlying_pct / 10**36 underlying_balances[i] = ul_balance return underlying_balances @view @internal def _get_coin_indices( _pool: address, _from: address, _to: address ) -> uint256[3]: """ Convert coin addresses to indices for use with pool methods. """ # the return value is stored as `uint256[3]` to reduce gas costs # from index, to index, is the market underlying? result: uint256[3] = empty(uint256[3]) found_market: bool = False # check coin markets for x in range(MAX_COINS): coin: address = self.pool_data[_pool].coins[x] if coin == ZERO_ADDRESS: # if we reach the end of the coins, reset `found_market` and try again # with the underlying coins found_market = False break if coin == _from: result[0] = x elif coin == _to: result[1] = x else: continue if found_market: # the second time we find a match, break out of the loop break # the first time we find a match, set `found_market` to True found_market = True if not found_market: # check underlying coin markets for x in range(MAX_COINS): coin: address = self.pool_data[_pool].ul_coins[x] if coin == ZERO_ADDRESS: raise "No available market" if coin == _from: result[0] = x elif coin == _to: result[1] = x else: continue if found_market: result[2] = 1 break found_market = True return result # targetted external getters, optimized for on-chain calls @view @external def find_pool_for_coins(_from: address, _to: address, i: uint256 = 0) -> address: """ @notice Find an available pool for exchanging two coins @param _from Address of coin to be sent @param _to Address of coin to be received @param i Index value. When multiple pools are available this value is used to return the n'th address. @return Pool address """ key: uint256 = bitwise_xor(convert(_from, uint256), convert(_to, uint256)) return self.markets[key][i] @view @external def get_n_coins(_pool: address) -> uint256[2]: """ @notice Get the number of coins in a pool @dev For non-metapools, both returned values are identical even when the pool does not use wrapping/lending @param _pool Pool address @return Number of wrapped coins, number of underlying coins """ n_coins: uint256 = self.pool_data[_pool].n_coins return [shift(n_coins, -128), n_coins % 2**128] @view @external def get_coins(_pool: address) -> address[MAX_COINS]: """ @notice Get the coins within a pool @dev For pools using lending, these are the wrapped coin addresses @param _pool Pool address @return List of coin addresses """ coins: address[MAX_COINS] = empty(address[MAX_COINS]) n_coins: uint256 = shift(self.pool_data[_pool].n_coins, -128) for i in range(MAX_COINS): if i == n_coins: break coins[i] = self.pool_data[_pool].coins[i] return coins @view @external def get_underlying_coins(_pool: address) -> address[MAX_COINS]: """ @notice Get the underlying coins within a pool @dev For pools that do not lend, returns the same value as `get_coins` @param _pool Pool address @return List of coin addresses """ coins: address[MAX_COINS] = empty(address[MAX_COINS]) n_coins: uint256 = self.pool_data[_pool].n_coins % 2**128 for i in range(MAX_COINS): if i == n_coins: break coins[i] = self.pool_data[_pool].ul_coins[i] return coins @view @external def get_decimals(_pool: address) -> uint256[MAX_COINS]: """ @notice Get decimal places for each coin within a pool @dev For pools using lending, these are the wrapped coin decimal places @param _pool Pool address @return uint256 list of decimals """ n_coins: uint256 = shift(self.pool_data[_pool].n_coins, -128) return self._unpack_decimals(self.pool_data[_pool].decimals, n_coins) @view @external def get_underlying_decimals(_pool: address) -> uint256[MAX_COINS]: """ @notice Get decimal places for each underlying coin within a pool @dev For pools that do not lend, returns the same value as `get_decimals` @param _pool Pool address @return uint256 list of decimals """ n_coins: uint256 = self.pool_data[_pool].n_coins % 2**128 return self._unpack_decimals(self.pool_data[_pool].underlying_decimals, n_coins) @view @external def get_rates(_pool: address) -> uint256[MAX_COINS]: """ @notice Get rates between coins and underlying coins @dev For coins where there is no underlying coin, or where the underlying coin cannot be swapped, the rate is given as 1e18 @param _pool Pool address @return Rates between coins and underlying coins """ return self._get_rates(_pool) @view @external def get_gauges(_pool: address) -> (address[10], int128[10]): """ @notice Get a list of LiquidityGauge contracts associated with a pool @param _pool Pool address @return address[10] of gauge addresses, int128[10] of gauge types """ liquidity_gauges: address[10] = empty(address[10]) gauge_types: int128[10] = empty(int128[10]) gauge_controller: address = self.gauge_controller for i in range(10): gauge: address = self.liquidity_gauges[_pool][i] if gauge == ZERO_ADDRESS: break liquidity_gauges[i] = gauge gauge_types[i] = GaugeController(gauge_controller).gauge_types(gauge) return liquidity_gauges, gauge_types @view @external def get_balances(_pool: address) -> uint256[MAX_COINS]: """ @notice Get balances for each coin within a pool @dev For pools using lending, these are the wrapped coin balances @param _pool Pool address @return uint256 list of balances """ return self._get_balances(_pool) @view @external def get_underlying_balances(_pool: address) -> uint256[MAX_COINS]: """ @notice Get balances for each underlying coin within a pool @dev For pools that do not lend, returns the same value as `get_balances` @param _pool Pool address @return uint256 list of underlyingbalances """ base_pool: address = self.pool_data[_pool].base_pool if base_pool == ZERO_ADDRESS: return self._get_underlying_balances(_pool) return self._get_meta_underlying_balances(_pool, base_pool) @view @external def get_virtual_price_from_lp_token(_token: address) -> uint256: """ @notice Get the virtual price of a pool LP token @param _token LP token address @return uint256 Virtual price """ return CurvePool(self.get_pool_from_lp_token[_token]).get_virtual_price() @view @external def get_A(_pool: address) -> uint256: return CurvePool(_pool).A() @view @external def get_parameters(_pool: address) -> PoolParams: """ @notice Get parameters for a pool @dev For older pools where `initial_A` is not public, this value is set to 0 @param _pool Pool address @return Pool amp, future amp, fee, admin fee, future fee, future admin fee, future owner, initial amp, initial amp time, future amp time """ pool_params: PoolParams = empty(PoolParams) pool_params.A = CurvePool(_pool).A() pool_params.future_A = CurvePool(_pool).future_A() pool_params.fee = CurvePool(_pool).fee() pool_params.future_fee = CurvePool(_pool).future_fee() pool_params.admin_fee = CurvePool(_pool).admin_fee() pool_params.future_admin_fee = CurvePool(_pool).future_admin_fee() pool_params.future_owner = CurvePool(_pool).future_owner() if self.pool_data[_pool].has_initial_A: pool_params.initial_A = CurvePool(_pool).initial_A() pool_params.initial_A_time = CurvePool(_pool).initial_A_time() pool_params.future_A_time = CurvePool(_pool).future_A_time() return pool_params @view @external def get_fees(_pool: address) -> uint256[2]: """ @notice Get the fees for a pool @dev Fees are expressed as integers @return Pool fee as uint256 with 1e10 precision Admin fee as 1e10 percentage of pool fee """ return [CurvePool(_pool).fee(), CurvePool(_pool).admin_fee()] @view @external def get_admin_balances(_pool: address) -> uint256[MAX_COINS]: """ @notice Get the current admin balances (uncollected fees) for a pool @param _pool Pool address @return List of uint256 admin balances """ balances: uint256[MAX_COINS] = self._get_balances(_pool) n_coins: uint256 = shift(self.pool_data[_pool].n_coins, -128) for i in range(MAX_COINS): coin: address = self.pool_data[_pool].coins[i] if i == n_coins: break if coin == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE: balances[i] = _pool.balance - balances[i] else: balances[i] = ERC20(coin).balanceOf(_pool) - balances[i] return balances @view @external def get_coin_indices( _pool: address, _from: address, _to: address ) -> (int128, int128, bool): """ @notice Convert coin addresses to indices for use with pool methods @param _from Coin address to be used as `i` within a pool @param _to Coin address to be used as `j` within a pool @return int128 `i`, int128 `j`, boolean indicating if `i` and `j` are underlying coins """ result: uint256[3] = self._get_coin_indices(_pool, _from, _to) return convert(result[0], int128), convert(result[1], int128), result[2] > 0 @view @external def estimate_gas_used(_pool: address, _from: address, _to: address) -> uint256: """ @notice Estimate the gas used in an exchange. @param _pool Pool address @param _from Address of coin to be sent @param _to Address of coin to be received @return Upper-bound gas estimate, in wei """ estimator: address = self.gas_estimate_contracts[_pool] if estimator != ZERO_ADDRESS: return GasEstimator(estimator).estimate_gas_used(_pool, _from, _to) # here we call `_get_coin_indices` to find out if the exchange involves wrapped # or underlying coins, and use the result as an index in `gas_estimate_values` # 0 == wrapped 1 == underlying idx_underlying: uint256 = self._get_coin_indices(_pool, _from, _to)[2] total: uint256 = self.gas_estimate_values[_pool][idx_underlying] assert total != 0 # dev: pool value not set for addr in [_from, _to]: _gas: uint256 = self.gas_estimate_values[addr][0] assert _gas != 0 # dev: coin value not set total += _gas return total @view @external def is_meta(_pool: address) -> bool: """ @notice Verify `_pool` is a metapool @param _pool Pool address @return True if `_pool` is a metapool """ return self.pool_data[_pool].base_pool != ZERO_ADDRESS @view @external def get_pool_name(_pool: address) -> String[64]: """ @notice Get the given name for a pool @param _pool Pool address @return The name of a pool """ return self.pool_data[_pool].name @view @external def get_coin_swap_count(_coin: address) -> uint256: """ @notice Get the number of unique coins available to swap `_coin` against @param _coin Coin address @return The number of unique coins available to swap for """ return self.coins[_coin].swap_count @view @external def get_coin_swap_complement(_coin: address, _index: uint256) -> address: """ @notice Get the coin available to swap against `_coin` at `_index` @param _coin Coin address @param _index An index in the `_coin`'s set of available counter coin's @return Address of a coin available to swap against `_coin` """ return self.coins[_coin].swap_for[_index] @view @external def get_pool_asset_type(_pool: address) -> uint256: """ @notice Query the asset type of `_pool` @param _pool Pool Address @return The asset type as an unstripped string """ return self.pool_data[_pool].asset_type # internal functionality used in admin setters @internal def _add_pool( _sender: address, _pool: address, _n_coins: uint256, _lp_token: address, _rate_info: bytes32, _has_initial_A: bool, _is_v1: bool, _name: String[64], ): assert _sender == self.address_provider.admin() # dev: admin-only function assert _lp_token != ZERO_ADDRESS assert self.pool_data[_pool].coins[0] == ZERO_ADDRESS # dev: pool exists assert self.get_pool_from_lp_token[_lp_token] == ZERO_ADDRESS # add pool to pool_list length: uint256 = self.pool_count self.pool_list[length] = _pool self.pool_count = length + 1 self.pool_data[_pool].location = length self.pool_data[_pool].rate_info = _rate_info self.pool_data[_pool].has_initial_A = _has_initial_A self.pool_data[_pool].is_v1 = _is_v1 self.pool_data[_pool].n_coins = _n_coins self.pool_data[_pool].name = _name # update public mappings self.get_pool_from_lp_token[_lp_token] = _pool self.get_lp_token[_pool] = _lp_token self.last_updated = block.timestamp log PoolAdded(_pool, slice(_rate_info, 28, 4)) @internal def _register_coin(_coin: address): if self.coins[_coin].register_count == 0: coin_count: uint256 = self.coin_count self.coins[_coin].index = coin_count self.get_coin[coin_count] = _coin self.coin_count += 1 self.coins[_coin].register_count += 1 @internal def _register_coin_pair(_coina: address, _coinb: address, _key: uint256): # register _coinb in _coina's array of coins coin_b_pos: uint256 = self.coins[_coina].swap_count self.coins[_coina].swap_for[coin_b_pos] = _coinb self.coins[_coina].swap_count += 1 # register _coina in _coinb's array of coins coin_a_pos: uint256 = self.coins[_coinb].swap_count self.coins[_coinb].swap_for[coin_a_pos] = _coina self.coins[_coinb].swap_count += 1 # register indexes (coina pos in coinb array, coinb pos in coina array) if convert(_coina, uint256) < convert(_coinb, uint256): self.coin_swap_indexes[_key] = shift(coin_a_pos, 128) + coin_b_pos else: self.coin_swap_indexes[_key] = shift(coin_b_pos, 128) + coin_a_pos @internal def _unregister_coin(_coin: address): self.coins[_coin].register_count -= 1 if self.coins[_coin].register_count == 0: self.coin_count -= 1 coin_count: uint256 = self.coin_count location: uint256 = self.coins[_coin].index if location < coin_count: coin_b: address = self.get_coin[coin_count] self.get_coin[location] = coin_b self.coins[coin_b].index = location self.coins[_coin].index = 0 self.get_coin[coin_count] = ZERO_ADDRESS @internal def _unregister_coin_pair(_coina: address, _coinb: address, _coinb_idx: uint256): """ @param _coinb_idx the index of _coinb in _coina's array of unique coin's """ # decrement swap counts for both coins self.coins[_coina].swap_count -= 1 # retrieve the last currently occupied index in coina's array coina_arr_last_idx: uint256 = self.coins[_coina].swap_count # if coinb's index in coina's array is less than the last # overwrite it's position with the last coin if _coinb_idx < coina_arr_last_idx: # here's our last coin in coina's array coin_c: address = self.coins[_coina].swap_for[coina_arr_last_idx] # get the bitwise_xor of the pair to retrieve their indexes key: uint256 = bitwise_xor(convert(_coina, uint256), convert(coin_c, uint256)) indexes: uint256 = self.coin_swap_indexes[key] # update the pairing's indexes if convert(_coina, uint256) < convert(coin_c, uint256): # least complicated most readable way of shifting twice to remove the lower order bits self.coin_swap_indexes[key] = shift(shift(indexes, -128), 128) + _coinb_idx else: self.coin_swap_indexes[key] = shift(_coinb_idx, 128) + indexes % 2 ** 128 # set _coinb_idx in coina's array to coin_c self.coins[_coina].swap_for[_coinb_idx] = coin_c self.coins[_coina].swap_for[coina_arr_last_idx] = ZERO_ADDRESS @internal def _get_new_pool_coins( _pool: address, _n_coins: uint256, _is_underlying: bool, _is_v1: bool ) -> address[MAX_COINS]: coin_list: address[MAX_COINS] = empty(address[MAX_COINS]) coin: address = ZERO_ADDRESS for i in range(MAX_COINS): if i == _n_coins: break if _is_underlying: if _is_v1: coin = CurvePoolV1(_pool).underlying_coins(convert(i, int128)) else: coin = CurvePool(_pool).underlying_coins(i) self.pool_data[_pool].ul_coins[i] = coin else: if _is_v1: coin = CurvePoolV1(_pool).coins(convert(i, int128)) else: coin = CurvePool(_pool).coins(i) self.pool_data[_pool].coins[i] = coin coin_list[i] = coin for i in range(MAX_COINS): if i == _n_coins: break self._register_coin(coin_list[i]) # add pool to markets i2: uint256 = i + 1 for x in range(i2, i2 + MAX_COINS): if x == _n_coins: break key: uint256 = bitwise_xor(convert(coin_list[i], uint256), convert(coin_list[x], uint256)) length: uint256 = self.market_counts[key] self.markets[key][length] = _pool self.market_counts[key] = length + 1 # register the coin pair if length == 0: self._register_coin_pair(coin_list[x], coin_list[i], key) return coin_list @view @internal def _get_new_pool_decimals(_coins: address[MAX_COINS], _n_coins: uint256) -> uint256: packed: uint256 = 0 value: uint256 = 0 n_coins: int128 = convert(_n_coins, int128) for i in range(MAX_COINS): if i == n_coins: break coin: address = _coins[i] if coin == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE: value = 18 else: value = ERC20(coin).decimals() assert value < 256 # dev: decimal overflow packed += shift(value, i * 8) return packed @internal def _remove_market(_pool: address, _coina: address, _coinb: address): key: uint256 = bitwise_xor(convert(_coina, uint256), convert(_coinb, uint256)) length: uint256 = self.market_counts[key] - 1 if length == 0: indexes: uint256 = self.coin_swap_indexes[key] if convert(_coina, uint256) < convert(_coinb, uint256): self._unregister_coin_pair(_coina, _coinb, indexes % 2 ** 128) self._unregister_coin_pair(_coinb, _coina, shift(indexes, -128)) else: self._unregister_coin_pair(_coina, _coinb, shift(indexes, -128)) self._unregister_coin_pair(_coinb, _coina, indexes % 2 ** 128) self.coin_swap_indexes[key] = 0 for i in range(65536): if i > length: break if self.markets[key][i] == _pool: if i < length: self.markets[key][i] = self.markets[key][length] self.markets[key][length] = ZERO_ADDRESS self.market_counts[key] = length break # admin functions @external def add_pool( _pool: address, _n_coins: uint256, _lp_token: address, _rate_info: bytes32, _decimals: uint256, _underlying_decimals: uint256, _has_initial_A: bool, _is_v1: bool, _name: String[64], ): """ @notice Add a pool to the registry @dev Only callable by admin @param _pool Pool address to add @param _n_coins Number of coins in the pool @param _lp_token Pool deposit token address @param _rate_info Encoded twenty-byte rate calculator address and/or four-byte function signature to query coin rates @param _decimals Coin decimal values, tightly packed as uint8 in a little-endian bytes32 @param _underlying_decimals Underlying coin decimal values, tightly packed as uint8 in a little-endian bytes32 @param _name The name of the pool """ self._add_pool( msg.sender, _pool, _n_coins + shift(_n_coins, 128), _lp_token, _rate_info, _has_initial_A, _is_v1, _name, ) coins: address[MAX_COINS] = self._get_new_pool_coins(_pool, _n_coins, False, _is_v1) decimals: uint256 = _decimals if decimals == 0: decimals = self._get_new_pool_decimals(coins, _n_coins) self.pool_data[_pool].decimals = decimals coins = self._get_new_pool_coins(_pool, _n_coins, True, _is_v1) decimals = _underlying_decimals if decimals == 0: decimals = self._get_new_pool_decimals(coins, _n_coins) self.pool_data[_pool].underlying_decimals = decimals @external def add_pool_without_underlying( _pool: address, _n_coins: uint256, _lp_token: address, _rate_info: bytes32, _decimals: uint256, _use_rates: uint256, _has_initial_A: bool, _is_v1: bool, _name: String[64], ): """ @notice Add a pool to the registry @dev Only callable by admin @param _pool Pool address to add @param _n_coins Number of coins in the pool @param _lp_token Pool deposit token address @param _rate_info Encoded twenty-byte rate calculator address and/or four-byte function signature to query coin rates @param _decimals Coin decimal values, tightly packed as uint8 in a little-endian bytes32 @param _use_rates Boolean array indicating which coins use lending rates, tightly packed in a little-endian bytes32 @param _name The name of the pool """ self._add_pool( msg.sender, _pool, _n_coins + shift(_n_coins, 128), _lp_token, _rate_info, _has_initial_A, _is_v1, _name, ) coins: address[MAX_COINS] = self._get_new_pool_coins(_pool, _n_coins, False, _is_v1) decimals: uint256 = _decimals if decimals == 0: decimals = self._get_new_pool_decimals(coins, _n_coins) self.pool_data[_pool].decimals = decimals udecimals: uint256 = 0 for i in range(MAX_COINS): if i == _n_coins: break offset: int128 = -8 * convert(i, int128) if shift(_use_rates, offset) % 256 == 0: self.pool_data[_pool].ul_coins[i] = coins[i] udecimals += shift(shift(decimals, offset) % 256, -offset) self.pool_data[_pool].underlying_decimals = udecimals @external def add_metapool( _pool: address, _n_coins: uint256, _lp_token: address, _decimals: uint256, _name: String[64], _base_pool: address = ZERO_ADDRESS ): """ @notice Add a pool to the registry @dev Only callable by admin @param _pool Pool address to add @param _n_coins Number of coins in the pool @param _lp_token Pool deposit token address @param _decimals Coin decimal values, tightly packed as uint8 in a little-endian bytes32 @param _name The name of the pool @param _base_pool Address of the base_pool useful for adding factory pools """ base_coin_offset: uint256 = _n_coins - 1 base_pool: address = _base_pool if base_pool == ZERO_ADDRESS: base_pool = CurveMetapool(_pool).base_pool() base_n_coins: uint256 = shift(self.pool_data[base_pool].n_coins, -128) assert base_n_coins > 0 # dev: base pool unknown self._add_pool( msg.sender, _pool, base_n_coins + base_coin_offset + shift(_n_coins, 128), _lp_token, EMPTY_BYTES32, True, False, _name, ) coins: address[MAX_COINS] = self._get_new_pool_coins(_pool, _n_coins, False, False) decimals: uint256 = _decimals if decimals == 0: decimals = self._get_new_pool_decimals(coins, _n_coins) self.pool_data[_pool].decimals = decimals self.pool_data[_pool].base_pool = base_pool base_coins: address[MAX_COINS] = empty(address[MAX_COINS]) coin: address = ZERO_ADDRESS for i in range(MAX_COINS): if i == base_n_coins + base_coin_offset: break if i < base_coin_offset: coin = coins[i] else: x: uint256 = i - base_coin_offset coin = self.pool_data[base_pool].coins[x] base_coins[x] = coin self._register_coin(base_coins[x]) self.pool_data[_pool].ul_coins[i] = coin underlying_decimals: uint256 = shift( self.pool_data[base_pool].decimals, 8 * convert(base_coin_offset, int128) ) underlying_decimals += decimals % 256 ** base_coin_offset self.pool_data[_pool].underlying_decimals = underlying_decimals for i in range(MAX_COINS): if i == base_coin_offset: break for x in range(MAX_COINS): if x == base_n_coins: break key: uint256 = bitwise_xor(convert(coins[i], uint256), convert(base_coins[x], uint256)) length: uint256 = self.market_counts[key] self.markets[key][length] = _pool self.market_counts[key] = length + 1 # register the coin pair if length == 0: self._register_coin_pair(coins[i], base_coins[x], key) @external def remove_pool(_pool: address): """ @notice Remove a pool to the registry @dev Only callable by admin @param _pool Pool address to remove """ assert msg.sender == self.address_provider.admin() # dev: admin-only function assert self.pool_data[_pool].coins[0] != ZERO_ADDRESS # dev: pool does not exist self.get_pool_from_lp_token[self.get_lp_token[_pool]] = ZERO_ADDRESS self.get_lp_token[_pool] = ZERO_ADDRESS # remove _pool from pool_list location: uint256 = self.pool_data[_pool].location length: uint256 = self.pool_count - 1 if location < length: # replace _pool with final value in pool_list addr: address = self.pool_list[length] self.pool_list[location] = addr self.pool_data[addr].location = location # delete final pool_list value self.pool_list[length] = ZERO_ADDRESS self.pool_count = length self.pool_data[_pool].underlying_decimals = 0 self.pool_data[_pool].decimals = 0 self.pool_data[_pool].n_coins = 0 self.pool_data[_pool].name = "" self.pool_data[_pool].asset_type = 0 coins: address[MAX_COINS] = empty(address[MAX_COINS]) ucoins: address[MAX_COINS] = empty(address[MAX_COINS]) for i in range(MAX_COINS): coins[i] = self.pool_data[_pool].coins[i] ucoins[i] = self.pool_data[_pool].ul_coins[i] if ucoins[i] == ZERO_ADDRESS and coins[i] == ZERO_ADDRESS: break if coins[i] != ZERO_ADDRESS: # delete coin address from pool_data self.pool_data[_pool].coins[i] = ZERO_ADDRESS self._unregister_coin(coins[i]) if ucoins[i] != ZERO_ADDRESS: # delete underlying_coin from pool_data self.pool_data[_pool].ul_coins[i] = ZERO_ADDRESS if self.coins[ucoins[i]].register_count != 0: self._unregister_coin(ucoins[i]) is_meta: bool = self.pool_data[_pool].base_pool != ZERO_ADDRESS for i in range(MAX_COINS): coin: address = coins[i] ucoin: address = ucoins[i] if coin == ZERO_ADDRESS: break # remove pool from markets i2: uint256 = i + 1 for x in range(i2, i2 + MAX_COINS): ucoinx: address = ucoins[x] if ucoinx == ZERO_ADDRESS: break coinx: address = coins[x] if coinx != ZERO_ADDRESS: self._remove_market(_pool, coin, coinx) if coin != ucoin or coinx != ucoinx: self._remove_market(_pool, ucoin, ucoinx) if is_meta and not ucoin in coins: key: uint256 = bitwise_xor(convert(ucoin, uint256), convert(ucoinx, uint256)) self._register_coin_pair(ucoin, ucoinx, key) self.pool_data[_pool].base_pool = ZERO_ADDRESS self.last_updated = block.timestamp log PoolRemoved(_pool) @external def set_pool_gas_estimates(_addr: address[5], _amount: uint256[2][5]): """ @notice Set gas estimate amounts @param _addr Array of pool addresses @param _amount Array of gas estimate amounts as `[(wrapped, underlying), ..]` """ assert msg.sender == self.address_provider.admin() # dev: admin-only function for i in range(5): _pool: address = _addr[i] if _pool == ZERO_ADDRESS: break self.gas_estimate_values[_pool] = _amount[i] self.last_updated = block.timestamp @external def set_coin_gas_estimates(_addr: address[10], _amount: uint256[10]): """ @notice Set gas estimate amounts @param _addr Array of coin addresses @param _amount Array of gas estimate amounts """ assert msg.sender == self.address_provider.admin() # dev: admin-only function for i in range(10): _coin: address = _addr[i] if _coin == ZERO_ADDRESS: break self.gas_estimate_values[_coin][0] = _amount[i] self.last_updated = block.timestamp @external def set_gas_estimate_contract(_pool: address, _estimator: address): """ @notice Set gas estimate contract @param _pool Pool address @param _estimator GasEstimator address """ assert msg.sender == self.address_provider.admin() # dev: admin-only function self.gas_estimate_contracts[_pool] = _estimator self.last_updated = block.timestamp @external def set_liquidity_gauges(_pool: address, _liquidity_gauges: address[10]): """ @notice Set liquidity gauge contracts`` @param _pool Pool address @param _liquidity_gauges Liquidity gauge address """ assert msg.sender == self.address_provider.admin() # dev: admin-only function _lp_token: address = self.get_lp_token[_pool] _gauge_controller: address = self.gauge_controller for i in range(10): _gauge: address = _liquidity_gauges[i] if _gauge != ZERO_ADDRESS: assert LiquidityGauge(_gauge).lp_token() == _lp_token # dev: wrong token GaugeController(_gauge_controller).gauge_types(_gauge) self.liquidity_gauges[_pool][i] = _gauge elif self.liquidity_gauges[_pool][i] != ZERO_ADDRESS: self.liquidity_gauges[_pool][i] = ZERO_ADDRESS else: break self.last_updated = block.timestamp @external def set_pool_asset_type(_pool: address, _asset_type: uint256): """ @notice Set the asset type name for a curve pool @dev This is a simple way to setting the cache of categories instead of performing some computation for no reason. Pool's don't necessarily change once they are deployed. @param _pool Pool address @param _asset_type String of asset type """ assert msg.sender == self.address_provider.admin() # dev: admin-only function self.pool_data[_pool].asset_type = _asset_type self.last_updated = block.timestamp @external def batch_set_pool_asset_type(_pools: address[32], _asset_types: uint256[32]): """ @notice Batch set the asset type name for curve pools @dev This is a simple way of setting the cache of categories instead of performing some computation for no reason. Pool's don't necessarily change once they are deployed. """ assert msg.sender == self.address_provider.admin() # dev: admin-only function for i in range(32): if _pools[i] == ZERO_ADDRESS: break self.pool_data[_pools[i]].asset_type = _asset_types[i] self.last_updated = block.timestamp
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"name":"PoolAdded","inputs":[{"name":"pool","type":"address","indexed":true},{"name":"rate_method_id","type":"bytes","indexed":false}],"anonymous":false,"type":"event"},{"name":"PoolRemoved","inputs":[{"name":"pool","type":"address","indexed":true}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_address_provider","type":"address"},{"name":"_gauge_controller","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"find_pool_for_coins","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"find_pool_for_coins","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"i","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"get_n_coins","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[2]"}],"gas":1521},{"stateMutability":"view","type":"function","name":"get_coins","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"address[8]"}],"gas":12102},{"stateMutability":"view","type":"function","name":"get_underlying_coins","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"address[8]"}],"gas":12194},{"stateMutability":"view","type":"function","name":"get_decimals","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[8]"}],"gas":7874},{"stateMutability":"view","type":"function","name":"get_underlying_decimals","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[8]"}],"gas":7966},{"stateMutability":"view","type":"function","name":"get_rates","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[8]"}],"gas":36992},{"stateMutability":"view","type":"function","name":"get_gauges","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"address[10]"},{"name":"","type":"int128[10]"}],"gas":20157},{"stateMutability":"view","type":"function","name":"get_balances","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[8]"}],"gas":16583},{"stateMutability":"view","type":"function","name":"get_underlying_balances","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[8]"}],"gas":162842},{"stateMutability":"view","type":"function","name":"get_virtual_price_from_lp_token","inputs":[{"name":"_token","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1927},{"stateMutability":"view","type":"function","name":"get_A","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1045},{"stateMutability":"view","type":"function","name":"get_parameters","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"A","type":"uint256"},{"name":"future_A","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"admin_fee","type":"uint256"},{"name":"future_fee","type":"uint256"},{"name":"future_admin_fee","type":"uint256"},{"name":"future_owner","type":"address"},{"name":"initial_A","type":"uint256"},{"name":"initial_A_time","type":"uint256"},{"name":"future_A_time","type":"uint256"}],"gas":6305},{"stateMutability":"view","type":"function","name":"get_fees","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[2]"}],"gas":1450},{"stateMutability":"view","type":"function","name":"get_admin_balances","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256[8]"}],"gas":36454},{"stateMutability":"view","type":"function","name":"get_coin_indices","inputs":[{"name":"_pool","type":"address"},{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"outputs":[{"name":"","type":"int128"},{"name":"","type":"int128"},{"name":"","type":"bool"}],"gas":27131},{"stateMutability":"view","type":"function","name":"estimate_gas_used","inputs":[{"name":"_pool","type":"address"},{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":32004},{"stateMutability":"view","type":"function","name":"is_meta","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"bool"}],"gas":1900},{"stateMutability":"view","type":"function","name":"get_pool_name","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"string"}],"gas":8323},{"stateMutability":"view","type":"function","name":"get_coin_swap_count","inputs":[{"name":"_coin","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":1951},{"stateMutability":"view","type":"function","name":"get_coin_swap_complement","inputs":[{"name":"_coin","type":"address"},{"name":"_index","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":2090},{"stateMutability":"view","type":"function","name":"get_pool_asset_type","inputs":[{"name":"_pool","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":2011},{"stateMutability":"nonpayable","type":"function","name":"add_pool","inputs":[{"name":"_pool","type":"address"},{"name":"_n_coins","type":"uint256"},{"name":"_lp_token","type":"address"},{"name":"_rate_info","type":"bytes32"},{"name":"_decimals","type":"uint256"},{"name":"_underlying_decimals","type":"uint256"},{"name":"_has_initial_A","type":"bool"},{"name":"_is_v1","type":"bool"},{"name":"_name","type":"string"}],"outputs":[],"gas":61485845},{"stateMutability":"nonpayable","type":"function","name":"add_pool_without_underlying","inputs":[{"name":"_pool","type":"address"},{"name":"_n_coins","type":"uint256"},{"name":"_lp_token","type":"address"},{"name":"_rate_info","type":"bytes32"},{"name":"_decimals","type":"uint256"},{"name":"_use_rates","type":"uint256"},{"name":"_has_initial_A","type":"bool"},{"name":"_is_v1","type":"bool"},{"name":"_name","type":"string"}],"outputs":[],"gas":31306062},{"stateMutability":"nonpayable","type":"function","name":"add_metapool","inputs":[{"name":"_pool","type":"address"},{"name":"_n_coins","type":"uint256"},{"name":"_lp_token","type":"address"},{"name":"_decimals","type":"uint256"},{"name":"_name","type":"string"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_metapool","inputs":[{"name":"_pool","type":"address"},{"name":"_n_coins","type":"uint256"},{"name":"_lp_token","type":"address"},{"name":"_decimals","type":"uint256"},{"name":"_name","type":"string"},{"name":"_base_pool","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"remove_pool","inputs":[{"name":"_pool","type":"address"}],"outputs":[],"gas":779731418758},{"stateMutability":"nonpayable","type":"function","name":"set_pool_gas_estimates","inputs":[{"name":"_addr","type":"address[5]"},{"name":"_amount","type":"uint256[2][5]"}],"outputs":[],"gas":390460},{"stateMutability":"nonpayable","type":"function","name":"set_coin_gas_estimates","inputs":[{"name":"_addr","type":"address[10]"},{"name":"_amount","type":"uint256[10]"}],"outputs":[],"gas":392047},{"stateMutability":"nonpayable","type":"function","name":"set_gas_estimate_contract","inputs":[{"name":"_pool","type":"address"},{"name":"_estimator","type":"address"}],"outputs":[],"gas":72629},{"stateMutability":"nonpayable","type":"function","name":"set_liquidity_gauges","inputs":[{"name":"_pool","type":"address"},{"name":"_liquidity_gauges","type":"address[10]"}],"outputs":[],"gas":400675},{"stateMutability":"nonpayable","type":"function","name":"set_pool_asset_type","inputs":[{"name":"_pool","type":"address"},{"name":"_asset_type","type":"uint256"}],"outputs":[],"gas":72667},{"stateMutability":"nonpayable","type":"function","name":"batch_set_pool_asset_type","inputs":[{"name":"_pools","type":"address[32]"},{"name":"_asset_types","type":"uint256[32]"}],"outputs":[],"gas":1173447},{"stateMutability":"view","type":"function","name":"address_provider","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2048},{"stateMutability":"view","type":"function","name":"gauge_controller","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2078},{"stateMutability":"view","type":"function","name":"pool_list","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":2217},{"stateMutability":"view","type":"function","name":"pool_count","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2138},{"stateMutability":"view","type":"function","name":"coin_count","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2168},{"stateMutability":"view","type":"function","name":"get_coin","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":2307},{"stateMutability":"view","type":"function","name":"get_pool_from_lp_token","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"address"}],"gas":2443},{"stateMutability":"view","type":"function","name":"get_lp_token","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"address"}],"gas":2473},{"stateMutability":"view","type":"function","name":"last_updated","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2288}]
Contract Creation Code
6f7fffffffffffffffffffffffffffffff6040526040615fbc610140396020615fbc60c03960c05160a01c1561003457600080fd5b60206020615fbc0160c03960c05160a01c1561004f57600080fd5b6101405160005561016051600155615fa456600436101561000d57613a15565b600035601c526f7fffffffffffffffffffffffffffffff604052600051341561003557600080fd5b63a87df06c81141561004c5760006101405261006d565b636982eb0b81141561006857602060446101403760005061006d565b6100cf565b60043560a01c1561007d57600080fd5b60243560a01c1561008d57600080fd5b6024356004351861016052610140516201000081106100ab57600080fd5b600d6101605160e05260c052604060c02060c052602060c020015460005260206000f35b63940494f181141561013e5760043560a01c156100eb57600080fd5b6007600460043560e05260c052604060c02060c052602060c0200154610140526101405160801c6101805261014051700100000000000000000000000000000000808206905090506101a0526040610180f35b639ac90d3d81141561020e5760043560a01c1561015a57600080fd5b61010036610140376007600460043560e05260c052604060c02060c052602060c020015460801c6102405261026060006008818352015b610240516102605114156101a457610204565b61026051600881106101b557600080fd5b6005600460043560e05260c052604060c02060c052602060c0200160c052602060c020015461014061026051600881106101ee57600080fd5b60200201525b8151600101808352811415610191575b5050610100610140f35b63a77576ef8114156102f45760043560a01c1561022a57600080fd5b61010036610140376007600460043560e05260c052604060c02060c052602060c0200154700100000000000000000000000000000000808206905090506102405261026060006008818352015b6102405161026051141561028a576102ea565b610260516008811061029b57600080fd5b6006600460043560e05260c052604060c02060c052602060c0200160c052602060c020015461014061026051600881106102d457600080fd5b60200201525b8151600101808352811415610277575b5050610100610140f35b6352b5155581141561039c5760043560a01c1561031057600080fd5b6007600460043560e05260c052604060c02060c052602060c020015460801c61014052610100610140516001600460043560e05260c052604060c02060c052602060c0200154610160526101405161018052610180516101605160065801613a1b565b6101e05261020052610220526102405261026052610280526102a0526102c052610140526101e0f35b634cb088f181141561045a5760043560a01c156103b857600080fd5b6007600460043560e05260c052604060c02060c052602060c02001547001000000000000000000000000000000008082069050905061014052610100610140516002600460043560e05260c052604060c02060c052602060c0200154610160526101405161018052610180516101605160065801613a1b565b6101e05261020052610220526102405261026052610280526102a0526102c052610140526101e0f35b63ce99e45a8114156104b25760043560a01c1561047657600080fd5b610100600435610140526101405160065801613b3f565b6101a0526101c0526101e05261020052610220526102405261026052610280526101a0f35b6356059ffb8114156107075760043560a01c156104ce57600080fd5b61028036610140376001546103c0526103e06000600a818352015b6103e051600a81106104fa57600080fd5b600f60043560e05260c052604060c02060c052602060c020015461040052610400511515610527576105ac565b610400516101406103e051600a811061053f57600080fd5b602002015260206104a06024633f9095b761042052610400516104405261043c6103c0515afa61056e57600080fd5b601f3d1161057b57600080fd5b6000506104a0516102806103e051600a811061059657600080fd5b60200201525b81516001018083528114156104e9575b50506103e080808080806101405181525050602081019050808061016051815250506020810190508080610180518152505060208101905080806101a0518152505060208101905080806101c0518152505060208101905080806101e051815250506020810190508080610200518152505060208101905080806102205181525050602081019050808061024051815250506020810190508080610260518152505050506101408101905080808080610280518152505060208101905080806102a0518152505060208101905080806102c0518152505060208101905080806102e05181525050602081019050808061030051815250506020810190508080610320518152505060208101905080806103405181525050602081019050808061036051815250506020810190508080610380518152505060208101905080806103a0518152505050506102809050905060c05260c0516103e0f35b6392e3cc2d81141561075f5760043560a01c1561072357600080fd5b610100600435610140526101405160065801613f83565b6101a0526101c0526101e05261020052610220526102405261026052610280526101a0f35b6359f4f3518114156108395760043560a01c1561077b57600080fd5b6004600460043560e05260c052604060c02060c052602060c0200154610140526101405115156107e9576101006101405160043561016052610160516006580161412b565b6101c0526101e05261020052610220526102405261026052610280526102a052610140526101c0f35b610100610140516004356101605261014051610180526101805161016051600658016145d7565b6101e05261020052610220526102405261026052610280526102a0526102c052610140526101e0f35b63c5b7074a8114156108a15760043560a01c1561085557600080fd5b60206101a0600463bb7b8b806101405261015c600960043560e05260c052604060c020545afa61088457600080fd5b601f3d1161089157600080fd5b6000506101a05160005260206000f35b6355b30b198114156108fb5760043560a01c156108bd57600080fd5b60206101a0600463f446c1d06101405261015c6004355afa6108de57600080fd5b601f3d116108eb57600080fd5b6000506101a05160005260206000f35b631f80a957811415610c375760043560a01c1561091757600080fd5b610140366101403760206102e0600463f446c1d06102805261029c6004355afa61094057600080fd5b601f3d1161094d57600080fd5b6000506102e0516101405260206102e0600463b4b577ad6102805261029c6004355afa61097957600080fd5b601f3d1161098657600080fd5b6000506102e0516101605260206102e0600463ddca3f436102805261029c6004355afa6109b257600080fd5b601f3d116109bf57600080fd5b6000506102e0516101805260206102e060046358680d0b6102805261029c6004355afa6109eb57600080fd5b601f3d116109f857600080fd5b6000506102e0516101c05260206102e0600463fee3f7f96102805261029c6004355afa610a2457600080fd5b601f3d11610a3157600080fd5b6000506102e0516101a05260206102e0600463e38244626102805261029c6004355afa610a5d57600080fd5b601f3d11610a6a57600080fd5b6000506102e0516101e05260206102e06004631ec0cdc16102805261029c6004355afa610a9657600080fd5b601f3d11610aa357600080fd5b6000506102e051610200526008600460043560e05260c052604060c02060c052602060c020015415610b7b5760206102e06004635409491a6102805261029c6004355afa610af057600080fd5b601f3d11610afd57600080fd5b6000506102e0516102205260206102e06004632081066c6102805261029c6004355afa610b2957600080fd5b601f3d11610b3657600080fd5b6000506102e0516102405260206102e0600463140522886102805261029c6004355afa610b6257600080fd5b601f3d11610b6f57600080fd5b6000506102e051610260525b610140610280808080845181525050602081019050808084602001518152505060208101905080808460400151815250506020810190508080846060015181525050602081019050808084608001518152505060208101905080808460a001518152505060208101905080808460c001518152505060208101905080808460e00151815250506020810190508080846101000151815250506020810190508080846101200151815250506101409050905060c05260c051610280f35b637cdb72b0811415610ccc5760043560a01c15610c5357600080fd5b60206101a0600463ddca3f436101405261015c6004355afa610c7457600080fd5b601f3d11610c8157600080fd5b6000506101a051610260526020610220600463fee3f7f96101c0526101dc6004355afa610cad57600080fd5b601f3d11610cba57600080fd5b60005061022051610280526040610260f35b63c11e45b8811415610f2d5760043560a01c15610ce857600080fd5b6101405161016051610180516101a0516101c0516101e0516102005161022051600435610240526102405160065801613f83565b6102a0526102c0526102e052610300526103205261034052610360526103805261022052610200526101e0526101c0526101a0526101805261016052610140526102a080516101405280602001516101605280604001516101805280606001516101a05280608001516101c0528060a001516101e0528060c00151610200528060e0015161022052506007600460043560e05260c052604060c02060c052602060c020015460801c6102405261026060006008818352015b6102605160088110610de557600080fd5b6005600460043560e05260c052604060c02060c052602060c0200160c052602060c02001546102805261024051610260511415610e2157610f23565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee610280511415610e8f57600435316101406102605160088110610e5857600080fd5b602002015180821015610e6a57600080fd5b808203905090506101406102605160088110610e8557600080fd5b6020020152610f13565b602061032060246370a082316102a0526004356102c0526102bc610280515afa610eb857600080fd5b601f3d11610ec557600080fd5b600050610320516101406102605160088110610ee057600080fd5b602002015180821015610ef257600080fd5b808203905090506101406102605160088110610f0d57600080fd5b60200201525b8151600101808352811415610dd4575b5050610100610140f35b63eb85226d8114156110435760043560a01c15610f4957600080fd5b60243560a01c15610f5957600080fd5b60443560a01c15610f6957600080fd5b6101405161016051610180516004356101a0526024356101c0526044356101e0526101e0516101c0516101a0516006580161493d565b6102405261026052610280526101805261016052610140526102408051610140528060200151610160528060400151610180525061014051604051811115610fe657600080fd5b6101a05261016051604051811115610ffd57600080fd5b6101c0526101e08080806101a0518152505060208101905080806101c051815250506020810190508080600061018051118152505060609050905060c05260c0516101e0f35b63b0bb365b81141561121e5760043560a01c1561105f57600080fd5b60243560a01c1561106f57600080fd5b60443560a01c1561107f57600080fd5b600c60043560e05260c052604060c020546101405260006101405118156110f4576020610220606463b0bb365b61016052600435610180526024356101a0526044356101c05261017c610140515afa6110d757600080fd5b601f3d116110e457600080fd5b6000506102205160005260206000f35b6101405161016051600435610180526024356101a0526044356101c0526101c0516101a051610180516006580161493d565b61022052610240526102605261016052610140526102206040015161016052610160516002811061115657600080fd5b600b60043560e05260c052604060c02060c052602060c0200154610180526000610180511861118457600080fd5b6024356101e052604435610200526101c060006002818352015b60206101c051026101e001516101a052600b6101a05160e05260c052604060c02060c052602060c0205461022052600061022051186111dc57600080fd5b6101808051610220518181830110156111f457600080fd5b808201905090508152505b815160010180835281141561119e575b50506101805160005260206000f35b63e4d332a98114156112635760043560a01c1561123a57600080fd5b60006004600460043560e05260c052604060c02060c052602060c0200154141560005260206000f35b635c9117418114156113315760043560a01c1561127f57600080fd5b600a600460043560e05260c052604060c02060c052602060c020018060c052602060c020610180602082540161012060006003818352015b826101205160200211156112ca576112ec565b61012051850154610120516020028501525b81516001018083528114156112b7575b50505050505061018051806101a001818260206001820306601f82010390500336823750506020610160526040610180510160206001820306601f8201039050610160f35b6398aede168114156113725760043560a01c1561134d57600080fd5b6002600660043560e05260c052604060c02060c052602060c020015460005260206000f35b635d2119828114156113db5760043560a01c1561138e57600080fd5b6024356f7fffffffffffffffffffffffffffffff81106113ad57600080fd5b6003600660043560e05260c052604060c02060c052602060c0200160c052602060c020015460005260206000f35b6366d3966c81141561141c5760043560a01c156113f757600080fd5b600b600460043560e05260c052604060c02060c052602060c020015460005260206000f35b6399209aa18114156119d05760043560a01c1561143857600080fd5b60443560a01c1561144857600080fd5b60c43560011c1561145857600080fd5b60e43560011c1561146857600080fd5b6060610104356004016101403760406101043560040135111561148a57600080fd5b6101405161016051610180516101a051610100336101c0526004356101e05260243560243560801b8181830110156114c157600080fd5b8082019050905061020052604435610220526064356102405260c4356102605260e43561028052806102a05261014080805160200180846101c0018284600060045af161150d57600080fd5b505050506102a051806101c00180518060206001820306601f82010390508201610360525050505b6102c06103605110156115475761155c565b61036051516020610360510361036052611535565b6102a05161028051610260516102405161022051610200516101e0516101c05160065801614b56565b6101a0526101805261016052610140526000506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516004356102c0526024356102e05260006103005260e4356103205261032051610300516102e0516102c0516006580161550f565b610380526103a0526103c0526103e052610400526104205261044052610460526102a05261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261038080516101c05280602001516101e0528060400151610200528060600151610220528060800151610240528060a00151610260528060c00151610280528060e001516102a052506084356102c0526102c051151561178f576101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516101c0516102e0526101e051610300526102005161032052610220516103405261024051610360526102605161038052610280516103a0526102a0516103c0526024356103e0526103e0516103c0516103a05161038051610360516103405161032051610300516102e05160065801615a10565b610440526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610440516102c0525b6102c0516001600460043560e05260c052604060c02060c052602060c02001556101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516004356102e0526024356103005260016103205260e435610340526103405161032051610300516102e0516006580161550f565b6103a0526103c0526103e05261040052610420526104405261046052610480526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103a080516101c05280602001516101e0528060400151610200528060600151610220528060800151610240528060a00151610260528060c00151610280528060e001516102a0525060a4356102c0526102c05115156119ae576101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516101c0516102e0526101e051610300526102005161032052610220516103405261024051610360526102605161038052610280516103a0526102a0516103c0526024356103e0526103e0516103c0516103a05161038051610360516103405161032051610300516102e05160065801615a10565b610440526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610440516102c0525b6102c0516002600460043560e05260c052604060c02060c052602060c0200155005b63dcee86a3811415611f5d5760043560a01c156119ec57600080fd5b60443560a01c156119fc57600080fd5b60c43560011c15611a0c57600080fd5b60e43560011c15611a1c57600080fd5b60606101043560040161014037604061010435600401351115611a3e57600080fd5b6101405161016051610180516101a051610100336101c0526004356101e05260243560243560801b818183011015611a7557600080fd5b8082019050905061020052604435610220526064356102405260c4356102605260e43561028052806102a05261014080805160200180846101c0018284600060045af1611ac157600080fd5b505050506102a051806101c00180518060206001820306601f82010390508201610360525050505b6102c0610360511015611afb57611b10565b61036051516020610360510361036052611ae9565b6102a05161028051610260516102405161022051610200516101e0516101c05160065801614b56565b6101a0526101805261016052610140526000506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516004356102c0526024356102e05260006103005260e4356103205261032051610300516102e0516102c0516006580161550f565b610380526103a0526103c0526103e052610400526104205261044052610460526102a05261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261038080516101c05280602001516101e0528060400151610200528060600151610220528060800151610240528060a00151610260528060c00151610280528060e001516102a052506084356102c0526102c0511515611d43576101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516101c0516102e0526101e051610300526102005161032052610220516103405261024051610360526102605161038052610280516103a0526102a0516103c0526024356103e0526103e0516103c0516103a05161038051610360516103405161032051610300516102e05160065801615a10565b610440526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a052610180526101605261014052610440516102c0525b6102c0516001600460043560e05260c052604060c02060c052602060c020015560006102e05261030060006008818352015b602435610300511415611d8757611f39565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff861030051604051811115611dbb57600080fd5b80820280806000811215611dcb57195b607f1c15611dd857600080fd5b90509050905061032052610320516000811215611dfc5760a435816000031c611e02565b60a435811b5b9050610100808206905090501515611f29576101c06103005160088110611e2857600080fd5b60200201516103005160088110611e3e57600080fd5b6006600460043560e05260c052604060c02060c052602060c0200160c052602060c02001556102e08051610320517fffffffffffffffffffffffffffffffff800000000000000000000000000000008113611e9857600080fd5b6000036000811215611edc57610320516000811215611ebf576102c051816000031c611ec6565b6102c051811b5b905061010080820690509050816000031c611f0d565b610320516000811215611ef7576102c051816000031c611efe565b6102c051811b5b905061010080820690509050811b5b9050818183011015611f1e57600080fd5b808201905090508152505b8151600101808352811415611d75575b50506102e0516002600460043560e05260c052604060c02060c052602060c0200155005b63ce6f94e1811415611f745760006101c052611fa5565b63d2a06baf811415611fa05760a43560a01c15611f9057600080fd5b602060a46101c037600050611fa5565b6128bb565b60043560a01c15611fb557600080fd5b60443560a01c15611fc557600080fd5b6060608435600401610140376040608435600401351115611fe557600080fd5b602435600180821015611ff757600080fd5b808203905090506101e0526101c0516102005261020051151561204e5760206102806004635d6362bb6102205261023c6004355afa61203557600080fd5b601f3d1161204257600080fd5b60005061028051610200525b600760046102005160e05260c052604060c02060c052602060c020015460801c610220526000610220511161208257600080fd5b6101405161016051610180516101a0516101c0516101e0516102005161022051610100336102405260043561026052610220516101e0518181830110156120c857600080fd5b8082019050905060243560801b8181830110156120e457600080fd5b80820190509050610280526044356102a05260006102c05260016102e05260006103005280610320526101408080516020018084610240018284600060045af161212d57600080fd5b5050505061032051806102400180518060206001820306601f820103905082016103e0525050505b6103406103e05110156121675761217c565b6103e0515160206103e051036103e052612155565b61032051610300516102e0516102c0516102a05161028051610260516102405160065801614b56565b61022052610200526101e0526101c0526101a0526101805261016052610140526000506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e0516103005161032051600435610340526024356103605260006103805260006103a0526103a0516103805161036051610340516006580161550f565b61040052610420526104405261046052610480526104a0526104c0526104e05261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405261040080516102405280602001516102605280604001516102805280606001516102a05280608001516102c0528060a001516102e0528060c00151610300528060e001516103205250606435610340526103405115156123fe576101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161024051610360526102605161038052610280516103a0526102a0516103c0526102c0516103e0526102e051610400526103005161042052610320516104405260243561046052610460516104405161042051610400516103e0516103c0516103a051610380516103605160065801615a10565b6104c0526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526104c051610340525b610340516001600460043560e05260c052604060c02060c052602060c0200155610200516004600460043560e05260c052604060c02060c052602060c0200155610120366103603761048060006008818352015b610220516101e05181818301101561246957600080fd5b8082019050905061048051141561247f576125f5565b6101e0516104805110156124af5761024061048051600881106124a157600080fd5b6020020151610460526125aa565b610480516101e051808210156124c457600080fd5b808203905090506104a0526104a051600881106124e057600080fd5b600560046102005160e05260c052604060c02060c052602060c0200160c052602060c020015461046052610460516103606104a0516008811061252257600080fd5b60200201526101406104c0525b6104c0515160206104c051016104c0526104c06104c05110156125515761252f565b6103606104a0516008811061256557600080fd5b60200201516104e0526104e05160065801614ef8565b6104a06104c0525b6104c0515260206104c051036104c0526101406104c0511015156125a657612583565b6000505b6104605161048051600881106125bf57600080fd5b6006600460043560e05260c052604060c02060c052602060c0200160c052602060c02001555b8151600101808352811415612452575b505060086101e05160405181111561260c57600080fd5b8082028080600081121561261c57195b607f1c1561262957600080fd5b905090509050600081121561265f57600160046102005160e05260c052604060c02060c052602060c0200154816000031c61267f565b600160046102005160e05260c052604060c02060c052602060c0200154811b5b90506104805261048080516103405160206101e0511061269e57600080fd5b6101e0516101000a80806126b157600080fd5b8206905090508181830110156126c657600080fd5b80820190509050815250610480516002600460043560e05260c052604060c02060c052602060c02001556104a060006008818352015b6101e0516104a051141561270f576128b7565b6104c060006008818352015b610220516104c051141561272e576128a4565b6103606104c0516008811061274257600080fd5b60200201516102406104a0516008811061275b57600080fd5b6020020151186104e052600e6104e05160e05260c052604060c02054610500526004356105005162010000811061279157600080fd5b600d6104e05160e05260c052604060c02060c052602060c02001556105005160018181830110156127c157600080fd5b80820190509050600e6104e05160e05260c052604060c0205561050051151561289457610140610520525b6105205151602061052051016105205261052061052051101561280e576127ec565b6102406104a0516008811061282257600080fd5b6020020151610540526103606104c0516008811061283f57600080fd5b6020020151610560526104e0516105805261058051610560516105405160065801614fca565b610500610520525b61052051526020610520510361052052610140610520511015156128905761286d565b6000505b815160010180835281141561271b575b50505b81516001018083528114156126fc575b5050005b63474932b081141561325a5760043560a01c156128d757600080fd5b60206101a0600463f851a4406101405261015c6000545afa6128f857600080fd5b601f3d1161290557600080fd5b6000506101a051331461291757600080fd5b60006005600460043560e05260c052604060c02060c052602060c0200160c052602060c020541861294757600080fd5b60006009600a60043560e05260c052604060c0205460e05260c052604060c020556000600a60043560e05260c052604060c02055600460043560e05260c052604060c02060c052602060c02054610140526003546001808210156129aa57600080fd5b808203905090506101605261016051610140511015612a2857610160516201000081106129d657600080fd5b600260c052602060c02001546101805261018051610140516201000081106129fd57600080fd5b600260c052602060c02001556101405160046101805160e05260c052604060c02060c052602060c020555b600061016051620100008110612a3d57600080fd5b600260c052602060c02001556101605160035560006002600460043560e05260c052604060c02060c052602060c020015560006001600460043560e05260c052604060c02060c052602060c020015560006007600460043560e05260c052604060c02060c052602060c020015560006101805261018080600a600460043560e05260c052604060c02060c052602060c0200160c052602060c020602082510161012060006001818352015b82610120516020021115612afb57612b1d565b61012051602002850151610120518501555b8151600101808352811415612ae8575b5050505050506000600b600460043560e05260c052604060c02060c052602060c0200155610200366101803761038060006008818352015b6103805160088110612b6657600080fd5b6005600460043560e05260c052604060c02060c052602060c0200160c052602060c02001546101806103805160088110612b9f57600080fd5b60200201526103805160088110612bb557600080fd5b6006600460043560e05260c052604060c02060c052602060c0200160c052602060c02001546102806103805160088110612bee57600080fd5b60200201526102806103805160088110612c0757600080fd5b60200201511515612c31576101806103805160088110612c2657600080fd5b602002015115612c34565b60005b15612c3e57612ec6565b60006101806103805160088110612c5457600080fd5b60200201511815612d5d5760006103805160088110612c7257600080fd5b6005600460043560e05260c052604060c02060c052602060c0200160c052602060c02001556101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516101806103805160088110612cf757600080fd5b60200201516103a0526103a051600658016151a2565b61038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526000505b60006102806103805160088110612d7357600080fd5b60200201511815612eb65760006103805160088110612d9157600080fd5b6006600460043560e05260c052604060c02060c052602060c0200160c052602060c02001556000600160066102806103805160088110612dd057600080fd5b602002015160e05260c052604060c02060c052602060c02001541815612eb6576101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e05161030051610320516103405161036051610380516102806103805160088110612e5057600080fd5b60200201516103a0526103a051600658016151a2565b61038052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526000505b8151600101808352811415612b55575b505060006004600460043560e05260c052604060c02060c052602060c02001541415610380526103a060006008818352015b6101806103a05160088110612f0c57600080fd5b60200201516103c0526102806103a05160088110612f2957600080fd5b60200201516103e0526103c0511515612f415761320b565b6103a0516001818183011015612f5657600080fd5b8082019050905061040052610420610400516008818352015b6102806104205160088110612f8357600080fd5b602002015161044052610440511515612f9b576131f8565b6101806104205160088110612faf57600080fd5b602002015161046052600061046051181561304957610140610480525b61048051516020610480510161048052610480610480511015612fee57612fcc565b6004356104a0526103c0516104c052610460516104e0526104e0516104c0516104a05160065801615b91565b610460610480525b610480515260206104805103610480526101406104805110151561304557613022565b6000505b6103e0516103c051181561305e576001613069565b610440516104605114155b156130f357610140610480525b6104805151602061048051016104805261048061048051101561309857613076565b6004356104a0526103e0516104c052610440516104e0526104e0516104c0516104a05160065801615b91565b610460610480525b61048051526020610480510361048052610140610480511015156130ef576130cc565b6000505b610380511561314d5760006104a0526104a061012060006008818352015b6101205160200261018001516103e05114156131305760018352613140565b8151600101808352811415613111575b5050506104a05115613150565b60005b156131e857610440516103e051186104c0526101406104e0525b6104e0515160206104e051016104e0526104e06104e051101561318c5761316a565b6103e0516105005261044051610520526104c0516105405261054051610520516105005160065801614fca565b6104c06104e0525b6104e0515260206104e051036104e0526101406104e0511015156131e4576131c1565b6000505b8151600101808352811415612f6f575b50505b8151600101808352811415612ef8575b505060006004600460043560e05260c052604060c02060c052602060c0200155426010556004357f4106dfdaa577573db51c0ca93f766dbedfa0758faa2e7f5bcdb7c142be803c3f60006000a2005b630733b67a8114156133865760043560a01c1561327657600080fd5b60243560a01c1561328657600080fd5b60443560a01c1561329657600080fd5b60643560a01c156132a657600080fd5b60843560a01c156132b657600080fd5b60206101a0600463f851a4406101405261015c6000545afa6132d757600080fd5b601f3d116132e457600080fd5b6000506101a05133146132f657600080fd5b61014060006005818352015b6004610140516005811061331557600080fd5b60200201356101605261016051151561332d5761337e565b600b6101605160e05260c052604060c02060c052602060c02060a4610140516005811061335957600080fd5b60400201803582558060200135600183015550505b8151600101808352811415613302575b505042601055005b63237f89f281141561348e576000610120525b610120516004013560a01c156133ae57600080fd5b60206101205101610120526101406101205110156133cb57613399565b60206101a0600463f851a4406101405261015c6000545afa6133ec57600080fd5b601f3d116133f957600080fd5b6000506101a051331461340b57600080fd5b6101406000600a818352015b600461014051600a811061342a57600080fd5b60200201356101605261016051151561344257613486565b61014461014051600a811061345657600080fd5b6020020135600b6101605160e05260c052604060c02060c052602060c020555b8151600101808352811415613417575b505042601055005b63ca991b148114156135145760043560a01c156134aa57600080fd5b60243560a01c156134ba57600080fd5b60206101a0600463f851a4406101405261015c6000545afa6134db57600080fd5b601f3d116134e857600080fd5b6000506101a05133146134fa57600080fd5b602435600c60043560e05260c052604060c0205542601055005b63ef6b97888114156137315760043560a01c1561353057600080fd5b6000610120525b610120516024013560a01c1561354c57600080fd5b602061012051016101205261014061012051101561356957613537565b60206101a0600463f851a4406101405261015c6000545afa61358a57600080fd5b601f3d1161359757600080fd5b6000506101a05133146135a957600080fd5b600a60043560e05260c052604060c0205461014052600154610160526101806000600a818352015b602461018051600a81106135e457600080fd5b60200201356101a05260006101a05118156136af5761014051602061022060046382c630666101c0526101dc6101a0515afa61361f57600080fd5b601f3d1161362c57600080fd5b600050610220511461363d57600080fd5b60206102406024633f9095b76101c0526101a0516101e0526101dc610160515afa61366757600080fd5b601f3d1161367457600080fd5b600050610240506101a05161018051600a811061369057600080fd5b600f60043560e05260c052604060c02060c052602060c0200155613719565b600061018051600a81106136c257600080fd5b600f60043560e05260c052604060c02060c052602060c0200154181561371457600061018051600a81106136f557600080fd5b600f60043560e05260c052604060c02060c052602060c0200155613719565b613729565b81516001018083528114156135d1575b505042601055005b6309e767748114156137b25760043560a01c1561374d57600080fd5b60206101a0600463f851a4406101405261015c6000545afa61376e57600080fd5b601f3d1161377b57600080fd5b6000506101a051331461378d57600080fd5b602435600b600460043560e05260c052604060c02060c052602060c020015542601055005b637542f0788114156138c9576000610120525b610120516004013560a01c156137da57600080fd5b60206101205101610120526104006101205110156137f7576137c5565b60206101a0600463f851a4406101405261015c6000545afa61381857600080fd5b601f3d1161382557600080fd5b6000506101a051331461383757600080fd5b61014060006020818352015b6004610140516020811061385657600080fd5b60200201351515613866576138c1565b610404610140516020811061387a57600080fd5b6020020135600b60046004610140516020811061389657600080fd5b602002013560e05260c052604060c02060c052602060c02001555b8151600101808352811415613843575b505042601055005b63ce50c2e78114156138e15760005460005260206000f35b63d8b9a0188114156138f95760015460005260206000f35b633a1d5d8e81141561392c5760043562010000811061391757600080fd5b600260c052602060c020015460005260206000f35b63956aae3a8114156139445760035460005260206000f35b635075770f81141561395c5760055460005260206000f35b6345f0db2481141561398f5760043562010000811061397a57600080fd5b600760c052602060c020015460005260206000f35b63bdf475c38114156139c55760043560a01c156139ab57600080fd5b600960043560e05260c052604060c0205460005260206000f35b63379510498114156139fb5760043560a01c156139e157600080fd5b600a60043560e05260c052604060c0205460005260206000f35b6368900961811415613a135760105460005260206000f35b505b60006000fd5b610180526101405261016052610100366101a03761016051604051811115613a4257600080fd5b6102a0526102c060006008818352015b6102a0516102c0511415613a6557613b01565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86102c05180820280806000811215613a9a57195b607f1c15613aa757600080fd5b9050905090506000811215613ac45761014051816000031c613acb565b61014051811b5b9050610100808206905090506101a06102c05160088110613aeb57600080fd5b60200201525b8151600101808352811415613a52575b50506101006102c0525b60006102c051111515613b1d57613b39565b60206102c051036101a0015160206102c051036102c052613b0b565b61018051565b61016052610140526101003661018037600460046101405160e05260c052604060c02060c052602060c020015461028052610280511515613e6957600360046101405160e05260c052604060c02060c052602060c02001546102a05260086014602082066103600160208284011115613bb757600080fd5b602080610380826102a0600060045af1505081815280905090509050806020015160008251806020901315613beb57600080fd5b8091901215613bf957600080fd5b806020036101000a82049050905090506102c052601c6004602082066103400160208284011115613c2957600080fd5b602080610360826102a0600060045af15050818152809050905090508051602001806102e08284600060045af1613c5f57600080fd5b505061034060006008818352015b6103405160088110613c7e57600080fd5b600560046101405160e05260c052604060c02060c052602060c0200160c052602060c020015461036052610360511515613cb757613e62565b6102a0511515613cc8576001613d05565b6103405160088110613cd957600080fd5b600660046101405160e05260c052604060c02060c052602060c0200160c052602060c020015461036051145b15613d3157670de0b6b3a76400006101806103405160088110613d2757600080fd5b6020020152613e52565b60006102c0511815613daa5760206104006024638f32207861038052610360516103a05261039c6102c0518060a01c15613d6a57600080fd5b8090505afa613d7857600080fd5b601f3d11613d8557600080fd5b600050610400516101806103405160088110613da057600080fd5b6020020152613e52565b6102e08051602001806104408284600060045af1613dc757600080fd5b505060206104c061044051610460610360515afa613de457600080fd5b60203d80821115613df55780613df7565b815b905090506104a0526104a0806020015160008251806020901315613e1a57600080fd5b8091901215613e2857600080fd5b806020036101000a82049050905090506101806103405160088110613e4c57600080fd5b60200201525b8151600101808352811415613c6d575b5050613f47565b600760046101405160e05260c052604060c02060c052602060c020015460801c600180821015613e9857600080fd5b808203905090506102a0526020610320600463bb7b8b806102c0526102dc610280515afa613ec557600080fd5b601f3d11613ed257600080fd5b600050610320516101806102a05160088110613eed57600080fd5b60200201526102c060006008818352015b6102a0516102c0511415613f1157613f44565b670de0b6b3a76400006101806102c05160088110613f2e57600080fd5b60200201525b8151600101808352811415613efe575b50505b6101006102a0525b60006102a051111515613f6157613f7d565b60206102a05103610180015160206102a051036102a052613f4f565b61016051565b6101605261014052600960046101405160e05260c052604060c02060c052602060c020015461018052610100366101a0376102a060006008818352015b6102a05160088110613fd157600080fd5b600560046101405160e05260c052604060c02060c052602060c0200160c052602060c020015415156140125760006102a0511861400d57600080fd5b6140ed565b6101805115614077576020610340602463065a80d86102c0526102a0516102e0526102dc610140515afa61404557600080fd5b601f3d1161405257600080fd5b600050610340516101a06102a0516008811061406d57600080fd5b60200201526140dd565b60206103406024634903b0d16102c0526102a051600081121561409957600080fd5b6102e0526102dc610140515afa6140af57600080fd5b601f3d116140bc57600080fd5b600050610340516101a06102a051600881106140d757600080fd5b60200201525b8151600101808352811415613fc0575b50506101006102a0525b60006102a05111151561410957614125565b60206102a051036101a0015160206102a051036102a0526140f7565b61016051565b61016052610140526101405161016051610180516101a0516101c0516101e0516102005161022051610240516102605161014051610280526102805160065801613f83565b6102e05261030052610320526103405261036052610380526103a0526103c052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526102e080516101805280602001516101a05280604001516101c05280606001516101e0528060800151610200528060a00151610220528060c00151610240528060e0015161026052506101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e0516103005161032051610340516103605161014051610380526103805160065801613b3f565b6103e05261040052610420526104405261046052610480526104a0526104c052610360526103405261032052610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a0526101805261016052610140526103e080516102805280602001516102a05280604001516102c05280606001516102e0528060800151610300528060a00151610320528060c00151610340528060e001516103605250600260046101405160e05260c052604060c02060c052602060c020015461038052610180516103a0526101a0516103c0526101c0516103e0526101e0516104005261020051610420526102205161044052610240516104605261026051610480526104a060006008818352015b6104a0516008811061438d57600080fd5b600560046101405160e05260c052604060c02060c052602060c0200160c052602060c02001546104c0526104c05115156143c657614599565b6104a051600881106143d757600080fd5b600660046101405160e05260c052604060c02060c052602060c0200160c052602060c02001546104e0526104e051151561441057614589565b6104c0516104e0511815614589576101806104a0516008811061443257600080fd5b60200201516102806104a0516008811061444b57600080fd5b6020020151808202821582848304141761446457600080fd5b80905090509050604e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86104a051808202808060008112156144a257195b607f1c156144af57600080fd5b90509050905060008112156144cc5761038051816000031c6144d3565b61038051811b5b905061010080820690509050106144e957600080fd5b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86104a0518082028080600081121561451e57195b607f1c1561452b57600080fd5b90509050905060008112156145485761038051816000031c61454f565b61038051811b5b905061010080820690509050600a0a808061456957600080fd5b8204905090506103a06104a0516008811061458357600080fd5b60200201525b815160010180835281141561437c575b50506101006104a0525b60006104a0511115156145b5576145d1565b60206104a051036103a0015160206104a051036104a0526145a3565b61016051565b610180526101405261016052600760046101405160e05260c052604060c02060c052602060c020015460801c60018082101561461257600080fd5b808203905090506101a052600960046101605160e05260c052604060c02060c052602060c02001546101c052602061026060046318160ddd6102005261021c600a6101605160e05260c052604060c020545afa61466e57600080fd5b601f3d1161467b57600080fd5b600050610260516101e052610140366102003760006101e051111561471d5760206103c06024634903b0d1610340526101a0516103605261035c610140515afa6146c457600080fd5b601f3d116146d157600080fd5b6000506103c0516ec097ce7bc90715b34b9f100000000080820282158284830414176146fc57600080fd5b809050905090506101e051808061471257600080fd5b820490509050610320525b61034060006008818352015b610340516008811061473a57600080fd5b600660046101405160e05260c052604060c02060c052602060c0200160c052602060c0200154151561476b576148ff565b6101a0516103405110156147c05760206103e06024634903b0d161036052610340516103805261037c610140515afa6147a357600080fd5b601f3d116147b057600080fd5b6000506103e051610300526148d1565b6101c051156148375760206103e0602463065a80d861036052610340516101a051808210156147ee57600080fd5b8082039050905060405181111561480457600080fd5b6103805261037c610160515afa61481a57600080fd5b601f3d1161482757600080fd5b6000506103e05161030052614892565b60206103e06024634903b0d161036052610340516101a0518082101561485c57600080fd5b808203905090506103805261037c610160515afa61487957600080fd5b601f3d1161488657600080fd5b6000506103e051610300525b610300516103205180820282158284830414176148ae57600080fd5b809050905090506ec097ce7bc90715b34b9f100000000080820490509050610300525b6103005161020061034051600881106148e957600080fd5b60200201525b8151600101808352811415614729575b5050610100610340525b60006103405111151561491b57614937565b6020610340510361020001516020610340510361034052614909565b61018051565b6101a0526101405261016052610180526080366101c03761024060006008818352015b610240516008811061497157600080fd5b600560046101405160e05260c052604060c02060c052602060c0200160c052602060c0200154610260526102605115156149b057600061022052614a10565b610160516102605114156149cb57610240516101c0526149eb565b610180516102605114156149e657610240516101e0526149eb565b614a00565b61022051156149f957614a10565b6001610220525b8151600101808352811415614960575b5050610220511515614b1b5761024060006008818352015b6102405160088110614a3957600080fd5b600660046101405160e05260c052604060c02060c052602060c0200160c052602060c020015461026052610260511515614ab2576308c379a06102805260206102a05260136102c0527f4e6f20617661696c61626c65206d61726b6574000000000000000000000000006102e0526102c050606461029cfd5b61016051610260511415614acd57610240516101c052614aed565b61018051610260511415614ae857610240516101e052614aed565b614b08565b6102205115614b0157600161020052614b18565b6001610220525b8151600101808352811415614a28575b50505b6060610240525b600061024051111515614b3457614b50565b602061024051036101c001516020610240510361024052614b22565b6101a051565b610240526101405261016052610180526101a0526101c0526101e05261020052610220526102605260006102e0525b6102605160206001820306601f82010390506102e051101515614ba757614bc0565b6102e05161028001526102e0516020016102e052614b85565b6000506020610360600463f851a4406103005261031c6000545afa614be457600080fd5b601f3d11614bf157600080fd5b600050610360516101405114614c0657600080fd5b60006101a05118614c1657600080fd5b600560046101605160e05260c052604060c02060c052602060c0200160c052602060c0205415614c4557600080fd5b60096101a05160e05260c052604060c0205415614c6157600080fd5b600354610300526101605161030051620100008110614c7f57600080fd5b600260c052602060c0200155610300516001818183011015614ca057600080fd5b808201905090506003556103005160046101605160e05260c052604060c02060c052602060c020556101c051600360046101605160e05260c052604060c02060c052602060c02001556101e051600860046101605160e05260c052604060c02060c052602060c020015561020051600960046101605160e05260c052604060c02060c052602060c020015561018051600760046101605160e05260c052604060c02060c052602060c020015561026080600a60046101605160e05260c052604060c02060c052602060c0200160c052602060c020602082510161012060006003818352015b82610120516020021115614d9857614dba565b61012051602002850151610120518501555b8151600101808352811415614d85575b5050505050506101605160096101a05160e05260c052604060c020556101a051600a6101605160e05260c052604060c0205542601055601c6004602082066103200160208284011115614e0c57600080fd5b602080610340826101c0600060045af15050818152809050905090508051602001806103a08284600060045af1614e4257600080fd5b505060206104005261040051610440526103a080516020018061040051610440018284600060045af1614e7457600080fd5b505061040051610440015180602061040051610440010101818260206001820306601f8201039050033682375050602061040051610440015160206001820306601f820103905061040051010161040052610160517fe485c16479ab7092c0b3fc4649843c06be7f072194675261590c84473ab0aea961040051610440a261024051565b6101605261014052600160066101405160e05260c052604060c02060c052602060c02001541515614f8b57600554610180526101805160066101405160e05260c052604060c02060c052602060c020556101405161018051620100008110614f5f57600080fd5b600760c052602060c0200155600580546001818183011015614f8057600080fd5b808201905090508155505b600160066101405160e05260c052604060c02060c052602060c0200180546001818183011015614fba57600080fd5b8082019050905081555061016051565b6101a052610140526101605261018052600260066101405160e05260c052604060c02060c052602060c02001546101c052610160516101c0516f7fffffffffffffffffffffffffffffff811061501f57600080fd5b600360066101405160e05260c052604060c02060c052602060c0200160c052602060c0200155600260066101405160e05260c052604060c02060c052602060c020018054600181818301101561507457600080fd5b80820190509050815550600260066101605160e05260c052604060c02060c052602060c02001546101e052610140516101e0516f7fffffffffffffffffffffffffffffff81106150c357600080fd5b600360066101605160e05260c052604060c02060c052602060c0200160c052602060c0200155600260066101605160e05260c052604060c02060c052602060c020018054600181818301101561511857600080fd5b8082019050905081555061016051610140511015615168576101e05160801b6101c05181818301101561514a57600080fd5b8082019050905060086101805160e05260c052604060c0205561519c565b6101c05160801b6101e05181818301101561518257600080fd5b8082019050905060086101805160e05260c052604060c020555b6101a051565b6101605261014052600160066101405160e05260c052604060c02060c052602060c0200180546001808210156151d757600080fd5b80820390509050815550600160066101405160e05260c052604060c02060c052602060c020015415156152f7576005805460018082101561521757600080fd5b808203905090508155506005546101805260066101405160e05260c052604060c02060c052602060c020546101a052610180516101a05110156152b9576101805162010000811061526757600080fd5b600760c052602060c02001546101c0526101c0516101a05162010000811061528e57600080fd5b600760c052602060c02001556101a05160066101c05160e05260c052604060c02060c052602060c020555b600060066101405160e05260c052604060c02060c052602060c020556000610180516201000081106152ea57600080fd5b600760c052602060c02001555b61016051565b6101a052610140526101605261018052600260066101405160e05260c052604060c02060c052602060c02001805460018082101561533a57600080fd5b80820390509050815550600260066101405160e05260c052604060c02060c052602060c02001546101c0526101c0516101805110156154c1576101c0516f7fffffffffffffffffffffffffffffff811061539357600080fd5b600360066101405160e05260c052604060c02060c052602060c0200160c052602060c02001546101e0526101e05161014051186102005260086102005160e05260c052604060c02054610220526101e051610140511015615429576102205160801c60801b6101805181818301101561540b57600080fd5b8082019050905060086102005160e05260c052604060c02055615476565b6101805160801b610220517001000000000000000000000000000000008082069050905081818301101561545c57600080fd5b8082019050905060086102005160e05260c052604060c020555b6101e051610180516f7fffffffffffffffffffffffffffffff811061549a57600080fd5b600360066101405160e05260c052604060c02060c052602060c0200160c052602060c02001555b60006101c0516f7fffffffffffffffffffffffffffffff81106154e357600080fd5b600360066101405160e05260c052604060c02060c052602060c0200160c052602060c02001556101a051565b6101c0526101405261016052610180526101a052610120366101e03761030060006008818352015b6101605161030051141561554a57615741565b6101805115615635576101a051156155b25760206103a0602463b739953e610320526103005160405181111561557f57600080fd5b6103405261033c610140515afa61559557600080fd5b601f3d116155a257600080fd5b6000506103a0516102e0526155f5565b60206103a0602463b9947eb061032052610300516103405261033c610140515afa6155dc57600080fd5b601f3d116155e957600080fd5b6000506103a0516102e0525b6102e051610300516008811061560a57600080fd5b600660046101405160e05260c052604060c02060c052602060c0200160c052602060c0200155615713565b6101a051156156945760206103a060246323746eb8610320526103005160405181111561566157600080fd5b6103405261033c610140515afa61567757600080fd5b601f3d1161568457600080fd5b6000506103a0516102e0526156d7565b60206103a0602463c661065761032052610300516103405261033c610140515afa6156be57600080fd5b601f3d116156cb57600080fd5b6000506103a0516102e0525b6102e05161030051600881106156ec57600080fd5b600560046101405160e05260c052604060c02060c052602060c0200160c052602060c02001555b6102e0516101e0610300516008811061572b57600080fd5b60200201525b8151600101808352811415615537575b505061030060006008818352015b61016051610300511415615762576159d2565b6101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e051610300516101e061030051600881106157b257600080fd5b6020020151610320526103205160065801614ef8565b610300526102e0526102c0526102a05261028052610260526102405261022052610200526101e0526101c0526101a05261018052610160526101405260005061030051600181818301101561581c57600080fd5b8082019050905061032052610340610320516008818352015b61016051610340511415615848576159bf565b6101e0610340516008811061585c57600080fd5b60200201516101e0610300516008811061587557600080fd5b60200201511861036052600e6103605160e05260c052604060c020546103805261014051610380516201000081106158ac57600080fd5b600d6103605160e05260c052604060c02060c052602060c02001556103805160018181830110156158dc57600080fd5b80820190509050600e6103605160e05260c052604060c020556103805115156159af576101406103a0525b6103a0515160206103a051016103a0526103a06103a051101561592957615907565b6101e0610340516008811061593d57600080fd5b60200201516103c0526101e0610300516008811061595a57600080fd5b60200201516103e0526103605161040052610400516103e0516103c05160065801614fca565b6103806103a0525b6103a0515260206103a051036103a0526101406103a0511015156159ab57615988565b6000505b8151600101808352811415615835575b50505b815160010180835281141561574f575b5050610100610300525b6000610300511115156159ee57615a0a565b602061030051036101e0015160206103005103610300526159dc565b6101c051565b610260526101405261016052610180526101a0526101c0526101e0526102005261022052610240526040366102803761024051604051811115615a5257600080fd5b6102c0526102e060006008818352015b6102c0516102e0511415615a7557615b7f565b6101406102e05160088110615a8957600080fd5b60200201516103005273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee610300511415615abc5760126102a052615b07565b6020610380600463313ce5676103205261033c610300515afa615ade57600080fd5b601f3d11615aeb57600080fd5b600050610380516102a0526101006102a05110615b0757600080fd5b61028080516102e051600880820280806000811215615b2257195b607f1c15615b2f57600080fd5b9050905090506000811215615b4c576102a051816000031c615b53565b6102a051811b5b9050818183011015615b6457600080fd5b808201905090508152505b8151600101808352811415615a62575b50506102805160005260005161026051565b6101a0526101405261016052610180526101805161016051186101c052600e6101c05160e05260c052604060c02054600180821015615bcf57600080fd5b808203905090506101e0526101e0511515615e1b5760086101c05160e05260c052604060c020546102005261018051610160511015615d09576101405161016051610180516101a0516101c0516101e0516102005161016051610220526101805161024052610200517001000000000000000000000000000000008082069050905061026052610260516102405161022051600658016152fd565b610200526101e0526101c0526101a0526101805261016052610140526000506102005160801c610220526101405161016051610180516101a0516101c0516101e0516102005161022051610180516102405261016051610260526102205161028052610280516102605161024051600658016152fd565b61022052610200526101e0526101c0526101a052610180526101605261014052600050615e06565b6102005160801c610220526101405161016051610180516101a0516101c0516101e0516102005161022051610160516102405261018051610260526102205161028052610280516102605161024051600658016152fd565b61022052610200526101e0526101c0526101a0526101805261016052610140526000506101405161016051610180516101a0516101c0516101e0516102005161018051610220526101605161024052610200517001000000000000000000000000000000008082069050905061026052610260516102405161022051600658016152fd565b610200526101e0526101c0526101a0526101805261016052610140526000505b600060086101c05160e05260c052604060c020555b610200600062010000818352015b6101e051610200511115615e3c57615f3a565b6101405161020051620100008110615e5357600080fd5b600d6101c05160e05260c052604060c02060c052602060c02001541415615f2a576101e051610200511015615edf576101e051620100008110615e9557600080fd5b600d6101c05160e05260c052604060c02060c052602060c020015461020051620100008110615ec357600080fd5b600d6101c05160e05260c052604060c02060c052602060c02001555b60006101e051620100008110615ef457600080fd5b600d6101c05160e05260c052604060c02060c052602060c02001556101e051600e6101c05160e05260c052604060c02055615f3a565b8151600101808352811415615e29575b50506101a051565b610062615fa403610062600039610062615fa4036000f30000000000000000000000000000000022d53366457f9d5e68ec105046fc43830000000000000000000000002f50d538606fa9edd2b11e2446beb18c9d5846bb
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000022d53366457f9d5e68ec105046fc43830000000000000000000000002f50d538606fa9edd2b11e2446beb18c9d5846bb
-----Decoded View---------------
Arg [0] : _address_provider (address): 0x0000000022D53366457F9d5E68Ec105046FC4383
Arg [1] : _gauge_controller (address): 0x2F50D538606Fa9EDD2B11E2446BEb18C9D5846bB
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000022d53366457f9d5e68ec105046fc4383
Arg [1] : 0000000000000000000000002f50d538606fa9edd2b11e2446beb18c9d5846bb
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.