def test_divide(self): assert Ray.from_number(4) / Ray.from_number(2) == Ray.from_number(2) assert Ray(4) / Ray.from_number(2) == Ray(2) assert Ray(3) / Ray.from_number(2) == Ray(1) assert Ray(39) / Ray.from_number(20) == Ray(1) assert Ray(40) / Ray.from_number(20) == Ray(2) assert Ray.from_number(0.2) / Ray.from_number(0.1) == Ray.from_number( 2)
def test_multiply_by_ray(self): assert Wad.from_number(2) * Ray.from_number(3) == Wad.from_number(6) assert Wad.from_number(2) * Ray(3) == Wad(0) assert Wad(2) * Ray(499999999999999999999999999) == Wad(0) assert Wad(2) * Ray(500000000000000000000000000) == Wad(1) assert Wad(2) * Ray(999999999999999999999999999) == Wad(1) assert Wad(2) * Ray(1000000000000000000000000000) == Wad(2)
def test_get_underwater_safes(self, geb: GfDeployment, keeper: SettlementKeeper, guy_address: Address, our_address: Address): print_out("test_get_underwater_safes") collateral_types = keeper.get_collateral_types() prev_underwater_safes = len( keeper.get_underwater_safes(collateral_types)) previous_eth_price = open_underwater_safe(geb, geb.collaterals['ETH-A'], guy_address) open_safe(geb, geb.collaterals['ETH-C'], our_address) safes = keeper.get_underwater_safes(collateral_types) assert type(safes) is list assert all(isinstance(x, SAFE) for x in safes) assert len(safes) == prev_underwater_safes + 1 assert safes[0].address.address == guy_address.address ## We've multiplied by a small Ray amount to counteract ## the residual dust (or lack thereof) in this step that causes ## create_debt_auction fail set_collateral_price(geb, geb.collaterals['ETH-A'], Wad(previous_eth_price * Ray.from_number(1.0001))) pytest.global_safes = safes
def reserve_system_coin(geb: GfDeployment, c: Collateral, usr: Address, amount: Wad, extra_collateral=Wad.from_number(1)): assert isinstance(geb, GfDeployment) assert isinstance(c, Collateral) assert isinstance(usr, Address) assert isinstance(amount, Wad) assert amount > Wad(0) # Determine how much collateral is needed collateral_type = geb.safe_engine.collateral_type(c.collateral_type.name) accumulated_rate = collateral_type.accumulated_rate # Ray safety_price = collateral_type.safety_price # Ray assert accumulated_rate >= Ray.from_number(1) collateral_required = Wad((Ray(amount) / safety_price) * accumulated_rate) * extra_collateral + Wad(1) print(f'accumulated_rate {accumulated_rate}') print(f'extra_collateral {extra_collateral}') print(f'current safety price {safety_price}') print( f'collateral_required for {str(amount)} system_coin is {str(collateral_required)}' ) wrap_eth(geb, usr, collateral_required) c.approve(usr) assert c.adapter.join(usr, collateral_required).transact(from_address=usr) assert geb.safe_engine.modify_safe_collateralization( c.collateral_type, usr, collateral_required, amount).transact(from_address=usr) assert geb.safe_engine.safe(c.collateral_type, usr).generated_debt >= amount
def test_should_cast_to_float(self): assert float(Ray.from_number(-4.5)) == -4.5 assert float(Ray.from_number(0.99)) == 0.99 assert float(Ray.from_number(1)) == 1.0 assert float(Ray.from_number(1.0)) == 1.0 assert float(Ray.from_number(1.5)) == 1.5 assert float(Ray.from_number(1.9999999999)) == 1.9999999999
def test_should_cast_to_int(self): assert int(Ray.from_number(-4.5)) == -4 assert int(Ray.from_number(0.99)) == 0 assert int(Ray.from_number(1)) == 1 assert int(Ray.from_number(1.0)) == 1 assert int(Ray.from_number(1.5)) == 1 assert int(Ray.from_number(1.9999999999)) == 1
def max_delta_debt(geb: GfDeployment, collateral: Collateral, our_address: Address) -> Wad: """Determines how much stablecoin should be reserved in an `safe` to make it as poorly collateralized as possible, such that a small change to the collateral price could trip the liquidation ratio.""" assert isinstance(geb, GfDeployment) assert isinstance(collateral, Collateral) assert isinstance(our_address, Address) safe = geb.safe_engine.safe(collateral.collateral_type, our_address) collateral_type = geb.safe_engine.collateral_type( collateral.collateral_type.name) # change in generated debt = (collateral balance * collateral price with safety margin) - SAFE's stablecoin debt delta_debt = safe.locked_collateral * collateral_type.safety_price - Wad( Ray(safe.generated_debt) * collateral_type.accumulated_rate) # change in debt must also take the rate into account delta_debt = delta_debt * Wad( Ray.from_number(1) / collateral_type.accumulated_rate) # prevent the change in debt from exceeding the collateral debt ceiling if (Rad(safe.generated_debt) + Rad(delta_debt)) >= collateral_type.debt_ceiling: print("max_delta_debt is avoiding collateral debt ceiling") delta_debt = Wad(collateral_type.debt_ceiling - Rad(safe.generated_debt)) # prevent the change in debt from exceeding the total debt ceiling debt = geb.safe_engine.global_debt() + Rad( collateral_type.accumulated_rate * delta_debt) debt_ceiling = Rad(collateral_type.debt_ceiling) if (debt + Rad(delta_debt)) >= debt_ceiling: print("max_delta_debt is avoiding total debt ceiling") delta_debt = Wad(debt - Rad(safe.generated_debt)) assert delta_debt > Wad(0) return delta_debt
def test_should_instantiate_from_a_ray(self): assert Rad(Ray.from_number(10)) == Rad.from_number(10)
def test_round(self): assert round(Ray.from_number(123.4567), 2) == Ray.from_number(123.46) assert round(Ray.from_number(123.4567), 0) == Ray.from_number(123.0) assert round(Ray.from_number(123.4567), -2) == Ray.from_number(100.0)
def test_multiply_by_int(self): assert Ray.from_number(2) * 3 == Ray.from_number(6) assert Ray.from_number(2) * 1 == Ray.from_number(2)
def test_multiply_by_wad(self): assert Ray.from_number(2) * Wad.from_number(3) == Ray.from_number(6) assert Ray.from_number(2) * Wad(3) == Ray(6000000000) assert Ray(2) * Wad(3) == Ray(0) assert Ray(2) * Wad(999999999999999999) == Ray(1) assert Ray(2) * Wad(1000000000000000000) == Ray(2)
def test_multiply(self): assert Ray.from_number(2) * Ray.from_number(3) == Ray.from_number(6) assert Ray.from_number(2) * Ray(3) == Ray(6) assert Ray.from_number(2.5) * Ray(3) == Ray(7) assert Ray.from_number(2.99999) * Ray(3) == Ray(8)
def test_should_have_nice_printable_representation(self): for ray in [Ray(1), Ray(100), Ray.from_number(2.5), Ray(-1)]: assert repr(ray) == f"Ray({ray.value})"