def cleanup_safe(geb: GfDeployment, collateral: Collateral, address: Address): assert isinstance(geb, GfDeployment) assert isinstance(collateral, Collateral) assert isinstance(address, Address) safe = geb.safe_engine.safe(collateral.collateral_type, address) collateral_type = geb.safe_engine.collateral_type( collateral.collateral_type.name) # If tax_collector.tax_single has been called, we won't have sufficient system_coin to repay the SAFE #if collateral_type.accumulated_rate > Ray.from_number(1): # return # Return if this address doens't have enough system to coin to repay full debt amount_to_raise = Wad( Ray(safe.generated_debt) * collateral_type.accumulated_rate) if amount_to_raise > geb.system_coin.balance_of(address): return # Repay borrowed system coin geb.approve_system_coin(address) # Put all the user's system coin back into the safe engine if geb.system_coin.balance_of(address) >= Wad(0): assert geb.system_coin_adapter.join( address, geb.system_coin.balance_of(address)).transact(from_address=address) amount_to_raise = Wad( Ray(safe.generated_debt) * collateral_type.accumulated_rate) print( f'amount_to_raise={str(amount_to_raise)}, rate={str(collateral_type.accumulated_rate)}, system_coin={str(geb.safe_engine.coin_balance(address))}' ) if safe.generated_debt > Wad(0): wrap_modify_safe_collateralization(geb, collateral, address, Wad(0), amount_to_raise * -1) # Withdraw collateral collateral.approve(address) safe = geb.safe_engine.safe(collateral.collateral_type, address) # delta_collateral = Wad((Ray(safe.generated_debt) * collateral_type.accumulated_rate) / collateral_type.safety_price) # print(f'delta_collateral={str(delta_collateral)}, locked_collateral={str(safe.locked_collateral)}') if safe.generated_debt == Wad(0) and safe.locked_collateral > Wad(0): wrap_modify_safe_collateralization(geb, collateral, address, safe.locked_collateral * -1, Wad(0)) assert collateral.adapter.exit( address, geb.safe_engine.token_collateral( collateral.collateral_type, address)).transact(from_address=address) TestSAFEEngine.ensure_clean_safe(geb, collateral, address)
def create_almost_risky_safe(geb: GfDeployment, c: Collateral, collateral_amount: Wad, auction_income_recipient_address: Address, draw_system_coin=True) -> SAFE: assert isinstance(geb, GfDeployment) assert isinstance(c, Collateral) assert isinstance(auction_income_recipient_address, Address) logging.debug("Creating almost risky safe") print("create_almost_risky") print( f"Liquidation price {geb.safe_engine.collateral_type(c.collateral_type.name).safety_price}" ) print( f"Safety price {geb.safe_engine.collateral_type(c.collateral_type.name).liquidation_price}" ) # Ensure vault isn't already unsafe (if so, this shouldn't be called) safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address) assert is_safe_safe( geb.safe_engine.collateral_type(c.collateral_type.name), safe) # Add collateral to auction_income_recipient vault if necessary c.approve(auction_income_recipient_address) token = Token(c.collateral_type.name, c.collateral.address, c.adapter.decimals()) print( f"collateral_amount={collateral_amount} locked_collateral={safe.locked_collateral}" ) delta_collateral = collateral_amount - safe.locked_collateral if delta_collateral > Wad(0): safe_engine_balance = geb.safe_engine.token_collateral( c.collateral_type, auction_income_recipient_address) balance = token.normalize_amount( c.collateral.balance_of(auction_income_recipient_address)) print( f"before join: delta_collateral={delta_collateral} safe_engine_balance={safe_engine_balance} balance={balance} safe_engine_gap={delta_collateral - safe_engine_balance}" ) if safe_engine_balance < delta_collateral: safe_engine_gap = delta_collateral - safe_engine_balance if balance < safe_engine_gap: if c.collateral_type.name.startswith("ETH"): wrap_eth(geb, auction_income_recipient_address, safe_engine_gap) else: raise RuntimeError("Insufficient collateral balance") amount_to_join = token.unnormalize_amount(safe_engine_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( auction_income_recipient_address, amount_to_join).transact( from_address=auction_income_recipient_address) safe_engine_balance = geb.safe_engine.token_collateral( c.collateral_type, auction_income_recipient_address) print( f"after join: delta_collateral={delta_collateral} safe_engine_balance={safe_engine_balance} balance={balance} safe_engine_gap={delta_collateral - safe_engine_balance}" ) assert safe_engine_balance >= delta_collateral assert geb.safe_engine.modify_safe_collateralization( c.collateral_type, auction_income_recipient_address, delta_collateral, Wad(0)).transact(from_address=auction_income_recipient_address) # Put auction_income_recipient SAFE at max possible debt delta_debt = max_delta_debt(geb, c, auction_income_recipient_address) - Wad(1) if delta_debt > Wad(0): print( f"Attempting to modify safe collateralization with delta_debt={delta_debt}" ) assert geb.safe_engine.modify_safe_collateralization( c.collateral_type, auction_income_recipient_address, Wad(0), delta_debt).transact(from_address=auction_income_recipient_address) # Draw our Dai, simulating the usual behavior safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address) if draw_system_coin and safe.generated_debt > Wad(0): geb.approve_system_coin(auction_income_recipient_address) assert geb.system_coin_adapter.exit( auction_income_recipient_address, safe.generated_debt).transact( from_address=auction_income_recipient_address) print(f"Exited {safe.generated_debt} System coin from safe") logging.debug("Almost risky safe created")