コード例 #1
0
    auction_state = json.loads(auction_input)

    # If we are already the high bidder, do nothing
    if auction_state['high_bidder'] == os.environ['KEEPER_ADDRESS']:
        continue

    # Ensure our custom bid increase is at least the minimum allowed
    MY_BID_DECREASE = max(Wad.from_number(MY_BID_DECREASE), Wad.from_number(auction_state['bid_decrease']))

    # Add slight amount to account for possible redemption price change between the time of model output and bid placement
    MY_BID_DECREASE += Wad.from_number(1e-4)

    # Bid price using `MY_BID_INCREASE`
    my_bid_amount = Wad.from_number(auction_state['amount_to_sell']) / MY_BID_DECREASE
    # Round up from Rad to Wad
    my_bid_price = Wad(Rad.from_number(auction_state['bid_amount']) * redemption_price / Rad(my_bid_amount)) + Wad(1)

    # Bid price using minimum bid increase allowed
    min_bid_amount = Wad.from_number(auction_state['amount_to_sell']) / Wad.from_number(auction_state['bid_decrease'])
    # Round up from Rad to Wad
    min_bid_price = Wad(Rad.from_number(auction_state['bid_amount']) * redemption_price  / Rad(min_bid_amount)) + Wad(1)

    # Try our bid increase first
    # If price is too low, then try minimum bid increase
    if my_bid_price <= Wad.from_number(MAXIMUM_FLX_MULTIPLIER * current_flx_usd_price):
        bid = {'price': str(my_bid_price)}
        print(json.dumps(bid), flush=True)
    elif min_bid_price <= Wad.from_number(MAXIMUM_FLX_MULTIPLIER * current_flx_usd_price):
        bid = {'price': str(min_bid_price)}
        print(json.dumps(bid), flush=True)
コード例 #2
0
 def test_min_value(self):
     assert Rad.min(Rad(10), Rad(20)) == Rad(10)
     assert Rad.min(Rad(25), Rad(15)) == Rad(15)
     assert Rad.min(Rad(25), Rad(15), Rad(5)) == Rad(5)
コード例 #3
0
 def test_min_value_should_reject_comparison_with_ints(self):
     with pytest.raises(ArithmeticError):
         Rad.min(Rad(10), 20)
     with pytest.raises(ArithmeticError):
         Rad.min(20, Rad(10))
コード例 #4
0
 def test_should_fail_to_divide_by_ints(self):
     with pytest.raises(ArithmeticError):
         Rad(4) / 2
コード例 #5
0
 def test_should_compare_rays_with_each_other(self):
     assert Rad(1000) == Rad(1000)
     assert Rad(1000) != Rad(999)
     assert Rad(1000) > Rad(999)
     assert Rad(999) < Rad(1000)
     assert Rad(999) <= Rad(1000)
     assert Rad(1000) <= Rad(1000)
     assert Rad(1000) >= Rad(1000)
     assert Rad(1000) >= Rad(999)
コード例 #6
0
 def test_multiply(self):
     assert Rad.from_number(2) * Rad.from_number(3) == Rad.from_number(6)
     assert Rad.from_number(2) * Rad(3) == Rad(6)
     assert Rad.from_number(2.5) * Rad(3) == Rad(7)
     assert Rad.from_number(2.99999) * Rad(3) == Rad(8)
コード例 #7
0
 def test_multiply_by_ray(self):
     assert Rad.from_number(2) * Ray.from_number(3) == Rad.from_number(6)
     assert Rad.from_number(2) * Ray(3) == Rad(6000000000000000000)
     assert Rad(2) * Ray(3) == Rad(0)
     assert Rad(2) * Ray(999999999999999999999999999) == Rad(1)
     assert Rad(2) * Ray(1000000000000000000000000000) == Rad(2)
コード例 #8
0
 def test_should_instantiate_from_a_wad(self):
     assert Rad(Wad(10000000000000000000)) == Rad.from_number(10)
コード例 #9
0
 def test_should_instantiate_from_a_ray(self):
     assert Rad(Ray.from_number(10)) == Rad.from_number(10)
コード例 #10
0
 def test_should_support_values_greater_than_uint256(self):
     Rad(2**256)
     Rad(2**256 + 1)
     Rad(2**512)
コード例 #11
0
 def test_should_instantiate_from_a_rad(self):
     assert Rad(Rad(1)) == Rad(1)
コード例 #12
0
 def test_should_support_negative_values(self):
     Rad(-1)
コード例 #13
0
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)
コード例 #14
0
def create_surplus_auction(geb: GfDeployment, deployment_address: Address,
                           our_address: Address):
    assert isinstance(geb, GfDeployment)
    assert isinstance(deployment_address, Address)
    assert isinstance(our_address, Address)

    surplus_auction_house = geb.surplus_auction_house
    print(
        f"Before Surplus: {geb.safe_engine.coin_balance(geb.accounting_engine.address)}"
    )
    create_surplus(geb, surplus_auction_house, deployment_address)
    print(
        f"After Surplus: {geb.safe_engine.coin_balance(geb.accounting_engine.address)}"
    )

    # start surplus auction
    surplus = geb.safe_engine.coin_balance(geb.accounting_engine.address)
    assert surplus > geb.safe_engine.debt_balance(geb.accounting_engine.address) + \
                     geb.accounting_engine.surplus_auction_amount_to_sell() + \
                     geb.accounting_engine.surplus_buffer()
    assert (geb.safe_engine.debt_balance(geb.accounting_engine.address) - \
            geb.accounting_engine.total_queued_debt()) - geb.accounting_engine.total_on_auction_debt() == Rad(0)
    assert geb.accounting_engine.auction_surplus().transact()
    auction_id = surplus_auction_house.auctions_started()
    assert auction_id == 1
    assert len(surplus_auction_house.active_auctions()) == 1

    mint_prot(geb.prot, our_address, Wad.from_number(10))
    surplus_auction_house.approve(geb.prot.address,
                                  directly(from_address=our_address))
    bid_amount = Wad.from_number(0.001)
    assert geb.prot.balance_of(our_address) > bid_amount
    assert surplus_auction_house.increase_bid_size(
        surplus_auction_house.auctions_started(),
        geb.accounting_engine.surplus_auction_amount_to_sell(),
        bid_amount).transact(from_address=our_address)
コード例 #15
0
 def test_modulo(self):
     assert Rad(10) % Rad(2) == Rad(0)
     assert Rad(11) % Rad(5) == Rad(1)
     assert Rad(11) % Rad(3) == Rad(2)
コード例 #16
0
 def test_should_instantiate_from_an_int(self):
     assert Rad(10).value == 10
コード例 #17
0
 def test_modulo_should_not_work_with_wads(self):
     with pytest.raises(ArithmeticError):
         Rad(10) % Wad(3)
コード例 #18
0
 def test_should_fail_to_instantiate_from_a_float(self):
     with pytest.raises(ArithmeticError):
         assert Rad(10.5)
コード例 #19
0
 def test_multiply_by_wad(self):
     assert Rad.from_number(2) * Wad.from_number(3) == Rad.from_number(6)
     assert Rad.from_number(2) * Wad(3) == Rad(6000000000000000000000000000)
     assert Rad(2) * Wad(3) == Rad(0)
     assert Rad(2) * Wad(999999999999999999) == Rad(1)
     assert Rad(2) * Wad(1000000000000000000) == Rad(2)
コード例 #20
0
 def test_should_have_nice_printable_representation(self):
     for ray in [Rad(1), Rad(100), Rad.from_number(2.5), Rad(-1)]:
         assert repr(ray) == f"Rad({ray.value})"
コード例 #21
0
 def test_should_fail_to_multiply_by_float(self):
     with pytest.raises(ArithmeticError):
         Rad(2) * 3.0
コード例 #22
0
 def test_add(self):
     assert Rad(1) + Rad(2) == Rad(3)
コード例 #23
0
 def test_should_support_abs(self):
     assert abs(Rad(1000)) == Rad(1000)
     assert abs(Rad(0)) == Rad(0)
     assert abs(Rad(-1000)) == Rad(1000)
コード例 #24
0
 def test_add_should_not_work_with_ints(self):
     with pytest.raises(ArithmeticError):
         Rad(1) + 2
コード例 #25
0
 def test_should_be_hashable(self):
     assert is_hashable(Rad(123))
コード例 #26
0
 def test_subtract(self):
     assert Rad(10) - Rad(2) == Rad(8)
     assert Rad(1) - Rad(2) == Rad(-1)
コード例 #27
0
 def test_min_value_should_reject_comparison_with_rays(self):
     with pytest.raises(ArithmeticError):
         Rad.min(Rad(10), Ray(20))
     with pytest.raises(ArithmeticError):
         Rad.min(Ray(25), Rad(15))
コード例 #28
0
 def test_subtract_should_not_work_with_rays(self):
     with pytest.raises(ArithmeticError):
         Rad(10) - Ray(2)
コード例 #29
0
 def test_max_value(self):
     assert Rad.max(Rad(10), Rad(20)) == Rad(20)
     assert Rad.max(Rad(25), Rad(15)) == Rad(25)
     assert Rad.max(Rad(25), Rad(15), Rad(40)) == Rad(40)
コード例 #30
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)