def test_move(self, mcd, our_address, other_address): # given collateral = mcd.collaterals['ETH-A'] collateral.approve(our_address) our_urn = mcd.vat.urn(collateral.ilk, our_address) wrap_eth(mcd, our_address, Wad.from_number(10)) assert collateral.adapter.join(our_address, Wad.from_number(3)).transact() assert mcd.vat.frob(collateral.ilk, our_address, Wad.from_number(3), Wad.from_number(30)).transact() other_balance_before = mcd.vat.dai(other_address) # when assert mcd.vat.move(our_address, other_address, Rad.from_number(30)).transact() # then other_balance_after = mcd.vat.dai(other_address) assert other_balance_before + Rad.from_number(30) == other_balance_after # confirm log was emitted and could be parsed from_block = mcd.web3.eth.blockNumber logs = mcd.vat.past_logs(from_block) assert isinstance(logs[0], Vat.LogMove) logmove: Vat.LogMove = logs[0] assert logmove.src == our_address assert logmove.dst == other_address assert logmove.dart == Rad.from_number(30) # rollback cleanup_urn(mcd, collateral, our_address)
def test_healthy_cdp(self, web3, mcd, our_address): collateral = mcd.collaterals['ETH-B'] ilk = collateral.ilk TestVat.ensure_clean_urn(mcd, collateral, our_address) initial_dai = mcd.vat.dai(our_address) wrap_eth(mcd, our_address, Wad.from_number(9)) # Ensure our collateral enters the urn collateral_balance_before = collateral.gem.balance_of(our_address) collateral.approve(our_address) assert collateral.adapter.join(our_address, Wad.from_number(9)).transact() assert collateral.gem.balance_of(our_address) == collateral_balance_before - Wad.from_number(9) # Add collateral without generating Dai frob(mcd, collateral, our_address, dink=Wad.from_number(3), dart=Wad(0)) print(f"After adding collateral: {mcd.vat.urn(ilk, our_address)}") assert mcd.vat.urn(ilk, our_address).ink == Wad.from_number(3) assert mcd.vat.urn(ilk, our_address).art == Wad(0) assert mcd.vat.gem(ilk, our_address) == Wad.from_number(9) - mcd.vat.urn(ilk, our_address).ink assert mcd.vat.dai(our_address) == initial_dai # Generate some Dai frob(mcd, collateral, our_address, dink=Wad(0), dart=Wad.from_number(153)) print(f"After generating dai: {mcd.vat.urn(ilk, our_address)}") assert mcd.vat.urn(ilk, our_address).ink == Wad.from_number(3) assert mcd.vat.urn(ilk, our_address).art == Wad.from_number(153) assert mcd.vat.dai(our_address) == initial_dai + Rad.from_number(153) # Add collateral and generate some more Dai frob(mcd, collateral, our_address, dink=Wad.from_number(6), dart=Wad.from_number(180)) print(f"After adding collateral and dai: {mcd.vat.urn(ilk, our_address)}") assert mcd.vat.urn(ilk, our_address).ink == Wad.from_number(9) assert mcd.vat.gem(ilk, our_address) == Wad(0) assert mcd.vat.urn(ilk, our_address).art == Wad.from_number(333) assert mcd.vat.dai(our_address) == initial_dai + Rad.from_number(333) # Mint and withdraw our Dai dai_balance_before = mcd.dai.balance_of(our_address) mcd.approve_dai(our_address) assert isinstance(mcd.dai_adapter, DaiJoin) assert mcd.dai_adapter.exit(our_address, Wad.from_number(333)).transact() assert mcd.dai.balance_of(our_address) == dai_balance_before + Wad.from_number(333) assert mcd.vat.dai(our_address) == initial_dai assert mcd.vat.debt() >= initial_dai + Rad.from_number(333) # Repay (and burn) our Dai assert mcd.dai_adapter.join(our_address, Wad.from_number(333)).transact() assert mcd.dai.balance_of(our_address) == Wad(0) assert mcd.vat.dai(our_address) == initial_dai + Rad.from_number(333) # Withdraw our collateral frob(mcd, collateral, our_address, dink=Wad(0), dart=Wad.from_number(-333)) frob(mcd, collateral, our_address, dink=Wad.from_number(-9), dart=Wad(0)) assert mcd.vat.gem(ilk, our_address) == Wad.from_number(9) assert collateral.adapter.exit(our_address, Wad.from_number(9)).transact() collateral_balance_after = collateral.gem.balance_of(our_address) assert collateral_balance_before == collateral_balance_after # Cleanup cleanup_urn(mcd, collateral, our_address)
def flog_and_heal(web3: Web3, mcd: DssDeployment, past_blocks=8, kiss=True, require_heal=True): # Raise debt from the queue (note that vow.wait is 0 on our testchain) bites = mcd.cat.past_bites(past_blocks) for bite in bites: era_bite = bite.era(web3) sin = mcd.vow.sin_of(era_bite) if sin > Rad(0): print( f'flogging era={era_bite} from block={bite.raw["blockNumber"]} ' f'with sin={str(mcd.vow.sin_of(era_bite))}') assert mcd.vow.flog(era_bite).transact() assert mcd.vow.sin_of(era_bite) == Rad(0) # Ensure there is no on-auction debt which a previous test failed to clean up if kiss and mcd.vow.ash() > Rad.from_number(0): assert mcd.vow.kiss(mcd.vow.ash()).transact() assert mcd.vow.ash() == Rad.from_number(0) # Cancel out surplus and debt joy = mcd.vat.dai(mcd.vow.address) woe = mcd.vow.woe() if require_heal: assert joy <= woe if joy <= woe: assert mcd.vow.heal(joy).transact()
def test_divide(self): assert Rad.from_number(4) / Rad.from_number(2) == Rad.from_number(2) assert Rad(4) / Rad.from_number(2) == Rad(2) assert Rad(3) / Rad.from_number(2) == Rad(1) assert Rad(39) / Rad.from_number(20) == Rad(1) assert Rad(40) / Rad.from_number(20) == Rad(2) assert Rad.from_number(0.2) / Rad.from_number(0.1) == Rad.from_number( 2)
def get_tab_discount(self): tot_tab = self.add_tab() if tot_tab > Rad.from_number(self.high_threshold): discount = self.high_discount elif tot_tab > Rad.from_number(self.low_threshold): discount = self.low_discount else: discount = 0 return(discount)
def test_ilk(self, mcd): assert mcd.vat.ilk('XXX') == Ilk('XXX', rate=Ray(0), ink=Wad(0), art=Wad(0), spot=Ray(0), line=Rad(0), dust=Rad(0)) ilk = mcd.collaterals["ETH-C"].ilk assert ilk.line == Rad.from_number(1000000) assert ilk.dust == Rad.from_number(20) representation = repr(ilk) assert "ETH-C" in representation
def test_getters(self, mcd): assert isinstance(mcd.cat.live(), bool) assert isinstance(mcd.cat.vat, Vat) assert isinstance(mcd.cat.vow, Vow) collateral = mcd.collaterals['ETH-C'] assert mcd.cat.flipper(collateral.ilk) == collateral.flipper.address assert mcd.cat.chop(collateral.ilk) == Wad.from_number(1.05) assert mcd.cat.dunk(collateral.ilk) == Rad.from_number(1000) assert mcd.cat.box() == Rad.from_number(5000)
def test_getters(self, mcd): assert isinstance(mcd.dog.live(), bool) assert isinstance(mcd.cat.vat, Vat) assert isinstance(mcd.cat.vow, Vow) collateral = mcd.collaterals['ETH-B'] assert not collateral.flipper assert mcd.dog.clipper(collateral.ilk) == collateral.clipper.address assert mcd.dog.chop(collateral.ilk) == Wad.from_number(1.05) assert mcd.dog.hole(collateral.ilk) == Rad.from_number(300) assert mcd.dog.dirt(collateral.ilk) == Rad(0) assert mcd.dog.dog_hole() == Rad.from_number(5000) assert mcd.dog.dog_dirt() == Rad(0)
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_kick( self, c, kick, mcd, keeper): # given (model, model_factory) = models(keeper, kick) # when keeper.check_all_auctions() wait_for_other_threads() initial_bid = c.flipper.bids(kick) # then model_factory.create_model.assert_called_once_with( Parameters(flipper=c.flipper.address, flapper=None, flopper=None, id=kick)) # and status = model.send_status.call_args[0][0] assert status.id == kick assert status.flipper == c.flipper.address assert status.flapper is None assert status.flopper is None assert status.bid == Rad.from_number(0) assert status.lot == initial_bid.lot assert status.tab == initial_bid.tab assert status.beg > Wad.from_number(1) assert status.guy == mcd.cat.address assert status.era > 0 assert status.end < status.era + c.flipper.tau() + 1 assert status.tic == 0 assert status.price == Wad(0)
def test_should_tick_if_auction_expired_due_to_tau(self, kick): # given (model, model_factory) = models(self.keeper, kick) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when time_travel_by(self.web3, self.flopper.tau() + 1) # and simulate_model_output(model=model, price=Wad.from_number(555.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then model.terminate.assert_not_called() auction = self.flopper.bids(kick) assert round(auction.bid / Rad(auction.lot), 2) == round(Rad.from_number(555.0), 2) # cleanup time_travel_by(self.web3, self.flopper.ttl() + 1) model_factory.create_model.assert_called_once() self.keeper.check_all_auctions() model.terminate.assert_called_once()
def create_dai_token(mcd: DssDeployment, our_address: Address): collateral = mcd.collaterals['ETH-B'] ilk = collateral.ilk # TestVat.ensure_clean_urn(mcd, collateral, our_address) initial_dai = mcd.vat.dai(our_address) wrap_eth(mcd, our_address, Wad.from_number(9)) # Ensure our collateral enters the urn collateral_balance_before = collateral.gem.balance_of(our_address) collateral.approve(our_address) assert collateral.adapter.join(our_address, Wad.from_number(9)).transact() assert collateral.gem.balance_of(our_address) == collateral_balance_before - Wad.from_number(9) # Add collateral without generating Dai frob(mcd, collateral, our_address, dink=Wad.from_number(3), dart=Wad(0)) print(f"After adding collateral: {mcd.vat.urn(ilk, our_address)}") assert mcd.vat.urn(ilk, our_address).ink == Wad.from_number(3) assert mcd.vat.urn(ilk, our_address).art == Wad(0) assert mcd.vat.gem(ilk, our_address) == Wad.from_number(9) - mcd.vat.urn(ilk, our_address).ink assert mcd.vat.dai(our_address) == initial_dai # Generate some Dai frob(mcd, collateral, our_address, dink=Wad(0), dart=Wad.from_number(153)) print(f"After generating dai: {mcd.vat.urn(ilk, our_address)}") assert mcd.vat.urn(ilk, our_address).ink == Wad.from_number(3) assert mcd.vat.urn(ilk, our_address).art == Wad.from_number(153) assert mcd.vat.dai(our_address) == initial_dai + Rad.from_number(153) assert mcd.vat.hope(mcd.dai_adapter.address).transact(from_address=our_address) assert mcd.dai_adapter.exit(our_address, Wad.from_number(153)).transact(from_address=our_address) assert mcd.dai.balance_of(our_address) == Wad.from_number(153)
def kick(web3: Web3, mcd: DssDeployment, gal_address, other_address) -> int: joy = mcd.vat.dai(mcd.vow.address) woe = (mcd.vat.sin(mcd.vow.address) - mcd.vow.sin()) - mcd.vow.ash() print(f'joy={str(joy)[:6]}, woe={str(woe)[:6]}') if woe < joy: # Bite gal CDP c = mcd.collaterals['ETH-B'] unsafe_cdp = create_unsafe_cdp(mcd, c, Wad.from_number(2), other_address, draw_dai=False) flip_kick = bite(mcd, c, unsafe_cdp) # Generate some Dai, bid on and win the flip auction without covering all the debt reserve_dai(mcd, c, gal_address, Wad.from_number(100), extra_collateral=Wad.from_number(1.1)) c.flipper.approve(mcd.vat.address, approval_function=hope_directly(from_address=gal_address)) current_bid = c.flipper.bids(flip_kick) bid = Rad.from_number(1.9) assert mcd.vat.dai(gal_address) > bid assert c.flipper.tend(flip_kick, current_bid.lot, bid).transact(from_address=gal_address) time_travel_by(web3, c.flipper.ttl()+1) assert c.flipper.deal(flip_kick).transact() flog_and_heal(web3, mcd, past_blocks=1200, kiss=False) # Kick off the flop auction woe = (mcd.vat.sin(mcd.vow.address) - mcd.vow.sin()) - mcd.vow.ash() assert mcd.vow.sump() <= woe assert mcd.vat.dai(mcd.vow.address) == Rad(0) assert mcd.vow.flop().transact(from_address=gal_address) return mcd.flopper.kicks()
def test_should_replace_pending_transactions_if_model_raises_bid_and_increases_gas_price(self, kick): # given (model, model_factory) = models(self.keeper, kick) lot = self.flapper.bids(kick).lot # when simulate_model_output(model=model, price=Wad.from_number(9.0), gas_price=10) # and self.start_ignoring_transactions() # and self.keeper.check_all_auctions() self.keeper.check_for_bids() # and self.end_ignoring_transactions() # and simulate_model_output(model=model, price=Wad.from_number(8.0), gas_price=15) # and self.keeper.check_for_bids() wait_for_other_threads() # then assert round(self.flapper.bids(kick).bid, 2) == round(Wad(lot / Rad.from_number(8.0)), 2) assert self.web3.eth.getBlock('latest', full_transactions=True).transactions[0].gasPrice == 15 # cleanup time_travel_by(self.web3, self.flapper.ttl() + 1) assert self.flapper.deal(kick).transact()
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 test_should_overbid_itself_if_model_has_updated_the_price(self, kick): # given (model, model_factory) = models(self.keeper, kick) # when simulate_model_output(model=model, price=Wad.from_number(100.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert round(Rad(self.flopper.bids(kick).lot), 2) == round(self.sump / Rad.from_number(100.0), 2) # when simulate_model_output(model=model, price=Wad.from_number(110.0)) self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.lot_implies_price(kick, Wad.from_number(110.0)) # cleanup time_travel_by(self.web3, self.flopper.ttl() + 1) assert self.flopper.deal(kick).transact()
def test_should_terminate_model_if_auction_is_dealt( self, mcd, c, kick, other_address, keeper): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when self.tend_with_dai(mcd, c, flipper, kick, other_address, Rad.from_number(90)) # and time_travel_by(self.web3, flipper.ttl() + 1) # and flipper.deal(kick).transact(from_address=other_address) # and keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once()
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_kick( self, kick): # given (model, model_factory) = models(self.keeper, kick) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once_with( Parameters(flipper=None, flapper=None, flopper=self.flopper.address, id=kick)) # and status = model.send_status.call_args[0][0] assert status.id == kick assert status.flipper is None assert status.flapper is None assert status.flopper == self.flopper.address assert status.bid > Rad.from_number(0) assert status.lot == self.mcd.vow.dump() assert status.tab is None assert status.beg > Wad.from_number(1) assert status.guy == self.mcd.vow.address assert status.era > 0 assert status.end < status.era + self.flopper.tau() + 1 assert status.tic == 0 assert status.price == Wad(status.bid / Rad(status.lot))
def test_should_terminate_model_if_auction_expired_due_to_ttl_and_somebody_else_won_it( self, mcd, c, kick, other_address, keeper): # given (model, model_factory) = models(keeper, kick) flipper = c.flipper # when keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_not_called() # when flipper.approve( flipper.vat(), approval_function=hope_directly(from_address=other_address)) new_bid_amount = Rad.from_number(85) self.tend_with_dai(mcd, c, flipper, kick, other_address, new_bid_amount) # and time_travel_by(self.web3, flipper.ttl() + 1) # and keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once() model.terminate.assert_called_once() # cleanup assert flipper.deal(kick).transact()
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_should_bid_even_if_there_is_already_a_bidder(self, kick): # given (model, model_factory) = models(self.keeper, kick) mkr_before = self.mcd.mkr.balance_of(self.keeper_address) # and lot = Wad.from_number(0.000016) assert self.flopper.dent( kick, lot, self.sump).transact(from_address=self.other_address) assert self.flopper.bids(kick).lot == lot # when simulate_model_output(model=model, price=Wad.from_number(825.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then auction = self.flopper.bids(kick) assert auction.lot != lot assert round(auction.bid / Rad(auction.lot), 2) == round(Rad.from_number(825.0), 2) mkr_after = self.mcd.mkr.balance_of(self.keeper_address) assert mkr_before == mkr_after # cleanup time_travel_by(self.web3, self.flopper.ttl() + 1) assert self.flopper.deal(kick).transact()
def create_debt(web3: Web3, mcd: DssDeployment, our_address: Address, deployment_address: Address): assert isinstance(web3, Web3) assert isinstance(mcd, DssDeployment) assert isinstance(our_address, Address) assert isinstance(deployment_address, Address) # Create a vault collateral = mcd.collaterals['ETH-A'] ilk = collateral.ilk wrap_eth(mcd, deployment_address, Wad.from_number(1)) collateral.approve(deployment_address) assert collateral.adapter.join(deployment_address, Wad.from_number(1)).transact( from_address=deployment_address) frob(mcd, collateral, deployment_address, dink=Wad.from_number(1), dart=Wad(0)) dart = max_dart(mcd, collateral, deployment_address) - Wad(1) frob(mcd, collateral, deployment_address, dink=Wad(0), dart=dart) assert not mcd.cat.can_bite(ilk, mcd.vat.urn(collateral.ilk, deployment_address)) # Undercollateralize by dropping the spot price, and then bite the vault to_price = Wad(Web3.toInt(collateral.pip.read())) / Wad.from_number(2) set_collateral_price(mcd, collateral, to_price) urn = mcd.vat.urn(collateral.ilk, deployment_address) assert urn.ink is not None and urn.art is not None assert ilk.spot is not None safe = Ray(urn.art) * mcd.vat.ilk(ilk.name).rate <= Ray(urn.ink) * ilk.spot assert not safe assert mcd.cat.can_bite(collateral.ilk, urn) assert mcd.cat.bite(collateral.ilk, urn).transact() flip_kick = collateral.flipper.kicks() # Generate some Dai, bid on and win the flip auction without covering all the debt wrap_eth(mcd, our_address, Wad.from_number(10)) collateral.approve(our_address) assert collateral.adapter.join(our_address, Wad.from_number(10)).transact(from_address=our_address) web3.eth.defaultAccount = our_address.address frob(mcd, collateral, our_address, dink=Wad.from_number(10), dart=Wad.from_number(200)) collateral.flipper.approve(mcd.vat.address, approval_function=hope_directly()) current_bid = collateral.flipper.bids(flip_kick) urn = mcd.vat.urn(collateral.ilk, our_address) assert Rad(urn.art) > current_bid.tab bid = Rad.from_number(6) TestFlipper.tend(collateral.flipper, flip_kick, our_address, current_bid.lot, bid) mcd.vat.can(our_address, collateral.flipper.address) wait(mcd, our_address, collateral.flipper.ttl()+1) assert collateral.flipper.deal(flip_kick).transact() # Raise debt from the queue (note that vow.wait is 0 on our testchain) bites = mcd.cat.past_bites(100) for bite in bites: era_bite = bite.era(web3) assert era_bite > int(datetime.now().timestamp()) - 120 assert mcd.vow.sin_of(era_bite) > Rad(0) assert mcd.vow.flog(era_bite).transact() assert mcd.vow.sin_of(era_bite) == Rad(0) # Cancel out surplus and debt dai_vow = mcd.vat.dai(mcd.vow.address) assert dai_vow <= mcd.vow.woe() assert mcd.vow.heal(dai_vow).transact() assert mcd.vow.woe() >= mcd.vow.sump()
def test_should_bid_even_if_there_is_already_a_bidder(self, kick, other_address): # given (model, model_factory) = models(self.keeper, kick) flipper = self.collateral.flipper # and self.tend_with_dai(self.mcd, self.collateral, flipper, kick, other_address, Rad.from_number(21)) assert flipper.bids(kick).bid == Rad.from_number(21) # when self.simulate_model_bid(self.mcd, self.collateral, model, Wad.from_number(23)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then auction = flipper.bids(kick) assert round(auction.bid / Rad(auction.lot), 2) == round(Rad.from_number(23), 2)
def test_pack(self, mcd, our_address): assert mcd.end.bag(our_address) == Wad(0) assert mcd.end.debt() > Rad(0) assert mcd.dai.approve(mcd.end.address).transact() assert mcd.vat.dai(our_address) >= Rad.from_number(10) # FIXME: `pack` fails, possibly because we're passing 0 to `vat.flux` assert mcd.end.pack(Wad.from_number(10)).transact() assert mcd.end.bag(our_address) == Wad.from_number(10)
def open_cdp(mcd: DssDeployment, collateral: Collateral, address: Address, debtMultiplier: int = 1): assert isinstance(mcd, DssDeployment) assert isinstance(collateral, Collateral) assert isinstance(address, Address) collateral.approve(address) wrap_eth(mcd, address, Wad.from_number(20)) assert collateral.adapter.join(address, Wad.from_number(20)).transact(from_address=address) frob(mcd, collateral, address, Wad.from_number(20), Wad.from_number(20 * debtMultiplier)) assert mcd.vat.debt() >= Rad(Wad.from_number(20 * debtMultiplier)) assert mcd.vat.dai(address) >= Rad.from_number(20 * debtMultiplier)
def test_should_cast_to_float(self): assert float(Rad.from_number(-4.5)) == -4.5 assert float(Rad.from_number(0.99)) == 0.99 assert float(Rad.from_number(1)) == 1.0 assert float(Rad.from_number(1.0)) == 1.0 assert float(Rad.from_number(1.5)) == 1.5 assert float(Rad.from_number(1.9999999999)) == 1.9999999999
def test_should_cast_to_int(self): assert int(Rad.from_number(-4.5)) == -4 assert int(Rad.from_number(0.99)) == 0 assert int(Rad.from_number(1)) == 1 assert int(Rad.from_number(1.0)) == 1 assert int(Rad.from_number(1.5)) == 1 assert int(Rad.from_number(1.9999999999)) == 1
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_kick( self, kick, other_address): # given (model, model_factory) = models(self.keeper, kick) flipper = self.collateral.flipper # when self.keeper.check_all_auctions() wait_for_other_threads() initial_bid = self.collateral.flipper.bids(kick) # then model_factory.create_model.assert_called_once_with( Parameters(flipper=flipper.address, flapper=None, flopper=None, id=kick)) # and status = model.send_status.call_args[0][0] assert status.id == kick assert status.flipper == flipper.address assert status.flapper is None assert status.flopper is None assert status.bid == Rad.from_number(0) assert status.lot == initial_bid.lot assert status.tab == initial_bid.tab assert status.beg > Wad.from_number(1) assert status.guy == self.mcd.cat.address assert status.era > 0 assert status.end < status.era + flipper.tau() + 1 assert status.tic == 0 assert status.price == Wad(0) # cleanup time_travel_by(self.web3, flipper.ttl() + 1) self.keeper.check_all_auctions() TestAuctionKeeperFlipper.tend_with_dai(self.mcd, self.collateral, flipper, kick, other_address, Rad.from_number(80)) flipper.deal(kick).transact(from_address=other_address)
def create_flip_auction(mcd: DssDeployment, deployment_address: Address, our_address: Address): assert isinstance(mcd, DssDeployment) assert isinstance(our_address, Address) assert isinstance(deployment_address, Address) # Create a CDP collateral = mcd.collaterals['ETH-A'] ilk = collateral.ilk wrap_eth(mcd, deployment_address, Wad.from_number(1)) collateral.approve(deployment_address) assert collateral.adapter.join( deployment_address, Wad.from_number(1)).transact(from_address=deployment_address) frob(mcd, collateral, deployment_address, dink=Wad.from_number(1), dart=Wad(0)) dart = max_dart(mcd, collateral, deployment_address) - Wad(1) frob(mcd, collateral, deployment_address, dink=Wad(0), dart=dart) # Undercollateralize and bite the CDP to_price = Wad(mcd.web3.toInt(collateral.pip.read())) / Wad.from_number(2) set_collateral_price(mcd, collateral, to_price) urn = mcd.vat.urn(collateral.ilk, deployment_address) ilk = mcd.vat.ilk(ilk.name) safe = Ray(urn.art) * mcd.vat.ilk(ilk.name).rate <= Ray(urn.ink) * ilk.spot assert not safe assert mcd.cat.can_bite(collateral.ilk, Urn(deployment_address)) assert mcd.cat.bite(collateral.ilk, Urn(deployment_address)).transact() flip_kick = collateral.flipper.kicks() # Generate some Dai, bid on the flip auction without covering all the debt wrap_eth(mcd, our_address, Wad.from_number(10)) collateral.approve(our_address) assert collateral.adapter.join( our_address, Wad.from_number(10)).transact(from_address=our_address) mcd.web3.eth.defaultAccount = our_address.address frob(mcd, collateral, our_address, dink=Wad.from_number(10), dart=Wad.from_number(200)) collateral.flipper.approve(mcd.vat.address, approval_function=hope_directly()) current_bid = collateral.flipper.bids(flip_kick) urn = mcd.vat.urn(collateral.ilk, our_address) assert Rad(urn.art) > current_bid.tab bid = Rad.from_number(6) tend(collateral.flipper, flip_kick, our_address, current_bid.lot, bid)
def test_getters(self, mcd, clipper): assert clipper.ilk_name() == "ETH-B" collateral = mcd.collaterals[clipper.ilk_name()] assert clipper.kicks() == 0 assert clipper.buf() == Ray.from_number(1.50) assert clipper.tail() == 10800 assert clipper.cusp() == Ray.from_number(0.3333) assert clipper.chip() == Wad.from_number(0.02) assert clipper.tip() == Rad.from_number(100) assert clipper.chost() == collateral.ilk.dust * Rad(mcd.dog.chop(collateral.ilk)) assert isinstance(clipper.calc, Address) assert clipper.calc != Address.zero() assert clipper.dog.address == mcd.dog.address assert clipper.vat.address == mcd.vat.address assert clipper.active_auctions() == []
def test_should_not_instantiate_model_if_auction_is_dealt(self, kick, other_address): # given (model, model_factory) = models(self.keeper, kick) flipper = self.collateral.flipper # and TestAuctionKeeperFlipper.tend_with_dai(self.mcd, self.collateral, flipper, kick, other_address, Rad.from_number(90)) # and time_travel_by(self.web3, flipper.ttl() + 1) # and flipper.deal(kick).transact(from_address=other_address) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_not_called()