def test_should_restart_auction_if_auction_expired_due_to_total_auction_length( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # 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.debt_auction_house.total_auction_length() + 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.debt_auction_house.bids(auction_id) assert round( auction.bid_amount * self.geb.oracle_relayer.redemption_price() / Rad(auction.amount_to_sell), 2) == round(Rad.from_number(555.0), 2) # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) model_factory.create_model.assert_called_once() self.keeper.check_all_auctions() model.terminate.assert_called_once()
def test_process_safe(self, geb, our_address): collateral_type = geb.collaterals['ETH-A'].collateral_type safe = geb.safe_engine.safe(collateral_type, our_address) assert safe.generated_debt > Wad(0) assert geb.safe_engine.collateral_type( collateral_type.name).accumulated_rate > Ray(0) assert geb.global_settlement.final_coin_per_collateral_price( collateral_type) > Ray(0) owe = Ray(safe.generated_debt) * geb.safe_engine.collateral_type( collateral_type.name ).accumulated_rate * geb.global_settlement.final_coin_per_collateral_price( collateral_type) assert owe > Ray(0) wad = min(Ray(safe.locked_collateral), owe) print(f"owe={owe} wad={wad}") assert geb.global_settlement.process_safe(collateral_type, our_address).transact() assert geb.safe_engine.safe(collateral_type, our_address).generated_debt == Wad(0) assert geb.safe_engine.safe(collateral_type, our_address).locked_collateral > Wad(0) assert geb.safe_engine.debt_balance( geb.accounting_engine.address) > Rad(0) assert geb.safe_engine.global_debt() > Rad(0) assert geb.safe_engine.global_unbacked_debt() > Rad(0)
def test_should_bid_even_if_there_is_already_a_bidder(self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) prot_before = self.geb.prot.balance_of(self.keeper_address) # and amount_to_sell = Wad.from_number(0.000016) assert self.debt_auction_house.decrease_sold_amount( auction_id, amount_to_sell, self.debt_auction_bid_size).transact( from_address=self.other_address) assert self.debt_auction_house.bids( auction_id).amount_to_sell == amount_to_sell # 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.debt_auction_house.bids(auction_id) assert auction.amount_to_sell != amount_to_sell assert round( auction.bid_amount * self.geb.oracle_relayer.redemption_price() / Rad(auction.amount_to_sell), 2) == round(Rad.from_number(825.0), 2) prot_after = self.geb.prot.balance_of(self.keeper_address) assert prot_before == prot_after # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) assert self.debt_auction_house.settle_auction(auction_id).transact()
def test_transfer_internal_coins(self, geb, our_address, other_address): # given collateral = geb.collaterals['ETH-A'] collateral.approve(our_address) our_safe = geb.safe_engine.safe(collateral.collateral_type, our_address) wrap_eth(geb, our_address, Wad.from_number(60)) assert collateral.adapter.join(our_address, Wad.from_number(60)).transact() assert geb.safe_engine.modify_safe_collateralization( collateral.collateral_type, our_address, Wad.from_number(60), Wad.from_number(20)).transact() other_balance_before = geb.safe_engine.coin_balance(other_address) # when assert geb.safe_engine.transfer_internal_coins( our_address, other_address, Rad(Wad.from_number(20))).transact() # then other_balance_after = geb.safe_engine.coin_balance(other_address) assert other_balance_before + Rad( Wad.from_number(20)) == other_balance_after # rollback cleanup_safe(geb, collateral, our_address)
def get_input(self, id: int) -> Status: assert isinstance(id, int) # Read auction state bid = self.staked_token_auction_house.bids(id) # get latest redemption price redemption_price = self.geb.oracle_relayer.redemption_price() # Prepare the model input from auction state return Status( id=id, collateral_auction_house=None, surplus_auction_house=None, debt_auction_house=None, staked_token_auction_house=self.staked_token_auction_house.address, bid_amount=bid.bid_amount, amount_to_sell=bid.amount_to_sell, amount_to_raise=None, sold_amount=None, raised_amount=None, bid_increase=self.bid_increase, bid_decrease=None, high_bidder=bid.high_bidder, block_time=block_time(self.staked_token_auction_house.web3), bid_expiry=bid.bid_expiry, auction_deadline=bid.auction_deadline, price=Wad(bid.bid_amount * Rad(redemption_price) / Rad(bid.amount_to_sell)) if Rad(bid.amount_to_sell) != Rad(0) else None)
def test_should_overbid_itself_if_model_has_updated_the_price( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # 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.debt_auction_house.bids(auction_id).amount_to_sell), 2) == round(self.debt_auction_bid_size / 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.amount_to_sell_implies_price(auction_id, Wad.from_number(110.0)) # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) assert self.debt_auction_house.settle_auction(auction_id).transact()
def test_flash_proxy_settle_auction(self, c: Collateral, web3, geb, auction_id, other_address): # given collateral_auction_house = self.collateral.collateral_auction_house if not isinstance(collateral_auction_house, FixedDiscountCollateralAuctionHouse): return set_collateral_price(geb, c, Wad.from_number(100)) eth_before = self.web3.eth.getBalance(self.keeper_address.address) # when self.keeper.check_all_auctions() wait_for_other_threads() assert self.web3.eth.getBalance( self.keeper_address.address) > eth_before current_status = collateral_auction_house.bids(auction_id) assert current_status.raised_amount == Rad(0) assert current_status.sold_amount == Wad(0) assert current_status.amount_to_raise == Rad(0) assert current_status.amount_to_sell == Wad(0) assert current_status.auction_deadline == 0 assert current_status.raised_amount == Rad(0)
def test_should_start_a_new_model_and_provide_it_with_info_on_auction_start( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when self.keeper.check_all_auctions() wait_for_other_threads() # then model_factory.create_model.assert_called_once_with( Parameters(collateral_auction_house=None, surplus_auction_house=None, debt_auction_house=self.debt_auction_house.address, staked_token_auction_house=None, id=auction_id)) # and status = model.send_status.call_args[0][0] assert status.id == auction_id assert status.collateral_auction_house is None assert status.surplus_auction_house is None assert status.debt_auction_house == self.debt_auction_house.address assert status.bid_amount > Rad.from_number(0) assert status.amount_to_sell == self.geb.accounting_engine.initial_debt_auction_minted_tokens( ) assert status.amount_to_raise is None assert status.bid_decrease > Wad.from_number(1) assert status.high_bidder == self.geb.accounting_engine.address assert status.block_time > 0 assert status.auction_deadline < status.block_time + self.debt_auction_house.total_auction_length( ) + 1 assert status.bid_expiry == 0 assert status.price == Wad(status.bid_amount * self.geb.oracle_relayer.redemption_price() / Rad(status.amount_to_sell))
def test_flash_proxy_liquidate_and_settle_auction(self, c: Collateral, web3, geb, auction_id, other_address): # given collateral_auction_house = self.collateral.collateral_auction_house if not isinstance(collateral_auction_house, FixedDiscountCollateralAuctionHouse): return set_collateral_price(geb, c, Wad.from_number(100)) eth_before = self.web3.eth.getBalance(self.keeper_address.address) auctions_started = collateral_auction_house.auctions_started() # when critical_safe = create_critical_safe(geb, c, bid_size, other_address) self.keeper.check_safes() wait_for_other_threads() assert self.web3.eth.getBalance( self.keeper_address.address) > eth_before assert collateral_auction_house.auctions_started( ) == auctions_started + 1 auction_status = collateral_auction_house.bids(auctions_started + 1) assert auction_status.raised_amount == Rad(0) assert auction_status.sold_amount == Wad(0) assert auction_status.amount_to_raise == Rad(0) assert auction_status.amount_to_sell == Wad(0) assert auction_status.auction_deadline == 0 assert auction_status.raised_amount == Rad(0)
def auction_id(web3: Web3, geb: GfDeployment, auction_income_recipient_address, other_address) -> int: total_surplus = geb.safe_engine.coin_balance(geb.accounting_engine.address) unqueued_unauctioned_debt = ( geb.safe_engine.debt_balance(geb.accounting_engine.address) - geb.accounting_engine.total_queued_debt() ) - geb.accounting_engine.total_on_auction_debt() print( f'total_surplus={str(total_surplus)[:6]}, unqueued_unauctioned_debt={str(unqueued_unauctioned_debt)[:6]}' ) if unqueued_unauctioned_debt < total_surplus or ( unqueued_unauctioned_debt == Rad(0) and total_surplus == Rad(0)): # Liquidate SAFE c = geb.collaterals['ETH-B'] critical_safe = create_critical_safe(geb, c, Wad.from_number(2), other_address, draw_system_coin=False) collateral_auction_id = liquidate(geb, c, critical_safe) # Generate some system coin, bid on and win the collateral auction without covering all the debt reserve_system_coin(geb, c, auction_income_recipient_address, Wad.from_number(100), extra_collateral=Wad.from_number(1.1)) c.collateral_auction_house.approve( geb.safe_engine.address, approval_function=approve_safe_modification_directly( from_address=auction_income_recipient_address)) current_bid = c.collateral_auction_house.bids(collateral_auction_id) bid_amount = Rad.from_number(1.9) assert geb.safe_engine.coin_balance( auction_income_recipient_address) > bid_amount #assert c.collateral_auction_house.increase_bid_size(collateral_auction_id, current_bid.amount_to_sell, bid_amount).transact(from_address=auction_income_recipient_address) #time_travel_by(web3, c.collateral_auction_house.bid_duration()+1) #assert c.collateral_auction_house.settle_auction(collateral_auction_id).transact() pop_debt_and_settle_debt(web3, geb, past_blocks=1200, cancel_auctioned_debt=False) # Start the debt auction unqueued_unauctioned_debt = ( geb.safe_engine.debt_balance(geb.accounting_engine.address) - geb.accounting_engine.total_queued_debt() ) - geb.accounting_engine.total_on_auction_debt() assert geb.accounting_engine.debt_auction_bid_size( ) <= unqueued_unauctioned_debt assert geb.safe_engine.coin_balance( geb.accounting_engine.address) == Rad(0) assert geb.accounting_engine.auction_debt().transact( from_address=auction_income_recipient_address) return geb.debt_auction_house.auctions_started()
def test_prepare_coins_for_redeeming(self, geb, our_address): assert geb.global_settlement.coin_bag(our_address) == Wad(0) assert geb.global_settlement.outstanding_coin_supply() > Rad(0) assert geb.system_coin.approve( geb.global_settlement.address).transact() assert geb.safe_engine.coin_balance(our_address) >= Rad.from_number(10) # FIXME: `prepareCoinsForRedeeming` fails, possibly because we're passing 0 to `safeEngine.transfer_collateral` assert geb.global_settlement.prepare_coins_for_redeeming( Wad.from_number(10)).transact() assert geb.global_settlement.coin_bag(our_address) == Wad.from_number( 10)
def eliminate_queued_debt(cls, web3, geb, keeper_address): if geb.safe_engine.debt_balance( geb.accounting_engine.address) == Rad(0): return # given the existence of queued debt c = geb.collaterals['ETH-A'] auction_id = c.collateral_auction_house.auctions_started() last_liquidation = geb.liquidation_engine.past_liquidations(10)[0] # when a bid covers the SAFE debt auction = c.collateral_auction_house.bids(auction_id) reserve_system_coin(geb, c, keeper_address, Wad(auction.amount_to_raise) + Wad(1)) c.collateral_auction_house.approve( c.collateral_auction_house.safe_engine(), approval_function=approve_safe_modification_directly( from_address=keeper_address)) c.approve(keeper_address) if isinstance(c.collateral_auction_house, EnglishCollateralAuctionHouse): assert c.collateral_auction_house.increase_bid_size( auction_id, auction.amount_to_sell, auction.amount_to_raise).transact(from_address=keeper_address) time_travel_by(web3, c.collateral_auction_house.bid_duration() + 1) assert c.collateral_auction_house.settle_auction( auction_id).transact() elif isinstance(c.collateral_auction_house, FixedDiscountCollateralAuctionHouse): assert c.collateral_auction_house.buy_collateral( auction_id, Wad(auction.amount_to_raise) + Wad(1)).transact(from_address=keeper_address) elif isinstance(c.collateral_auction_house, IncreasingDiscountCollateralAuctionHouse): assert c.collateral_auction_house.buy_collateral( auction_id, Wad(auction.amount_to_raise) + Wad(1)).transact(from_address=keeper_address) # when a bid covers the vow debt assert geb.accounting_engine.debt_queue_of( last_liquidation.block_time(web3)) > Rad(0) assert geb.accounting_engine.pop_debt_from_queue( last_liquidation.block_time(web3)).transact( from_address=keeper_address) assert geb.accounting_engine.settle_debt( geb.safe_engine.debt_balance( geb.accounting_engine.address)).transact() # then ensure queued debt has been auctioned off assert geb.safe_engine.debt_balance( geb.accounting_engine.address) == Rad(0)
def wipe_debt(geb: GfDeployment, collateral: Collateral, address: Address): safe = geb.safe_engine.safe(collateral.collateral_type, address) assert Rad(safe.generated_debt) >= geb.safe_engine.coin_balance(address) delta_collateral = Ray(geb.safe_engine.coin_balance( address)) / geb.safe_engine.collateral_type( collateral.collateral_type.name).accumulated_rate wrap_modify_safe_collateralization( geb, collateral, address, Wad(0), Wad(delta_collateral) * -1) #because there is residual state on the testchain assert geb.safe_engine.coin_balance(address) <= Rad( Wad(1)) # pesky dust amount in Dai amount
def __init__(self, log): args = log['args'] self.id = int(args['id']) self.amount_to_sell = Wad(args['amountToSell']) self.bid_amount = Rad(args['initialBid']) self.amount_to_raise = Rad(args['amountToRaise']) self.forgone_collateral_receiver = Address( args['forgoneCollateralReceiver']) self.auction_income_recipient = Address( args['auctionIncomeRecipient']) self.block = log['blockNumber'] self.tx_hash = log['transactionHash'].hex()
def test_should_change_gas_strategy_when_model_output_changes( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when first_bid = Wad.from_number(90) simulate_model_output(model=model, price=first_bid, gas_price=2000) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.web3.eth.getBlock( 'latest', full_transactions=True).transactions[0].gasPrice == 2000 # when second_bid = Wad.from_number(100) simulate_model_output(model=model, price=second_bid) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert round( Rad(self.debt_auction_house.bids(auction_id).amount_to_sell), 2) == round(self.debt_auction_bid_size / Rad(second_bid), 2) assert self.web3.eth.getBlock('latest', full_transactions=True).transactions[0].gasPrice == \ self.default_gas_price # when third_bid = Wad.from_number(110) new_gas_price = int(self.default_gas_price * 1.25) simulate_model_output(model=model, price=third_bid, gas_price=new_gas_price) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert round( Rad(self.debt_auction_house.bids(auction_id).amount_to_sell), 2) == round(self.debt_auction_bid_size / Rad(third_bid), 2) assert self.web3.eth.getBlock( 'latest', full_transactions=True).transactions[0].gasPrice == new_gas_price # cleanup time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1) assert self.debt_auction_house.settle_auction(auction_id).transact()
def test_init(self, geb, deployment_address, our_address): assert geb.esm is not None assert isinstance(geb.esm, ESM) assert isinstance(geb.esm.address, Address) assert geb.esm.trigger_threshold() > Wad(0) assert not geb.esm.settled() coin_balance = geb.safe_engine.coin_balance( geb.accounting_engine.address) awe = geb.safe_engine.debt_balance(geb.accounting_engine.address) # If `test_shutdown.py` is run in isolation, create a surplus auction to exercise `terminate_auction_prematurely` if coin_balance == Rad(0) and awe == Rad(0): create_surplus_auction(geb, deployment_address, our_address, geb.collaterals['ETH-A'])
def test_collateral_type(self, geb): assert geb.safe_engine.collateral_type('XXX') == CollateralType( 'XXX', accumulated_rate=Ray(0), safe_collateral=Wad(0), safe_debt=Wad(0), safety_price=Ray(0), debt_ceiling=Rad(0), debt_floor=Rad(0)) collateral_type = geb.collaterals["ETH-C"].collateral_type representation = repr(collateral_type) assert "ETH-C" in representation
def open_safe(geb: GfDeployment, collateral: Collateral, address: Address): assert isinstance(geb, GfDeployment) assert isinstance(collateral, Collateral) assert isinstance(address, Address) collateral.approve(address) wrap_eth(geb, address, Wad.from_number(10)) assert collateral.adapter.join( address, Wad.from_number(10)).transact(from_address=address) wrap_modify_safe_collateralization(geb, collateral, address, Wad.from_number(10), Wad.from_number(15)) assert geb.safe_engine.global_debt() >= Rad(Wad.from_number(15)) assert geb.safe_engine.coin_balance(address) >= Rad.from_number(10)
def create_surplus_auction(geb: GfDeployment, deployment_address: Address, our_address: Address, collateral: Collateral): assert isinstance(geb, GfDeployment) assert isinstance(deployment_address, Address) assert isinstance(our_address, Address) surplus_auction_house = geb.surplus_auction_house create_surplus(geb, surplus_auction_house, deployment_address, collateral) coin_balance = geb.safe_engine.coin_balance(geb.accounting_engine.address) assert coin_balance > geb.safe_engine.debt_balance( geb.accounting_engine.address ) + geb.accounting_engine.surplus_auction_amount_to_sell( ) + geb.accounting_engine.surplus_buffer() assert (geb.safe_engine.debt_balance(geb.accounting_engine.address) - geb.accounting_engine.total_queued_debt() ) - geb.accounting_engine.total_on_auction_debt() == Rad(0) assert geb.accounting_engine.auction_surplus().transact() mint_prot(geb.prot, our_address, Wad.from_number(10)) surplus_auction_house.approve(geb.prot.address, directly(from_address=our_address)) bid = Wad.from_number(0.001) assert geb.prot.balance_of(our_address) > bid assert surplus_auction_house.increase_bid_size( surplus_auction_house.auctions_started(), geb.accounting_engine.surplus_auction_amount_to_sell(), bid).transact(from_address=our_address)
def test_should_not_bid_on_rounding_errors_with_small_amounts( self, auction_id): # given (model, model_factory) = models(self.keeper, auction_id) # when simulate_model_output(model=model, price=Wad.from_number(1400.0)) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.debt_auction_house.bids(auction_id).amount_to_sell == Wad( self.debt_auction_bid_size * self.geb.oracle_relayer.redemption_price() / Rad.from_number(1400.0)) # when tx_count = self.web3.eth.getTransactionCount( self.keeper_address.address) # and self.keeper.check_all_auctions() self.keeper.check_for_bids() wait_for_other_threads() # then assert self.web3.eth.getTransactionCount( self.keeper_address.address) == tx_count
def settlement_active_auctions(self, parent_obj) -> List: """ Returns auctions that meet the requiremenets to be called by GlobalSettlement.fastTrackAuction, SurplusAuctionHouse.terminateAuctionPrematurely and DebtAuctionHouse.terminateAuctionPrematurely """ active_auctions = [] auction_count = parent_obj.auctions_started() # english collateral auction if isinstance(parent_obj, EnglishCollateralAuctionHouse): for index in range(auction_count + 1): bid = parent_obj._bids(index) if bid.high_bidder != Address( "0x0000000000000000000000000000000000000000"): if bid.bid_amount < bid.amount_to_raise: active_auctions.append(bid) # fixed discount collateral auction elif isinstance(parent_obj, FixedDiscountCollateralAuctionHouse): for index in range(auction_count + 1): bid = parent_obj._bids(index) if bid.amount_to_sell != Wad(0) and bid.amount_to_raise != Rad( 0): active_auctions.append(bid) # surplus and debt auctions else: for index in range(auction_count + 1): bid = parent_obj._bids(index) if bid.high_bidder != Address( "0x0000000000000000000000000000000000000000"): active_auctions.append(bid) return active_auctions
def test_should_provide_model_with_updated_info_after_somebody_else_partial_bids(self, auction_id, other_address): # given collateral_auction_house = self.collateral.collateral_auction_house if not isinstance(collateral_auction_house, FixedDiscountCollateralAuctionHouse): return (model, model_factory) = models(self.keeper, auction_id) # when self.keeper.check_all_auctions() wait_for_other_threads() # then assert model.send_status.call_count == 1 # when collateral_auction_house.approve(collateral_auction_house.safe_engine(), approval_function=approve_safe_modification_directly(from_address=other_address)) previous_bid = collateral_auction_house.bids(auction_id) new_bid_amount = Wad.from_number(30) self.buy_collateral_with_system_coin(self.geb, self.collateral, collateral_auction_house, model.id, other_address, new_bid_amount) # and self.keeper.check_all_auctions() wait_for_other_threads() # then assert model.send_status.call_count > 1 # and status = model.send_status.call_args[0][0] assert status.id == auction_id assert status.collateral_auction_house == collateral_auction_house.address assert status.surplus_auction_house is None assert status.debt_auction_house is None assert status.raised_amount == Rad(new_bid_amount) assert status.amount_to_sell == previous_bid.amount_to_sell assert status.amount_to_raise == previous_bid.amount_to_raise assert status.block_time > 0 assert status.auction_deadline > status.block_time
def increase_bid_size(collateral_auction_house: EnglishCollateralAuctionHouse, id: int, address: Address, amount_to_sell: Wad, bid_amount: Rad): assert (isinstance(collateral_auction_house, EnglishCollateralAuctionHouse)) assert (isinstance(id, int)) assert (isinstance(amount_to_sell, Wad)) assert (isinstance(bid_amount, Rad)) current_bid = collateral_auction_house.bids(id) assert current_bid.high_bidder != Address( "0x0000000000000000000000000000000000000000") assert current_bid.bid_expiry > datetime.now().timestamp( ) or current_bid.bid_expiry == 0 assert current_bid.auction_deadline > datetime.now().timestamp() assert amount_to_sell == current_bid.amount_to_sell assert bid_amount <= current_bid.amount_to_raise assert bid_amount > current_bid.bid_amount assert (bid_amount >= Rad(collateral_auction_house.bid_increase()) * current_bid.bid_amount) or (bid_amount == current_bid.amount_to_raise) assert collateral_auction_house.increase_bid_size( id, amount_to_sell, bid_amount).transact(from_address=address)
def bid(self, id: int ) -> Tuple[Optional[Wad], Optional[Transact], Optional[Rad]]: assert isinstance(id, int) bid = self.collateral_auction_house.bids(id) remaining_to_raise = bid.amount_to_raise - bid.raised_amount remaining_to_sell = bid.amount_to_sell - bid.sold_amount if remaining_to_sell < self.min_amount_to_sell: self.logger.debug( f"remaining_to_sell {remaining_to_sell} less than minimum {self.min_amount_to_sell} for auction {id}" ) return None, None, None # Always bid our entire balance. If auction amount_to_raise is less, FixedDiscountCollateralAuctionHouse will reduce it. our_bid = Wad(self.geb.safe_engine.coin_balance(self.our_address)) if our_bid <= self.collateral_auction_house.minimum_bid(): self.logger.info( f"Our system coin balance is less than FixedDiscountCollateralAuctionHouse.minimum_bid(). Not bidding" ) return None, None, None approximate_collateral, our_adjusted_bid = self.collateral_auction_house.get_approximate_collateral_bought( id, our_bid) if approximate_collateral == Wad(0): self.logger.info( f"Approximate collateral bought for auction {id} would be Wad(0). Not bidding" ) return None, None, None our_approximate_price = our_adjusted_bid / approximate_collateral return our_approximate_price, self.collateral_auction_house.buy_collateral( id, our_bid), Rad(our_bid)
def test_active_auctions(self, geb: GfDeployment, keeper: SettlementKeeper, our_address: Address, other_address: Address, deployment_address: Address): print_out("test_active_auctions") print( f"debt balance: {geb.safe_engine.debt_balance(geb.accounting_engine.address)}" ) print( f"system coin: {geb.safe_engine.coin_balance(geb.accounting_engine.address)}" ) create_surplus_auction(geb, deployment_address, our_address) create_debt_auction(geb, deployment_address, other_address) # this collateral auction sets the collateral back to a price that makes the guy's vault underwater again. # 49 to make it underwater, and create_collateral_auction sets it to 33 create_collateral_auction(geb, deployment_address, our_address) auctions = keeper.all_active_auctions() assert "collateral_auctions" in auctions assert "debt_auctions" in auctions assert "surplus_auctions" in auctions nobody = Address("0x0000000000000000000000000000000000000000") # All auctions active before terminations for collateral_type in auctions["collateral_auctions"].keys(): # pyflex create_debt() doesn't bid/settle on collateral auction. # so one extra auction is present #assert len(auctions["collateral_auctions"][collateral_type]) == 1 for auction in auctions["collateral_auctions"][collateral_type]: if isinstance( geb.collaterals[collateral_type]. collateral_auction_house, EnglishCollateralAuctionHouse): assert auction.id > 0 assert auction.bid_amount < auction.amount_to_raise assert auction.high_bidder != nobody #assert auction.high_bidder == our_address elif isinstance( geb.collaterals[collateral_type]. collateral_auction_house, FixedDiscountCollateralAuctionHouse): assert auction.amount_to_sell != Wad( 0) and auction.amount_to_raise != Rad(0) assert len(auctions["surplus_auctions"]) == 1 for auction in auctions["surplus_auctions"]: assert auction.id > 0 assert auction.high_bidder != nobody assert auction.high_bidder == our_address assert len(auctions["debt_auctions"]) == 1 for auction in auctions["debt_auctions"]: assert auction.id > 0 assert auction.high_bidder != nobody assert auction.high_bidder == other_address pytest.global_auctions = auctions
def bid(self, id: int, price: Wad ) -> Tuple[Optional[Wad], Optional[Transact], Optional[Rad]]: assert isinstance(id, int) assert isinstance(price, Wad) bid = self.staked_token_auction_house.bids(id) redemption_price = self.geb.oracle_relayer.redemption_price() our_bid = Rad(price) * Rad(bid.amount_to_sell) / Rad(redemption_price) if our_bid > bid.bid_amount * self.bid_increase: return price, self.staked_token_auction_house.increase_bid_size( id, bid.amount_to_sell, our_bid), bid.bid_amount else: self.logger.debug( f"our_bid {our_bid} at price {price} would not exceed the min bid increase {self.bid_increase} over bid_amount {bid.bid_amount} for amount to sell {bid.amount_to_sell} for auction {id} and redemption price {redemption_price}" ) return None, None, None
def __init__(self, log): args = log['args'] self.id = int(args['id']) self.high_bidder = Address(args['highBidder']) self.amount_to_buy = Wad(args['amountToBuy']) self.bid = Rad(args['bid']) self.bid_expiry = int(args['bidExpiry']) self.block = log['blockNumber'] self.tx_hash = log['transactionHash'].hex()
def bid(self, id: int, price: Wad ) -> Tuple[Optional[Wad], Optional[Transact], Optional[Rad]]: assert isinstance(id, int) assert isinstance(price, Wad) bid = self.debt_auction_house.bids(id) redemption_price = self.geb.oracle_relayer.redemption_price() our_amount = bid.bid_amount * redemption_price / Rad(price) if Ray(our_amount) * self.bid_decrease <= Ray( bid.amount_to_sell) and our_amount < Rad(bid.amount_to_sell): return price, self.debt_auction_house.decrease_sold_amount( id, Wad(our_amount), bid.bid_amount), bid.bid_amount else: self.logger.debug( f"our_amount {our_amount} at price {price} would not exceed the bid decrease {self.bid_decrease} for amount to sell {bid.amount_to_sell} for auction {id} and redemption price {redemption_price}" ) return None, None, None
def create_almost_risky_safe(): # Create a safe close to the liquidation ratio if is_critical_safe( geb.safe_engine.collateral_type(collateral.collateral_type.name), safe): logging.info("SAFE is already critical; no action taken") else: collateral_amount = Wad( collateral_type.debt_floor / (Rad(osm_price) / Rad(redemption_price)) * Rad(geb.oracle_relayer.safety_c_ratio(collateral_type)) * Rad(collateral_type.accumulated_rate)) + flub_amount logging.info( f"Opening/adjusting safe with {collateral_amount} {collateral_type.name}" ) create_almost_risky_safe(geb, collateral, collateral_amount, our_address, False) logging.info("Created almost risky safe")
def active_auctions(self) -> list: active_auctions = [] auction_count = self.auctions_started() for index in range(1, auction_count + 1): bid = self._bids(index) if bid.amount_to_sell > Wad(0) and bid.amount_to_raise > Rad(0): active_auctions.append(bid) return active_auctions