def registry_susd(Registry, accounts, pool_susd, calculator, lp_susd, USDT): registry = Registry.deploy({'from': accounts[0]}) registry.add_pool(pool_susd, 4, lp_susd, calculator, "0x00", pack_values([18, 6, 6, 18]), pack_values([18, 6, 6, 18]), True, {'from': accounts[0]}) yield registry
def rule_add_pool(self, st_pool, st_decimals): """ Attempt to add a pool to the registry. Decimal values are randomized with `st_decimals` - this has no effect on other rules, and helps to verify `Registry.get_pool_coins` Revert Paths ------------ * The pool has already been added """ n_coins = st_pool.n_coins() if st_pool in self.added_pools: with brownie.reverts("dev: pool exists"): self.registry.add_pool(st_pool, n_coins, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", "0x00", "0x00", True, True, {'from': self.accounts[0]}) else: decimals = st_decimals[:n_coins] + [0] * (8 - n_coins) udecimals = st_decimals[-n_coins:] + [0] * (8 - n_coins) self.registry.add_pool(st_pool, n_coins, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", pack_values(decimals), pack_values(udecimals), True, True, {'from': self.accounts[0]}) self.added_pools.add(st_pool) self.pool_info[st_pool]['decimals'] = decimals self.pool_info[st_pool]['underlying_decimals'] = udecimals
def test_without_underlying_admin_only(accounts, registry, pool_compound): with brownie.reverts("dev: admin-only function"): registry.add_pool_without_underlying(pool_compound, 2, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", pack_values([8, 8]), pack_values([True] + [False] * 7), {'from': accounts[1]})
def test_cannot_add_twice(accounts, registry_compound, pool_compound, lp_compound): with brownie.reverts("dev: pool exists"): registry_compound.add_pool(pool_compound, 2, lp_compound, ZERO_ADDRESS, "0x00", pack_values([8, 8]), pack_values([18, 6]), True, True, {'from': accounts[0]})
def test_without_underlying_already_exists(accounts, registry_compound, pool_compound): with brownie.reverts("dev: pool exists"): registry_compound.add_pool_without_underlying( pool_compound, 2, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", pack_values([8, 8]), pack_values([True] + [False] * 7), {'from': accounts[0]})
def registry( Registry, alice, gauge_controller, swap, pool_token, n_coins, wrapped_coins, wrapped_decimals, underlying_decimals, pool_data, ): registry = Registry.deploy(gauge_controller, {'from': alice}) rate_sig = "0x00" if next((i for i in wrapped_coins if hasattr(i, "get_rate")), False): contract = next(i for i in wrapped_coins if hasattr(i, "get_rate")) rate_sig = right_pad(contract.get_rate.signature) if hasattr(swap, "underlying_coins"): registry.add_pool(swap, n_coins, pool_token, ZERO_ADDRESS, rate_sig, pack_values(wrapped_decimals), pack_values(underlying_decimals), hasattr(swap, "initial_A"), {'from': alice}) else: registry.add_pool_without_underlying(swap, n_coins, pool_token, ZERO_ADDRESS, rate_sig, pack_values(underlying_decimals), pack_values([True] + [False] * 7), hasattr(swap, "initial_A"), {'from': alice}) yield registry
def registry( Registry, provider, gauge_controller, alice, swap, meta_swap, lp_token, meta_lp_token, n_coins, n_metacoins, is_v1, underlying_decimals, meta_decimals, ): registry = Registry.deploy(provider, gauge_controller, {"from": alice}) registry.add_pool_without_underlying( swap, n_coins, lp_token, "0x00", pack_values(underlying_decimals), 0, # use rates hasattr(swap, "initial_A"), is_v1, {"from": alice}, ) registry.add_metapool(meta_swap, n_metacoins, meta_lp_token, pack_values(meta_decimals), {"from": alice}) registry.remove_pool(meta_swap, {'from': alice}) yield registry
def registry( Registry, provider, gauge_controller, alice, lending_swap, lp_token, n_coins, is_v1, rate_method_id, underlying_decimals, wrapped_decimals, ): registry = Registry.deploy(provider, gauge_controller, {"from": alice}) registry.add_pool( lending_swap, n_coins, lp_token, rate_method_id, pack_values(wrapped_decimals), pack_values(underlying_decimals), hasattr(lending_swap, "initial_A"), is_v1, {"from": alice}, ) registry.remove_pool(lending_swap, {"from": alice}) yield registry
def test_token_returns_false(PoolMock, accounts, BAD, DAI, registry): coins = [DAI, BAD, ZERO_ADDRESS, ZERO_ADDRESS] returns_none = [ZERO_ADDRESS] * 4 pool = PoolMock.deploy(2, coins, coins, returns_none, 70, 4000000, {'from': accounts[0]}) registry.add_pool(pool, 2, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", pack_values([18, 18]), pack_values([18, 18]), {'from': accounts[0]}) DAI._mint_for_testing(10**18, {'from': accounts[0]}) DAI.approve(registry, 10**18, {'from': accounts[0]}) expected = registry.get_exchange_amount(pool, DAI, BAD, 10**18) registry.exchange(pool, DAI, BAD, 10**18, 0, {'from': accounts[0]}) assert DAI.balanceOf(accounts[0]) == 0 assert BAD.balanceOf(accounts[0]) == expected new_expected = registry.get_exchange_amount(pool, BAD, DAI, expected) BAD.approve(registry, expected, {'from': accounts[0]}) registry.exchange(pool, BAD, DAI, expected, 0, {'from': accounts[0]}) assert DAI.balanceOf(accounts[0]) == new_expected assert BAD.balanceOf(accounts[0]) == 0
def test_fix_incorrect_calldata(accounts, registry, pool_compound, lp_compound, cDAI): registry.add_pool( pool_compound, 2, lp_compound, ZERO_ADDRESS, right_pad("0xdEAdbEEf"), pack_values([8, 8]), pack_values([18, 6]), True, True, {'from': accounts[0]} ) with brownie.reverts("dev: bad response"): registry.get_pool_rates(pool_compound) registry.remove_pool(pool_compound) registry.add_pool( pool_compound, 2, lp_compound, ZERO_ADDRESS, right_pad(cDAI.exchangeRateStored.signature), pack_values([8, 8]), pack_values([18, 6]), True, True, {'from': accounts[0]} ) assert registry.get_pool_rates(pool_compound) == [10**18, 10**18, 0, 0, 0, 0, 0, 0]
def registry_susd(Registry, accounts, pool_susd, calculator, lp_susd, USDT): returns_none = [USDT, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS] registry = Registry.deploy(returns_none, {'from': accounts[0]}) registry.add_pool(pool_susd, 4, lp_susd, calculator, "0x00", pack_values([18, 6, 6, 18]), pack_values([18, 6, 6, 18]), {'from': accounts[0]}) yield registry
def registry_y(Registry, accounts, pool_y, calculator, lp_y, yDAI, USDT): registry = Registry.deploy({'from': accounts[0]}) registry.add_pool(pool_y, 4, lp_y, calculator, right_pad(yDAI.getPricePerFullShare.signature), pack_values([18, 6, 6, 18]), pack_values([18, 6, 6, 18]), True, {'from': accounts[0]}) yield registry
def registry_renbtc(accounts, registry, calculator, pool_renbtc, lp_renbtc): registry.add_pool_without_underlying(pool_renbtc, 2, lp_renbtc, calculator, right_pad("0xbd6d894d"), pack_values([8, 8]), pack_values([True] + [False] * 7), {'from': accounts[0]}) yield registry
def test_token_returns_false_revert(PoolMock, accounts, BAD, DAI, registry): coins = [DAI, BAD, ZERO_ADDRESS, ZERO_ADDRESS] pool = PoolMock.deploy(2, coins, coins, 70, 4000000, {'from': accounts[0]}) registry.add_pool(pool, 2, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", pack_values([18, 18]), pack_values([18, 18]), True, True, {'from': accounts[0]}) with brownie.reverts(): registry.exchange(pool, BAD, DAI, 10**18, 0, {'from': accounts[0]})
def registry_compound(accounts, Registry, pool_compound, calculator, lp_compound, cDAI, USDT): registry = Registry.deploy({'from': accounts[0]}) registry.add_pool(pool_compound, 2, lp_compound, calculator, right_pad(cDAI.exchangeRateStored.signature), pack_values([8, 8]), pack_values([18, 6]), True, {'from': accounts[0]}) yield registry
def test_min_dy(accounts, registry, pool_compound, lp_compound, DAI, USDC): registry.add_pool(pool_compound, 2, lp_compound, ZERO_ADDRESS, "0x00", pack_values([8, 8]), pack_values([18, 6]), True, True, {'from': accounts[0]}) DAI._mint_for_testing(10**18, {'from': accounts[0]}) DAI.approve(registry, 10**18, {'from': accounts[0]}) expected = registry.get_exchange_amount(pool_compound, DAI, USDC, 10**18) with brownie.reverts(): registry.exchange(pool_compound, DAI, USDC, 10**18, expected + 1, {'from': accounts[0]})
def add_pool(data, registry, deployer): swap = Contract(data["swap_address"]) token = data["lp_token_address"] n_coins = len(data["coins"]) decimals = pack_values( [i.get("decimals", i.get("wrapped_decimals")) for i in data["coins"]]) if "base_pool" in data: # adding a metapool registry.add_metapool(swap, n_coins, token, decimals, { "from": deployer, "gas_price": gas_strategy }) return is_v1 = data["lp_contract"] == "CurveTokenV1" has_initial_A = hasattr(swap, "intitial_A") rate_method_id = "0x00" if "wrapped_contract" in data: rate_method_id = RATE_METHOD_IDS[data["wrapped_contract"]] if hasattr(swap, "exchange_underlying"): wrapped_decimals = pack_values( [i.get("wrapped_decimals", i["decimals"]) for i in data["coins"]]) registry.add_pool( swap, n_coins, token, rate_method_id, wrapped_decimals, decimals, has_initial_A, is_v1, { "from": deployer, "gas_price": gas_strategy }, ) else: use_lending_rates = pack_values( ["wrapped_decimals" in i for i in data["coins"]]) registry.add_pool_without_underlying( swap, n_coins, token, rate_method_id, decimals, use_lending_rates, has_initial_A, is_v1, { "from": deployer, "gas_price": gas_strategy }, )
def test_without_underlying(accounts, registry, pool_compound, cDAI, cUSDC): registry.add_pool_without_underlying(pool_compound, 2, ZERO_ADDRESS, ZERO_ADDRESS, "0x00", pack_values([8, 8]), pack_values([True] + [False] * 7), {'from': accounts[0]}) coin_info = registry.get_pool_coins(pool_compound) assert coin_info['coins'] == [cDAI, cUSDC] + [ZERO_ADDRESS] * 6 assert coin_info['underlying_coins'] == [ZERO_ADDRESS, cUSDC ] + [ZERO_ADDRESS] * 6 assert coin_info['decimals'] == [8, 8, 0, 0, 0, 0, 0, 0] assert coin_info['underlying_decimals'] == [0, 8, 0, 0, 0, 0, 0, 0]
def test_no_initial_A(accounts, yDAI, registry, pool_y, lp_y): registry.add_pool(pool_y, 4, lp_y, ZERO_ADDRESS, right_pad(yDAI.getPricePerFullShare.signature), pack_values([18, 6, 6, 18]), pack_values([18, 6, 6, 18]), False, {'from': accounts[0]}) pool_y._set_A(1000, 2000, 3000, 4000, 5000, {'from': accounts[0]}) pool_info = registry.get_pool_info(pool_y) assert pool_info['A'] == 1000 assert pool_info['initial_A'] == 0 assert pool_info['initial_A_time'] == 0 assert pool_info['future_A'] == 4000 assert pool_info['future_A_time'] == 0
def test_get_pool_info(accounts, registry, pool_y, pool_susd, lp_y, lp_susd, yDAI): registry.add_pool(pool_y, 4, lp_y, ZERO_ADDRESS, right_pad(yDAI.getPricePerFullShare.signature), pack_values([1, 2, 3, 4]), pack_values([9, 8, 7, 6]), {'from': accounts[0]}) y_pool_info = registry.get_pool_info.call(pool_y) registry.add_pool(pool_susd, 4, lp_susd, ZERO_ADDRESS, "0x00", pack_values([33, 44, 55, 66]), pack_values([99, 88, 77, 22]), {'from': accounts[0]}) susd_pool_info = registry.get_pool_info.call(pool_susd) assert y_pool_info != susd_pool_info
def test_get_pool_info(accounts, registry_all, pool_y, pool_susd, lp_susd): pool_info = registry_all.get_pool_info.call(pool_susd) registry_all.remove_pool(pool_y, {'from': accounts[0]}) assert registry_all.get_pool_info.call(pool_susd) == pool_info registry_all.remove_pool(pool_susd, {'from': accounts[0]}) with brownie.reverts(): registry_all.get_pool_info(pool_susd) registry_all.add_pool(pool_susd, 4, lp_susd, ZERO_ADDRESS, "0x00", pack_values([18, 6, 6, 18]), pack_values([18, 6, 6, 18]), {'from': accounts[0]}) assert registry_all.get_pool_info.call(pool_susd) == pool_info
def registry( Registry, alice, gauge_controller, swap, pool_token, n_coins, wrapped_coins, wrapped_decimals, pool_data, ): registry = Registry.deploy(gauge_controller, {'from': alice}) rate_sig = "0x00" if next((i for i in wrapped_coins if hasattr(i, "get_rate")), False): contract = next(i for i in wrapped_coins if hasattr(i, "get_rate")) rate_sig = right_pad(contract.get_rate.signature) has_initial_A = hasattr(swap, "initial_A") is_v1 = pool_data['lp_contract'] == "CurveTokenV1" if hasattr(swap, "underlying_coins"): registry.add_pool( swap, n_coins, pool_token, ZERO_ADDRESS, rate_sig, pack_values(wrapped_decimals), pack_values([i['decimals'] for i in pool_data['coins']]), has_initial_A, is_v1, {'from': alice} ) else: use_rates = [i['wrapped'] for i in pool_data['coins']] + [False] * (8 - n_coins) registry.add_pool_without_underlying( swap, n_coins, pool_token, ZERO_ADDRESS, rate_sig, pack_values([i['decimals'] for i in pool_data['coins']]), pack_values(use_rates), has_initial_A, is_v1, {'from': alice} ) return registry
def rule_add_metapool(self, st_random): if len(self.state.base_pools) == 0: return # select a random base pool pool_index = st_random % len(self.state.base_pools) # base_pool base_pool: Pool = self.state.base_pools[pool_index] # deploy our coins meta_coins = self._batch_deploy_erc20() + [base_pool.lp_token] # number of coins n_coins = len(meta_coins) # deploy meta_pool meta_pool = self._deploy_meta_pool(meta_coins, base_pool.coins, base_pool.address) # lp token lp_token = self._deploy_erc20() # add the pool on chain tx = self.registry.add_metapool(meta_pool, n_coins, lp_token, pack_values([18] * n_coins), "", self.tx_params) # update state self.state.add_metapool( meta_pool.address, list(map(str, meta_coins)), lp_token.address, base_pool.coins, tx.timestamp, )
def rule_add_pool_without_underlying(self): # deploy 3 coins coins = self._batch_deploy_erc20() # number of coins n_coins = len(coins) # deploy the base pool base_pool = self._deploy_base_pool(coins) # make an lp token lp_token = self._deploy_erc20() # add the pool on chain tx = self.registry.add_pool_without_underlying( base_pool, # the swap, but I call it a pool n_coins, lp_token, "0x00", pack_values([18] * n_coins), 0, hasattr(base_pool, "initial_A"), False, # is_v1 "", self.tx_params, ) # update our state self.state.add_pool_without_underlying(base_pool.address, list(map(str, coins)), lp_token.address, tx.timestamp)
def registry( Registry, provider, gauge_controller, alice, swap, lp_token, n_coins, is_v1, underlying_decimals, chain, ): registry = Registry.deploy(provider, gauge_controller, {"from": alice}) registry.add_pool_without_underlying( swap, n_coins, lp_token, "0x00", pack_values(underlying_decimals), 0, # use rates hasattr(swap, "initial_A"), is_v1, "", {"from": alice}, ) chain.sleep(10) registry.remove_pool(swap, {"from": alice}) yield registry
def registry( Registry, provider, gauge_controller, alice, swap, lp_token, n_coins, is_v1, underlying_decimals, ): registry = Registry.deploy(provider, gauge_controller, {"from": alice}) registry.add_pool_without_underlying( swap, n_coins, lp_token, "0x00", pack_values(underlying_decimals), 0, # use rates hasattr(swap, "initial_A"), is_v1, {"from": alice}, ) provider.set_address(0, registry, {"from": alice}) yield registry
def test_add_multiple(accounts, registry, pool_y, pool_susd, lp_y): for pool in (pool_y, pool_susd): registry.add_pool(pool, 4, lp_y, ZERO_ADDRESS, "0x00", pack_values([18, 6, 6, 18]), pack_values([1, 2, 3, 4]), {'from': accounts[0]}) assert registry.pool_count() == 2 assert registry.pool_list(0) == pool_y assert registry.pool_list(1) == pool_susd for pool in [pool_y, pool_susd]: coin_info = registry.get_pool_coins(pool) assert coin_info['decimals'] == [18, 6, 6, 18, 0, 0, 0, 0] assert coin_info['underlying_decimals'] == [1, 2, 3, 4, 0, 0, 0, 0] for i in range(4): assert coin_info['coins'][i] == pool.coins(i) assert coin_info['underlying_coins'][i] == pool.underlying_coins(i)
def registry(ERC20, Registry, RateCalcMock, provider, gauge_controller, alice, ankr_swap, lp_token): registry = Registry.deploy(provider, gauge_controller, {"from": alice}) rate_calc = RateCalcMock.deploy({"from": alice}) registry.add_pool( ankr_swap, 1, lp_token, rate_calc.address + "71ca337d", pack_values([18]), pack_values([18]), hasattr(ankr_swap, "initial_A"), False, "Test pool", {"from": alice}, ) provider.set_address(0, registry, {"from": alice}) yield registry
def test_without_underlying(accounts, registry, pool_compound, cDAI, cUSDC): registry.add_pool_without_underlying( pool_compound, 2, ZERO_ADDRESS, ZERO_ADDRESS, right_pad(cDAI.exchangeRateStored.signature), pack_values([8, 8]), pack_values([True] + [False] * 7), {'from': accounts[0]} ) assert registry.get_pool_rates.call(pool_compound) == [10**18, 10**18, 0, 0, 0, 0, 0, 0] cDAI._set_exchange_rate(31337, {'from': accounts[0]}) cUSDC._set_exchange_rate(31337, {'from': accounts[0]}) assert registry.get_pool_rates.call(pool_compound) == [31337, 10**18, 0, 0, 0, 0, 0, 0]
def registry( Registry, provider, gauge_controller, alice, swap, meta_swap, lp_token, meta_lp_token, n_coins, n_metacoins, is_v1, underlying_decimals, meta_decimals, request, ): registry = Registry.deploy(provider, gauge_controller, {"from": alice}) registry.add_pool_without_underlying( swap, n_coins, lp_token, "0x00", pack_values(underlying_decimals), 0, # use rates hasattr(swap, "initial_A"), is_v1, "", {"from": alice}, ) # A factory pool is essentially a metapool, the default for base_pool arg # is ZERO_ADDRESS so we can use a ternary to just switch between testing # explicitly setting the base_pool arg registry.add_metapool( meta_swap, n_metacoins, meta_lp_token, pack_values(meta_decimals), "Meta Swap", ZERO_ADDRESS if request.param == "meta" else swap, {"from": alice}, ) provider.set_address(0, registry, {"from": alice}) yield registry