def setup_method(self): self.web3 = web3() self.our_address = our_address(self.web3) self.keeper_address = keeper_address(self.web3) self.other_address = other_address(self.web3) self.gal_address = gal_address(self.web3) self.mcd = mcd(self.web3) self.flapper = self.mcd.flapper self.flapper.approve(self.mcd.mkr.address, directly(from_address=self.other_address)) self.keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address} " f"--type flap " f"--from-block 1 " f"--model ./bogus-model.sh"), web3=self.web3) self.keeper.approve() mint_mkr(self.mcd.mkr, self.keeper_address, Wad.from_number(50000)) mint_mkr(self.mcd.mkr, self.other_address, Wad.from_number(50000)) assert isinstance(self.keeper.gas_price, DynamicGasPrice) # Since no args were assigned, gas strategy should return a GeometricGasPrice starting at 10 Gwei self.default_gas_price = 10 * DynamicGasPrice.GWEI
def setup_method(self): self.web3 = get_web3() self.our_address = get_our_address(self.web3) self.keeper_address = get_keeper_address(self.web3) self.other_address = get_other_address(self.web3) self.auction_income_recipient_address = get_auction_income_recipient_address(self.web3) self.geb = get_geb(self.web3) self.surplus_auction_house = self.geb.surplus_auction_house self.surplus_auction_house.approve(self.geb.prot.address, directly(from_address=self.other_address)) #self.min_auction = self.geb.surplus_auction_house.auctions_started() + 1 self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type surplus " f"--from-block 1 " f"--bid-delay 0 " #f"--min-auction {self.min_auction} " f"--model ./bogus-model.sh"), web3=self.web3) self.keeper.approve() mint_prot(self.geb.prot, self.keeper_address, Wad.from_number(50000)) mint_prot(self.geb.prot, self.other_address, Wad.from_number(50000)) assert isinstance(self.keeper.gas_price, DynamicGasPrice) # Since no args were assigned, gas strategy should return a GeometricGasPrice starting at the node gas price self.default_gas_price = get_node_gas_price(self.web3)
def test_deal_list(self, web3, keeper_address: Address): accounts = ["0x40418beb7f24c87ab2d5ffb8404665414e91d858", "0x4A8638b3788c554563Ef2444f86F943ab0Cd9761", "0xdb33dfd3d61308c33c63209845dad3e6bfb2c674"] default_behavior = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip --from-block 1 " f"--ilk ETH-B " f"--model ./bogus-model.sh"), web3=web3) assert 1 == len(default_behavior.deal_for) assert keeper_address == list(default_behavior.deal_for)[0] assert not default_behavior.deal_all deal_for_3_accounts = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flap --from-block 1 " f"--deal-for {accounts[0]} {accounts[1]} {accounts[2]} " f"--model ./bogus-model.sh"), web3=web3) assert 3 == len(deal_for_3_accounts.deal_for) for account in accounts: assert Address(account) in deal_for_3_accounts.deal_for assert not deal_for_3_accounts.deal_all disable_deal = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flop --from-block 1 " f"--deal-for NONE " f"--model ./bogus-model.sh"), web3=web3) assert 0 == len(disable_deal.deal_for) assert not disable_deal.deal_all deal_all = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flop --from-block 1 " f"--deal-for ALL " f"--model ./bogus-model.sh"), web3=web3) assert deal_all.deal_all
def setup_class(self): """ I'm excluding initialization of a specific collateral perchance we use multiple collaterals to improve test speeds. This prevents us from instantiating the keeper as a class member. """ self.web3 = get_web3() self.geb = get_geb(self.web3) self.keeper_address = get_keeper_address(self.web3) self.collateral = self.geb.collaterals['ETH-B'] self.min_auction = self.collateral.collateral_auction_house.auctions_started( ) + 1 self.keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address.address} " f"--type collateral " f"--flash-swap " f"--from-block {self.geb.starting_block_number} " f"--min-auction {self.min_auction} " f"--model ../models/collateral_model.sh " f"--collateral-type {self.collateral.collateral_type.name}"), web3=self.geb.web3) self.keeper.approve() #flash-swap should disable rebalance assert self.keeper.rebalance_system_coin() == Wad(0) assert isinstance(self.keeper.gas_price, DynamicGasPrice) self.default_gas_price = self.keeper.gas_price.get_gas_price(0)
def setup_method(self): self.web3 = web3() self.our_address = our_address(self.web3) self.keeper_address = keeper_address(self.web3) self.other_address = other_address(self.web3) self.gal_address = gal_address(self.web3) self.mcd = mcd(self.web3) self.flopper = self.mcd.flopper self.flopper.approve( self.mcd.vat.address, approval_function=hope_directly(from_address=self.keeper_address)) self.flopper.approve( self.mcd.vat.address, approval_function=hope_directly(from_address=self.other_address)) self.keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address} " f"--type flop " f"--from-block 1 " f"--model ./bogus-model.sh"), web3=self.web3) self.keeper.approve() assert isinstance(self.keeper.gas_price, DynamicGasPrice) self.default_gas_price = self.keeper.gas_price.get_gas_price(0) reserve_dai(self.mcd, self.mcd.collaterals['ETH-C'], self.keeper_address, Wad.from_number(200.00000)) reserve_dai(self.mcd, self.mcd.collaterals['ETH-C'], self.other_address, Wad.from_number(200.00000)) self.sump = self.mcd.vow.sump() # Rad
def check_async_transaction_still_works(self): balance_before = self.mcd.vat.gem(self.ilk, self.keeper_address) amount = Wad.from_number(0.01) AuctionKeeper._run_future(self.collateral.adapter.exit(self.keeper_address, amount).transact_async()) wait_for_other_threads() balance_after = self.mcd.vat.gem(self.ilk, self.keeper_address) assert balance_before - amount == balance_after
def setup_method(self): self.web3 = web3() self.our_address = our_address(self.web3) self.keeper_address = keeper_address(self.web3) self.other_address = other_address(self.web3) self.gal_address = gal_address(self.web3) self.mcd = mcd(self.web3) self.flopper = self.mcd.flopper self.flopper.approve( self.mcd.vat.address, approval_function=hope_directly(from_address=self.keeper_address)) self.flopper.approve( self.mcd.vat.address, approval_function=hope_directly(from_address=self.other_address)) self.keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address} " f"--type flop " f"--from-block 1 " f"--bid-check-interval 0.05 " f"--model ./bogus-model.sh"), web3=self.web3) self.keeper.approve() reserve_dai(self.mcd, self.mcd.collaterals['ETH-C'], self.keeper_address, Wad.from_number(200.00000)) reserve_dai(self.mcd, self.mcd.collaterals['ETH-C'], self.other_address, Wad.from_number(200.00000)) self.sump = self.mcd.vow.sump() # Rad
def test_poanetwork(self, geb, keeper_address): # given c = geb.collaterals['ETH-A'] keeper = AuctionKeeper(args=args( f"--eth-from {keeper_address} " f"--type collateral " f"--from-block 1 " f"--collateral-type {c.collateral_type.name} " f"--poanetwork-gas-price " f"--model ./bogus-model.sh"), web3=geb.web3) assert isinstance(keeper.gas_price.gas_station, POANetwork) assert keeper.gas_price.gas_station.URL == "https://gasprice.poa.network" keeper = AuctionKeeper(args=args( f"--eth-from {keeper_address} " f"--type collateral " f"--from-block 1 " f"--collateral-type {c.collateral_type.name} " f"--poanetwork-gas-price " f"--poanetwork-url http://localhost:8000 " f"--model ./bogus-model.sh"), web3=geb.web3) assert isinstance(keeper.gas_price.gas_station, POANetwork) assert keeper.gas_price.gas_station.URL == "http://localhost:8000"
def keeper(web3, c: Collateral, keeper_address: Address, d: DssDeployment): keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--flipper {c.flipper.address} " f"--model ./bogus-model.sh"), web3=web3) keeper.approve() return keeper
def create_keeper_join_all(self): keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type flop " f"--from-block 1 " f"--vat-dai-target all " f"--model ./bogus-model.sh"), web3=self.web3) assert self.web3.eth.defaultAccount == self.keeper_address.address keeper.startup() return keeper
def setup_method(self): self.web3 = Web3(HTTPProvider("http://localhost:8555")) self.web3.eth.defaultAccount = self.web3.eth.accounts[0] self.keeper_address = Address(self.web3.eth.defaultAccount) self.gal_address = Address(self.web3.eth.accounts[1]) self.other_address = Address(self.web3.eth.accounts[2]) # GemMock version of DSToken with push(bytes32, uint function) an hope(address) gem_abi = Contract._load_abi(__name__, '../lib/pymaker/tests/abi/GemMock.abi') gem_bin = Contract._load_bin(__name__, '../lib/pymaker/tests/abi/GemMock.bin') self.gem_addr = Contract._deploy(self.web3, gem_abi, gem_bin, [b'ABC']) self.gem = DSToken(web3=self.web3, address=self.gem_addr) self.dai_addr = Contract._deploy(self.web3, gem_abi, gem_bin, [b'DAI']) self.dai = DSToken(web3=self.web3, address=self.dai_addr) self.flipper = Flipper.deploy(self.web3, self.dai.address, self.gem.address) # Set allowance to allow flipper to move dai and gem self.dai.approve(self.flipper.address).transact() self.dai.approve( self.flipper.address).transact(from_address=self.gal_address) self.dai.approve( self.flipper.address).transact(from_address=self.other_address) self.gem.approve( self.flipper.address).transact(from_address=self.gal_address) self.gem.approve( self.flipper.address).transact(from_address=self.other_address) self.keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address} " f"--flipper {self.flipper.address} " f"--model ./bogus-model.sh"), web3=self.web3) self.keeper.approve() # So that `keeper_address` and `other_address` can bid in auctions, # they both need to have DAI in their accounts. self.dai.mint(Wad.from_number(20000000)).transact() self.dai.transfer(self.other_address, Wad.from_number(10000000)).transact() # So that `gal_address` can kick auction he need to have GEM in his accounts self.gem.mint(Wad.from_number(1000000)).transact() self.gem.transfer(self.gal_address, Wad.from_number(1000000)).transact() self.model = MagicMock() self.model.get_stance = MagicMock(return_value=None) self.model_factory = self.keeper.auctions.model_factory self.model_factory.create_model = MagicMock(return_value=self.model)
def other_keeper(web3, c: Collateral, other_address: Address, d: DssDeployment): keeper = AuctionKeeper(args=args(f"--eth-from {other_address} " f"--flipper {c.flipper.address} " f"--cat {d.cat.address} " f"--ilk {c.ilk.name} " f"--model ./bogus-model.sh"), web3=web3) keeper.approve() return keeper
def create_keeper(self, dai: float): assert isinstance(dai, float) keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type flop " f"--from-block 1 " f"--vat-dai-target {dai} " f"--model ./bogus-model.sh"), web3=self.web3) assert self.web3.eth.defaultAccount == self.keeper_address.address keeper.startup() return keeper
def create_keeper(self, dai: float): assert isinstance(dai, float) keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type flop " f"--network testnet " f"--vat-dai-target {dai} " f"--model ./bogus-model.sh"), web3=self.web3) assert self.web3.eth.defaultAccount == self.keeper_address.address assert keeper.vat_dai_target == Wad.from_number(dai) keeper.startup() return keeper
def create_keeper(self, system_coin: float): assert isinstance(system_coin, float) keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address} " f"--type debt " f"--from-block 1 " f"--safe-engine-system-coin-target {system_coin} " f"--model ./bogus-model.sh"), web3=self.web3) assert self.web3.eth.defaultAccount == self.keeper_address.address keeper.startup() return keeper
def test_shouldnt_need_urn_history_when_only_bidding(self, web3, keeper_address: Address): with pytest.raises(RuntimeError) as e: AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--ilk ETH-A " f"--model ./bogus-model.sh"), web3=web3) keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--ilk ETH-A " f"--bid-only " f"--model ./bogus-model.sh"), web3=web3) assert keeper.urn_history is None
def test_config_negative(self, web3, keeper_address): with pytest.raises(SystemExit): missing_arg = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flop --from-block 1 " f"--gas-reactive-multiplier " f"--model ./bogus-model.sh"), web3=web3) with pytest.raises(SystemExit): conflicting_args = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flop --from-block 1 " f"--etherchain-gas-price " f"--poanetwork-gas-price " f"--model ./bogus-model.sh"), web3=web3)
def create_keeper(mcd: DssDeployment, c: Collateral, address=None): assert isinstance(mcd, DssDeployment) assert isinstance(c, Collateral) if address is None: address = Address(mcd.web3.eth.accounts[1]) assert isinstance(address, Address) keeper = AuctionKeeper(args=args(f"--eth-from {address} " f"--type flip " f"--network testnet " f"--ilk {c.ilk.name} " f"--model ./bogus-model.sh"), web3=mcd.web3) keeper.approve() return keeper
def test_bite_only(self, other_keeper: AuctionKeeper, d: DssDeployment, c: Collateral, unsafe_cdp: Urn): # given nflip = d.cat.nflip() nkick = c.flipper.kicks() # when other_keeper.check_cdps() wait_for_other_threads() # then urn = d.vat.urn(unsafe_cdp.ilk, unsafe_cdp.address) assert urn.art == Wad(0) # unsafe cdp has been biten assert urn.ink == Wad(0) # unsafe cdp is now safe ... assert d.cat.nflip() == nflip + 1 # One more flip available assert c.flipper.kicks() == nkick # No auction started because no available fund to tend()
def test_flip_keeper_negative(self, web3, keeper_address: Address): with pytest.raises(RuntimeError) as e: AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--from-block 1 " f"--model ./bogus-model.sh"), web3=web3) assert "ilk" in str(e)
def create_sharded_keeper(self, web3, keeper_address: Address, shard: int): return AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--from-block 1 " f"--ilk ETH-B " f"--shards 3 --shard-id {shard} " f"--model ./bogus-model.sh"), web3=web3)
def setup_class(self): """ I'm excluding initialization of a specific collateral perchance we use multiple collaterals to improve test speeds. This prevents us from instantiating the keeper as a class member. """ self.web3 = web3() self.mcd = mcd(self.web3) self.keeper_address = keeper_address(self.web3) self.collateral = self.mcd.collaterals['ETH-B'] self.keeper = AuctionKeeper(args=args( f"--eth-from {self.keeper_address.address} " f"--type flip " f"--from-block 1 " f"--ilk {self.collateral.ilk.name} " f"--bid-check-interval 0.03 " f"--model ./bogus-model.sh"), web3=self.mcd.web3) self.keeper.approve()
def create_keeper(self, exit_dai_on_shutdown: bool, exit_gem_on_shutdown: bool): assert isinstance(exit_dai_on_shutdown, bool) assert isinstance(exit_gem_on_shutdown, bool) vat_dai_behavior = "" if exit_dai_on_shutdown else "--keep-dai-in-vat-on-exit" vat_gem_behavior = "" if exit_gem_on_shutdown else "--keep-gem-in-vat-on-exit" keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type flop " f"--from-block 1 " f"{vat_dai_behavior} " f"{vat_gem_behavior} " f"--model ./bogus-model.sh"), web3=self.web3) assert self.web3.eth.defaultAccount == self.keeper_address.address assert keeper.arguments.exit_dai_on_shutdown == exit_dai_on_shutdown keeper.startup() return keeper
def test_shouldnt_need_safe_history_when_only_bidding( self, web3, keeper_address: Address): keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type collateral " f"--collateral-type ETH-A " f"--bid-only " f"--model ./bogus-model.sh"), web3=web3) assert keeper.safe_history is None
def create_keeper(self, mocker, dai_target="all"): # Create a keeper mocker.patch("web3.net.Net.peer_count", return_value=1) self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type flip --ilk ETH-A --bid-only " f"--vat-dai-target {dai_target} " f"--return-gem-interval 3 " f"--model ./bogus-model.sh"), web3=self.web3) assert self.web3.eth.defaultAccount == self.keeper_address.address self.web3 = self.keeper.web3 self.mcd = self.keeper.mcd assert self.keeper.auctions self.collateral = self.keeper.collateral self.collateral.approve(self.keeper_address) self.thread = threading.Thread(target=self.keeper.main, daemon=True) self.thread.start() return self.keeper
def setup_class(self): """ I'm excluding initialization of a specific collateral perchance we use multiple collaterals to improve test speeds. This prevents us from instantiating the keeper as a class member. """ self.web3 = web3() self.mcd = mcd(self.web3) self.c = self.mcd.collaterals['ETH-C'] self.keeper_address = keeper_address(self.web3) self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address.address} " f"--type flip " f"--from-block 1 " f"--ilk {self.c.ilk.name} " f"--model ./bogus-model.sh"), web3=self.mcd.web3) self.keeper.approve() # Keeper won't bid with a 0 Dai balance purchase_dai(Wad.from_number(20), self.keeper_address) assert self.mcd.dai_adapter.join(self.keeper_address, Wad.from_number(20)).transact( from_address=self.keeper_address)
def setup_method(self): self.web3 = web3() self.our_address = our_address(self.web3) self.keeper_address = keeper_address(self.web3) self.other_address = other_address(self.web3) self.gal_address = gal_address(self.web3) self.mcd = mcd(self.web3) self.flapper = self.mcd.flapper self.flapper.approve(self.mcd.mkr.address, directly(from_address=self.other_address)) self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} " f"--type flap " f"--from-block 1 " f"--model ./bogus-model.sh"), web3=self.web3) self.keeper.approve() mint_mkr(self.mcd.mkr, self.keeper_address, Wad.from_number(50000)) mint_mkr(self.mcd.mkr, self.other_address, Wad.from_number(50000))
def test_config_negative(self, web3, keeper_address): with pytest.raises(SystemExit): missing_arg = AuctionKeeper(args=args( f"--eth-from {keeper_address} " f"--type flop --from-block 1 " f"--gas-reactive-multiplier " f"--model ./bogus-model.sh"), web3=web3) kill_other_threads()
def test_replace_async_transaction(self): balance_before = self.mcd.vat.gem(self.ilk, self.keeper_address) self.start_ignoring_transactions() amount1 = Wad.from_number(0.11) tx1 = self.collateral.adapter.join(self.keeper_address, amount1) AuctionKeeper._run_future(tx1.transact_async()) self.end_ignoring_transactions() amount2 = Wad.from_number(0.14) tx2 = self.collateral.adapter.join(self.keeper_address, amount2) AuctionKeeper._run_future(tx2.transact_async(replace=tx1)) # Wait for async tx threads to exit normally (should consider doing this after every async test) wait_for_other_threads() balance_after = self.mcd.vat.gem(self.ilk, self.keeper_address) assert balance_before + amount2 == balance_after self.check_sync_transaction_still_works() self.check_async_transaction_still_works()
def test_settle_list(self, web3, keeper_address: Address): accounts = [ "0x40418beb7f24c87ab2d5ffb8404665414e91d858", "0x4A8638b3788c554563Ef2444f86F943ab0Cd9761", "0xdb33dfd3d61308c33c63209845dad3e6bfb2c674" ] default_behavior = AuctionKeeper(args=args( f"--eth-from {keeper_address} " f"--type collateral --from-block 1 " f"--collateral-type ETH-B " f"--model ./bogus-model.sh"), web3=web3) assert 0 == len(default_behavior.settle_auctions_for) assert not default_behavior.settle_all settle_for_3_accounts = AuctionKeeper(args=args( f"--eth-from {keeper_address} " f"--type surplus --from-block 1 " f"--settle-auctions-for {accounts[0]} {accounts[1]} {accounts[2]} " f"--model ./bogus-model.sh"), web3=web3) assert 3 == len(settle_for_3_accounts.settle_auctions_for) for account in accounts: assert Address( account) in settle_for_3_accounts.settle_auctions_for assert not settle_for_3_accounts.settle_all disable_settle = AuctionKeeper(args=args( f"--eth-from {keeper_address} " f"--type debt --from-block 1 " f"--settle-auctions-for NONE " f"--model ./bogus-model.sh"), web3=web3) assert 0 == len(disable_settle.settle_auctions_for) assert not disable_settle.settle_all settle_all = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type debt --from-block 1 " f"--settle-auctions-for ALL " f"--model ./bogus-model.sh"), web3=web3) assert settle_all.settle_all