def create_surplus(geb: GfDeployment,
                   surplus_auction_house: PreSettlementSurplusAuctionHouse,
                   deployment_address: Address):
    assert isinstance(geb, GfDeployment)
    assert isinstance(surplus_auction_house, PreSettlementSurplusAuctionHouse)
    assert isinstance(deployment_address, Address)

    surplus = geb.safe_engine.coin_balance(geb.accounting_engine.address)

    if surplus < geb.accounting_engine.surplus_buffer(
    ) + geb.accounting_engine.surplus_auction_amount_to_sell():
        # Create a SAFE with surplus
        print('Creating a SAFE with surplus')
        collateral = geb.collaterals['ETH-B']
        assert surplus_auction_house.auctions_started() == 0
        wrap_eth(geb, deployment_address, Wad.from_number(10))
        collateral.approve(deployment_address)
        assert collateral.adapter.join(
            deployment_address,
            Wad.from_number(10)).transact(from_address=deployment_address)
        wrap_modify_safe_collateralization(
            geb,
            collateral,
            deployment_address,
            delta_collateral=Wad.from_number(10),
            delta_debt=Wad.from_number(300))
        assert geb.tax_collector.tax_single(
            collateral.collateral_type).transact(
                from_address=deployment_address)
        surplus = geb.safe_engine.coin_balance(geb.accounting_engine.address)
        assert surplus > geb.accounting_engine.surplus_buffer(
        ) + geb.accounting_engine.surplus_auction_amount_to_sell()
    else:
        print(f'Surplus of {surplus} already exists; skipping SAFE creation')
def create_debt_auction(geb: GfDeployment, deployment_address: Address,
                        our_address: Address):
    assert isinstance(geb, GfDeployment)
    assert isinstance(deployment_address, Address)
    assert isinstance(our_address, Address)

    debt_auction_house = geb.debt_auction_house
    print(
        f"Before Debt: {geb.safe_engine.debt_balance(geb.accounting_engine.address)}"
    )
    if geb.accounting_engine.unqueued_unauctioned_debt(
    ) <= geb.accounting_engine.debt_auction_bid_size():
        create_debt(geb.web3, geb, our_address, deployment_address,
                    geb.collaterals['ETH-A'])
    print(
        f"After Debt: {geb.safe_engine.debt_balance(geb.accounting_engine.address)}"
    )

    # start debt auction
    auction_id = debt_auction_house.auctions_started()
    assert auction_id == 0
    assert len(debt_auction_house.active_auctions()) == 0
    assert geb.safe_engine.coin_balance(
        geb.accounting_engine.address) == Rad(0)
    assert geb.accounting_engine.auction_debt().transact()
    auction_id = debt_auction_house.auctions_started()
    assert auction_id == 1
    assert len(debt_auction_house.active_auctions()) == 1
    check_active_auctions(debt_auction_house)
    current_bid = debt_auction_house.bids(auction_id)

    amount_to_sell = Wad.from_number(0.000005)
    # current_bid.bid_amount = 0.001
    # current_bid.amount_to_sell = 0.0001
    debt_auction_house.approve(
        geb.safe_engine.address,
        approval_function=approve_safe_modification_directly(
            from_address=our_address))
    assert geb.safe_engine.safe_rights(our_address, debt_auction_house.address)

    collateral = geb.collaterals['ETH-A']
    wrap_eth(geb, our_address, Wad.from_number(1))
    collateral.approve(our_address)
    assert collateral.adapter.join(
        our_address, Wad.from_number(1)).transact(from_address=our_address)
    #web3.eth.defaultAccount = our_address.address
    wrap_modify_safe_collateralization(geb,
                                       collateral,
                                       our_address,
                                       delta_collateral=Wad.from_number(1),
                                       delta_debt=Wad.from_number(10))

    assert geb.safe_engine.coin_balance(our_address) >= current_bid.bid_amount
    decrease_sold_amount(debt_auction_house, auction_id, our_address,
                         amount_to_sell, current_bid.bid_amount)
    current_bid = debt_auction_house.bids(auction_id)
    assert current_bid.high_bidder == our_address
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 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_collateral_auction(geb: GfDeployment, deployment_address: Address,
                              our_address: Address):
    assert isinstance(geb, GfDeployment)
    assert isinstance(our_address, Address)
    assert isinstance(deployment_address, Address)

    # Create a SAFE
    collateral = geb.collaterals['ETH-A']
    collateral_type = collateral.collateral_type
    wrap_eth(geb, deployment_address, Wad.from_number(1))
    collateral.approve(deployment_address)
    assert collateral.adapter.join(
        deployment_address,
        Wad.from_number(1)).transact(from_address=deployment_address)
    wrap_modify_safe_collateralization(geb,
                                       collateral,
                                       deployment_address,
                                       delta_collateral=Wad.from_number(1),
                                       delta_debt=Wad(0))
    delta_debt = max_delta_debt(geb, collateral, deployment_address) - Wad(1)
    wrap_modify_safe_collateralization(geb,
                                       collateral,
                                       deployment_address,
                                       delta_collateral=Wad(0),
                                       delta_debt=delta_debt)

    # Undercollateralize and bite the SAFE
    to_price = Wad(geb.web3.toInt(collateral.osm.read())) / Wad.from_number(2)
    set_collateral_price(geb, collateral, to_price)
    safe = geb.safe_engine.safe(collateral.collateral_type, deployment_address)
    collateral_type = geb.safe_engine.collateral_type(collateral_type.name)
    safe = Ray(safe.generated_debt) * geb.safe_engine.collateral_type(
        collateral_type.name).accumulated_rate <= Ray(
            safe.locked_collateral) * collateral_type.safety_price
    assert not safe
    assert geb.liquidation_engine.can_liquidate(collateral.collateral_type,
                                                SAFE(deployment_address))
    assert geb.liquidation_engine.liquidate_safe(
        collateral.collateral_type, SAFE(deployment_address)).transact()
    auction_id = collateral.collateral_auction_house.auctions_started()

    # Generate some system coin, bid on the collateral auction without covering all the debt
    wrap_eth(geb, our_address, Wad.from_number(10))
    collateral.approve(our_address)
    assert collateral.adapter.join(
        our_address, Wad.from_number(10)).transact(from_address=our_address)
    geb.web3.eth.defaultAccount = our_address.address
    wrap_modify_safe_collateralization(geb,
                                       collateral,
                                       our_address,
                                       delta_collateral=Wad.from_number(10),
                                       delta_debt=Wad.from_number(50))
    collateral.collateral_auction_house.approve(
        geb.safe_engine.address,
        approval_function=approve_safe_modification_directly())
    current_bid = collateral.collateral_auction_house.bids(auction_id)
    safe = geb.safe_engine.safe(collateral.collateral_type, our_address)
    assert Rad(safe.generated_debt) > current_bid.amount_to_raise
    bid_amount = Rad.from_number(6)
    if isinstance(collateral.collateral_auction_house,
                  EnglishCollateralAuctionHouse):
        increase_bid_size(collateral.collateral_auction_house, auction_id,
                          our_address, current_bid.amount_to_sell, bid_amount)
    elif isinstance(collateral.collateral_auction_house,
                    FixedDiscountCollateralAuctionHouse):
        assert collateral.collateral_auction_house.get_collateral_bought(
            auction_id, Wad(bid_amount)).transact(from_address=our_address)
        assert collateral.collateral_auction_house.buy_collateral(
            auction_id, Wad(bid_amount)).transact(from_address=our_address)
Exemple #6
0
    def test_flash_settle_auction(self, web3, geb, collateral,
                                  keeper_flash_proxy,
                                  fixed_collateral_auction_house, our_address,
                                  other_address, deployment_address):
        if not isinstance(keeper_flash_proxy, GebETHKeeperFlashProxy):
            return

        #collateral = geb.collaterals['ETH-A']
        auctions_started_before = fixed_collateral_auction_house.auctions_started(
        )
        collateral_type = collateral.collateral_type

        # Generate eth and join
        wrap_eth(geb, deployment_address, Wad.from_number(1))
        collateral.approve(deployment_address)
        assert collateral.adapter.join(
            deployment_address,
            Wad.from_number(1)).transact(from_address=deployment_address)

        # generate the maximum debt possible
        wrap_modify_safe_collateralization(geb,
                                           collateral,
                                           deployment_address,
                                           delta_collateral=Wad.from_number(1),
                                           delta_debt=Wad(0))
        delta_debt = max_delta_debt(geb, collateral,
                                    deployment_address) - Wad(1)
        debt_before = geb.safe_engine.safe(collateral_type,
                                           deployment_address).generated_debt
        wrap_modify_safe_collateralization(geb,
                                           collateral,
                                           deployment_address,
                                           delta_collateral=Wad(0),
                                           delta_debt=delta_debt)

        # Mint and withdraw all the system coin
        '''
        geb.approve_system_coin(deployment_address)
        assert geb.system_coin_adapter.exit(deployment_address, delta_debt).transact(from_address=deployment_address)

        assert geb.system_coin.balance_of(deployment_address) == delta_debt
        assert geb.safe_engine.coin_balance(deployment_address) == Rad(0)
        '''

        # Undercollateralize the SAFE
        to_price = Wad(Web3.toInt(collateral.osm.read())) / Wad.from_number(2)
        set_collateral_price(geb, collateral, to_price)
        safe = geb.safe_engine.safe(collateral.collateral_type,
                                    deployment_address)
        collateral_type = geb.safe_engine.collateral_type(collateral_type.name)

        # Make sure the SAFE is not safe
        assert collateral_type.accumulated_rate is not None
        assert collateral_type.safety_price is not None
        safe = Ray(safe.generated_debt) * geb.safe_engine.collateral_type(collateral_type.name).accumulated_rate <= \
               Ray(safe.locked_collateral) * collateral_type.safety_price

        assert not safe
        assert len(fixed_collateral_auction_house.active_auctions()) == 0
        on_auction_before = geb.liquidation_engine.current_on_auction_system_coins(
        )

        # Ensure there is no saviour
        saviour = geb.liquidation_engine.safe_saviours(
            collateral.collateral_type, deployment_address)
        assert saviour == Address('0x0000000000000000000000000000000000000000')

        # Liquidate the SAFE
        safe = geb.safe_engine.safe(collateral.collateral_type,
                                    deployment_address)
        '''
        assert safe.locked_collateral > Wad(0)
        generated_debt = min(safe.generated_debt, Wad(geb.liquidation_engine.liquidation_quantity(collateral_type)))  # Wad
        amount_to_raise = generated_debt * collateral_type.accumulated_rate  # Wad
        assert amount_to_raise == delta_debt
        '''

        # Ensure safe can be liquidated
        assert geb.liquidation_engine.can_liquidate(collateral_type, safe)

        assert geb.liquidation_engine.liquidate_safe(collateral_type,
                                                     safe).transact()
        liquidated_id = collateral.collateral_auction_house.auctions_started()
        assert liquidated_id == auctions_started_before + 1

        eth_before = web3.eth.getBalance(our_address.address)
        # liquidate and settle
        #assert collateral.keeper_flash_proxy.liquidate_and_settle_safe(safe).transact(gas=800000, from_address=our_address)
        assert collateral.keeper_flash_proxy.settle_auction(
            liquidated_id).transact(from_address=our_address)

        eth_after = web3.eth.getBalance(our_address.address)
        print(f"Ether profit {(eth_after - eth_before)/1000000000000000000}")
        assert eth_after > eth_before

        # Ensure auction was started
        auction_id = fixed_collateral_auction_house.auctions_started()
        assert auction_id == auctions_started_before + 1

        assert len(fixed_collateral_auction_house.active_auctions()) == 0

        # Check safe_engine, accounting_engine, and liquidation_engine
        liquidations = geb.liquidation_engine.past_liquidations(1)
        assert len(liquidations) == 1
        last_liquidation = liquidations[0]
        assert last_liquidation.amount_to_raise > Rad(0)

        # Check the fixed_collateral_auction_house
        current_bid = fixed_collateral_auction_house.bids(auction_id)
        assert isinstance(current_bid, FixedDiscountCollateralAuctionHouse.Bid)
        assert current_bid.amount_to_sell == Wad(0)
        assert current_bid.amount_to_raise == Rad(0)
        assert current_bid.raised_amount == Rad(0)
        assert current_bid.sold_amount == Wad(0)

        # Ensure auction has ended
        assert len(fixed_collateral_auction_house.active_auctions()) == 0

        # Cleanup
        set_collateral_price(geb, collateral, Wad.from_number(230))
        cleanup_safe(geb, collateral, other_address)