def test_flash_proxy_liquidate_and_settle_auction(self, c: Collateral,
                                                      web3, geb, auction_id,
                                                      other_address):
        # given
        collateral_auction_house = self.collateral.collateral_auction_house
        if not isinstance(collateral_auction_house,
                          FixedDiscountCollateralAuctionHouse):
            return

        set_collateral_price(geb, c, Wad.from_number(100))
        eth_before = self.web3.eth.getBalance(self.keeper_address.address)
        auctions_started = collateral_auction_house.auctions_started()

        # when
        critical_safe = create_critical_safe(geb, c, bid_size, other_address)
        self.keeper.check_safes()
        wait_for_other_threads()
        assert self.web3.eth.getBalance(
            self.keeper_address.address) > eth_before
        assert collateral_auction_house.auctions_started(
        ) == auctions_started + 1

        auction_status = collateral_auction_house.bids(auctions_started + 1)
        assert auction_status.raised_amount == Rad(0)
        assert auction_status.sold_amount == Wad(0)
        assert auction_status.amount_to_raise == Rad(0)
        assert auction_status.amount_to_sell == Wad(0)
        assert auction_status.auction_deadline == 0
        assert auction_status.raised_amount == Rad(0)
def auction_id(web3: Web3, geb: GfDeployment, auction_income_recipient_address,
               other_address) -> int:

    total_surplus = geb.safe_engine.coin_balance(geb.accounting_engine.address)
    unqueued_unauctioned_debt = (
        geb.safe_engine.debt_balance(geb.accounting_engine.address) -
        geb.accounting_engine.total_queued_debt()
    ) - geb.accounting_engine.total_on_auction_debt()
    print(
        f'total_surplus={str(total_surplus)[:6]}, unqueued_unauctioned_debt={str(unqueued_unauctioned_debt)[:6]}'
    )

    if unqueued_unauctioned_debt < total_surplus or (
            unqueued_unauctioned_debt == Rad(0) and total_surplus == Rad(0)):
        # Liquidate SAFE
        c = geb.collaterals['ETH-B']
        critical_safe = create_critical_safe(geb,
                                             c,
                                             Wad.from_number(2),
                                             other_address,
                                             draw_system_coin=False)
        collateral_auction_id = liquidate(geb, c, critical_safe)

        # Generate some system coin, bid on and win the collateral auction without covering all the debt
        reserve_system_coin(geb,
                            c,
                            auction_income_recipient_address,
                            Wad.from_number(100),
                            extra_collateral=Wad.from_number(1.1))
        c.collateral_auction_house.approve(
            geb.safe_engine.address,
            approval_function=approve_safe_modification_directly(
                from_address=auction_income_recipient_address))
        current_bid = c.collateral_auction_house.bids(collateral_auction_id)
        bid_amount = Rad.from_number(1.9)
        assert geb.safe_engine.coin_balance(
            auction_income_recipient_address) > bid_amount
        #assert c.collateral_auction_house.increase_bid_size(collateral_auction_id, current_bid.amount_to_sell, bid_amount).transact(from_address=auction_income_recipient_address)
        #time_travel_by(web3, c.collateral_auction_house.bid_duration()+1)
        #assert c.collateral_auction_house.settle_auction(collateral_auction_id).transact()

    pop_debt_and_settle_debt(web3,
                             geb,
                             past_blocks=1200,
                             cancel_auctioned_debt=False)

    # Start the debt auction
    unqueued_unauctioned_debt = (
        geb.safe_engine.debt_balance(geb.accounting_engine.address) -
        geb.accounting_engine.total_queued_debt()
    ) - geb.accounting_engine.total_on_auction_debt()
    assert geb.accounting_engine.debt_auction_bid_size(
    ) <= unqueued_unauctioned_debt
    assert geb.safe_engine.coin_balance(
        geb.accounting_engine.address) == Rad(0)
    assert geb.accounting_engine.auction_debt().transact(
        from_address=auction_income_recipient_address)
    return geb.debt_auction_house.auctions_started()
def auction_id(geb, c: Collateral, auction_income_recipient_address) -> int:
    # set to pymaker price
    set_collateral_price(geb, c, Wad.from_number(500))
    # Ensure we start with a clean safe
    safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address)
    assert safe.locked_collateral == Wad(0)
    assert safe.generated_debt == Wad(0)

    # liquidate SAFE
    critical_safe = create_critical_safe(geb, c, bid_size, auction_income_recipient_address)
    return liquidate(geb, c, critical_safe)
    def test_should_detect_debt_auction(self, web3, c, geb, other_address,
                                        keeper_address):
        # given a count of debt auctions
        reserve_system_coin(geb, c, keeper_address, Wad.from_number(230))
        auctions_started = geb.debt_auction_house.auctions_started()

        # and an undercollateralized SAFE is liquidated
        critical_safe = create_critical_safe(geb,
                                             c,
                                             Wad.from_number(1),
                                             other_address,
                                             draw_system_coin=False)
        assert geb.liquidation_engine.liquidate_safe(
            critical_safe.collateral_type, critical_safe).transact()

        # when the auction ends without debt being covered
        if isinstance(c.collateral_auction_house,
                      EnglishCollateralAuctionHouse):
            time_travel_by(
                web3,
                c.collateral_auction_house.total_auction_length() + 1)

        # then ensure testchain is in the appropriate state
        total_surplus = geb.safe_engine.coin_balance(
            geb.accounting_engine.address)
        total_debt = geb.safe_engine.debt_balance(
            geb.accounting_engine.address)
        unqueued_unauctioned_debt = (
            geb.safe_engine.debt_balance(geb.accounting_engine.address) -
            geb.accounting_engine.total_queued_debt()
        ) - geb.accounting_engine.total_on_auction_debt()
        debt_queue = geb.accounting_engine.total_queued_debt()
        debt_auction_bid_size = geb.accounting_engine.debt_auction_bid_size()
        wait = geb.accounting_engine.pop_debt_delay()
        assert total_surplus < total_debt
        assert unqueued_unauctioned_debt + debt_queue >= debt_auction_bid_size
        assert wait == 0

        # when
        self.keeper.check_debt()
        wait_for_other_threads()

        # then ensure another debt auction was started
        auction_id = geb.debt_auction_house.auctions_started()
        assert auction_id == auctions_started + 1

        # clean up by letting someone else bid and waiting until the auction ends
        self.decrease_sold_amount(auction_id, self.other_address,
                                  Wad.from_number(0.000012),
                                  self.debt_auction_bid_size)
        time_travel_by(web3, geb.debt_auction_house.bid_duration() + 1)
    def test_liquidation_and_collateral_auction(
            self, web3, geb, auction_income_recipient_address, keeper_address):
        # given
        c = geb.collaterals['ETH-A']
        set_collateral_price(geb, c, Wad.from_number(500))
        keeper = AuctionKeeper(args=args(
            f"--eth-from {keeper_address} "
            f"--type collateral "
            f"--from-block 1 "
            f"--collateral-type {c.collateral_type.name} "
            f"--model ./bogus-model.sh"),
                               web3=geb.web3)
        keeper.approve()
        unsafe_safe = create_critical_safe(geb, c, Wad.from_number(1.2),
                                           auction_income_recipient_address)
        assert len(geb.active_auctions()["collateral_auctions"][
            c.collateral_type.name]) == 0

        # Keeper won't bid with a 0 system coin balance
        purchase_system_coin(Wad.from_number(20), keeper_address)
        assert geb.system_coin_adapter.join(
            keeper_address,
            Wad.from_number(20)).transact(from_address=keeper_address)

        # when
        keeper.check_safes()
        wait_for_other_threads()

        # then
        assert len(geb.liquidation_engine.past_liquidations(10)) > 0
        safe = geb.safe_engine.safe(unsafe_safe.collateral_type,
                                    unsafe_safe.address)
        assert safe.generated_debt == Wad(0)  # unsafe safe has been liquidated
        assert safe.locked_collateral == Wad(0)  # unsafe safe is now safe ...
        assert c.collateral_auction_house.auctions_started(
        ) == 1  # One auction started
def auction_small(geb, c: Collateral, auction_income_recipient_address) -> int:
    critical_safe = create_critical_safe(geb, c, bid_size_small,
                                         auction_income_recipient_address)
    return liquidate(geb, c, critical_safe)