Exemple #1
0
 def __init__(self, log):
     self.maker = Address(log['args']['makerAddress'])
     self.fee_recipient = Address(log['args']['feeRecipientAddress'])
     self.sender = Address(log['args']['senderAddress'])
     self.pay_asset = Asset.deserialize(
         bytes_to_hexstring(log['args']['makerAssetData']))
     self.buy_asset = Asset.deserialize(
         bytes_to_hexstring(log['args']['takerAssetData']))
     self.order_hash = bytes_to_hexstring(log['args']['orderHash'])
     self.raw = log
Exemple #2
0
    def fill_order(self, order: Order, fill_buy_amount: Wad) -> Transact:
        """Fills an order.

        Args:
            order: The order to be filled.
            fill_buy_amount: The amount (in terms of `buy_token` of the original order) to be filled.

        Returns:
            A :py:class:`pyflex.Transact` instance, which can be used to trigger the transaction.
        """
        assert (isinstance(order, Order))
        assert (isinstance(fill_buy_amount, Wad))

        method_signature = self.web3.keccak(
            text=f"fillOrder({self.ORDER_INFO_TYPE},uint256,bytes)")[0:4]
        method_parameters = encode_single(
            f"({self.ORDER_INFO_TYPE},uint256,bytes)", [
                self._order_tuple(order), fill_buy_amount.value,
                hexstring_to_bytes(order.signature)
            ])

        request = bytes_to_hexstring(method_signature + method_parameters)

        return Transact(self, self.web3, self.abi, self.address,
                        self._contract, None, [request])
Exemple #3
0
 def __init__(self, log):
     self.sender = Address(log['args']['senderAddress'])
     self.maker = Address(log['args']['makerAddress'])
     self.taker = Address(log['args']['takerAddress'])
     self.fee_recipient = Address(log['args']['feeRecipientAddress'])
     self.pay_asset = Asset.deserialize(
         bytes_to_hexstring(log['args']['makerAssetData']))
     self.buy_asset = Asset.deserialize(
         bytes_to_hexstring(log['args']['takerAssetData']))
     self.filled_pay_amount = Wad(int(
         log['args']['makerAssetFilledAmount']))
     self.filled_buy_amount = Wad(int(
         log['args']['takerAssetFilledAmount']))
     self.paid_maker_fee = Wad(int(log['args']['makerFeePaid']))
     self.paid_taker_fee = Wad(int(log['args']['takerFeePaid']))
     self.order_hash = bytes_to_hexstring(log['args']['orderHash'])
     self.raw = log
Exemple #4
0
    def zrx_asset(self) -> str:
        """Get the asset data of the ZRX token contract associated with this `ExchangeV2` contract.

        Returns:
            The asset data of the `ZRX` token.
        """
        return str(
            bytes_to_hexstring(
                self._contract.functions.ZRX_ASSET_DATA().call()))
Exemple #5
0
    def __init__(self, value):
        if isinstance(value, str):
            assert (value.startswith('0x'))
            self.value = value

        elif isinstance(value, bytes):
            self.value = bytes_to_hexstring(value)

        else:
            raise Exception(f"Unable to create calldata from '{value}'")
Exemple #6
0
def eth_sign(message: bytes,
             web3: Web3,
             key=None,
             in_hexbytes=False,
             account=None):
    assert (isinstance(message, bytes))
    assert (isinstance(web3, Web3))

    local_account = _registered_accounts.get(
        (web3, Address(web3.eth.defaultAccount)))

    if local_account or (account is not None):

        if key is None:
            pkey = local_account.privateKey
        else:
            pkey = key

        start_time = time.time()
        start_clock = time.process_time()
        try:
            if in_hexbytes:
                message_hash = message
            else:
                message_hash = defunct_hash_message(primitive=message)
            signature = web3.eth.account.signHash(
                message_hash, private_key=pkey).signature.hex()
        finally:
            end_time = time.time()
            end_clock = time.process_time()

        logging.debug(
            f"Local signing took {end_time - start_time:.3f}s time, {end_clock - start_clock:.3f}s clock"
        )

        return signature

    else:
        signature = bytes_to_hexstring(
            web3.manager.request_blocking(
                "eth_sign",
                [web3.eth.defaultAccount,
                 encode_hex(message)],
            ))

        # for `EthereumJS TestRPC/v2.2.1/ethereum-js`
        if signature.endswith("00"):
            signature = signature[:-2] + "1b"

        if signature.endswith("01"):
            signature = signature[:-2] + "1c"

        return signature
Exemple #7
0
    def sign_order(self, order: Order) -> Order:
        """Signs an order so it can be submitted to the relayer.

        Order will be signed by the `web3.eth.defaultAccount` account.

        Args:
            order: Order you want to sign.

        Returns:
            Signed order. Copy of the order passed as a parameter with the `signature` field filled with signature.
        """
        assert (isinstance(order, Order))

        signature = eth_sign(hexstring_to_bytes(self.get_order_hash(order)),
                             self.web3)
        v, r, s = to_vrs(signature)

        signed_order = copy.copy(order)
        signed_order.signature = bytes_to_hexstring(bytes([v])) + \
                                 bytes_to_hexstring(r)[2:] + \
                                 bytes_to_hexstring(s)[2:] + \
                                 "03"  # EthSign
        return signed_order
Exemple #8
0
    def get_order_hash(self, order: Order) -> str:
        """Calculates hash of an order.

        Args:
            order: Order you want to calculate the hash of.

        Returns:
            Order hash as a hex string starting with `0x`.
        """
        assert (isinstance(order, Order))

        # the hash depends on the exchange contract address as well
        assert (order.exchange_contract_address == self.address)

        return bytes_to_hexstring(self._get_order_info(order)[0][1])
Exemple #9
0
    def _get_order_info(self, order):
        assert (isinstance(order, Order))

        method_signature = self.web3.keccak(
            text=f"getOrderInfo({self.ORDER_INFO_TYPE})")[0:4]
        method_parameters = encode_single(f"({self.ORDER_INFO_TYPE})",
                                          [self._order_tuple(order)])

        request = bytes_to_hexstring(method_signature + method_parameters)
        response = self.web3.eth.call({
            'to': self.address.address,
            'data': request
        })
        response_decoded = decode_single("((uint8,bytes32,uint256))", response)

        return response_decoded
Exemple #10
0
    def cancel_order(self, order: Order) -> Transact:
        """Cancels an order.

        Args:
            order: Order you want to cancel.

        Returns:
            A :py:class:`pyflex.Transact` instance, which can be used to trigger the transaction.
        """
        assert (isinstance(order, Order))

        method_signature = self.web3.keccak(
            text=f"cancelOrder({self.ORDER_INFO_TYPE})")[0:4]
        method_parameters = encode_single(f"({self.ORDER_INFO_TYPE})",
                                          [self._order_tuple(order)])

        request = bytes_to_hexstring(method_signature + method_parameters)

        return Transact(self, self.web3, self.abi, self.address,
                        self._contract, None, [request])
Exemple #11
0
    async def cancel_async(self, gas_price: GasPrice):
        assert isinstance(gas_price, GasPrice)
        initial_time = time.time()
        self.gas_price_last = self.current_gas
        self.tx_hashes.clear()

        if gas_price.get_gas_price(0) <= self.current_gas * 1.125:
            self.logger.warning(
                f"Recovery gas price is less than current gas price {self.current_gas}; "
                "cancellation will be deferred until the strategy produces an acceptable price."
            )

        while True:
            seconds_elapsed = int(time.time() - initial_time)
            gas_price_value = gas_price.get_gas_price(seconds_elapsed)
            if gas_price_value > self.gas_price_last * 1.125:
                self.gas_price_last = gas_price_value
                # Transaction lock isn't needed here, as we are replacing an existing nonce
                tx_hash = bytes_to_hexstring(
                    self.web3.eth.sendTransaction({
                        'from': self.address.address,
                        'to': self.address.address,
                        'gasPrice': gas_price_value,
                        'nonce': self.nonce,
                        'value': 0
                    }))
                self.tx_hashes.append(tx_hash)
                self.logger.info(
                    f"Attempting to cancel recovered tx with nonce={self.nonce}, "
                    f"gas_price={gas_price_value} (tx_hash={tx_hash})")

            for tx_hash in self.tx_hashes:
                receipt = self._get_receipt(tx_hash)
                if receipt:
                    self.logger.info(
                        f"{self.name()} was cancelled (tx_hash={tx_hash})")
                    return

            await asyncio.sleep(0.75)
Exemple #12
0
def test_bytes_to_hexstring():
    assert bytes_to_hexstring(bytes([0x00])) == '0x00'
    assert bytes_to_hexstring(bytes([0x01, 0x02, 0x03])) == '0x010203'
    assert bytes_to_hexstring(bytes([0xff, 0xff])) == '0xffff'
Exemple #13
0
 def format_parameter(parameter):
     if isinstance(parameter, bytes):
         return bytes_to_hexstring(parameter)
     else:
         return parameter