def create_risky_cdp(mcd: DssDeployment, c: Collateral, collateral_amount: Wad, gal_address: Address, draw_dai=True) -> Urn: assert isinstance(mcd, DssDeployment) assert isinstance(c, Collateral) assert isinstance(gal_address, Address) # Ensure vault isn't already unsafe (if so, this shouldn't be called) urn = mcd.vat.urn(c.ilk, gal_address) assert is_cdp_safe(mcd.vat.ilk(c.ilk.name), urn) # Add collateral to gal vault if necessary c.approve(gal_address) token = Token(c.ilk.name, c.gem.address, c.adapter.dec()) print(f"collateral_amount={collateral_amount} ink={urn.ink}") dink = collateral_amount - urn.ink if dink > Wad(0): vat_balance = mcd.vat.gem(c.ilk, gal_address) balance = token.normalize_amount(c.gem.balance_of(gal_address)) print( f"before join: dink={dink} vat_balance={vat_balance} balance={balance} vat_gap={dink - vat_balance}" ) if vat_balance < dink: vat_gap = dink - vat_balance if balance < vat_gap: if c.ilk.name.startswith("ETH"): wrap_eth(mcd, gal_address, vat_gap) else: raise RuntimeError("Insufficient collateral balance") amount_to_join = token.unnormalize_amount(vat_gap) if amount_to_join == Wad( 0): # handle dusty balances with non-18-decimal tokens amount_to_join += token.unnormalize_amount(token.min_amount) assert c.adapter.join( gal_address, amount_to_join).transact(from_address=gal_address) vat_balance = mcd.vat.gem(c.ilk, gal_address) print( f"after join: dink={dink} vat_balance={vat_balance} balance={balance} vat_gap={dink - vat_balance}" ) assert vat_balance >= dink assert mcd.vat.frob(c.ilk, gal_address, dink, Wad(0)).transact(from_address=gal_address) # Put gal CDP at max possible debt dart = max_dart(mcd, c, gal_address) - Wad(1) if dart > Wad(0): print(f"Attempting to frob with dart={dart}") assert mcd.vat.frob(c.ilk, gal_address, Wad(0), dart).transact(from_address=gal_address) # Draw our Dai, simulating the usual behavior urn = mcd.vat.urn(c.ilk, gal_address) if draw_dai and urn.art > Wad(0): mcd.approve_dai(gal_address) assert mcd.dai_adapter.exit(gal_address, urn.art).transact(from_address=gal_address) print(f"Exited {urn.art} Dai from urn")
def setup_method(self): self.web3 = Web3(HTTPProvider("http://localhost:8555")) self.web3.eth.defaultAccount = self.web3.eth.accounts[0] self.our_address = Address(self.web3.eth.defaultAccount) self.token1 = DSToken.deploy(self.web3, 'AAA') self.token1.mint(Wad.from_number(10000)).transact() self.token1_tokenclass = Token('AAA', self.token1.address, 18) self.token2 = DSToken.deploy(self.web3, 'BBB') self.token2.mint(Wad.from_number(10000)).transact() self.token2_tokenclass = Token('BBB', self.token2.address, 18) price_oracle = OasisMockPriceOracle.deploy(self.web3) self.otc = MatchingMarket.deploy(self.web3, self.token1.address, Wad(0), price_oracle.address) self.otc.add_token_pair_whitelist(self.token1.address, self.token2.address).transact() self.otc.approve([self.token1, self.token2], directly()) for amount in [11,55,44,34,36,21,45,51,15]: self.otc.make(p_token=self.token1_tokenclass, pay_amount=Wad.from_number(1), b_token=self.token2_tokenclass, buy_amount=Wad.from_number(amount)).transact()
def test_mint_token_pool_low_price_and_slippage(self): """ Test minting a position for a pool that is a small fraction """ test_token_1 = Token( "test_1", Address("0x0000000000000000000000000000000000000001"), 18) test_token_2 = Token( "test_2", Address("0x0000000000000000000000000000000000000002"), 18) token_1_balance = Wad.from_number(10) token_2_balance = Wad.from_number(100) # sqrt_price_ratio = self.get_starting_sqrt_ratio(3000, 1) sqrt_price_ratio = self.get_starting_sqrt_ratio( Wad.from_number(3000).value, Wad.from_number(1).value) current_tick = get_tick_at_sqrt_ratio(sqrt_price_ratio) ticks = [] test_pool = Pool(test_token_1, test_token_2, FEES.MEDIUM.value, sqrt_price_ratio, 0, current_tick, ticks) # set Position.from_amounts() params tick_lower = current_tick - TICK_SPACING.MEDIUM.value * 5 tick_upper = current_tick + TICK_SPACING.MEDIUM.value * 7 rounded_tick_lower = Tick.nearest_usable_tick( tick_lower, TICK_SPACING.MEDIUM.value) rounded_tick_upper = Tick.nearest_usable_tick( tick_upper, TICK_SPACING.MEDIUM.value) calculated_position = Position.from_amounts( test_pool, rounded_tick_lower, rounded_tick_upper, token_1_balance.value, token_2_balance.value, False) test_liquidity = calculated_position.liquidity test_position = Position(test_pool, rounded_tick_lower, rounded_tick_upper, test_liquidity) amount_0, amount_1 = test_position.mint_amounts() slippage_tolerance = Fraction(2, 100) amount_0_min, amount_1_min = test_position.mint_amounts_with_slippage( slippage_tolerance) # check that mint amounts will pass periphery contract assertions assert amount_0_min > 0 and amount_1_min > 0 assert amount_0_min < amount_0 and amount_1_min < amount_1
def exit_gem(self): if not self.collateral: return token = Token(self.collateral.ilk.name.split('-')[0], self.collateral.gem.address, self.collateral.adapter.dec()) vat_balance = self.vat.gem(self.ilk, self.our_address) if vat_balance > token.min_amount: self.logger.info(f"Exiting {str(vat_balance)} {self.ilk.name} from the Vat") assert self.gem_join.exit(self.our_address, token.unnormalize_amount(vat_balance)).transact(gas_price=self.gas_price)
def __init__(self, args: list, **kwargs): parser = argparse.ArgumentParser(prog='uniswap-market-maker-keeper') self.add_arguments(parser=parser) self.arguments = parser.parse_args(args) setup_logging(self.arguments) provider = HTTPProvider( endpoint_uri=self.arguments.rpc_host, request_kwargs={'timeout': self.arguments.rpc_timeout}) self.web3: Web3 = kwargs['web3'] if 'web3' in kwargs else Web3( provider) self.web3.eth.defaultAccount = self.arguments.eth_from register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) self.uniswap_router = UniswapRouter( web3=self.web3, router=Address(self.arguments.uniswap_router_address)) self.first_token = ERC20Token(web3=self.web3, address=Address( self.arguments.first_token_address)) self.second_token = ERC20Token( web3=self.web3, address=Address(self.arguments.second_token_address)) self.token_first = Token(name=self.arguments.first_token_name, address=Address( self.arguments.first_token_address), decimals=self.arguments.first_token_decimals) self.token_second = Token( name=self.arguments.second_token_name, address=Address(self.arguments.second_token_address), decimals=self.arguments.second_token_decimals) self.min_eth_balance = Wad.from_number(self.arguments.min_eth_balance) self.gas_price = GasPriceFactory().create_gas_price(self.arguments) self.max_delta_on_percent = self.arguments.max_delta_on_percent self.price_feed = PriceFeedFactory().create_price_feed(self.arguments)
def setup_method(self): self.web3 = Web3(HTTPProvider("http://localhost:8555")) self.web3.eth.defaultAccount = self.web3.eth.accounts[0] self.our_address = Address(self.web3.eth.defaultAccount) self.token1 = DSToken.deploy(self.web3, 'AAA') self.token1_tokenclass = Token('AAA', self.token1.address, 18) self.token1.mint(Wad.from_number(10000)).transact() self.token2 = DSToken.deploy(self.web3, 'BBB') self.token2_tokenclass = Token('BBB', self.token2.address, 6) self.token2.mint(Wad.from_number(10000)).transact() support_abi = Contract._load_abi(__name__, '../pymaker/abi/MakerOtcSupportMethods.abi') support_bin = Contract._load_bin(__name__, '../pymaker/abi/MakerOtcSupportMethods.bin') support_address = Contract._deploy(self.web3, support_abi, support_bin, []) price_oracle = OasisMockPriceOracle.deploy(self.web3) self.otc = MatchingMarket.deploy(self.web3, self.token1.address, Wad(0), price_oracle.address, support_address) self.otc.add_token_pair_whitelist(self.token1.address, self.token2.address).transact() self.otc.approve([self.token1, self.token2], directly())
def setup_method(self): # Use Ganache docker container self.web3 = Web3(HTTPProvider("http://0.0.0.0:8555")) self.web3.eth.defaultAccount = Web3.toChecksumAddress( "0x9596C16D7bF9323265C2F2E22f43e6c80eB3d943") register_private_key( self.web3, "0x91cf2cc3671a365fcbf38010ff97ee31a5b7e674842663c56769e41600696ead" ) self.our_address = Address(self.web3.eth.defaultAccount) self.weth_address = self._deploy(self.web3, self.weth_abi, self.weth_bin, []) self.factory_address = self._deploy(self.web3, self.factory_abi, self.factory_bin, [self.our_address.address]) self.router_address = self._deploy( self.web3, self.router_abi, self.router_bin, [self.factory_address.address, self.weth_address.address]) self._weth_contract = self._get_contract(self.web3, self.weth_abi, self.weth_address) self.ds_dai = DSToken.deploy(self.web3, 'DAI') self.ds_usdc = DSToken.deploy(self.web3, 'USDC') self.token_dai = Token("DAI", self.ds_dai.address, 18) self.token_usdc = Token("USDC", self.ds_usdc.address, 6) self.token_weth = Token("WETH", self.weth_address, 18) self.dai_usdc_uniswap = UniswapV2(self.web3, self.token_dai, self.token_usdc, self.our_address, self.router_address, self.factory_address) self.dai_eth_uniswap = UniswapV2(self.web3, self.token_dai, self.token_weth, self.our_address, self.router_address, self.factory_address) ## Useful for debugging failing transactions logger = logging.getLogger('eth') logger.setLevel(8)
def __init__(self, data: dict): assert (isinstance(data, dict)) self.tokens = [ Token(name=key, address=Address(value['tokenAddress']) if 'tokenAddress' in value else None, decimals=value['tokenDecimals'] if 'tokenDecimals' in value else 18) for key, value in data['tokens'].items() ]
def setup_method(self): self.ds_dai = DSToken.deploy(self.web3, 'DAI') self.ds_usdc = DSToken.deploy(self.web3, 'USDC') self.token_dai = Token("DAI", self.ds_dai.address, 18) self.token_usdc = Token("USDC", self.ds_usdc.address, 6) self.token_weth = Token("WETH", self.weth_address, 18) self.position_manager.approve(self.token_dai) self.position_manager.approve(self.token_usdc) self.position_manager.approve(self.token_weth) self.swap_router.approve(self.token_dai) self.swap_router.approve(self.token_usdc) self.swap_router.approve(self.token_weth) dai_balance = Wad.from_number(10000000) usdc_balance = Wad.from_number(10000000) self.ds_dai.mint(dai_balance).transact(from_address=self.our_address) self.ds_usdc.mint( self.token_usdc.unnormalize_amount(usdc_balance)).transact( from_address=self.our_address)
def setup_method(self): # Use Ganache docker container self.web3 = Web3(HTTPProvider("http://0.0.0.0:8555")) self.web3.eth.defaultAccount = Web3.toChecksumAddress( "0x9596C16D7bF9323265C2F2E22f43e6c80eB3d943") self.our_address = Address(self.web3.eth.defaultAccount) self.private_key = "0x91cf2cc3671a365fcbf38010ff97ee31a5b7e674842663c56769e41600696ead" register_private_key(self.web3, self.private_key) self.weth_address = Contract._deploy(self.web3, self.weth_abi, self.weth_bin, []) self.factory_address = Contract._deploy(self.web3, self.factory_abi, self.factory_bin, [self.our_address.address]) self.router_address = Contract._deploy( self.web3, self.router_abi, self.router_bin, [self.factory_address.address, self.weth_address.address]) self._weth_contract = Contract._get_contract(self.web3, self.weth_abi, self.weth_address) self.ds_dai = DSToken.deploy(self.web3, 'DAI') self.ds_dai.mint( Wad.from_number(500)).transact(from_address=self.our_address) self.token_dai = Token("DAI", self.ds_dai.address, 18) self.token_weth = Token("WETH", self.weth_address, 18) token_config = { "tokens": { "DAI": { "tokenAddress": self.ds_dai.address.address }, "WETH": { "tokenAddress": self.weth_address.address } } } # write token config with locally deployed addresses to file with open("test-token-config.json", "w+") as outfile: outfile.write(json.dumps(token_config))
def test_liquidity_given_balance(self): """ Test liquidity and mint amount calculations """ test_token_1 = Token( "test_1", Address("0x0000000000000000000000000000000000000001"), 18) test_token_2 = Token( "test_2", Address("0x0000000000000000000000000000000000000002"), 6) token_1_balance = test_token_1.unnormalize_amount(Wad.from_number(10)) token_2_balance = test_token_2.unnormalize_amount(Wad.from_number(500)) sqrt_price_ratio = self.get_starting_sqrt_ratio( Wad.from_number(1).value, test_token_2.unnormalize_amount(Wad.from_number(3000)).value) current_tick = get_tick_at_sqrt_ratio(sqrt_price_ratio) ticks = [] test_pool = Pool(test_token_1, test_token_2, FEES.MEDIUM.value, sqrt_price_ratio, 0, current_tick, ticks) tick_lower = current_tick - TICK_SPACING.MEDIUM.value * 5 tick_upper = current_tick + TICK_SPACING.MEDIUM.value * 7 rounded_tick_lower = Tick.nearest_usable_tick( tick_lower, TICK_SPACING.MEDIUM.value) rounded_tick_upper = Tick.nearest_usable_tick( tick_upper, TICK_SPACING.MEDIUM.value) calculated_position = Position.from_amounts( test_pool, rounded_tick_lower, rounded_tick_upper, token_1_balance.value, token_2_balance.value, False) test_liquidity = calculated_position.liquidity assert test_liquidity == 252860870269028 test_position = Position(test_pool, rounded_tick_lower, rounded_tick_upper, test_liquidity) amount_0, amount_1 = test_position.mint_amounts() assert amount_0 == 95107120950731527 assert amount_1 == 208677042
def instantiate_tokens(self, pair: str) -> Tuple[Token, Token]: assert (isinstance(pair, str)) def get_address(value) -> Address: return Address( value['tokenAddress']) if 'tokenAddress' in value else None def get_decimals(value) -> int: return value['tokenDecimals'] if 'tokenDecimals' in value else 18 token_a_name = 'WETH' if self.is_eth and self.eth_position == 0 else self.pair( ).split('-')[0] token_b_name = 'WETH' if self.is_eth and self.eth_position == 1 else self.pair( ).split('-')[1] token_a = Token(token_a_name, get_address(self.token_config[token_a_name]), get_decimals(self.token_config[token_a_name])) token_b = Token(token_b_name, get_address(self.token_config[token_b_name]), get_decimals(self.token_config[token_b_name])) return token_a, token_b
def setup_method(self): # reduce logspew logging.getLogger("web3").setLevel(logging.INFO) logging.getLogger("urllib3").setLevel(logging.INFO) logging.getLogger("asyncio").setLevel(logging.INFO) self.web3 = Web3(HTTPProvider("http://localhost:8555")) self.web3.eth.defaultAccount = self.web3.eth.accounts[0] self.our_address = Address(self.web3.eth.defaultAccount) self.price_oracle = OasisMockPriceOracle.deploy(self.web3) self.price_oracle.set_price(Wad.from_number(10)) self.token1 = DSToken.deploy(self.web3, 'AAA') self.token1_tokenclass = Token('AAA', self.token1.address, 18) self.token1.mint(Wad.from_number(10000)).transact() self.token2 = DSToken.deploy(self.web3, 'BBB') self.token2_tokenclass = Token('BBB', self.token2.address, 18) self.token2.mint(Wad.from_number(10000)).transact() self.token3 = DSToken.deploy(self.web3, 'CCC') self.token3_tokenclass = Token('CCC', self.token3.address, 18) self.token3.mint(Wad.from_number(10000)).transact() self.otc = None
def deploy_liquidity_token(self) -> Token: # deploy uniswap contracts self.weth_address = self._deploy(self.web3, self.weth_abi, self.weth_bin, []) self.factory_address = self._deploy(self.web3, self.factory_abi, self.factory_bin, [self.our_address.address]) self.router_address = self._deploy(self.web3, self.router_abi, self.router_bin, [self.factory_address.address, self.weth_address.address]) self._weth_contract = self._get_contract(self.web3, self.weth_abi, self.weth_address) # deploy dai contract and instantiate DAI token self.ds_dai = DSToken.deploy(self.web3, 'DAI') self.token_dai = Token("DAI", self.ds_dai.address, 18) self.token_weth = Token("WETH", self.weth_address, 18) # self.dai_usdc_uniswap = UniswapV2(self.web3, self.token_dai, self.token_usdc, self.our_address, self.router_address, self.factory_address) self.dai_eth_uniswap = UniswapV2(self.web3, self.token_dai, self.token_weth, self.our_address, self.router_address, self.factory_address) # add liquidity self.add_liquidity_eth() # set liquidity token self.dai_eth_uniswap.set_pair_token(self.dai_eth_uniswap.get_pair_address(self.token_dai.address, self.token_weth.address)) liquidity_token = self.dai_eth_uniswap.pair_token return liquidity_token
def deploy_tokens(self): self.ds_dai = DSToken.deploy(self.web3, 'DAI') self.ds_keep = DSToken.deploy(self.web3, 'KEEP') self.ds_lev = DSToken.deploy(self.web3, 'LEV') self.ds_usdc = DSToken.deploy(self.web3, 'USDC') self.ds_wbtc = DSToken.deploy(self.web3, 'WBTC') self.token_dai = Token("DAI", self.ds_dai.address, 18) self.token_keep = Token("KEEP", self.ds_keep.address, 18) self.token_lev = Token("LEV", self.ds_lev.address, 9) self.token_usdc = Token("USDC", self.ds_usdc.address, 6) self.token_wbtc = Token("WBTC", self.ds_wbtc.address, 8) self.token_weth = Token("WETH", self.weth_address, 18)
def setup_method(self): # Use Ganache docker container self.web3 = Web3(HTTPProvider("http://0.0.0.0:8555")) self.web3.eth.defaultAccount = Web3.toChecksumAddress("0x9596C16D7bF9323265C2F2E22f43e6c80eB3d943") register_private_key(self.web3, "0x91cf2cc3671a365fcbf38010ff97ee31a5b7e674842663c56769e41600696ead") self.our_address = Address(self.web3.eth.defaultAccount) self.ds_reward_token = DSToken.deploy(self.web3, 'REWARD') self.reward_token = Token("REWARD", self.ds_reward_token.address, 18) # Deploy UniswapV2 contracts and set liquidity token self.liquidity_token = self.deploy_liquidity_token() self.staking_rewards_address = self._deploy(self.web3, self.staking_rewards_abi, self.staking_rewards_bin, [self.our_address.address, self.reward_token.address.address, self.liquidity_token.address.address]) self.uniswap_staking_rewards = UniswapStakingRewards(self.web3, self.our_address, Address(self.staking_rewards_address), "UniswapStakingRewards") ## Useful for debugging failing transactions logger = logging.getLogger('eth') logger.setLevel(8)
def deploy_staking_rewards(self, liquidity_token_address: Address): self.ds_reward_dai = DSToken.deploy(self.web3, 'REWARD_DAI') self.reward_token = Token("REWARD_DAI", self.ds_dai.address, 18) self.uni_staking_rewards_address = Contract._deploy(self.web3, self.uni_staking_rewards_abi, self.uni_staking_rewards_bin, [self.our_address.address, self.reward_token.address.address, liquidity_token_address.address]) self.uni_staking_rewards = UniswapStakingRewards(self.web3, self.our_address, Address(self.uni_staking_rewards_address), "UniswapStakingRewards")
def set_pair_token(self, pair_address: Address): self.pair_address = pair_address self._pair_contract = self._get_contract(self.web3, self.pair_abi['abi'], self.pair_address) self.pair_token = Token('Liquidity', self.pair_address, 18) self.is_new_pool = False
def test_should_mint_with_nonstandard_decimals(self): """ mint a position with one of the tokens having nonstandard decimals. Verify that the positions price and minted amounts accounts for decimals. """ test_token_1 = Token( "test_1", Address("0x0000000000000000000000000000000000000001"), 18) test_token_2 = Token( "test_2", Address("0x0000000000000000000000000000000000000002"), 6) # instantiate test pool # sqrt_price_ratio = self.get_starting_sqrt_ratio(Wad.from_number(1).value, Wad.from_number(3500).value) sqrt_price_ratio = self.get_starting_sqrt_ratio(1, 3500) current_tick = get_tick_at_sqrt_ratio(sqrt_price_ratio) ticks = [] test_pool = Pool(test_token_1, test_token_2, FEES.MEDIUM.value, sqrt_price_ratio, 0, current_tick, ticks) # based upon current price (expressed in token1/token0), determine the tick to mint the position at tick_spacing = TICK_SPACING.MEDIUM.value desired_price = PriceFraction(test_token_1, test_token_2, 1, 3500) desired_tick = PriceFraction.get_tick_at_price(desired_price) # identify upper and lower tick bounds for the position desired_lower_tick = Tick.nearest_usable_tick( desired_tick - tick_spacing * 5, tick_spacing) desired_upper_tick = Tick.nearest_usable_tick( desired_tick + tick_spacing * 7, tick_spacing) # calculate amount to add for each position. ## since test_token_2 has 6 decimals, we must unnormalize the Wad amount from 18 -> 6 token_1_balance = Wad.from_number(10) token_2_balance = Wad.from_number(100) token_1_to_add = test_token_1.unnormalize_amount(token_1_balance).value token_2_to_add = test_token_2.unnormalize_amount(token_2_balance).value # token_1_to_add = token_1_balance.value # token_2_to_add = token_2_balance.value calculated_position = Position.from_amounts(test_pool, desired_lower_tick, desired_upper_tick, token_1_to_add, token_2_to_add, False) amount_0, amount_1 = calculated_position.mint_amounts() slippage_tolerance = Fraction(2, 100) amount_0_min, amount_1_min = calculated_position.mint_amounts_with_slippage( slippage_tolerance) # check that mint amounts will pass periphery contract assertions assert amount_0 > 0 and amount_1 > 0 assert amount_0_min > 0 and amount_1_min > 0 assert amount_0_min < amount_0 and amount_1_min < amount_1 # assume pool.tick_current < desired_upper_tick expected_amount_0 = SqrtPriceMath.get_amount_0_delta( test_pool.square_root_ratio_x96, get_sqrt_ratio_at_tick(desired_upper_tick), calculated_position.liquidity, True) expected_amount_1 = SqrtPriceMath.get_amount_1_delta( get_sqrt_ratio_at_tick(desired_lower_tick), test_pool.square_root_ratio_x96, calculated_position.liquidity, True) assert amount_0 == expected_amount_0 assert amount_1 == expected_amount_1 # get amounts from liquidity price_lower_tick = pow(1.0001, calculated_position.tick_lower) price_upper_tick = pow(1.0001, calculated_position.tick_upper) assert price_lower_tick < 3500 < price_upper_tick position_token_0 = calculated_position.liquidity / math.sqrt( price_upper_tick) position_token_1 = calculated_position.liquidity * math.sqrt( price_lower_tick) # compare original sqrt_price_ratio_x96 to the ratio determined by liquidity to mint assert str(sqrt_price_ratio)[:2] == str( encodeSqrtRatioX96(int(position_token_1), int(position_token_0)))[:2] assert sqrt_price_ratio // Q96 == encodeSqrtRatioX96( int(position_token_1), int(position_token_0)) // (2**96)
def __init__(self, args: list, **kwargs): parser = argparse.ArgumentParser(prog='oasis-market-maker-keeper') parser.add_argument( "--endpoint-uri", type=str, help="JSON-RPC uri (example: `http://localhost:8545`)") parser.add_argument( "--rpc-host", default="localhost", type=str, help="[DEPRECATED] JSON-RPC host (default: `localhost')") parser.add_argument( "--rpc-port", default=8545, type=int, help="[DEPRECATED] JSON-RPC port (default: `8545')") parser.add_argument("--rpc-timeout", type=int, default=10, help="JSON-RPC timeout (in seconds, default: 10)") parser.add_argument( "--eth-from", type=str, required=True, help="Ethereum account from which to send transactions") parser.add_argument( "--eth-key", type=str, nargs='*', help= "Ethereum private key(s) to use (e.g. 'key_file=aaa.json,pass_file=aaa.pass')" ) parser.add_argument("--tub-address", type=str, required=False, help="Ethereum address of the Tub contract") parser.add_argument("--oasis-address", type=str, required=True, help="Ethereum address of the OasisDEX contract") parser.add_argument( "--oasis-support-address", type=str, required=False, help="Ethereum address of the OasisDEX support contract") parser.add_argument("--buy-token-address", type=str, required=True, help="Ethereum address of the buy token") parser.add_argument("--sell-token-address", type=str, required=True, help="Ethereum address of the sell token") parser.add_argument("--buy-token-name", type=str, required=True, help="Ethereum address of the buy token") parser.add_argument("--sell-token-name", type=str, required=True, help="Ethereum address of the sell token") parser.add_argument("--buy-token-decimals", type=int, required=True, help="Ethereum address of the buy token") parser.add_argument("--sell-token-decimals", type=int, required=True, help="Ethereum address of the sell token") parser.add_argument("--config", type=str, required=True, help="Bands configuration file") parser.add_argument("--price-feed", type=str, required=True, help="Source of price feed") parser.add_argument( "--price-feed-expiry", type=int, default=120, help="Maximum age of the price feed (in seconds, default: 120)") parser.add_argument("--spread-feed", type=str, help="Source of spread feed") parser.add_argument( "--spread-feed-expiry", type=int, default=3600, help="Maximum age of the spread feed (in seconds, default: 3600)") parser.add_argument("--control-feed", type=str, help="Source of control feed") parser.add_argument( "--control-feed-expiry", type=int, default=86400, help="Maximum age of the control feed (in seconds, default: 86400)" ) parser.add_argument("--order-history", type=str, help="Endpoint to report active orders to") parser.add_argument( "--order-history-every", type=int, default=30, help= "Frequency of reporting active orders (in seconds, default: 30)") parser.add_argument( "--round-places", type=int, default=2, help="Number of decimal places to round order prices to (default=2)" ) parser.add_argument( "--min-eth-balance", type=float, default=0, help="Minimum ETH balance below which keeper will cease operation") parser.add_argument("--gas-price", type=int, default=0, help="Gas price (in Wei)") parser.add_argument( "--smart-gas-price", dest='smart_gas_price', action='store_true', help= "Use smart gas pricing strategy, based on the ethgasstation.info feed" ) parser.add_argument("--ethgasstation-api-key", type=str, default=None, help="ethgasstation API key") parser.add_argument( "--refresh-frequency", type=int, default=10, help="Order book refresh frequency (in seconds, default: 10)") parser.add_argument("--debug", dest='debug', action='store_true', help="Enable debug output") self.arguments = parser.parse_args(args) setup_logging(self.arguments) if 'web3' in kwargs: self.web3 = kwargs['web3'] elif self.arguments.endpoint_uri: self.web3: Web3 = web3_via_http(self.arguments.endpoint_uri, self.arguments.rpc_timeout) else: self.logger.warning( "Configuring node endpoint by host and port is deprecated; please use --endpoint-uri" ) self.web3 = Web3( HTTPProvider( endpoint_uri= f"http://{self.arguments.rpc_host}:{self.arguments.rpc_port}", request_kwargs={"timeout": self.arguments.rpc_timeout})) self.web3.eth.defaultAccount = self.arguments.eth_from register_keys(self.web3, self.arguments.eth_key) self.our_address = Address(self.arguments.eth_from) self.otc = MatchingMarket( web3=self.web3, address=Address(self.arguments.oasis_address), support_address=Address(self.arguments.oasis_support_address) if self.arguments.oasis_support_address else None) tub = Tub(web3=self.web3, address=Address(self.arguments.tub_address)) \ if self.arguments.tub_address is not None else None self.token_buy = ERC20Token(web3=self.web3, address=Address( self.arguments.buy_token_address)) self.token_sell = ERC20Token(web3=self.web3, address=Address( self.arguments.sell_token_address)) self.buy_token = Token(name=self.arguments.buy_token_name, address=Address( self.arguments.buy_token_address), decimals=self.arguments.buy_token_decimals) self.sell_token = Token(name=self.arguments.sell_token_name, address=Address( self.arguments.sell_token_address), decimals=self.arguments.sell_token_decimals) self.min_eth_balance = Wad.from_number(self.arguments.min_eth_balance) self.bands_config = ReloadableConfig(self.arguments.config) self.gas_price = GasPriceFactory().create_gas_price( self.web3, self.arguments) self.price_feed = PriceFeedFactory().create_price_feed( self.arguments, tub) self.spread_feed = create_spread_feed(self.arguments) self.control_feed = create_control_feed(self.arguments) self.order_history_reporter = create_order_history_reporter( self.arguments) self.history = History() self.order_book_manager = OrderBookManager( refresh_frequency=self.arguments.refresh_frequency) self.order_book_manager.get_orders_with(lambda: self.our_orders()) self.order_book_manager.place_orders_with(self.place_order_function) self.order_book_manager.cancel_orders_with(self.cancel_order_function) self.order_book_manager.enable_history_reporting( self.order_history_reporter, self.our_buy_orders, self.our_sell_orders) self.order_book_manager.start()
NonfungiblePositionManager_abi = Contract._load_abi(__name__, '../pyexchange/abi/NonfungiblePositionManager.abi')['abi'] # Uniswap contracts are deployed to the same addresses on every network position_manager_address = Address("0xC36442b4a4522E871399CD717aBDD847Ab11FE88") swap_router_address = Address("0xE592427A0AEce92De3Edee1F18E0157C05861564") factory_address = Address("0x1F98431c8aD98523631AE4a59f267346ea31F984") ticklens_address = Address("0xbfd8137f7d1516D3ea5cA83523914859ec47F573") mainnet_weth_address = Address("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") quoter_address = Address("0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6") DAI_KOVAN_ADDRESS = Address("0x4f96fe3b7a6cf9725f59d353f723c1bdb64ca6aa") DAI_MAINNET_ADDRESS = Address("0x6B175474E89094C44Da98b954EedeAC495271d0F") WETH_KOVAN_ADDRESS = Address("0xd0a1e359811322d97991e03f863a0c30c2cf029c") USDC_KOVAN_ADDRESS = Address("0x198419c5c340e8de47ce4c0e4711a03664d42cb2") weth_token_kovan = Token("WETH", WETH_KOVAN_ADDRESS, 18) weth_token_mainnet = Token("WETH", mainnet_weth_address, 18) dai_token_kovan = Token("DAI", DAI_KOVAN_ADDRESS, 18) dai_token_mainnet = Token("DAI", DAI_MAINNET_ADDRESS, 18) usdc_token_kovan = Token("USDC", USDC_KOVAN_ADDRESS, 6) provider = sys.argv[1] private_key = sys.argv[2] account_address = Address(sys.argv[3]) http_provider = HTTPProvider(provider) web3 = Web3(http_provider) web3.eth.defaultAccount = Web3.toChecksumAddress(account_address.address) register_private_key(web3, private_key) # useful for debugging
WETH_KOVAN_ADDRESS = Address("0xd0a1e359811322d97991e03f863a0c30c2cf029c") DAI_ADDRESS = Address("0x6B175474E89094C44Da98b954EedeAC495271d0F") DAI_KOVAN_ADDRESS = Address("0x4f96fe3b7a6cf9725f59d353f723c1bdb64ca6aa") USDC_ADDRESS = Address("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48") MKR_ADDRESS = Address("0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2") MKR_KOVAN_ADDRESS = Address("0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD") FACTORY_ADDRESS = Address("0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f") ROUTER_ADDRESS = Address("0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D") web3 = Web3(HTTPProvider(sys.argv[1], request_kwargs={"timeout": 600})) web3.eth.defaultAccount = sys.argv[2] register_key(web3, sys.argv[3]) Transact.gas_estimate_for_bad_txs = 210000 dai = Token("DAI", DAI_KOVAN_ADDRESS, 18) weth_kovan = Token("WETH", WETH_KOVAN_ADDRESS, 18) weth_mainnet = Token("WETH", WETH_ADDRESS, 18) usdc_kovan = Token("USDC", USDC_KOVAN_ADDRESS, 6) usdc_mainnet = Token("USDC", USDC_MAINNET_ADDRESS, 6) wbtc = Token('WBTC', Address("0xe0c9275e44ea80ef17579d33c55136b7da269aeb"), 8) uniswap = UniswapV2(web3, dai, weth_kovan) dai_weth_pair = Token( "POOL", uniswap.get_pair_address(DAI_KOVAN_ADDRESS, WETH_KOVAN_ADDRESS), 18) # uniswap.approve(wbtc, web3.toWei(5, 'ether')) # uniswap.approve(weth, web3.toWei(5, 'ether')) # amounts_in = uniswap.get_amounts_in(web3.toWei(0.5, 'ether'), [DAI_KOVAN_ADDRESS.address, MKR_KOVAN_ADDRESS.address])
def setup_class(self): self.token = Token( "COW", Address('0xbeef00000000000000000000000000000000BEEF'), 4)
logging.basicConfig(format='%(asctime)-15s %(levelname)-8s %(message)s', level=logging.DEBUG) # reduce logspew logging.getLogger('urllib3').setLevel(logging.INFO) logging.getLogger("web3").setLevel(logging.INFO) logging.getLogger("asyncio").setLevel(logging.INFO) logging.getLogger("requests").setLevel(logging.INFO) # Usage: # python3 tests/manual_test_create_unsafe_vault [ADDRESS] [KEY] [COLLATERAL_TYPE] mcd = DssDeployment.from_node(web3) our_address = Address(web3.eth.defaultAccount) collateral = mcd.collaterals[str(sys.argv[3])] if len(sys.argv) > 3 else mcd.collaterals['ETH-A'] ilk = mcd.vat.ilk(collateral.ilk.name) token = Token(collateral.gem.symbol(), collateral.gem.address, collateral.adapter.dec()) urn = mcd.vat.urn(collateral.ilk, our_address) # mcd.approve_dai(our_address) # Uncomment upon first execution for the account # Transact.gas_estimate_for_bad_txs = 20000 # Uncomment to debug transaction failures onchain # mcd.spotter.poke(ilk).transact() # Uncomment if the Kovan spot price is out-of-sync osm_price = collateral.pip.peek() action = sys.argv[4] if len(sys.argv) > 4 else "create" def r(value, decimals=1): return round(float(value), decimals) logging.info(f"{ilk.name:<6}: dust={r(ilk.dust)} osm_price={r(osm_price)} mat={r(mcd.spotter.mat(ilk))} spot={r(ilk.spot)} ") logging.info(f"{'':<7} duty={mcd.jug.duty(ilk)} min_amount={token.min_amount}")
def get_token(self, symbol): decimal = self.tokens[symbol].get( 'tokenDecimals') if self.tokens[symbol].get( 'tokenDecimals') else 18 return Token(symbol, Address(self.tokens[symbol]['tokenAddress']), decimal)