Example #1
0
    def _convert_balance_to_wad(self, balance: dict, decimals: int) -> dict:
        wei_balance = float(balance['wei'])
        pending_balance = float(balance['pendingWei'])

        ## DyDx can have negative balances from native margin trading
        is_negative = False
        if wei_balance < 0:
            is_negative = True

        converted_balance = from_wei(abs(int(wei_balance)), 'ether')
        converted_pending_balance = from_wei(abs(int(pending_balance)),
                                             'ether')

        if decimals == 6:
            converted_balance = from_wei(abs(int(wei_balance)), 'mwei')
            converted_pending_balance = from_wei(abs(int(pending_balance)),
                                                 'mwei')

        # reconvert Wad to negative value if balance is negative
        if is_negative == True:
            converted_balance = converted_balance * -1

        # Handle the edge case where orders are filled but balance change is still pending
        if converted_balance > 0:
            balance['wad'] = Wad.from_number(
                converted_balance) - Wad.from_number(converted_pending_balance)
        else:
            balance['wad'] = Wad.from_number(
                converted_balance) + Wad.from_number(converted_pending_balance)

        return balance
Example #2
0
 def from_trade(pair, trade):
     return BinanceUsTrade(trade_id=str(trade['id']),
                           timestamp=trade['time'],
                           pair=pair,
                           is_sell=not trade['isBuyerMaker'],
                           price=Wad.from_number(trade['price']),
                           amount=Wad.from_number(trade['qty']))
Example #3
0
def test_local_accounts_register_key():
    # given
    # [that address is not recognized by ganache, this way we can be sure it's the local account being used for signing]
    web3 = Web3(HTTPProvider("http://localhost:8555"))
    web3.eth.defaultAccount = Address(
        '0x13314e21cd6d343ceb857073f3f6d9368919d1ef').address

    # and
    keyfile_path = pkg_resources.resource_filename(
        __name__, "accounts/4_0x13314e21cd6d343ceb857073f3f6d9368919d1ef.json")
    passfile_path = pkg_resources.resource_filename(__name__, "accounts/pass")
    register_key(web3, f"key_file={keyfile_path},pass_file={passfile_path}")

    # and
    # [as ganache does not know this address, we need to send some ETH to it first]
    eth_transfer(web3, Address(web3.eth.defaultAccount), Wad.from_number(100)) \
        .transact(from_address=Address(web3.eth.accounts[0]))

    # when
    # [we deploy some test contract and mint some tokens]
    token = DSToken.deploy(web3, 'XYZ', 'XYZ')
    token.mint(Wad.from_number(150000)).transact()

    # then
    # [these operations were successful]
    assert token.balance_of(Address(
        web3.eth.defaultAccount)) == Wad.from_number(150000)
Example #4
0
    def test_convert(self):
        # two
        chain_amount = Wad(20000)
        assert self.token.normalize_amount(chain_amount) == Wad.from_number(2)

        # three
        normalized_amount = Wad.from_number(3)
        assert self.token.unnormalize_amount(normalized_amount) == Wad(30000)
Example #5
0
 def from_all_list(pair, trade):
     return Trade(trade_id=trade['trade_id'],
                  timestamp=int(
                      dateutil.parser.parse(trade['time']).timestamp()),
                  pair=pair,
                  is_sell=True if trade['side'] == 'sell' else False,
                  price=Wad.from_number(trade['price']),
                  amount=Wad.from_number(trade['size']))
Example #6
0
 def create(item):
     return BinanceUsOrder(
         order_id=str(item['orderId']),
         pair=item['symbol'],
         is_sell=True if item['side'] == 'SELL' else False,
         price=Wad.from_number(item['price']),
         amount=Wad.from_number(item['origQty']),
         timestamp=item['time'])
Example #7
0
 def test_get_orders(self, mocker):
     instrument_id = "WETH-DAI"
     mocker.patch("dydx.client.Client.get_my_orders", side_effect=DydxMockServer.handle_get_orders)
     response = self.dydx.get_orders(instrument_id)
     assert (len(response) > 0)
     for order in response:
         assert(isinstance(order.is_sell, bool))
         assert(Wad(order.price) > Wad(0))
     TestDydx.check_orders(response)
 def test_get_orders(self, mocker):
     pair = "ETH-KRW"
     mocker.patch("requests.request", side_effect=self.binaceUsMockServer.handle_request)
     response = self.binance_us.get_orders(pair)
     assert (len(response) > 0)
     for order in response:
         assert (isinstance(order.is_sell, bool))
         assert (Wad(order.price) > Wad(0))
     TestBinanceUs.check_orders(response)
 def test_order_placement_and_cancellation(self, mocker):
     pair = "ETH-KRW"
     side = "ask"
     mocker.patch("requests.request", side_effect=self.binaceUsMockServer.handle_request)
     order_id = self.binance_us.place_order(pair, True, Wad.from_number(241700), Wad.from_number(10))
     assert (isinstance(order_id, str))
     assert (order_id is not None)
     cancel_result = self.binance_us.cancel_order(order_id, pair)
     assert (cancel_result == True)
Example #10
0
    def get_balances(self, pair: Pair):
        assert(isinstance(pair, Pair))

        token_buy = ERC20Token(web3=self.zrx_exchange.web3, address=Address(pair.buy_token_address))
        token_sell = ERC20Token(web3=self.zrx_exchange.web3, address=Address(pair.sell_token_address))
        our_address = Address(self.zrx_exchange.web3.eth.defaultAccount)

        return token_sell.balance_of(our_address) * Wad.from_number(10 ** (18 - pair.sell_token_decimals)), \
               token_buy.balance_of(our_address) * Wad.from_number(10 ** (18 - pair.buy_token_decimals))
Example #11
0
def test_direct_approval_should_not_approve_if_already_approved():
    # given
    global web3, our_address, second_address, token
    token.approve(second_address, Wad(2**248 + 17)).transact()

    # when
    directly()(token, second_address, "some-name")

    # then
    assert token.allowance_of(our_address, second_address) == Wad(2**248 + 17)
Example #12
0
    def get_exchange_rate(self) -> Wad:
        token_a_reserve = self.get_exchange_balance(self.token_a,
                                                    self.pair_address)
        token_b_reserve = self.get_exchange_balance(self.token_b,
                                                    self.pair_address)

        if token_a_reserve == Wad.from_number(
                0) or token_b_reserve == Wad.from_number(0):
            return Wad.from_number(0)
        else:
            return token_b_reserve / token_a_reserve
Example #13
0
    def _blockchain_to_wad(pair: Pair, amount: Wad, token_address: Address):
        assert(isinstance(pair, Pair))
        assert(isinstance(amount, Wad))
        assert(isinstance(token_address, Address))

        assert(token_address in [pair.buy_token_address, pair.sell_token_address])

        if token_address == pair.buy_token_address:
            return amount * Wad.from_number(10 ** (18 - pair.buy_token_decimals))

        elif token_address == pair.sell_token_address:
            return amount * Wad.from_number(10 ** (18 - pair.sell_token_decimals))
Example #14
0
    def add_liquidity(self, amount: Wad) -> Transact:
        assert (isinstance(amount, Wad))

        min_liquidity = Wad.from_number(0.5) * amount
        max_token = amount * self.get_exchange_rate() * Wad.from_number(
            1.00000001)

        return Transact(
            self, self.web3, self.abi, self.exchange, self._contract,
            'addLiquidity',
            [min_liquidity.value, max_token.value,
             self._deadline()], {'value': amount.value})
 def test_order(self):
     price = Wad.from_number(4.8765)
     amount = Wad.from_number(0.222)
     order = Order(
         order_id="153153",
         timestamp=int(time.time()),
         pair="ETH-KRW",
         is_sell=False,
         price=price,
         amount=amount
     )
     assert (order.price == order.sell_to_buy_price)
     assert (order.price == order.buy_to_sell_price)
Example #16
0
def test_via_tx_manager_approval_should_not_approve_if_already_approved():
    # given
    global web3, our_address, second_address, token
    tx = TxManager.deploy(web3)
    tx.execute([],
               [token.approve(second_address, Wad(2**248 + 19)).invocation()
                ]).transact()

    # when
    via_tx_manager(tx)(token, second_address, "some-name")

    # then
    assert token.allowance_of(tx.address, second_address) == Wad(2**248 + 19)
Example #17
0
    def from_message(trade, pair: str, market_info: dict) -> Trade:
        decimal_exponent = 18 - int(market_info['quoteCurrency']['decimals'])
        price = Wad.from_number(float(trade['price']) * 10**decimal_exponent)

        return Trade(trade_id=trade['uuid'],
                     timestamp=int(
                         dateutil.parser.parse(
                             trade['createdAt']).timestamp()),
                     pair=trade["market"],
                     is_sell=True if trade['side'] == 'SELL' else False,
                     price=price,
                     amount=Wad.from_number(
                         from_wei(abs(int(float(trade['amount']))), 'ether')))
Example #18
0
    def from_message(item: list, pair: str, market_info: dict) -> Order:
        decimal_exponent = 18 - int(market_info['quoteCurrency']['decimals'])
        price = Wad.from_number(float(item['price']) * 10**decimal_exponent)

        return Order(order_id=item['id'],
                     timestamp=int(
                         dateutil.parser.parse(item['createdAt']).timestamp()),
                     pair=pair,
                     is_sell=True if item['side'] == 'SELL' else False,
                     price=price,
                     amount=Wad.from_number(
                         from_wei(abs(int(float(item['baseAmount']))),
                                  'ether')))
Example #19
0
    def get_amounts_out(self, amount_in: Wad,
                        tokens: List[Token]) -> List[Wad]:
        """ Calculate maximum output amount of a given input.

        Desired amount_in must be less than available liquidity or call will fail.

        Args:
            amounts_in: Desired amount of tokens out.
            tokens: List of tokens used to form a path for swap and normalize amounts for token decimals
        Returns:
            A list of uint256 reserve amounts required.
        """
        assert (isinstance(amount_in, Wad))
        assert (isinstance(tokens, List))

        token_addresses = list(map(lambda token: token.address.address,
                                   tokens))
        amounts = self._router_contract.functions.getAmountsOut(
            amount_in.value, token_addresses).call()
        wad_amounts = list(
            map(lambda amount: Wad.from_number(Web3.fromWei(amount, 'ether')),
                amounts))

        for index, token in enumerate(tokens):
            wad_amounts[index] = token.normalize_amount(wad_amounts[index])

        return wad_amounts
Example #20
0
    def get_our_exchange_balance(self, token: Token,
                                 pair_address: Address) -> Wad:
        assert (isinstance(token, Token))
        assert (isinstance(pair_address, Address))

        if self.is_new_pool:
            return Wad.from_number(0)

        current_liquidity = self.get_current_liquidity()
        if current_liquidity == Wad.from_number(0):
            return Wad.from_number(0)

        total_liquidity = self.get_total_liquidity()
        exchange_balance = self.get_exchange_balance(token, pair_address)

        return current_liquidity * exchange_balance / total_liquidity
Example #21
0
    def main(self):
        self.startup()

        pending_txes = get_pending_transactions(web3)
        pprint(
            list(
                map(lambda t: f"{t.name()} with gas {t.current_gas}",
                    pending_txes)))

        if len(pending_txes) > 0:
            while len(pending_txes) > 0:
                pending_txes[0].cancel(gas_price=increasing_gas)
                # After the synchronous cancel, wait to see if subsequent transactions get mined
                time.sleep(15)
                pending_txes = get_pending_transactions(web3)
        else:
            logging.info(
                f"No pending transactions were found; submitting {stuck_txes_to_submit}"
            )
            for i in range(1, stuck_txes_to_submit + 1):
                self._run_future(
                    weth.deposit(Wad(i)).transact_async(
                        gas_price=FixedGasPrice(int(0.4 * i * GWEI))))
            time.sleep(2)

        self.shutdown()
Example #22
0
    def get_orders(self, pair: Pair, zrx_orders: list) -> List[Order]:
        assert (isinstance(pair, Pair))
        assert (isinstance(zrx_orders, list))

        result = []

        for zrx_order in zrx_orders:
            is_sell = zrx_order.buy_token == pair.buy_token_address and zrx_order.pay_token == pair.sell_token_address
            is_buy = zrx_order.buy_token == pair.sell_token_address and zrx_order.pay_token == pair.buy_token_address

            if is_sell or is_buy:
                amount = zrx_order.remaining_sell_amount if is_sell else zrx_order.remaining_buy_amount
                price = zrx_order.buy_to_sell_price if is_sell else zrx_order.sell_to_buy_price

                result.append(
                    Order(order_id=zrx_order.order_id,
                          is_sell=is_sell,
                          price=price /
                          Wad.from_number(10**(pair.buy_token_decimals -
                                               pair.sell_token_decimals)),
                          amount=self._blockchain_to_wad(
                              pair, amount, pair.sell_token_address),
                          zrx_order=zrx_order))

        return result
Example #23
0
 def check_sync_transaction_still_works(self):
     balance_before = self.geb.safe_engine.token_collateral(
         self.collateral_type, self.keeper_address)
     amount = Wad.from_number(0.01)
     assert self.collateral.adapter.join(self.keeper_address,
                                         amount).transact()
     balance_after = self.geb.safe_engine.token_collateral(
         self.collateral_type, self.keeper_address)
     assert balance_before + amount == balance_after
Example #24
0
def test_direct_approval():
    # given
    global web3, our_address, second_address, token

    # when
    directly()(token, second_address, "some-name")

    # then
    assert token.allowance_of(our_address, second_address) == Wad(2**256 - 1)
Example #25
0
def test_via_tx_manager_approval():
    # given
    global web3, our_address, second_address, token
    tx = TxManager.deploy(web3)

    # when
    via_tx_manager(tx)(token, second_address, "some-name")

    # then
    assert token.allowance_of(tx.address, second_address) == Wad(2**256 - 1)
Example #26
0
 def check_async_transaction_still_works(self):
     balance_before = self.geb.safe_engine.token_collateral(
         self.collateral_type, self.keeper_address)
     amount = Wad.from_number(0.01)
     AuctionKeeper._run_future(
         self.collateral.adapter.exit(self.keeper_address,
                                      amount).transact_async())
     wait_for_other_threads()
     balance_after = self.geb.safe_engine.token_collateral(
         self.collateral_type, self.keeper_address)
     assert balance_before - amount == balance_after
Example #27
0
    def test_replace_async_transaction(self):
        balance_before = self.geb.safe_engine.token_collateral(
            self.collateral_type, self.keeper_address)
        self.start_ignoring_transactions()
        amount1 = Wad.from_number(0.11)
        tx1 = self.collateral.adapter.join(self.keeper_address, amount1)
        AuctionKeeper._run_future(tx1.transact_async(gas_price=self.gas))
        self.end_ignoring_transactions()

        amount2 = Wad.from_number(0.14)
        tx2 = self.collateral.adapter.join(self.keeper_address, amount2)
        AuctionKeeper._run_future(tx2.transact_async(replace=tx1))

        # Wait for async tx threads to exit normally (should consider doing this after every async test)
        wait_for_other_threads()
        balance_after = self.geb.safe_engine.token_collateral(
            self.collateral_type, self.keeper_address)
        assert balance_before + amount2 == balance_after

        self.check_sync_transaction_still_works()
        self.check_async_transaction_still_works()
Example #28
0
def test_direct_approval_should_obey_from_address():
    # given
    global web3, our_address, second_address, third_address, token
    # and
    # [there is already approval from the `defaultAccount`]
    # [so that we make sure we check for the existing approval properly]
    directly()(token, second_address, "some-name")

    # when
    directly(from_address=third_address)(token, second_address, "some-name")

    # then
    assert token.allowance_of(third_address, second_address) == Wad(2**256 - 1)
Example #29
0
    def test_min_amount(self):
        assert self.token.min_amount == Wad.from_number(0.0001)
        assert float(self.token.min_amount) == 0.0001
        assert self.token.unnormalize_amount(self.token.min_amount) == Wad(1)

        assert Wad.from_number(0.0004) > self.token.min_amount
        assert Wad.from_number(0.00005) < self.token.min_amount

        assert self.token.unnormalize_amount(
            Wad.from_number(0.0006)) > self.token.unnormalize_amount(
                self.token.min_amount)
        assert self.token.unnormalize_amount(
            Wad.from_number(0.00007)) < self.token.unnormalize_amount(
                self.token.min_amount)
        assert self.token.unnormalize_amount(
            Wad.from_number(0.00008)) == Wad(0)
Example #30
0
    def test_ignore_sync_transaction(self):
        balance_before = self.geb.safe_engine.token_collateral(
            self.collateral_type, self.keeper_address)

        self.start_ignoring_sync_transactions()
        assert self.collateral.adapter.join(self.keeper_address,
                                            Wad.from_number(0.2)).transact()
        self.end_ignoring_sync_transactions()

        balance_after = self.geb.safe_engine.token_collateral(
            self.collateral_type, self.keeper_address)
        assert balance_before == balance_after

        self.check_sync_transaction_still_works()
        self.check_async_transaction_still_works()