def test_balance_added_after_startup(self, mocker): try: # given gem balances after starting keeper token_balance_before = self.get_dai_token_balance() self.create_keeper(mocker) time.sleep(6) # wait for keeper to join everything on startup vat_balance_before = self.get_dai_vat_balance() assert self.get_dai_token_balance() == Wad(0) assert vat_balance_before == Wad(0) # when adding Dai purchase_dai(Wad.from_number(77), self.keeper_address) assert self.get_dai_token_balance() == Wad.from_number(77) # and pretending there's a bid which requires Dai reservoir = Reservoir(self.keeper.vat.dai(self.keeper_address)) assert self.keeper.check_bid_cost(id=1, cost=Rad.from_number(20), reservoir=reservoir) # then ensure all Dai is joined assert self.get_dai_token_balance() == Wad(0) assert self.get_dai_vat_balance() == Wad.from_number(77) # when adding more Dai and pretending there's a bid we cannot cover purchase_dai(Wad.from_number(23), self.keeper_address) assert self.get_dai_token_balance() == Wad.from_number(23) reservoir = Reservoir(self.keeper.vat.dai(self.keeper_address)) assert not self.keeper.check_bid_cost(id=2, cost=Rad(Wad.from_number(120)), reservoir=reservoir) # then ensure the added Dai was joined anyway assert self.get_dai_token_balance() == Wad(0) assert self.get_dai_vat_balance() == Wad.from_number(100) finally: self.shutdown_keeper() self.give_away_dai()
def test_fixed_dai_target(self, mocker): try: # given a keeper configured to maintained a fixed amount of Dai target = Wad.from_number(100) purchase_dai(target * 2, self.keeper_address) assert self.get_dai_token_balance() == Wad.from_number(200) self.create_keeper(mocker, target) time.sleep(6) # wait for keeper to join 100 on startup vat_balance_before = self.get_dai_vat_balance() assert vat_balance_before == target # when spending Dai assert self.keeper.dai_join.exit(self.keeper_address, Wad.from_number(22)).transact() assert self.get_dai_vat_balance() == Wad.from_number(78) # and pretending there's a bid which requires more Dai reservoir = Reservoir(self.keeper.vat.dai(self.keeper_address)) assert self.keeper.check_bid_cost(id=3, cost=Rad.from_number(79), reservoir=reservoir) # then ensure Dai was joined up to the target assert self.get_dai_vat_balance() == target # when pretending there's a bid which we have plenty of Dai to cover reservoir = Reservoir(self.keeper.vat.dai(self.keeper_address)) assert self.keeper.check_bid_cost(id=4, cost=Rad(Wad.from_number(1)), reservoir=reservoir) # then ensure Dai levels haven't changed assert self.get_dai_vat_balance() == target finally: self.shutdown_keeper()
def repay_vault(cls, web3, mcd, c, gal_address): # Borrow dai from ETH-C to repay the ETH-B vault urn = mcd.vat.urn(c.ilk, gal_address) # Procure enough Dai to close the vault dai_balance: Wad = mcd.dai.balance_of(gal_address) vat_balance: Wad = Wad(mcd.vat.dai(gal_address)) if vat_balance < urn.art: needed_in_vat = urn.art - vat_balance if dai_balance < needed_in_vat: print("Purchasing Dai to repay vault") purchase_dai(needed_in_vat - dai_balance, gal_address) print("Joining Dai to repay vault") mcd.dai_adapter.join(needed_in_vat).transact(from_address=gal_address) print(f"We have {mcd.vat.dai(gal_address)} Dai to pay off {urn.art} debt") print("Closing vault") mcd.vat.validate_frob(c.ilk, urn.address, Wad(0), urn.art*-1) assert mcd.vat.frob(c.ilk, urn.address, Wad(0), urn.art*-1).transact(from_address=gal_address) mcd.vat.validate_frob(c.ilk, urn.address, urn.ink * -1, Wad(0)) assert mcd.vat.frob(c.ilk, urn.address, urn.ink * -1, Wad(0)).transact(from_address=gal_address) urn = mcd.vat.urn(c.ilk, gal_address) assert urn.ink == Wad(0) assert urn.art == Wad(0)
def test_bite_and_flip(self, web3, mcd, gal_address, keeper_address): # given c = mcd.collaterals['ETH-A'] keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} " f"--type flip " f"--from-block 1 " f"--ilk {c.ilk.name} " f"--model ./bogus-model.sh"), web3=mcd.web3) keeper.approve() unsafe_cdp = create_unsafe_cdp(mcd, c, Wad.from_number(1.2), gal_address) assert len(mcd.active_auctions()["flips"][c.ilk.name]) == 0 # Keeper won't bid with a 0 Dai balance purchase_dai(Wad(20), keeper_address) assert mcd.dai_adapter.join( keeper_address, Wad(20)).transact(from_address=keeper_address) # when keeper.check_cdps() wait_for_other_threads() # then print(mcd.cat.past_bites(10)) assert len(mcd.cat.past_bites(10)) > 0 urn = mcd.vat.urn(unsafe_cdp.ilk, unsafe_cdp.address) assert urn.art == Wad(0) # unsafe cdp has been bitten assert urn.ink == Wad(0) # unsafe cdp is now safe ... assert c.flipper.kicks() == 1 # One auction started
def test_join_enough(self, keeper_address): # given purchasing some dai purchase_dai(Wad.from_number(237), keeper_address) token_balance_before = self.get_dai_token_balance() assert token_balance_before == Wad.from_number(237) # when rebalancing with a smaller amount than we have self.create_keeper(153.0) # then ensure dai was joined to the vat assert token_balance_before > self.get_dai_token_balance() assert self.get_dai_vat_balance() == Wad.from_number(153)
def setup_class(cls): super().setup_class() cls.keeper = AuctionKeeper(args=args(f"--eth-from {cls.keeper_address.address} " f"--type clip " f"--from-block 1 " f"--ilk {cls.collateral.ilk.name} " f"--kick-only"), web3=cls.mcd.web3) cls.keeper.approve() assert get_collateral_price(cls.collateral) == Wad.from_number(200) # Keeper won't bid with a 0 Dai balance if cls.mcd.vat.dai(cls.keeper_address) == Rad(0): purchase_dai(Wad.from_number(20), cls.keeper_address) assert cls.mcd.dai_adapter.join(cls.keeper_address, Wad.from_number(20)).transact( from_address=cls.keeper_address)
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 clean_up_dead_auctions(self, address: Address): assert isinstance(self.collateral, Collateral) assert isinstance(address, Address) for kick in range(1, self.clipper.kicks() + 1): (needs_redo, auction_price, lot, tab) = self.clipper.status(kick) if needs_redo: print(f"Cleaning up dangling {self.collateral.ilk.name} clip auction {kick}") purchase_dai(Wad(tab) + Wad(1), address) assert self.mcd.dai_adapter.join(address, Wad(tab) + Wad(1)).transact(from_address=address) assert self.mcd.vat.dai(address) >= tab assert self.clipper.redo(kick, address).transact() bid_price = Ray(tab / Rad(lot)) while auction_price > bid_price: time_travel_by(self.mcd.web3, 1) (needs_redo, auction_price, lot, tab) = self.clipper.status(kick) self.clipper.validate_take(kick, lot, bid_price, address) assert self.clipper.take(kick, lot, bid_price).transact(from_address=address) (needs_redo, auction_price, lot, tab) = self.clipper.status(kick) assert not needs_redo
def test_empty_gem_only(self): # given gem balances before gem_token_balance_before = self.get_gem_token_balance() gem_vat_balance_before = self.get_gem_vat_balance() # when adding dai purchase_dai(Wad.from_number(79), self.keeper_address) assert self.mcd.dai_adapter.join(self.keeper_address, Wad.from_number(79)).transact( from_address=self.keeper_address) dai_token_balance_before = self.get_dai_token_balance() dai_vat_balance_before = self.get_dai_vat_balance() # and creating and shutting down the keeper keeper = self.create_keeper(False, True) keeper.shutdown() # then ensure dai was not emptied assert dai_token_balance_before == self.get_dai_token_balance() assert dai_vat_balance_before == self.get_dai_vat_balance() # and gem was emptied assert gem_token_balance_before == gem_token_balance_before + gem_vat_balance_before assert self.get_gem_vat_balance() == Wad(0)
def test_do_not_empty(self): # given dai and gem in the vat keeper = self.create_keeper(False, False) purchase_dai(Wad.from_number(153), self.keeper_address) assert self.get_dai_token_balance() >= Wad.from_number(153) assert self.mcd.dai_adapter.join(self.keeper_address, Wad.from_number(153)).transact( from_address=self.keeper_address) wrap_eth(self.mcd, self.keeper_address, Wad.from_number(6)) # and balances before dai_token_balance_before = self.get_dai_token_balance() dai_vat_balance_before = self.get_dai_vat_balance() gem_token_balance_before = self.get_gem_token_balance() gem_vat_balance_before = self.get_gem_vat_balance() # when creating and shutting down the keeper keeper.shutdown() # then ensure no balances changed assert dai_token_balance_before == self.get_dai_token_balance() assert dai_vat_balance_before == self.get_dai_vat_balance() assert gem_token_balance_before == self.get_gem_token_balance() assert gem_vat_balance_before == self.get_gem_vat_balance()