예제 #1
0
    def test_tokens_swap(self):
        # given
        add_liquidity = self.add_liquidity_tokens()

        balance_systemcoin_before_swap = self.systemcoin_usdc_uniswap.get_account_token_balance(
            self.token_systemcoin)
        balance_usdc_before_swap = self.systemcoin_usdc_uniswap.get_account_token_balance(
            self.token_usdc)

        # when
        swap = self.systemcoin_usdc_uniswap.swap_exact_tokens_for_tokens(
            Wad.from_number(.2),
            self.token_usdc.unnormalize_amount(Wad.from_number(.01)),
            [self.ds_systemcoin.address.address, self.ds_usdc.address.address
             ]).transact(from_address=self.our_address)

        # then
        assert swap.successful == True

        balance_systemcoin_after_swap = self.systemcoin_usdc_uniswap.get_account_token_balance(
            self.token_systemcoin)
        balance_usdc_after_swap = self.systemcoin_usdc_uniswap.get_account_token_balance(
            self.token_usdc)

        assert balance_systemcoin_after_swap < balance_systemcoin_before_swap
        assert balance_usdc_before_swap < balance_usdc_after_swap
예제 #2
0
    def test_collateral_removal(self, mocker):
        try:
            # given a keeper configured to return all collateral upon rebalance
            token_balance_before = self.get_collateral_token_balance()
            safe_engine_balance_before = self.get_collateral_safe_engine_balance(
            )
            self.create_keeper(mocker)
            time.sleep(6)  # wait for keeper to startup
            assert self.get_collateral_token_balance() == token_balance_before
            assert self.get_collateral_safe_engine_balance(
            ) == safe_engine_balance_before

            # when some ETH was wrapped and joined
            wrap_eth(self.geb, self.keeper_address, Wad.from_number(1.53))
            token_balance = self.get_collateral_token_balance()
            assert token_balance > Wad(0)
            self.collateral.adapter.join(self.keeper_address,
                                         token_balance).transact()
            assert self.get_collateral_safe_engine_balance(
            ) == safe_engine_balance_before + token_balance

            # then wait to ensure collateral was exited automatically
            time.sleep(4)
            assert self.get_collateral_safe_engine_balance() == Wad(0)
            assert self.get_collateral_token_balance(
            ) == token_balance_before + Wad.from_number(1.53)

        finally:
            self.shutdown_keeper()

        self.give_away_system_coin()
예제 #3
0
    def setup_method(self):
        self.web3 = Web3(HTTPProvider("http://localhost:8555"))
        self.web3.eth.defaultAccount = self.web3.eth.accounts[0]
        self.our_address = Address(self.web3.eth.defaultAccount)
        self.zrx_token = ERC20Token(web3=self.web3,
                                    address=deploy_contract(
                                        self.web3, 'ZRXToken'))

        self.asset_proxy = deploy_contract(self.web3, 'ExchangeV2-ERC20Proxy')
        self.exchange = ZrxExchangeV2.deploy(
            self.web3,
            None)  #"0xf47261b0" + self.zrx_token.address.address - unused yet
        self.exchange._contract.functions.registerAssetProxy(
            self.asset_proxy.address).transact()

        token_proxy_abi = json.loads(
            pkg_resources.resource_string('pyflex.deployment',
                                          f'abi/ExchangeV2-ERC20Proxy.abi'))
        asset_proxy_contract = self.web3.eth.contract(abi=token_proxy_abi)(
            address=self.asset_proxy.address)
        asset_proxy_contract.functions.addAuthorizedAddress(
            self.exchange.address.address).transact()

        self.token1 = DSToken.deploy(self.web3, 'AAA', 'AAA')
        self.token1.mint(Wad.from_number(100)).transact()
        self.token2 = DSToken.deploy(self.web3, 'BBB', 'BBB')
        self.token2.mint(Wad.from_number(100)).transact()
예제 #4
0
    def liquidate_safe(cls, web3, geb, c, auction_income_recipient_address, our_address):
        safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address)

        delta_debt = max_delta_debt(geb, c, auction_income_recipient_address) - Wad.from_number(1)
        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)
        safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address)
        set_collateral_price(geb, c, Wad.from_number(10))

        # Ensure the SAFE isn't safe
        assert not is_safe_safe(geb.safe_engine.collateral_type(c.collateral_type.name), safe)

        # Determine how many liquidations will be required
        liquidation_quantity = Wad(geb.liquidation_engine.liquidation_quantity(c.collateral_type))
        liquidations_required = math.ceil(safe.generated_debt / liquidation_quantity)
        print(f"locked_collateral={safe.locked_collateral} generated_debt={safe.generated_debt} so {liquidations_required} liquidations are required")
        c.collateral_auction_house.approve(geb.safe_engine.address, approval_function=approve_safe_modification_directly(from_address=our_address))

        # First auction that will be started
        first_auction_id = c.collateral_auction_house.auctions_started() + 1

        # liquidate and bid on each auction
        for _ in range(liquidations_required):
            auction_id = liquidate(geb, c, safe)
            assert auction_id > 0
            auction = c.collateral_auction_house.bids(auction_id)
            bid_amount = Wad(auction.amount_to_raise) + Wad(1)
            reserve_system_coin(geb, c, our_address, bid_amount)
            assert c.collateral_auction_house.increase_bid_size(auction_id, auction.amount_to_sell, auction.amount_to_raise).transact(from_address=our_address)

        time_travel_by(web3, c.collateral_auction_house.total_auction_length()+1)
        for auction_id in range(first_auction_id, c.collateral_auction_house.auctions_started()+1):
            assert c.collateral_auction_house.settle_auction(auction_id).transact()

        set_collateral_price(geb, c, Wad.from_number(200))
        safe = geb.safe_engine.safe(c.collateral_type, auction_income_recipient_address)
예제 #5
0
    def setup_method(self):
        self.web3 = get_web3()
        self.our_address = get_our_address(self.web3)
        self.keeper_address = get_keeper_address(self.web3)
        self.other_address = get_other_address(self.web3)
        self.auction_income_recipient_address = get_auction_income_recipient_address(self.web3)
        self.geb = get_geb(self.web3)
        self.surplus_auction_house = self.geb.surplus_auction_house
        self.surplus_auction_house.approve(self.geb.prot.address, directly(from_address=self.other_address))
        #self.min_auction = self.geb.surplus_auction_house.auctions_started() + 1

        self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} "
                                              f"--type surplus "
                                              f"--from-block 1 "
                                              f"--bid-delay 0 "
                                              #f"--min-auction {self.min_auction} "
                                              f"--model ./bogus-model.sh"), web3=self.web3)
        self.keeper.approve()

        mint_prot(self.geb.prot, self.keeper_address, Wad.from_number(50000))
        mint_prot(self.geb.prot, self.other_address, Wad.from_number(50000))

        assert isinstance(self.keeper.gas_price, DynamicGasPrice)
        # Since no args were assigned, gas strategy should return a GeometricGasPrice starting at the node gas price
        self.default_gas_price = get_node_gas_price(self.web3)
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')
예제 #7
0
    def test_equality(self):
        # given
        transfer1a = Transfer(
            token_address=Address(
                '0x0000011111222223333344444555556666677777'),
            from_address=Address('0x0000000000111111111100000000001111111111'),
            to_address=Address('0x1111111111000000000011111111110000000000'),
            value=Wad.from_number(20))
        transfer1b = Transfer(
            token_address=Address(
                '0x0000011111222223333344444555556666677777'),
            from_address=Address('0x0000000000111111111100000000001111111111'),
            to_address=Address('0x1111111111000000000011111111110000000000'),
            value=Wad.from_number(20))
        transfer2 = Transfer(
            token_address=Address(
                '0x0000011111222223333344444555556666677777'),
            from_address=Address('0x0000000000111111111100000000001111111111'),
            to_address=Address('0x1111111111000000000011111111112222222222'),
            value=Wad.from_number(20))

        # expect
        assert transfer1a == transfer1b
        assert transfer1b == transfer1a
        assert transfer1a != transfer2
        assert transfer1b != transfer2
        assert transfer2 != transfer1a
        assert transfer2 != transfer1b
예제 #8
0
def liquidate(web3: Web3, geb: GfDeployment, our_address: Address):
    collateral = geb.collaterals['ETH-A']

    # Add collateral to our SAFE
    delta_collateral = Wad.from_number(1)
    wrap_eth(geb, our_address, delta_collateral)
    assert collateral.collateral.balance_of(our_address) >= delta_collateral
    assert collateral.adapter.join(our_address, delta_collateral).transact()
    wrap_modify_safe_collateralization(geb, collateral, our_address,
                                       delta_collateral, Wad(0))

    # Define required liquidation parameters
    to_price = Wad(Web3.toInt(collateral.osm.read())) / Wad.from_number(2)

    # Manipulate price to make our SAFE underwater
    # Note this will only work on a testchain deployed with fixed prices, where OSM is a DSValue
    wrap_modify_safe_collateralization(
        geb, collateral, our_address, Wad(0),
        max_delta_debt(geb, collateral, our_address))
    set_collateral_price(geb, collateral, to_price)

    # Liquidate the SAFE
    assert geb.liquidation_engine.can_liquidate(collateral.collateral_type,
                                                SAFE(our_address))

    assert geb.liquidation_engine.liquidate_safe(collateral.collateral_type,
                                                 SAFE(our_address)).transact()
예제 #9
0
    def test_should_overbid_itself_if_model_has_updated_the_price(self, auction_id):
        # given
        (model, model_factory) = models(self.keeper, auction_id)
        amount_to_sell = self.surplus_auction_house.bids(auction_id).amount_to_sell

        # when
        first_bid = Wad.from_number(0.0000004)
        simulate_model_output(model=model, price=first_bid)
        # and
        self.keeper.check_all_auctions()
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        assert self.surplus_auction_house.bids(auction_id).bid_amount == Wad(amount_to_sell * self.geb.oracle_relayer.redemption_price()  / Rad(first_bid))

        # when
        second_bid = Wad.from_number(0.0000003)
        simulate_model_output(model=model, price=second_bid)
        self.keeper.check_all_auctions()
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        assert self.surplus_auction_house.bids(auction_id).bid_amount == Wad(amount_to_sell * self.geb.oracle_relayer.redemption_price() / Rad(second_bid))

        # cleanup
        time_travel_by(self.web3, self.surplus_auction_house.bid_duration() + 1)
        assert self.surplus_auction_house.settle_auction(auction_id).transact()
예제 #10
0
    def test_past_cancel(self):
        # given
        self.exchange.approve([self.token1, self.token2], directly())

        # when
        order = self.exchange.create_order(pay_token=self.token1.address,
                                           pay_amount=Wad.from_number(10),
                                           buy_token=self.token2.address,
                                           buy_amount=Wad.from_number(4),
                                           expiration=1763920792)
        # and
        self.exchange.cancel_order(self.exchange.sign_order(order)).transact()

        # then
        past_cancel = self.exchange.past_cancel(PAST_BLOCKS)
        assert len(past_cancel) == 1
        assert past_cancel[0].maker == self.our_address
        assert past_cancel[0].fee_recipient == Address(
            "0x0000000000000000000000000000000000000000")
        assert past_cancel[0].pay_token == self.token1.address
        assert past_cancel[0].cancelled_pay_amount == Wad.from_number(10)
        assert past_cancel[0].buy_token == self.token2.address
        assert past_cancel[0].cancelled_buy_amount == Wad.from_number(4)
        assert past_cancel[0].tokens.startswith('0x')
        assert past_cancel[0].order_hash == self.exchange.get_order_hash(
            self.exchange.sign_order(order))
        assert past_cancel[0].raw['blockNumber'] > 0
예제 #11
0
    def test_should_be_hashable(self):
        # given
        order = Order(
            exchange=None,
            maker=Address("0x9e56625509c2f60af937f23b7b532600390e8c8b"),
            taker=Address("0x0000000000000000000000000000000000000000"),
            maker_fee=Wad.from_number(123),
            taker_fee=Wad.from_number(456),
            pay_token=Address("0x323b5d4c32345ced77393b3530b1eed0f346429d"),
            pay_amount=Wad(10000000000000000),
            buy_token=Address("0xef7fff64389b814a946f3e92105513705ca6b990"),
            buy_amount=Wad(20000000000000000),
            salt=
            67006738228878699843088602623665307406148487219438534730168799356281242528500,
            fee_recipient=Address(
                '0x6666666666666666666666666666666666666666'),
            expiration=42,
            exchange_contract_address=Address(
                "0x12459c951127e0c374ff9105dda097662a027093"),
            ec_signature_r=
            "0xf9f6a3b67b52d40c16387df2cd6283bbdbfc174577743645dd6f4bd828c7dbc3",
            ec_signature_s=
            "0x15baf69f6c3cc8ac0f62c89264d73accf1ae165cce5d6e2a0b6325c6e4bab964",
            ec_signature_v=28)

        # expect
        assert is_hashable(order)
    def test_should_overbid_itself_if_model_has_updated_the_price(
            self, auction_id):
        # given
        (model, model_factory) = models(self.keeper, auction_id)

        # when
        simulate_model_output(model=model, price=Wad.from_number(100.0))
        # and
        self.keeper.check_all_auctions()
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        assert round(
            Rad(self.debt_auction_house.bids(auction_id).amount_to_sell),
            2) == round(self.debt_auction_bid_size / Rad.from_number(100.0), 2)

        # when
        simulate_model_output(model=model, price=Wad.from_number(110.0))
        self.keeper.check_all_auctions()
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        assert self.amount_to_sell_implies_price(auction_id,
                                                 Wad.from_number(110.0))

        # cleanup
        time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1)
        assert self.debt_auction_house.settle_auction(auction_id).transact()
    def test_should_replace_pending_transactions_if_model_lowers_bid_and_increases_gas_price(
            self, auction_id):
        # given
        (model, model_factory) = models(self.keeper, auction_id)

        # when
        simulate_model_output(model=model,
                              price=Wad.from_number(80.0),
                              gas_price=10)
        # and
        self.start_ignoring_transactions()
        # and
        self.keeper.check_all_auctions()
        # and
        time.sleep(2)
        # and
        self.end_ignoring_transactions()
        # and
        simulate_model_output(model=model,
                              price=Wad.from_number(70.0),
                              gas_price=15)
        # and
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        assert self.amount_to_sell_implies_price(auction_id,
                                                 Wad.from_number(70.0))
        assert self.web3.eth.getBlock(
            'latest', full_transactions=True).transactions[0].gasPrice == 15

        # cleanup
        time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1)
        assert self.debt_auction_house.settle_auction(auction_id).transact()
예제 #14
0
    def test_should_replace_pending_transactions_if_model_lowers_bid_and_increases_gas_price(self, auction_id):
        # given
        (model, model_factory) = models(self.keeper, auction_id)
        amount_to_sell = self.surplus_auction_house.bids(auction_id).amount_to_sell

        # when
        simulate_model_output(model=model, price=Wad.from_number(10.0), gas_price=10)
        # and
        self.start_ignoring_transactions()
        # and
        self.keeper.check_all_auctions()
        self.keeper.check_for_bids()
        # and
        self.end_ignoring_transactions()
        # and
        simulate_model_output(model=model, price=Wad.from_number(8.0), gas_price=15)
        # and
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        assert self.surplus_auction_house.bids(auction_id).bid_amount == Wad(amount_to_sell * self.geb.oracle_relayer.redemption_price()) / Wad.from_number(8.0)
        assert self.web3.eth.getBlock('latest', full_transactions=True).transactions[0].gasPrice == 15

        # cleanup
        time_travel_by(self.web3, self.surplus_auction_house.bid_duration() + 1)
        assert self.surplus_auction_house.settle_auction(auction_id).transact()
    def test_should_bid_even_if_there_is_already_a_bidder(self, auction_id):
        # given
        (model, model_factory) = models(self.keeper, auction_id)
        prot_before = self.geb.prot.balance_of(self.keeper_address)
        # and
        amount_to_sell = Wad.from_number(0.000016)
        assert self.debt_auction_house.decrease_sold_amount(
            auction_id, amount_to_sell, self.debt_auction_bid_size).transact(
                from_address=self.other_address)
        assert self.debt_auction_house.bids(
            auction_id).amount_to_sell == amount_to_sell

        # when
        simulate_model_output(model=model, price=Wad.from_number(825.0))
        # and
        self.keeper.check_all_auctions()
        self.keeper.check_for_bids()
        wait_for_other_threads()
        # then
        auction = self.debt_auction_house.bids(auction_id)
        assert auction.amount_to_sell != amount_to_sell
        assert round(
            auction.bid_amount * self.geb.oracle_relayer.redemption_price() /
            Rad(auction.amount_to_sell), 2) == round(Rad.from_number(825.0), 2)
        prot_after = self.geb.prot.balance_of(self.keeper_address)
        assert prot_before == prot_after

        # cleanup
        time_travel_by(self.web3, self.debt_auction_house.bid_duration() + 1)
        assert self.debt_auction_house.settle_auction(auction_id).transact()
예제 #16
0
def create_surplus_auction(geb: GfDeployment, deployment_address: Address,
                           our_address: Address, collateral: Collateral):
    assert isinstance(geb, GfDeployment)
    assert isinstance(deployment_address, Address)
    assert isinstance(our_address, Address)

    surplus_auction_house = geb.surplus_auction_house
    create_surplus(geb, surplus_auction_house, deployment_address, collateral)
    coin_balance = geb.safe_engine.coin_balance(geb.accounting_engine.address)
    assert coin_balance > 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()

    mint_prot(geb.prot, our_address, Wad.from_number(10))
    surplus_auction_house.approve(geb.prot.address,
                                  directly(from_address=our_address))
    bid = Wad.from_number(0.001)
    assert geb.prot.balance_of(our_address) > bid
    assert surplus_auction_house.increase_bid_size(
        surplus_auction_house.auctions_started(),
        geb.accounting_engine.surplus_auction_amount_to_sell(),
        bid).transact(from_address=our_address)
예제 #17
0
    def test_do_not_empty(self):
        # given system_coin and collateral in the safe_engine
        keeper = self.create_keeper(False, False)
        purchase_system_coin(Wad.from_number(153), self.keeper_address)
        assert self.get_system_coin_token_balance() >= Wad.from_number(153)
        assert self.geb.system_coin_adapter.join(
            self.keeper_address,
            Wad.from_number(153)).transact(from_address=self.keeper_address)
        wrap_eth(self.geb, self.keeper_address, Wad.from_number(6))
        # and balances before
        system_coin_token_balance_before = self.get_system_coin_token_balance()
        system_coin_safe_engine_balance_before = self.get_system_coin_safe_engine_balance(
        )
        collateral_token_balance_before = self.get_collateral_token_balance()
        collateral_safe_engine_balance_before = self.get_collateral_safe_engine_balance(
        )

        # when creating and shutting down the keeper
        keeper.shutdown()

        # then ensure no balances changed
        assert system_coin_token_balance_before == self.get_system_coin_token_balance(
        )
        assert system_coin_safe_engine_balance_before == self.get_system_coin_safe_engine_balance(
        )
        assert collateral_token_balance_before == self.get_collateral_token_balance(
        )
        assert collateral_safe_engine_balance_before == self.get_collateral_safe_engine_balance(
        )
예제 #18
0
    def test_empty_collateral_only(self):
        # given collateral balances before
        collateral_token_balance_before = self.get_collateral_token_balance()
        collateral_safe_engine_balance_before = self.get_collateral_safe_engine_balance(
        )

        # when adding system_coin
        purchase_system_coin(Wad.from_number(79), self.keeper_address)
        assert self.geb.system_coin_adapter.join(
            self.keeper_address,
            Wad.from_number(79)).transact(from_address=self.keeper_address)
        system_coin_token_balance_before = self.get_system_coin_token_balance()
        system_coin_safe_engine_balance_before = self.get_system_coin_safe_engine_balance(
        )
        # and creating and shutting down the keeper
        keeper = self.create_keeper(False, True)
        keeper.shutdown()

        # then ensure system_coin was not emptied
        assert self.get_system_coin_token_balance() == Wad(0)
        assert system_coin_safe_engine_balance_before < self.get_system_coin_safe_engine_balance(
        )
        # and collateral was emptied
        assert collateral_token_balance_before == collateral_token_balance_before + collateral_safe_engine_balance_before
        assert self.get_collateral_safe_engine_balance() == Wad(0)
예제 #19
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)
예제 #20
0
 def test_round_inequality(self):
     # should hold for all x, ndigits
     x = Wad.from_number(7654.321)
     ndigits = 1
     round_difference = x - round(x, ndigits)
     round_distance = Wad(abs(round_difference.value))
     assert round_distance <= Wad.from_number(0.5 * 10**(-ndigits))
예제 #21
0
 def test_price(self, web3, geb):
     collateral = geb.collaterals['ETH-B']
     set_collateral_price(geb, collateral, Wad.from_number(200))
     # Note this isn't actually an OSM, but we can still read storage slots
     osm = OSM(web3, collateral.osm.address)
     raw_price = osm.read()
     assert isinstance(raw_price, int)
     assert Wad.from_number(200) == Wad(raw_price)
예제 #22
0
 def test_divide(self):
     assert Wad.from_number(4) / Wad.from_number(2) == Wad.from_number(2)
     assert Wad(4) / Wad.from_number(2) == Wad(2)
     assert Wad(3) / Wad.from_number(2) == Wad(1)
     assert Wad(39) / Wad.from_number(20) == Wad(1)
     assert Wad(40) / Wad.from_number(20) == Wad(2)
     assert Wad.from_number(0.2) / Wad.from_number(0.1) == Wad.from_number(
         2)
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 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
예제 #25
0
 def setup_method(self):
     self.web3 = Web3(HTTPProvider("http://localhost:8555"))
     self.web3.eth.defaultAccount = self.web3.eth.accounts[0]
     self.our_address = Address(self.web3.eth.defaultAccount)
     self.other_address = Address(self.web3.eth.accounts[1])
     self.tx = TxManager.deploy(self.web3)
     self.token1 = DSToken.deploy(self.web3, 'ABC', 'ABC')
     self.token1.mint(Wad.from_number(1000000)).transact()
     self.token2 = DSToken.deploy(self.web3, 'DEF', 'DEF')
     self.token2.mint(Wad.from_number(1000000)).transact()
예제 #26
0
    def test_getting_balances(self):
        # given
        self.dgx.mint(Wad(17 * 10**9)).transact()
        self.dai.mint(Wad.from_number(17)).transact()

        # when
        balances = self.zrx_api.get_balances(self.pair)
        # then
        assert balances[0] == Wad.from_number(17)
        assert balances[1] == Wad.from_number(17)
예제 #27
0
 def test_prepare_coins_for_redeeming(self, geb, our_address):
     assert geb.global_settlement.coin_bag(our_address) == Wad(0)
     assert geb.global_settlement.outstanding_coin_supply() > Rad(0)
     assert geb.system_coin.approve(
         geb.global_settlement.address).transact()
     assert geb.safe_engine.coin_balance(our_address) >= Rad.from_number(10)
     # FIXME: `prepareCoinsForRedeeming` fails, possibly because we're passing 0 to `safeEngine.transfer_collateral`
     assert geb.global_settlement.prepare_coins_for_redeeming(
         Wad.from_number(10)).transact()
     assert geb.global_settlement.coin_bag(our_address) == Wad.from_number(
         10)
예제 #28
0
    def test_eth_transfer(self):
        # given
        initial_balance = eth_balance(self.web3, self.second_address)

        # when
        eth_transfer(self.web3, self.second_address,
                     Wad.from_number(1.5)).transact()

        # then
        assert eth_balance(
            self.web3,
            self.second_address) == initial_balance + Wad.from_number(1.5)
예제 #29
0
    def test_join_all(self):
        # given system_coin we just exited
        token_balance_before = self.get_system_coin_token_balance()
        assert token_balance_before == Wad.from_number(237)

        # when keeper is started with a token balance
        self.create_keeper_join_all()

        # then ensure all available tokens were joined
        assert self.get_system_coin_token_balance() == Wad(0)
        assert self.get_system_coin_safe_engine_balance() == Wad.from_number(
            237)
예제 #30
0
    def test_exit_all(self):
        # given balances before
        assert self.get_system_coin_token_balance() == Wad.from_number(37)
        assert self.get_system_coin_safe_engine_balance() == Wad.from_number(
            200)

        # when rebalancing to 0
        self.create_keeper(0.0)

        # then ensure all system_coin has been exited
        assert self.get_system_coin_token_balance() == Wad.from_number(237)
        assert self.get_system_coin_safe_engine_balance() == Wad(0)