def test_should_ignore_orders_owned_by_others(self, deployment: Deployment):
        # given
        keeper = OasisMarketMakerCancel(args=args(f"--eth-from {deployment.web3.eth.defaultAccount} "
                                             f"--oasis-address {deployment.otc.address}"),
                                        web3=deployment.web3)

        # and
        DSToken(web3=deployment.web3, address=deployment.gem.address).mint(Wad.from_number(1000)).transact()
        DSToken(web3=deployment.web3, address=deployment.sai.address).mint(Wad.from_number(1000)).transact()

        # and
        deployment.gem.transfer(Address(deployment.web3.eth.accounts[1]), Wad.from_number(500)).transact()
        deployment.sai.transfer(Address(deployment.web3.eth.accounts[1]), Wad.from_number(500)).transact()

        # and
        deployment.otc.approve([deployment.gem, deployment.sai], directly())
        deployment.otc.make(deployment.gem.address, Wad.from_number(10), deployment.sai.address, Wad.from_number(5)).transact()

        # and
        deployment.web3.eth.defaultAccount = deployment.web3.eth.accounts[1]
        deployment.otc.approve([deployment.gem, deployment.sai], directly())
        deployment.otc.make(deployment.sai.address, Wad.from_number(5), deployment.gem.address, Wad.from_number(12)).transact()
        deployment.web3.eth.defaultAccount = deployment.web3.eth.accounts[0]

        # and
        assert len(deployment.otc.get_orders()) == 2

        # when
        keeper.main()

        # then
        assert len(deployment.otc.get_orders()) == 1
        assert deployment.otc.get_orders()[0].maker == Address(deployment.web3.eth.accounts[1])
    def test_should_cancel_all_orders_but_not_terminate_if_market_gets_closed(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 2

        # when
        deployment.otc._contract.transact().stop()

        # and
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 0
        assert not keeper.lifecycle.terminated_internally
    def test_should_cancel_orders_on_shutdown(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        assert len(deployment.otc.get_orders()) == 2

        # when
        keeper.shutdown()

        # then
        assert len(deployment.otc.get_orders()) == 0
    def test_should_use_specified_gas_price_for_all_transactions(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file} "
                                                  f"--gas-price 70000000000"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        start_block_number = deployment.web3.eth.blockNumber

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        keeper.shutdown()

        # then
        for block_number in range(start_block_number+1, deployment.web3.eth.blockNumber+1):
            for transaction in deployment.web3.eth.getBlock(block_number, full_transactions=True).transactions:
                assert transaction.gasPrice == 70000000000
    def test_should_not_create_any_orders_but_not_terminate_if_eth_balance_before_minimum(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.two_adjacent_bands_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file} "
                                                  f"--min-eth-balance 100.0"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        self.leave_only_some_eth(deployment, Wad.from_number(10.0))  # there is a 5.0 ETH block reward even in testrpc,
                                                                     # that's why `--min-eth-balance` is higher than 10

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 0
        assert not keeper.lifecycle.terminated_internally
    def test_should_support_config_files_with_variables(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.with_variables_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 1

        # and
        assert self.orders_by_token(deployment, deployment.gem)[0].maker == deployment.our_address
        assert self.orders_by_token(deployment, deployment.gem)[0].pay_amount == Wad.from_number(5.0)
        assert self.orders_by_token(deployment, deployment.gem)[0].pay_token == deployment.gem.address
        assert self.orders_by_token(deployment, deployment.gem)[0].buy_amount == Wad.from_number(520)
        assert self.orders_by_token(deployment, deployment.gem)[0].buy_token == deployment.sai.address
    def test_should_place_extra_order_only_if_order_brought_below_min(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        assert len(deployment.otc.get_orders()) == 2
        sai_order_id = self.orders_by_token(deployment, deployment.sai)[0].order_id

        # when
        deployment.otc.take(sai_order_id, Wad.from_number(20)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 2

        # when
        deployment.otc.take(sai_order_id, Wad.from_number(5)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 2

        # when
        deployment.otc.take(sai_order_id, Wad.from_number(1)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 3
        assert deployment.otc.get_orders()[2].pay_amount == Wad.from_number(26)
        assert deployment.otc.get_orders()[2].pay_token == deployment.sai.address
        assert deployment.otc.get_orders()[2].buy_amount == Wad(270833333333333333)
        assert deployment.otc.get_orders()[2].buy_token == deployment.gem.address
    def test_should_cancel_selected_sell_orders_to_bring_the_band_total_below_max_and_closest_to_it(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        assert len(deployment.otc.get_orders()) == 2

        # when [7.5+2.0 = 9.5]
        deployment.otc.make(deployment.gem.address, Wad.from_number(2), deployment.sai.address, Wad.from_number(208)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 3

        # when [9.5+0.5 = 10]
        deployment.otc.make(deployment.gem.address, Wad.from_number(0.5), deployment.sai.address, Wad.from_number(52)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 4

        # when [10+0.1 = 10.1] --> above max!
        deployment.otc.make(deployment.gem.address, Wad.from_number(0.1), deployment.sai.address, Wad.from_number(10.4)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 4
        assert reduce(Wad.__add__, map(lambda order: order.pay_amount, self.orders_by_token(deployment, deployment.gem)), Wad(0)) \
               == Wad.from_number(10.0)
Exemplo n.º 9
0
    def test_should_cancel_the_only_buy_order_and_place_a_new_one_if_above_max(
            self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} "
            f"--tub-address {deployment.tub.address} "
            f"--oasis-address {deployment.otc.address} "
            f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()

        # and
        # [one artificially created order above the max band threshold]
        deployment.otc.make(deployment.sai.address,
                            Wad.from_number(170), deployment.gem.address,
                            Wad.from_number(1.770805)).transact()

        # when
        self.synchronize_orders_twice(keeper)

        # then
        # [the artificial order gets cancelled, a new one gets created instead]
        assert len(deployment.otc.get_orders()) == 2
        assert self.orders_by_token(
            deployment, deployment.sai)[0].maker == deployment.our_address
        assert self.orders_by_token(
            deployment, deployment.sai)[0].pay_amount == Wad.from_number(75)
        assert self.orders_by_token(
            deployment, deployment.sai)[0].pay_token == deployment.sai.address
        assert self.orders_by_token(
            deployment,
            deployment.sai)[0].buy_amount == Wad.from_number(0.78125)
        assert self.orders_by_token(
            deployment, deployment.sai)[0].buy_token == deployment.gem.address
    def test_should_support_config_files_with_variables(
            self, deployment: Deployment, tmpdir: py.path.local):
        # given
        config_file = BandConfig.with_variables_config(tmpdir)

        # and
        keeper = EtherDeltaMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} --config {config_file}"
            f" --tub-address {deployment.tub.address}"
            f" --etherdelta-address {deployment.etherdelta.address}"
            f" --etherdelta-socket https://127.0.0.1:99999/"
            f" --order-age 3600 --eth-reserve 10"
            f" --min-eth-deposit 1 --min-sai-deposit 400"
            f" --cancel-on-shutdown --withdraw-on-shutdown"),
                                             web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)
        keeper.etherdelta_api.publish_order = MagicMock()

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        keeper.synchronize_orders(
        )  # ... first call is so it can made deposits
        keeper.synchronize_orders(
        )  # ... second call is so the actual orders can get placed

        # then
        assert len(self.orders(keeper)) == 1

        # and
        assert self.orders_by_token(
            keeper, EtherDelta.ETH_TOKEN)[0].maker == deployment.our_address
        assert self.orders_by_token(
            keeper, EtherDelta.ETH_TOKEN)[0].pay_amount == Wad.from_number(5.0)
        assert self.orders_by_token(
            keeper, EtherDelta.ETH_TOKEN)[0].pay_token == EtherDelta.ETH_TOKEN
        assert self.orders_by_token(
            keeper, EtherDelta.ETH_TOKEN)[0].buy_amount == Wad.from_number(520)
        assert self.orders_by_token(
            keeper,
            EtherDelta.ETH_TOKEN)[0].buy_token == deployment.sai.address
Exemplo n.º 11
0
    def test_should_cancel_all_orders_outside_bands(self,
                                                    deployment: Deployment,
                                                    tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} "
            f"--tub-address {deployment.tub.address} "
            f"--oasis-address {deployment.otc.address} "
            f"--price-feed tub "
            f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        assert len(deployment.otc.get_orders()) == 2

        # when
        deployment.otc.make(
            deployment.sai.address, Wad.from_number(5), deployment.gem.address,
            Wad.from_number(0.0538)).transact()  #price=92.936802973977695
        deployment.otc.make(deployment.sai.address,
                            Wad.from_number(5), deployment.gem.address,
                            Wad.from_number(0.0505)).transact()  #price=99.0
        deployment.otc.make(deployment.gem.address,
                            Wad.from_number(0.5), deployment.sai.address,
                            Wad.from_number(50.5)).transact()  #price=101
        deployment.otc.make(deployment.gem.address,
                            Wad.from_number(0.5), deployment.sai.address,
                            Wad.from_number(53.5)).transact()  #price=107
        assert len(deployment.otc.get_orders()) == 6
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 2
Exemplo n.º 12
0
    def setup_method(self):
        self.web3 = web3()
        self.our_address = our_address(self.web3)
        self.keeper_address = keeper_address(self.web3)
        self.other_address = other_address(self.web3)
        self.gal_address = gal_address(self.web3)
        self.mcd = mcd(self.web3)
        self.flapper = self.mcd.flapper
        self.flapper.approve(self.mcd.mkr.address, directly(from_address=self.other_address))

        self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} "
                                              f"--type flap "
                                              f"--from-block 1 "
                                              f"--bid-check-interval 0.05 "
                                              f"--model ./bogus-model.sh"), web3=self.web3)
        self.keeper.approve()

        mint_mkr(self.mcd.mkr, self.keeper_address, Wad.from_number(50000))
        mint_mkr(self.mcd.mkr, self.other_address, Wad.from_number(50000))
Exemplo n.º 13
0
    def test_should_bite_unsafe_cups_only(self, deployment: Deployment):
        # given
        keeper = BiteKeeper(args=args(
            f"--eth-from {deployment.web3.eth.defaultAccount} --tub-address {deployment.tub.address}"
        ),
                            web3=deployment.web3)

        # and
        deployment.tub.join(Wad.from_number(10)).transact()
        deployment.tub.mold_cap(Wad.from_number(100000)).transact()
        DSValue(web3=deployment.web3,
                address=deployment.tub.pip()).poke_with_int(
                    Wad.from_number(250).value).transact()

        # and
        deployment.tub.open().transact()
        deployment.tub.lock(1, Wad.from_number(4)).transact()
        deployment.tub.draw(1, Wad.from_number(1000)).transact()

        # and
        assert deployment.tub.safe(1)

        # when
        keeper.check_all_cups()

        # then
        assert deployment.tub.safe(1)
        assert deployment.tub.tab(1) == Wad.from_number(1000)

        # when
        DSValue(web3=deployment.web3,
                address=deployment.tub.pip()).poke_with_int(
                    Wad.from_number(150).value).transact()

        # and
        assert not deployment.tub.safe(1)

        # and
        keeper.check_all_cups()

        # then
        assert deployment.tub.safe(1)
        assert deployment.tub.tab(1) == Wad.from_number(0)
Exemplo n.º 14
0
    def test_should_cancel_all_orders_but_not_terminate_if_eth_balance_before_minimum(
            self, deployment: Deployment, tmpdir: py.path.local):
        # given
        config_file = BandConfig.two_adjacent_bands_config(tmpdir)

        # and
        keeper = EtherDeltaMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} --config {config_file}"
            f" --tub-address {deployment.tub.address}"
            f" --etherdelta-address {deployment.etherdelta.address}"
            f" --etherdelta-socket https://127.0.0.1:99999/"
            f" --order-age 3600 --eth-reserve 200"
            f" --min-eth-balance 100.0"
            f" --min-eth-deposit 1 --min-sai-deposit 400"),
                                             web3=deployment.web3)
        keeper.lifecycle = Web3Lifecycle(web3=keeper.web3)
        keeper.etherdelta_api.publish_order = MagicMock()

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        keeper.synchronize_orders(
        )  # ... first call is so it can made deposits
        keeper.synchronize_orders(
        )  # ... second call is so the actual orders can get placed

        # then
        assert len(self.orders(keeper)) == 2

        # when
        self.leave_only_some_eth(deployment, Wad.from_number(
            10.0))  # there is a 5.0 ETH block reward even in testrpc,
        # that's why `--min-eth-balance` is higher than 10

        # and
        keeper.synchronize_orders()

        # then
        assert len(self.orders(keeper)) == 0
        assert not keeper.lifecycle.terminated_internally
Exemplo n.º 15
0
    def create_keeper(self, exit_dai_on_shutdown: bool,
                      exit_gem_on_shutdown: bool):
        assert isinstance(exit_dai_on_shutdown, bool)
        assert isinstance(exit_gem_on_shutdown, bool)

        vat_dai_behavior = "" if exit_dai_on_shutdown else "--keep-dai-in-vat-on-exit"
        vat_gem_behavior = "" if exit_gem_on_shutdown else "--keep-gem-in-vat-on-exit"

        keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} "
                                         f"--type flop "
                                         f"--network testnet "
                                         f"{vat_dai_behavior} "
                                         f"{vat_gem_behavior} "
                                         f"--model ./bogus-model.sh"),
                               web3=self.web3)
        assert self.web3.eth.defaultAccount == self.keeper_address.address
        assert keeper.arguments.exit_dai_on_shutdown == exit_dai_on_shutdown
        keeper.startup()
        return keeper
Exemplo n.º 16
0
    def test_should_reload_config_file_if_changed(self, deployment: Deployment,
                                                  tmpdir: py.path.local):
        # given
        config_file = BandConfig.with_variables_config(tmpdir)

        # and
        keeper = EtherDeltaMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} --config {config_file}"
            f" --tub-address {deployment.tub.address}"
            f" --etherdelta-address {deployment.etherdelta.address}"
            f" --etherdelta-socket https://127.0.0.1:99999/"
            f" --order-age 3600 --eth-reserve 10"
            f" --min-eth-deposit 1 --min-sai-deposit 400"),
                                             web3=deployment.web3)
        keeper.lifecycle = Web3Lifecycle(web3=keeper.web3)
        keeper.etherdelta_api.publish_order = MagicMock()

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        keeper.synchronize_orders(
        )  # ... first call is so it can made deposits
        keeper.synchronize_orders(
        )  # ... second call is so the actual orders can get placed

        # then
        assert len(self.orders(keeper)) == 1

        # when
        second_config_file = BandConfig.sample_config(tmpdir)
        shutil.copyfile(second_config_file, config_file)

        # and
        keeper.synchronize_orders(
        )  # ... first call is so it can made deposits
        keeper.synchronize_orders(
        )  # ... second call is so the actual orders can get placed

        # then
        assert len(self.orders(keeper)) == 2
Exemplo n.º 17
0
    def test_should_cancel_selected_sell_orders_to_bring_the_band_total_below_max_and_closest_to_it(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Web3Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        assert len(deployment.otc.get_orders()) == 2

        # when [7.5+2.0 = 9.5]
        deployment.otc.make(deployment.gem.address, Wad.from_number(2), deployment.sai.address, Wad.from_number(208)).transact()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 3

        # when [9.5+0.5 = 10]
        deployment.otc.make(deployment.gem.address, Wad.from_number(0.5), deployment.sai.address, Wad.from_number(52)).transact()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 4

        # when [10+0.1 = 10.1] --> above max!
        deployment.otc.make(deployment.gem.address, Wad.from_number(0.1), deployment.sai.address, Wad.from_number(10.4)).transact()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 4
        assert reduce(Wad.__add__, map(lambda order: order.pay_amount, self.orders_by_token(deployment, deployment.gem)), Wad(0)) \
               == Wad.from_number(10.0)
    def test_should_not_do_anything_if_no_arbitrage_opportunities(
            self, deployment: Deployment):
        # given
        keeper = ArbitrageKeeper(args=args(
            f"--eth-from {deployment.our_address.address}"
            f" --tub-address {deployment.tub.address}"
            f" --tap-address {deployment.tap.address}"
            f" --oasis-address {deployment.otc.address}"
            f" --base-token {deployment.sai.address}"
            f" --min-profit 1.0 --max-engagement 1000.0"),
                                 web3=deployment.web3)

        DSValue(web3=deployment.web3,
                address=deployment.tub.pip()).poke_with_int(
                    Wad.from_number(500).value).transact()
        deployment.tap.mold_gap(Wad.from_number(1.05)).transact()

        # when
        keeper.approve()
        keeper.process_block()
Exemplo n.º 19
0
    def create_keeper(self, exit_dai_on_shutdown: bool, exit_gem_on_shutdown: bool):
        assert isinstance(exit_dai_on_shutdown, bool)
        assert isinstance(exit_gem_on_shutdown, bool)

        vat_dai_behavior = "" if exit_dai_on_shutdown else "--keep-dai-in-vat-on-exit"
        vat_gem_behavior = "" if exit_gem_on_shutdown else "--keep-gem-in-vat-on-exit"

        keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} "
                                         f"--type flip --ilk {self.collateral.ilk.name} "
                                         f"--from-block 1 "
                                         f"{vat_dai_behavior} "
                                         f"{vat_gem_behavior} "
                                         f"--model ./bogus-model.sh"), web3=self.web3)
        self.web3 = keeper.web3
        self.mcd = keeper.mcd
        assert self.web3.eth.defaultAccount == self.keeper_address.address
        assert keeper.arguments.exit_dai_on_shutdown == exit_dai_on_shutdown
        assert keeper.arguments.exit_gem_on_shutdown == exit_gem_on_shutdown
        keeper.startup()
        return keeper
Exemplo n.º 20
0
    def test_should_cancel_orders_on_shutdown_and_withdraw_if_asked_to_do_so(
            self, deployment: Deployment, tmpdir: py.path.local):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = EtherDeltaMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} --config {config_file}"
            f" --tub-address {deployment.tub.address}"
            f" --etherdelta-address {deployment.etherdelta.address}"
            f" --etherdelta-socket https://127.0.0.1:99999/"
            f" --order-age 3600 --eth-reserve 10"
            f" --min-eth-deposit 1 --min-sai-deposit 400"
            f" --cancel-on-shutdown --withdraw-on-shutdown"),
                                             web3=deployment.web3)
        keeper.lifecycle = Web3Lifecycle(web3=keeper.web3)
        keeper.etherdelta_api.publish_order = MagicMock()

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        keeper.synchronize_orders(
        )  # ... first call is so it can made deposits
        keeper.synchronize_orders(
        )  # ... second call is so the actual orders can get placed
        assert len(self.orders(keeper)) == 2

        # when
        keeper.shutdown()

        # then
        assert len(self.orders(keeper)) == 0

        # and
        assert deployment.etherdelta.balance_of(
            deployment.our_address) == Wad(0)
        assert deployment.etherdelta.balance_of_token(
            deployment.sai.address, deployment.our_address) == Wad(0)
Exemplo n.º 21
0
    def create_keeper(self, mocker, dai_target="all"):
        # Create a keeper
        mocker.patch("web3.net.Net.peer_count", return_value=1)
        self.keeper = AuctionKeeper(args=args(
            f"--eth-from {self.keeper_address} "
            f"--type flip --ilk ETH-C --bid-only "
            f"--vat-dai-target {dai_target} "
            f"--return-gem-interval 3 "
            f"--model ./bogus-model.sh"),
                                    web3=self.web3)
        assert self.web3.eth.defaultAccount == self.keeper_address.address
        self.web3 = self.keeper.web3
        self.mcd = self.keeper.mcd
        assert self.keeper.auctions
        # Changed the collateral to ETH-C because our testchain didn't have dust set for ETH-A or ETH-B
        self.collateral = self.keeper.collateral
        self.collateral.approve(self.keeper_address)

        self.thread = threading.Thread(target=self.keeper.main, daemon=True)
        self.thread.start()
        return self.keeper
Exemplo n.º 22
0
    def test_should_cancel_orders_owned_by_us(self, deployment: Deployment):
        # given
        keeper = OasisMarketMakerCancel(args=args(f"--eth-from {deployment.web3.eth.defaultAccount} "
                                             f"--oasis-address {deployment.otc.address}"),
                                        web3=deployment.web3)

        # and
        DSToken(web3=deployment.web3, address=deployment.gem.address).mint(Wad.from_number(1000)).transact()
        DSToken(web3=deployment.web3, address=deployment.sai.address).mint(Wad.from_number(1000)).transact()

        # and
        deployment.otc.approve([deployment.gem, deployment.sai], directly())
        deployment.otc.make(deployment.gem.address, Wad.from_number(10), deployment.sai.address, Wad.from_number(5)).transact()
        deployment.otc.make(deployment.sai.address, Wad.from_number(5), deployment.gem.address, Wad.from_number(12)).transact()
        assert len(deployment.otc.get_orders()) == 2

        # when
        keeper.main()

        # then
        assert len(deployment.otc.get_orders()) == 0
Exemplo n.º 23
0
    def setup_method(self):
        self.web3 = web3()
        self.our_address = our_address(self.web3)
        self.keeper_address = keeper_address(self.web3)
        self.other_address = other_address(self.web3)
        self.gal_address = gal_address(self.web3)
        self.mcd = mcd(self.web3)
        self.flopper = self.mcd.flopper
        self.flopper.approve(self.mcd.vat.address, approval_function=hope_directly(from_address=self.keeper_address))
        self.flopper.approve(self.mcd.vat.address, approval_function=hope_directly(from_address=self.other_address))

        self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} "
                                              f"--type flop "
                                              f"--network testnet "
                                              f"--model ./bogus-model.sh"), web3=self.web3)
        self.keeper.approve()

        reserve_dai(self.mcd, self.mcd.collaterals['ETH-C'], self.keeper_address, Wad.from_number(200.00000))
        reserve_dai(self.mcd, self.mcd.collaterals['ETH-C'], self.other_address, Wad.from_number(200.00000))

        self.sump = self.mcd.vow.sump()  # Rad
Exemplo n.º 24
0
    def test_default_gas_config(self, web3, keeper_address):
        keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} "
                                         f"--type flop --from-block 1 "
                                         f"--model ./bogus-model.sh"),
                               web3=web3)

        assert isinstance(keeper.gas_price, DynamicGasPrice)
        assert keeper.gas_price.initial_multiplier == 1.0
        assert keeper.gas_price.reactive_multiplier == 1.125
        assert keeper.gas_price.gas_maximum == default_max_gas * GWEI

        default_initial_gas = get_node_gas_price(web3)
        assert keeper.gas_price.get_gas_price(0) == default_initial_gas
        assert keeper.gas_price.get_gas_price(
            1 + every_secs) == default_initial_gas * 1.125
        assert keeper.gas_price.get_gas_price(
            1 + every_secs * 2) == default_initial_gas * 1.125**2
        assert keeper.gas_price.get_gas_price(
            1 + every_secs * 3) == default_initial_gas * 1.125**3
        assert keeper.gas_price.get_gas_price(every_secs *
                                              80) == default_max_gas * GWEI
Exemplo n.º 25
0
    def test_fixed_with_explicit_max(self, web3, keeper_address):
        keeper = AuctionKeeper(args=args(f"--eth-from {keeper_address} "
                                         f"--type flap "
                                         f"--fixed-gas 100 "
                                         f'--gas-maximum 4000 '
                                         f"--model ./bogus-model.sh"),
                               web3=web3)

        assert isinstance(keeper.gas_price, DynamicGasPrice)
        assert keeper.gas_price.fixed_gas == 100 * GWEI
        assert keeper.gas_price.reactive_multiplier == 1.125
        assert keeper.gas_price.gas_maximum == 4000 * GWEI

        assert keeper.gas_price.get_gas_price(0) == 100 * GWEI
        assert keeper.gas_price.get_gas_price(1 +
                                              every_secs) == 100 * GWEI * 1.125
        assert keeper.gas_price.get_gas_price(1 + every_secs *
                                              2) == 100 * GWEI * 1.125**2
        assert keeper.gas_price.get_gas_price(1 + every_secs *
                                              3) == 100 * GWEI * 1.125**3
        assert keeper.gas_price.get_gas_price(every_secs * 60) == 4000 * GWEI
Exemplo n.º 26
0
    def test_should_cancel_all_orders_but_not_terminate_if_eth_balance_below_minimum(
            self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.two_adjacent_bands_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} "
            f"--tub-address {deployment.tub.address} "
            f"--oasis-address {deployment.otc.address} "
            f"--buy-token-address {deployment.sai.address} "
            f"--sell-token-address {deployment.gem.address} "
            f"--price-feed tub "
            f"--config {config_file} "
            f"--min-eth-balance 100.0"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 2

        # when
        self.leave_only_some_eth(deployment, Wad.from_number(
            10.0))  # there is a 5.0 ETH block reward even in testrpc,
        # that's why `--min-eth-balance` is higher than 10

        # and
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 0
        assert not keeper.lifecycle.terminated_internally
Exemplo n.º 27
0
    def test_should_use_specified_gas_price_for_all_transactions(
            self, deployment: Deployment, tmpdir: py.path.local):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = EtherDeltaMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} --config {config_file}"
            f" --tub-address {deployment.tub.address}"
            f" --etherdelta-address {deployment.etherdelta.address}"
            f" --etherdelta-socket https://127.0.0.1:99999/"
            f" --order-age 3600 --eth-reserve 10"
            f" --min-eth-deposit 1 --min-sai-deposit 400"
            f" --cancel-on-shutdown"
            f" --gas-price 69000000000"),
                                             web3=deployment.web3)
        keeper.lifecycle = Web3Lifecycle(web3=keeper.web3)
        keeper.etherdelta_api.publish_order = MagicMock()

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        start_block_number = deployment.web3.eth.blockNumber

        # when
        keeper.approve()
        keeper.synchronize_orders(
        )  # ... first call is so it can made deposits
        keeper.synchronize_orders(
        )  # ... second call is so the actual orders can get placed
        keeper.shutdown()

        # then
        for block_number in range(start_block_number + 1,
                                  deployment.web3.eth.blockNumber + 1):
            for transaction in deployment.web3.eth.getBlock(
                    block_number, full_transactions=True).transactions:
                assert transaction.gasPrice == 69000000000
    def test_should_create_orders_in_multiple_bands(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.two_adjacent_bands_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 2

        # and
        assert self.orders_sorted(deployment.otc.get_orders())[0].maker == deployment.our_address
        assert self.orders_sorted(deployment.otc.get_orders())[0].pay_amount == Wad.from_number(7.5)
        assert self.orders_sorted(deployment.otc.get_orders())[0].pay_token == deployment.gem.address
        assert self.orders_sorted(deployment.otc.get_orders())[0].buy_amount == Wad.from_number(780)
        assert self.orders_sorted(deployment.otc.get_orders())[0].buy_token == deployment.sai.address

        # and
        assert self.orders_sorted(deployment.otc.get_orders())[1].maker == deployment.our_address
        assert self.orders_sorted(deployment.otc.get_orders())[1].pay_amount == Wad.from_number(9.5)
        assert self.orders_sorted(deployment.otc.get_orders())[1].pay_token == deployment.gem.address
        assert self.orders_sorted(deployment.otc.get_orders())[1].buy_amount == Wad.from_number(1026)
        assert self.orders_sorted(deployment.otc.get_orders())[1].buy_token == deployment.sai.address
    def test_should_create_orders_in_multiple_bands(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.two_adjacent_bands_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed eth_dai-tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 2

        # and
        assert self.orders_sorted(deployment.otc.get_orders())[0].maker == deployment.our_address
        assert self.orders_sorted(deployment.otc.get_orders())[0].pay_amount == Wad.from_number(7.5)
        assert self.orders_sorted(deployment.otc.get_orders())[0].pay_token == deployment.gem.address
        assert self.orders_sorted(deployment.otc.get_orders())[0].buy_amount == Wad.from_number(780)
        assert self.orders_sorted(deployment.otc.get_orders())[0].buy_token == deployment.sai.address

        # and
        assert self.orders_sorted(deployment.otc.get_orders())[1].maker == deployment.our_address
        assert self.orders_sorted(deployment.otc.get_orders())[1].pay_amount == Wad.from_number(9.5)
        assert self.orders_sorted(deployment.otc.get_orders())[1].pay_token == deployment.gem.address
        assert self.orders_sorted(deployment.otc.get_orders())[1].buy_amount == Wad.from_number(1026)
        assert self.orders_sorted(deployment.otc.get_orders())[1].buy_token == deployment.sai.address
Exemplo n.º 30
0
    def test_should_fail_to_operate_if_bands_overlap(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.bands_overlapping_invalid_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Web3Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()

        # expect
        with pytest.raises(Exception):
            self.synchronize_orders_twice(keeper)
Exemplo n.º 31
0
    def setup_class(cls):
        super().setup_class()
        assert cls.collateral.clipper
        assert not cls.collateral.flipper
        cls.keeper = AuctionKeeper(args=args(f"--eth-from {cls.keeper_address.address} "
                                              f"--type clip "
                                              f"--from-block 1 "
                                              f"--ilk {cls.collateral.ilk.name} "
                                              f"--model ./bogus-model.sh"), web3=cls.mcd.web3)
        cls.keeper.approve()

        # Clean up the urn used for bark testing such that it doesn't impact our flip tests
        assert get_collateral_price(cls.collateral) == Wad.from_number(200)
        if not repay_urn(cls.mcd, cls.collateral, cls.gal_address):
            liquidate_urn(cls.mcd, cls.collateral, cls.gal_address, cls.keeper_address)

        # approve another taker
        cls.collateral.approve(cls.other_address)
        cls.collateral.clipper.approve(cls.mcd.vat.address, hope_directly(from_address=cls.other_address))

        assert isinstance(cls.keeper.gas_price, DynamicGasPrice)
        cls.default_gas_price = cls.keeper.gas_price.get_gas_price(0)
Exemplo n.º 32
0
    def setup_method(self):
        self.web3 = web3()
        self.our_address = our_address(self.web3)
        self.keeper_address = keeper_address(self.web3)
        self.other_address = other_address(self.web3)
        self.gal_address = gal_address(self.web3)
        self.mcd = mcd(self.web3)
        self.flapper = self.mcd.flapper
        self.flapper.approve(self.mcd.mkr.address, directly(from_address=self.other_address))

        self.keeper = AuctionKeeper(args=args(f"--eth-from {self.keeper_address} "
                                              f"--type flap "
                                              f"--from-block 1 "
                                              f"--model ./bogus-model.sh"), web3=self.web3)
        self.keeper.approve()

        mint_mkr(self.mcd.mkr, self.keeper_address, Wad.from_number(50000))
        mint_mkr(self.mcd.mkr, 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)
Exemplo n.º 33
0
    def setup_method(self):
        self.web3 = Web3(HTTPProvider("http://localhost:8555"))
        self.web3.eth.defaultAccount = self.web3.eth.accounts[0]
        self.keeper_address = Address(self.web3.eth.defaultAccount)
        self.gal_address = Address(self.web3.eth.accounts[1])
        self.other_address = Address(self.web3.eth.accounts[2])

        # GemMock version of DSToken with push(bytes32, uint function) an hope(address)
        gem_abi = Contract._load_abi(__name__,
                                     '../lib/pymaker/tests/abi/GemMock.abi')
        gem_bin = Contract._load_bin(__name__,
                                     '../lib/pymaker/tests/abi/GemMock.bin')
        self.dai_addr = Contract._deploy(self.web3, gem_abi, gem_bin, [b'DAI'])
        self.dai = DSToken(web3=self.web3, address=self.dai_addr)
        self.dai.mint(Wad.from_number(10000000)).transact()
        self.dai.transfer(self.other_address,
                          Wad.from_number(1000000)).transact()
        self.mkr = DSToken.deploy(self.web3, 'MKR')
        self.flopper = Flopper.deploy(self.web3, self.dai.address,
                                      self.mkr.address)

        # so the Flopper can mint MKR
        dad = DSGuard.deploy(self.web3)
        dad.permit(self.flopper.address, self.mkr.address,
                   DSGuard.ANY).transact()
        self.mkr.set_authority(dad.address).transact()

        self.keeper = AuctionKeeper(args=args(
            f"--eth-from {self.keeper_address} "
            f"--flopper {self.flopper.address} "
            f"--model ./bogus-model.sh"),
                                    web3=self.web3)

        self.keeper.approve()

        self.model = MagicMock()
        self.model.get_stance = MagicMock(return_value=None)
        self.model_factory = self.keeper.auctions.model_factory
        self.model_factory.create_model = MagicMock(return_value=self.model)
Exemplo n.º 34
0
    def test_should_cancel_all_orders_but_not_terminate_if_config_file_becomes_invalid(
            self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} "
            f"--tub-address {deployment.tub.address} "
            f"--oasis-address {deployment.otc.address} "
            f"--buy-token-address {deployment.sai.address} "
            f"--sell-token-address {deployment.gem.address} "
            f"--price-feed tub "
            f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 2

        # when
        second_config_file = BandConfig.bands_overlapping_invalid_config(
            tmpdir)
        shutil.copyfile(second_config_file, config_file)

        # and
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 0
        assert not keeper.lifecycle.terminated_internally
Exemplo n.º 35
0
    def test_should_support_config_files_with_variables(
            self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.with_variables_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(
            f"--eth-from {deployment.our_address} "
            f"--tub-address {deployment.tub.address} "
            f"--oasis-address {deployment.otc.address} "
            f"--buy-token-address {deployment.sai.address} "
            f"--sell-token-address {deployment.gem.address} "
            f"--price-feed tub "
            f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # when
        keeper.approve()
        self.synchronize_orders_twice(keeper)

        # then
        assert len(deployment.otc.get_orders()) == 1

        # and
        assert self.orders_by_token(
            deployment, deployment.gem)[0].maker == deployment.our_address
        assert self.orders_by_token(
            deployment, deployment.gem)[0].pay_amount == Wad.from_number(5.0)
        assert self.orders_by_token(
            deployment, deployment.gem)[0].pay_token == deployment.gem.address
        assert self.orders_by_token(
            deployment, deployment.gem)[0].buy_amount == Wad.from_number(520)
        assert self.orders_by_token(
            deployment, deployment.gem)[0].buy_token == deployment.sai.address
    def test_should_cancel_the_only_sell_order_and_place_a_new_one_if_above_max(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()

        # and
        # [one artificially created order above the max band threshold]
        deployment.otc.make(deployment.gem.address, Wad.from_number(20), deployment.sai.address, Wad.from_number(2080)).transact()
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()

        # when
        self.synchronize_orders_twice(keeper)

        # then
        # [the artificial order gets cancelled, a new one gets created instead]
        assert len(deployment.otc.get_orders()) == 2
        assert self.orders_by_token(deployment, deployment.gem)[0].maker == deployment.our_address
        assert self.orders_by_token(deployment, deployment.gem)[0].pay_amount == Wad.from_number(7.5)
        assert self.orders_by_token(deployment, deployment.gem)[0].pay_token == deployment.gem.address
        assert self.orders_by_token(deployment, deployment.gem)[0].buy_amount == Wad.from_number(780)
        assert self.orders_by_token(deployment, deployment.gem)[0].buy_token == deployment.sai.address
    def test_should_use_gas_price_specified(self, deployment: Deployment):
        # given
        some_gas_price = 15000000000
        keeper = OasisMarketMakerCancel(args=args(f"--eth-from {deployment.web3.eth.defaultAccount} "
                                             f"--oasis-address {deployment.otc.address} "
                                             f"--gas-price {some_gas_price}"),
                                        web3=deployment.web3)

        # and
        DSToken(web3=deployment.web3, address=deployment.gem.address).mint(Wad.from_number(1000)).transact()
        DSToken(web3=deployment.web3, address=deployment.sai.address).mint(Wad.from_number(1000)).transact()

        # and
        deployment.otc.approve([deployment.gem, deployment.sai], directly())
        deployment.otc.make(deployment.sai.address, Wad.from_number(5), deployment.gem.address, Wad.from_number(12)).transact()
        assert len(deployment.otc.get_orders()) == 1

        # when
        keeper.main()

        # then
        assert len(deployment.otc.get_orders()) == 0
        assert deployment.web3.eth.getBlock('latest', True)['transactions'][0]['gasPrice'] == some_gas_price
Exemplo n.º 38
0
    def test_no_api_non_fixed(self, mcd, keeper_address):
        c = mcd.collaterals['ETH-A']

        reactive_multipler = 1.125 * 3

        keeper = AuctionKeeper(args=args(
            f"--eth-from {keeper_address} "
            f"--type flip "
            f"--from-block 1 "
            f"--ilk {c.ilk.name} "
            f"--gas-reactive-multiplier {reactive_multipler} "
            f"--model ./bogus-model.sh"),
                               web3=mcd.web3)
        initial_amount = get_node_gas_price(mcd.web3)
        assert keeper.gas_price.get_gas_price(0) == initial_amount
        assert keeper.gas_price.get_gas_price(
            1 + every_secs) == initial_amount * reactive_multipler
        assert keeper.gas_price.get_gas_price(
            1 + every_secs * 2) == initial_amount * reactive_multipler**2
        assert keeper.gas_price.get_gas_price(
            1 + every_secs * 3) == initial_amount * reactive_multipler**3
        assert keeper.gas_price.get_gas_price(every_secs *
                                              12) == default_max_gas * GWEI
Exemplo n.º 39
0
    def create_keeper(self, exit_system_coin_on_shutdown: bool,
                      exit_collateral_on_shutdown: bool):
        assert isinstance(exit_system_coin_on_shutdown, bool)
        assert isinstance(exit_collateral_on_shutdown, bool)

        safe_engine_system_coin_behavior = "" if exit_system_coin_on_shutdown else "--keep-system-coin-in-safe-engine-on-exit"
        safe_engine_collateral_behavior = "" if exit_collateral_on_shutdown else "--keep-collateral-in-safe-engine-on-exit"

        keeper = AuctionKeeper(args=args(
            f"--eth-from {self.keeper_address} "
            f"--type collateral --collateral-type {self.collateral.collateral_type.name} "
            f"--from-block 1 "
            f"{safe_engine_system_coin_behavior} "
            f"{safe_engine_collateral_behavior} "
            f"--model ./bogus-model.sh"),
                               web3=self.web3)
        self.web3 = keeper.web3
        self.geb = keeper.geb
        assert self.web3.eth.defaultAccount == self.keeper_address.address
        assert keeper.arguments.exit_system_coin_on_shutdown == exit_system_coin_on_shutdown
        assert keeper.arguments.exit_collateral_on_shutdown == exit_collateral_on_shutdown
        keeper.startup()
        return keeper
Exemplo n.º 40
0
    def create_keeper(self, mocker, system_coin_target="all"):
        # Create a keeper
        mocker.patch("web3.net.Net.peer_count", return_value=1)
        self.keeper = AuctionKeeper(args=args(
            f"--eth-from {self.keeper_address} "
            f"--type collateral --collateral-type ETH-B --bid-only "
            f"--safe-engine-system-coin-target {system_coin_target} "
            f"--return-collateral-interval 3 "
            f"--swap-collateral "
            f"--max-swap-slippage 0.00001 "
            f"--model ./bogus-model.sh"),
                                    web3=self.web3)
        assert self.web3.eth.defaultAccount == self.keeper_address.address
        self.web3 = self.keeper.web3
        self.geb = self.keeper.geb
        assert self.keeper.auctions
        # Changed the collateral to ETH-C because our testchain didn't have dust set for ETH-A or ETH-B
        self.collateral = self.keeper.collateral
        self.collateral.approve(self.keeper_address)

        self.thread = threading.Thread(target=self.keeper.main, daemon=True)
        self.thread.start()
        return self.keeper
Exemplo n.º 41
0
    def test_should_use_gas_price_specified(self, deployment: Deployment):
        # given
        some_gas_price = 15000000000
        keeper = OasisMarketMakerCancel(args=args(f"--eth-from {deployment.web3.eth.defaultAccount} "
                                             f"--oasis-address {deployment.otc.address} "
                                             f"--gas-price {some_gas_price}"),
                                        web3=deployment.web3)

        # and
        DSToken(web3=deployment.web3, address=deployment.gem.address).mint(Wad.from_number(1000)).transact()
        DSToken(web3=deployment.web3, address=deployment.sai.address).mint(Wad.from_number(1000)).transact()

        # and
        deployment.otc.approve([deployment.gem, deployment.sai], directly())
        deployment.otc.make(deployment.sai.address, Wad.from_number(5), deployment.gem.address, Wad.from_number(12)).transact()
        assert len(deployment.otc.get_orders()) == 1

        # when
        keeper.main()

        # then
        assert len(deployment.otc.get_orders()) == 0
        assert deployment.web3.eth.getBlock('latest', True)['transactions'][0]['gasPrice'] == some_gas_price
    def test_should_cancel_all_orders_outside_bands(self, deployment: Deployment, tmpdir):
        # given
        config_file = BandConfig.sample_config(tmpdir)

        # and
        keeper = OasisMarketMakerKeeper(args=args(f"--eth-from {deployment.our_address} "
                                                  f"--tub-address {deployment.tub.address} "
                                                  f"--oasis-address {deployment.otc.address} "
                                                  f"--buy-token-address {deployment.sai.address} "
                                                  f"--sell-token-address {deployment.gem.address} "
                                                  f"--price-feed tub "
                                                  f"--config {config_file}"),
                                        web3=deployment.web3)
        keeper.lifecycle = Lifecycle(web3=keeper.web3)

        # and
        self.mint_tokens(deployment)
        self.set_price(deployment, Wad.from_number(100))

        # and
        keeper.approve()
        self.synchronize_orders_twice(keeper)
        assert len(deployment.otc.get_orders()) == 2

        # when
        deployment.otc.make(deployment.sai.address, Wad.from_number(5), deployment.gem.address, Wad.from_number(0.0538)).transact() #price=92.936802973977695
        deployment.otc.make(deployment.sai.address, Wad.from_number(5), deployment.gem.address, Wad.from_number(0.0505)).transact() #price=99.0
        deployment.otc.make(deployment.gem.address, Wad.from_number(0.5), deployment.sai.address, Wad.from_number(50.5)).transact() #price=101
        deployment.otc.make(deployment.gem.address, Wad.from_number(0.5), deployment.sai.address, Wad.from_number(53.5)).transact() #price=107
        assert len(deployment.otc.get_orders()) == 6
        # and
        keeper.order_book_manager.wait_for_order_book_refresh()
        # and
        self.synchronize_orders_twice(keeper)
        # then
        assert len(deployment.otc.get_orders()) == 2