Example #1
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)
Example #2
0
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")