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_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 is_safe_safe(collateral_type: CollateralType, safe: SAFE) -> bool:
    assert isinstance(safe, SAFE)
    assert safe.generated_debt is not None
    assert collateral_type.accumulated_rate is not None
    assert safe.locked_collateral is not None
    assert collateral_type.safety_price is not None

    #print(f'art={safe.generated_debt} * rate={collateral_type.rate} <=? locked_collateral={safe.locked_collateral} * spot={collateral_type.spot}')
    return (Ray(safe.generated_debt) * collateral_type.accumulated_rate
            ) <= Ray(safe.locked_collateral) * collateral_type.safety_price
Exemple #4
0
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 max_delta_debt(geb: GfDeployment, collateral: Collateral,
                   our_address: Address) -> Wad:
    assert isinstance(geb, GfDeployment)
    assert isinstance(collateral, Collateral)
    assert isinstance(our_address, Address)
    print("max_delta_debt")
    print(
        f"Liquidation price {geb.safe_engine.collateral_type(collateral.collateral_type.name).liquidation_price}"
    )
    print(
        f"Safety price {geb.safe_engine.collateral_type(collateral.collateral_type.name).safety_price}"
    )
    safe = geb.safe_engine.safe(collateral.collateral_type, our_address)
    collateral_type = geb.safe_engine.collateral_type(
        collateral.collateral_type.name)

    # change in 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)
    print(f"max_delta_debt for collateral_type {collateral_type.name}")
    print(
        f"delta debt: {delta_debt} = locked_collateral {safe.locked_collateral} * safety_price {collateral_type.safety_price} - debt {Ray(safe.generated_debt)}"
    )

    # change in debt must also take the rate into account
    delta_debt = Wad(Ray(delta_debt) / 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(geb.safe_engine.global_debt_ceiling())
    if (debt + Rad(delta_debt)) >= debt_ceiling:
        print(
            f"debt {debt} + delta_debt {delta_debt} >= {debt_ceiling}; max_delta_debt is avoiding total debt ceiling"
        )
        delta_debt = Wad(debt - Rad(safe.generated_debt))

    # ensure we've met the debt_floor cutoff
    if Rad(safe.generated_debt + delta_debt) < collateral_type.debt_floor:
        print(
            f"max_delta_debt is being bumped from {safe.generated_debt + delta_debt} to {collateral_type.debt_floor} to reach debt_floor cutoff"
        )
        delta_debt = Wad(collateral_type.debt_floor)

    return delta_debt
Exemple #6
0
    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
Exemple #7
0
 def get_collateral_median_price(self) -> Ray:
     """Returns the market price from system coin oracle.
    
     Returns:
         System coin market price
     """
     return Ray(self._contract.functions.getCollateralMedianPrice().call())
Exemple #8
0
 def final_coin_per_collateral_price(
         self, collateral_type: CollateralType) -> Ray:
     """Shutdown price for the collateral"""
     assert isinstance(collateral_type, CollateralType)
     return Ray(
         self._contract.functions.finalCoinPerCollateralPrice(
             collateral_type.toBytes()).call())
    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
Exemple #10
0
    def per_second_discount_update_rate(self) -> Ray:
        """Returns the perSecondDiscountUpdateRate

        Returns:
            The per second discount update rate
        """
        return Ray(
            self._contract.functions.perSecondDiscountUpdateRate().call())
def is_safe_critical(collateral_type: CollateralType, safe: SAFE) -> bool:
    assert isinstance(safe, SAFE)
    assert safe.generated_debt is not None
    assert collateral_type.accumulated_rate is not None
    assert safe.locked_collateral is not None
    assert collateral_type.safety_price is not None

    #print(f'art={safe.generated_debt} * rate={collateral_type.rate} <=? locked_collateral={safe.locked_collateral} * spot={collateral_type.spot}')
    print("in is_safe_critical()")
    print(f"debt: {Ray(safe.generated_debt)}")
    print(f"rate: {collateral_type.accumulated_rate}")
    print(f"locked collateral: {Ray(safe.locked_collateral)}")
    print(f"liq price: {collateral_type.liquidation_price}")
    print(f"safety price: {collateral_type.safety_price}")
    return True

    return (Ray(safe.generated_debt) * collateral_type.accumulated_rate) > Ray(
        safe.locked_collateral) * collateral_type.liquidation_price
Exemple #12
0
    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
Exemple #13
0
    def test_freeze_collateral_type(self, geb):
        collateral_type = geb.collaterals['ETH-A'].collateral_type

        assert geb.global_settlement.freeze_collateral_type(
            collateral_type).transact()
        assert geb.global_settlement.collateral_total_debt(
            collateral_type) > Wad(0)
        assert geb.global_settlement.final_coin_per_collateral_price(
            collateral_type) > Ray(0)
Exemple #14
0
    def test_getters(self, geb):
        assert not geb.global_settlement.contract_enabled()
        assert datetime.utcnow() - timedelta(
            minutes=5) < geb.global_settlement.shutdown_time(
            ) < datetime.utcnow()
        assert geb.global_settlement.shutdown_cooldown() >= 0
        assert geb.global_settlement.outstanding_coin_supply() >= Rad(0)

        for collateral in geb.collaterals.values():
            collateral_type = collateral.collateral_type
            assert geb.global_settlement.final_coin_per_collateral_price(
                collateral_type) == Ray(0)
            assert geb.global_settlement.collateral_shortfall(
                collateral_type) == Wad(0)
            assert geb.global_settlement.collateral_total_debt(
                collateral_type) == Wad(0)
            assert geb.global_settlement.collateral_cash_price(
                collateral_type) == Ray(0)
Exemple #15
0
    def get_underwater_safes(self, collateral_types: List) -> List[SAFE]:
        """ With all safes every frobbed, compile and return a list safes that are under-collateralized up to 100%  """

        underwater_safes = []

        self.logger.info(f'Getting underwater safes for {collateral_types}')
        for collateral_type in collateral_types:

            safe_history = SAFEHistory(self.web3, self.geb, collateral_type,
                                       self.deployment_block,
                                       self.arguments.graph_endpoint)

            safes = safe_history.get_safes()

            self.logger.info(
                f'Collected {len(safes)} safes from {collateral_type}')

            for i, safe in enumerate(safes.values()):
                safe.collateral_type = self.geb.safe_engine.collateral_type(
                    safe.collateral_type.name)
                safety_ratio = self.geb.oracle_relayer.safety_c_ratio(
                    safe.collateral_type)

                debt = Ray(safe.generated_debt
                           ) * safe.collateral_type.accumulated_rate
                collateral = Ray(
                    safe.locked_collateral
                ) * safe.collateral_type.safety_price * safety_ratio

                # Check if underwater ->
                # safe.generated_debt * collateral_type.accumulated_rate >
                # safe.locked_collateral * collateral_type.safety_price * oracle_relayer.safety_c_ratio[collateral_type]
                if debt > collateral:
                    underwater_safes.append(safe)

                if i % 100 == 0:
                    self.logger.info(
                        f'Processed {i} safes of {collateral_type.name}')

        self.logger.info(
            f'Found {len(underwater_safes)} underwater safes for all collateral-types'
        )
        return underwater_safes
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
Exemple #17
0
 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)
Exemple #18
0
 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
Exemple #19
0
 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_settlement_keeper(self, geb: GfDeployment,
                               keeper: SettlementKeeper, our_address: Address,
                               other_address: Address):
        print_out("test_settlement_keeper")
        collateral_types = keeper.get_collateral_types()
        safes = pytest.global_safes
        auctions = pytest.global_auctions

        for collateral_type in collateral_types:
            # Check if freeze_collateral_type(collateral_type) called on all collateral_types
            assert geb.global_settlement.final_coin_per_collateral_price(
                collateral_type) > Ray(0)

            # Check if calculate_cash_price(collateral_type) called on all collateral_types
            assert geb.global_settlement.collateral_cash_price(
                collateral_type) > Ray(0)

        # All underwater safes present before ES have been processed
        for i in safes:
            safe = geb.safe_engine.safe(i.collateral_type, i.address)
            assert safe.generated_debt == Wad(0)

        # All auctions active before settlement have been terminated prematurely
        for collateral_type in auctions["collateral_auctions"].keys():
            for auction in auctions["collateral_auctions"][collateral_type]:
                assert geb.collaterals[
                    collateral_type].collateral_auction_house.bids(
                        auction.id).amount_to_sell == Wad(0)

        for auction in auctions["surplus_auctions"]:
            assert geb.surplus_auction_house.bids(
                auction.id).amount_to_sell == Rad(0)

        for auction in auctions["debt_auctions"]:
            assert geb.debt_auction_house.bids(
                auction.id).amount_to_sell == Wad(0)

        # setOutstandingCoinSupply() has been called
        assert geb.global_settlement.outstanding_coin_supply() != Rad(0)
Exemple #21
0
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
Exemple #22
0
 def test_should_reject_comparison_with_ints(self):
     with pytest.raises(ArithmeticError):
         assert Ray(1000) == 100
     with pytest.raises(ArithmeticError):
         assert Ray(1000) != 999
     with pytest.raises(ArithmeticError):
         assert Ray(1000) > 999
     with pytest.raises(ArithmeticError):
         assert Ray(999) < 1000
     with pytest.raises(ArithmeticError):
         assert Ray(999) <= 1000
     with pytest.raises(ArithmeticError):
         assert Ray(1000) <= 1000
     with pytest.raises(ArithmeticError):
         assert Ray(1000) >= 1000
     with pytest.raises(ArithmeticError):
         assert Ray(1000) >= 999
Exemple #23
0
 def test_should_reject_comparison_with_rays(self):
     with pytest.raises(ArithmeticError):
         assert Rad(1000) == Ray(1000)
     with pytest.raises(ArithmeticError):
         assert Rad(1000) != Ray(999)
     with pytest.raises(ArithmeticError):
         assert Rad(1000) > Ray(999)
     with pytest.raises(ArithmeticError):
         assert Rad(999) < Ray(1000)
     with pytest.raises(ArithmeticError):
         assert Rad(999) <= Ray(1000)
     with pytest.raises(ArithmeticError):
         assert Rad(1000) <= Ray(1000)
     with pytest.raises(ArithmeticError):
         assert Rad(1000) >= Ray(1000)
     with pytest.raises(ArithmeticError):
         assert Rad(1000) >= Ray(999)
Exemple #24
0
 def test_should_reject_comparison_with_wads(self):
     with pytest.raises(ArithmeticError):
         assert Ray(1000) == Wad(1000)
     with pytest.raises(ArithmeticError):
         assert Ray(1000) != Wad(999)
     with pytest.raises(ArithmeticError):
         assert Ray(1000) > Wad(999)
     with pytest.raises(ArithmeticError):
         assert Ray(999) < Wad(1000)
     with pytest.raises(ArithmeticError):
         assert Ray(999) <= Wad(1000)
     with pytest.raises(ArithmeticError):
         assert Ray(1000) <= Wad(1000)
     with pytest.raises(ArithmeticError):
         assert Ray(1000) >= Wad(1000)
     with pytest.raises(ArithmeticError):
         assert Ray(1000) >= Wad(999)
Exemple #25
0
 def test_should_format_to_string_nicely(self):
     assert str(Ray(1)) == "0.000000000000000000000000001"
     assert str(Ray(
         500000000000000000000000000)) == "0.500000000000000000000000000"
     assert str(Ray(
         1500000000000000000000000000)) == "1.500000000000000000000000000"
     assert str(Ray(
         -1500000000000000000000000000)) == "-1.500000000000000000000000000"
     assert str(Ray(
         -500000000000000000000000000)) == "-0.500000000000000000000000000"
     assert str(Ray(-1)) == "-0.000000000000000000000000001"
Exemple #26
0
def handle_returned_collateral():
    # Handle collateral returned to the safe after a liquidation is settled
    available_to_generate = (
        safe.locked_collateral * collateral_type.safety_price) - Wad(
            Ray(safe.generated_debt) * collateral_type.accumulated_rate)
    if available_to_generate > token.min_amount + flub_amount:
        logging.info(
            f"Attempting to generate {available_to_generate} system coin")
        geb.safe_engine.modify_safe_collateralization(
            collateral_type, our_address, Wad(0),
            available_to_generate).transact()
    system_coin_balance = Wad(
        geb.safe_engine.system_coin(our_address)) - Wad(1)
    if system_coin_balance > token.min_amount:
        logging.info(f"Attempting to exit {system_coin_balance} system_coin")
        geb.system_coin_adapter.exit(our_address,
                                     system_coin_balance).transact()
Exemple #27
0
    def test_exact_safety_c_ratio(self, geb):
        collateral_type = geb.collaterals['ETH-A'].collateral_type
        #set_collateral_price(geb, coll, Wad.from_number(250))
        collateral_price = Wad(geb.collaterals['ETH-A'].osm.read())

        geb.oracle_relayer.update_collateral_price(collateral_type)

        safe_collateral_type = geb.safe_engine.collateral_type('ETH-A')

        redemption_price = geb.oracle_relayer.redemption_price()
        safe_c_ratio = geb.oracle_relayer.safety_c_ratio(collateral_type)
        liquidation_c_ratio = geb.oracle_relayer.liquidation_c_ratio(
            collateral_type)

        calc_ratio = Ray(
            collateral_price
        ) / redemption_price / safe_collateral_type.safety_price
        assert safe_c_ratio == calc_ratio
Exemple #28
0
    def test_close_safe(self, web3, geb, our_address):
        collateral = geb.collaterals['ETH-A']
        collateral_type = collateral.collateral_type

        assert geb.global_settlement.free_collateral(
            collateral_type).transact()
        assert geb.safe_engine.safe(collateral_type,
                                    our_address).locked_collateral == Wad(0)
        assert geb.safe_engine.token_collateral(collateral_type,
                                                our_address) > Wad(0)
        assert collateral.adapter.exit(
            our_address,
            geb.safe_engine.token_collateral(collateral_type,
                                             our_address)).transact()

        assert geb.global_settlement.shutdown_cooldown() == 0
        time_travel_by(web3, 5)
        assert geb.global_settlement.set_outstanding_coin_supply().transact()
        assert geb.global_settlement.calculate_cash_price(
            collateral_type).transact()
        assert geb.global_settlement.collateral_cash_price(
            collateral_type) > Ray(0)
Exemple #29
0
    def bids(self, id: int) -> Bid:
        """Returns the auction details.

        Args:
            id: Auction identifier.

        Returns:
            The auction details.
        """
        assert (isinstance(id, int))

        array = self._contract.functions.bids(id).call()

        return IncreasingDiscountCollateralAuctionHouse.Bid(
            id=id,
            amount_to_sell=Wad(array[0]),
            amount_to_raise=Rad(array[1]),
            current_discount=Wad(array[2]),
            max_discount=Wad(array[3]),
            per_second_discount_update_rate=Ray(array[4]),
            latest_discount_update_time=int(array[5]),
            discount_increase_deadline=int(array[6]),
            forgone_collateral_receiver=Address(array[7]),
            auction_income_recipient=Address(array[8]))
Exemple #30
0
 def collateral_cash_price(self, collateral_type: CollateralType) -> Ray:
     """Final cash price for the collateral"""
     assert isinstance(collateral_type, CollateralType)
     return Ray(
         self._contract.functions.collateralCashPrice(
             collateral_type.toBytes()).call())