Ejemplo n.º 1
0
    def fill_or_kill_order(
        self,
        order: Order,
        taker_amount: int,
        signature: str,
        tx_params: Optional[TxParams] = None,
        view_only: bool = False,
    ) -> Union[HexBytes, bytes]:
        """Attemp to `fillOrder`, revert if fill is not exact amount.

        :param order: instance of :class:`zero_ex.order_utils.Order`
        :param taker_amount: integer taker amount in Wei (1 Wei is 10e-18 ETH)
        :param signature: str or hexstr or bytes of order hash signature
        :param tx_params: default None, :class:`TxParams` transaction params
        :param view_only: default False, boolean of whether to transact or
            view only

        :returns: transaction hash
        """
        assert_valid(order_to_jsdict(order, self.address), "/orderSchema")
        is_valid_signature(
            self._provider,
            generate_order_hash_hex(order, self.address),
            signature,
            order["makerAddress"],
        )
        # safeguard against fractional inputs
        taker_fill_amount = int(taker_amount)
        normalized_signature = bytes.fromhex(remove_0x_prefix(signature))
        func = self._exchange.functions.fillOrKillOrder(
            order, taker_fill_amount, normalized_signature)
        return self._invoke_function_call(func=func,
                                          tx_params=tx_params,
                                          view_only=view_only)
Ejemplo n.º 2
0
def test_is_valid_signature__signature_not_hex_string():
    """Test that passing a non-hex-string signature raises a ValueError."""
    with pytest.raises(ValueError):
        is_valid_signature(
            Web3.HTTPProvider("http://127.0.0.1:8545"),
            "0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
            + "0",
            "jjj",
            "0x5409ed021d9299bf6814279a6a1411a7e866a631",
        )
Ejemplo n.º 3
0
def test_is_valid_signature__signature_not_string():
    """Test that passng a non-string signature raises a TypeError."""
    with pytest.raises(TypeError):
        is_valid_signature(
            Web3.HTTPProvider("http://127.0.0.1:8545"),
            "powerchain6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
            + "0",
            123,
            "powerchain5409ed021d9299bf6814279a6a1411a7e866a631",
        )
Ejemplo n.º 4
0
def test_is_valid_signature__data_not_hex_string():
    """Test that giving non-hex-string `data` raises a ValueError."""
    with pytest.raises(ValueError):
        is_valid_signature(
            Web3.HTTPProvider("http://127.0.0.1:8545"),
            "jjj",
            "0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
            + "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
            + "225403",
            "0x5409ed021d9299bf6814279a6a1411a7e866a631",
        )
Ejemplo n.º 5
0
def test_is_valid_signature__signer_address_not_hex_string():
    """Test that giving a non-hex-str `signer_address` raises a ValueError."""
    with pytest.raises(ValueError):
        is_valid_signature(
            Web3.HTTPProvider("http://127.0.0.1:8545"),
            "0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
            + "0",
            "0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
            + "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
            + "225403",
            "jjj",
        )
Ejemplo n.º 6
0
def test_is_valid_signature__provider_wrong_type():
    """Test that giving a non-HTTPProvider raises a TypeError."""
    with pytest.raises(TypeError):
        is_valid_signature(
            123,
            "0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b"
            + "0",
            "0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
            + "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace"
            + "225403",
            "0x5409ed021d9299bf6814279a6a1411a7e866a631",
        )
Ejemplo n.º 7
0
def test_sign_hash_to_bytes_and_validate__golden_path():
    """Test the happy path through sign_hash_to_bytes()."""
    provider = Web3.HTTPProvider("http://127.0.0.1:8545")

    signing_address = Web3(  # pylint: disable=no-member
        provider
    ).geth.personal.listAccounts()[0]

    order_hash_hex = (
        "0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004"
    )

    signature = sign_hash_to_bytes(provider, signing_address, order_hash_hex)

    assert (
        signature
        == b"1b117902c86dfb95fe0d1badd983ee166ad259b27acb220174cbb4460d872871137feabdfe76e05924b484789f79af4ee7fa29ec006cedce1bbf369320d034e10b03"  # noqa: E501 (line too long)
    )

    is_valid = is_valid_signature(
        Web3.HTTPProvider("http://127.0.0.1:8545"),
        order_hash_hex,
        signature.decode("utf-8"),
        signing_address,
    )

    assert is_valid is True
Ejemplo n.º 8
0
def test_local_message_signer__sign_order():
    """Test signing order with the local_message_signer middleware"""
    expected_signature = (
        "0x1cd17d75b891accf16030c572a64cf9e7955de63bcafa5b084439cec630ade2d7"
        "c00f47a2f4d5b6a4508267bf4b8527100bd97cf1af9984c0a58e42d25b13f4f0a03")
    address = "0x5409ED021D9299bf6814279A6A1411A7e866A631"
    exchange = NETWORK_TO_ADDRESSES[NetworkId.GANACHE].exchange
    private_key = (
        "f2f48ee19680706196e2e339e5da3491186e0c4c5030670656b0e0164837257d")
    ganache = HTTPProvider("http://127.0.0.1:8545")
    web3_instance = Web3(ganache)
    web3_instance.middleware_onion.add(
        construct_local_message_signer(private_key))
    order = {
        "makerAddress": "0x0000000000000000000000000000000000000000",
        "takerAddress": "0x0000000000000000000000000000000000000000",
        "senderAddress": "0x0000000000000000000000000000000000000000",
        "feeRecipientAddress": "0x0000000000000000000000000000000000000000",
        "makerAssetData": (b"\x00") * 20,
        "takerAssetData": (b"\x00") * 20,
        "salt": 0,
        "makerFee": 0,
        "takerFee": 0,
        "makerAssetAmount": 0,
        "takerAssetAmount": 0,
        "expirationTimeSeconds": 0,
    }
    order_hash = generate_order_hash_hex(order, exchange)
    signature = sign_hash(ganache, to_checksum_address(address), order_hash)
    assert signature == expected_signature
    is_valid = is_valid_signature(ganache, order_hash, signature, address)[0]
    assert is_valid is True
Ejemplo n.º 9
0
    def fill_order(
        self,
        order: Order,
        taker_amount: int,
        signature: str,
        tx_params: Optional[TxParams] = None,
        view_only: bool = False,
    ) -> Union[HexBytes, bytes]:
        """Fill a signed order with given amount of taker asset.

        This is the most basic way to fill an order. All of the other methods
        call fillOrder under the hood with additional logic. This function
        will attempt to fill the amount specified by the caller. However, if
        the remaining fillable amount is less than the amount specified, the
        remaining amount will be filled. Partial fills are allowed when
        filling orders.

        See the specification docs for `fillOrder
        <https://github.com/0xProject/0x-protocol-specification/blob/master
        /v2/v2-specification.md#fillorder>`_.

        :param order: instance of :class:`zero_ex.order_utils.Order`
        :param taker_amount: integer taker amount in Wei (1 Wei is 10e-18 ETH)
        :param signature: str or hexstr or bytes of order hash signature
        :param tx_params: default None, :class:`TxParams` transaction params
        :param view_only: default False, boolean of whether to transact or
            view only

        :returns: transaction hash
        """
        assert_valid(order_to_jsdict(order, self.address), "/orderSchema")
        is_valid_signature(
            self._provider,
            generate_order_hash_hex(order, self.address),
            signature,
            order["makerAddress"],
        )
        # safeguard against fractional inputs
        taker_fill_amount = int(taker_amount)
        normalized_signature = bytes.fromhex(remove_0x_prefix(signature))
        func = self._exchange.functions.fillOrder(order, taker_fill_amount,
                                                  normalized_signature)
        return self._invoke_function_call(func=func,
                                          tx_params=tx_params,
                                          view_only=view_only)
Ejemplo n.º 10
0
def test_is_valid_signature__unsupported_sig_types():
    """Test that passing in a sig w/invalid type raises error.

    To induce this error, the last byte of the signature is tweaked from 03 to
    ff."""
    try:
        is_valid_signature(
            Web3.HTTPProvider("http://127.0.0.1:8545"),
            "powerchain6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222"
            + "b0",
            "powerchain1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351b"
            +
            "c3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace" +
            "225401",
            "powerchain5409ed021d9299bf6814279a6a1411a7e866a631",
        )
    except SignatureError as signature_error:
        assert (signature_error.errorCode ==
                SignatureErrorCodes.INVALID_LENGTH.value)
    else:
        pytest.fail("Expected exception")
def fix_signature(provider, signer_address, hash_hex, signature) -> str:
    valid_v_param_values = [27, 28]

    # HACK: There is no consensus on whether the signatureHex string should be
    # formatted as v + r + s OR r + s + v, and different clients (even
    # different versions of the same client) return the signature params in
    # different orders. In order to support all client implementations, we
    # parse the signature in both ways, and evaluate if either one is a valid
    # signature.  r + s + v is the most prevalent format from eth_sign, so we
    # attempt this first.

    ec_signature = _parse_signature_hex_as_rsv(signature)
    if ec_signature["v"] in valid_v_param_values:
        signature_as_vrst_hex = (
            _convert_ec_signature_to_vrs_hex(ec_signature) +
            _Constants.SignatureType.ETH_SIGN.value.to_bytes(
                1, byteorder="big").hex())

        (valid, _) = is_valid_signature(provider, hash_hex,
                                        signature_as_vrst_hex, signer_address)

        if valid is True:
            return signature_as_vrst_hex

    ec_signature = _parse_signature_hex_as_vrs(signature)
    if ec_signature["v"] in valid_v_param_values:
        signature_as_vrst_hex = (
            _convert_ec_signature_to_vrs_hex(ec_signature) +
            _Constants.SignatureType.ETH_SIGN.value.to_bytes(
                1, byteorder="big").hex())
        (valid, _) = is_valid_signature(provider, hash_hex,
                                        signature_as_vrst_hex, signer_address)

        if valid is True:
            return signature_as_vrst_hex

    raise RuntimeError(
        "Signature returned from web3 provider is in an unknown format." +
        " Attempted to parse as RSV and as VRS.")
Ejemplo n.º 12
0
def test_is_valid_signature__unsupported_sig_types():
    """Test that passing in a sig w/invalid type raises error.

    To induce this error, the last byte of the signature is tweaked from 03 to
    ff."""
    (is_valid, reason) = is_valid_signature(
        Web3.HTTPProvider("http://127.0.0.1:8545"),
        "0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0",
        "0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc334"
        + "0349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254ff",
        "0x5409ed021d9299bf6814279a6a1411a7e866a631",
    )
    assert is_valid is False
    assert reason == "SIGNATURE_UNSUPPORTED"