Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Add OrderValidator and WalletOrderValidator signature strategies to Exchange #1774

Merged
merged 18 commits into from
Apr 19, 2019

Conversation

dorothy-zbornak
Copy link
Contributor

@dorothy-zbornak dorothy-zbornak commented Apr 10, 2019

Description

This adds support for two new order signature strategies to the Exchange: SignatureType.OrderValidator and SignatureType.WalletOrderValidator.

The new signature callbacks are similar to the existing Validator and Wallet strategies, but instead of passing just a bytes32 orderHash to the validator's isValidSignature(), we also pass an Order order struct to the validating contract's isValidOrderSignature() function (see IWallet and IOrderValidator).

Here is a sample validator contract for use with either SignatureType.OrderValidator or SignatureType.WalletOrderValidator (they have identical function signatures):

pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;

contract OrderValidator {
    
    // 0x order structure
    struct Order {
        address makerAddress;
        address takerAddress;
        address feeRecipientAddress;
        address senderAddress;
        uint256 makerAssetAmount;
        uint256 takerAssetAmount;
        uint256 makerFee;
        uint256 takerFee;
        uint256 expirationTimeSeconds;
        uint256 salt;
        bytes makerAssetData;
        bytes takerAssetData;
    }

    /// @dev Validate an order AND signature.
    /// @param order The full order.
    /// @param orderHash The order hash.
    /// @param signature Signature data for the order.
    /// @return `true` if valid.
    function isValidOrderSignature(
        Order calldata order,
        bytes32 orderHash,
        bytes calldata signature
    )
        external 
        view
        returns (bool isValid)
    {
        // Validate the order
        // ...
        return true;
    }
}

Other notes:

  • Just like SignatureType.Validator and SignatureType.Wallet, the validator contract is called via staticall() and will fail if the validator contract attempts to update state.
  • OrderValidators must be registered for a maker ahead of time via setOrderValidatorApproval(), which is distinct from setSignatureValidatorApproval() used by Validator.
  • The public function isValidSignature() has been supplanted by isValidHashSignature() and
    isValidOrderSignature().
  • Transactions use isValidHashSignature(), so they do not support the new signature strategies (which wouldn't make sense anyway).

Testing instructions

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

  • Prefix PR title with [WIP] if necessary.
  • Add tests to cover changes as needed.
  • Update documentation as needed.
  • Add new entries to the relevant CHANGELOG.jsons.

@coveralls
Copy link

coveralls commented Apr 10, 2019

Coverage Status

Coverage decreased (-0.009%) to 84.342% when pulling 9d08d67 on feature/3.0/exchange/order-validator-signature into 07fe677 on 3.0.

@dorothy-zbornak dorothy-zbornak changed the title [WIP] Add SignatureType.OrderValidator support to Exchange Add SignatureType.OrderValidator support to Exchange Apr 15, 2019
Copy link
Member

@abandeali1 abandeali1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point we should also add the Wallet equivalent of this signature type, but that can be in a separate PR.

/// @return True if the address recovered from the provided signature matches the input signer address.
function validateOrderValidatorSignature(
Order memory order,
bytes32 orderHash,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orderHash and signerAddress both feel redundant to me since they can be derived from the order.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see an argument for keeping orderHash since it prevents duplication of the hash calculation, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, signerAddress can definitely go.

I see this as potentially supplanting the SignatureType.Validator scheme, so it's likely validators will want the orderHash anyway.

// Read the validator address from the signature.
address validatorAddress = signature.readAddress(signatureLength - 21);
// Ensure signer has approved validator.
if (!allowedValidators[signerAddress][validatorAddress]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the same mapping for both types of validators could be a bit of a security flaw. What if a user wants to use one of the validation functions but not the other? This is probably also an argument for separating the interfaces into 2 different contracts (I know I said otherwise earlier - sorry for the thrash).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in new version.

@dorothy-zbornak
Copy link
Contributor Author

At some point we should also add the Wallet equivalent of this signature type, but that can be in a separate PR.

I can do that in this one. The work is fairly similar. Stay tuned. 📺

@dorothy-zbornak dorothy-zbornak changed the title Add SignatureType.OrderValidator support to Exchange Add OrderValidator and WalletOrderValidator signature strategies to Exchange Apr 17, 2019
Copy link
Member

@abandeali1 abandeali1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small nits, then looks good to me!

/// @param signature Proof of signing.
/// @return Validity of signature.
function isValidOrderSignature(
LibOrder.Order calldata order,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised this actually compiles. Will have to check out the most recent version of Solidity :)

address signerAddress,
bytes memory signature
)
public
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is never actually used internally, right? We should make it external if not.

/// @param hash Any 32 byte hash.
/// @param signerAddress Address that should have signed the given hash.
/// @param hash Any 32-byte hash.
/// @param signerAddress Address that should have signed the.Signat given hash.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo

bytes32 hash,
address signerAddress,
bytes memory signature
)
public
view
returns (bool isValid)
{
SignatureType signatureType = readValidSignatureType(hash, signerAddress, signature);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'd default to putting any function calls with >2 arguments onto multiple lines.

view
returns (bool isValid)
{
SignatureType signatureType = readValidSignatureType(orderHash, signerAddress, signature);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

…public` because passing `calldata` to internal functions isn't supported.
@dorothy-zbornak dorothy-zbornak merged commit fdac439 into 3.0 Apr 19, 2019
abandeali1 pushed a commit that referenced this pull request Apr 22, 2019
…xchange (#1774)

* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
dorothy-zbornak added a commit that referenced this pull request May 6, 2019
…xchange (#1774)

* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
abandeali1 pushed a commit that referenced this pull request Jun 2, 2019
…xchange (#1774)

* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
abandeali1 pushed a commit that referenced this pull request Jun 7, 2019
…xchange (#1774)

* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
@dekz dekz added this to the v3 development milestone Jun 21, 2019
abandeali1 pushed a commit that referenced this pull request Jun 24, 2019
…xchange (#1774)

* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
abandeali1 pushed a commit that referenced this pull request Jul 24, 2019
…xchange (#1774)

* In `@0x/contracts-exchange`: Add `SignatureType.OrderValidator` support to contracts and refactor signature validation functions.

* In `@0x/types`: Add `SignatureType.OrderValidator` and `RevertReason.InappropriateSignature`.

* In `@0x/contracts-exchange`: Fix contracts and update tests for `SignatureType.OrderValidator`.

* Ran prettier/linter

* Update changelogs

* In `@0x/order-utils`: Add `SignatureOrderValidatorError` to `ExchangeRevertErrors`.

* In `@0x/contracts-exchange`: Add `SignatureOrderValidatorError` rich revert. Fix rebase issues. Rename `IValidator.isValidOrder` to `IValidator.isValidOrderSignature`.

* In `@0x/contracts-exchange`: Add revert test cases for `OrderValidator` signature type.

* In `@0x/order-utils`: Update changelog.

* In `@0x/contracts-exchange`: Split off `SignatureType.OrderValidator` scheme into its own interface and registry.

* In `@0x/types`: Add `SignatureType.WalletOrderValidator`.

* In `@0x/order-utils`: Add `SignatureWalletOrderValidatorError`.

* In `@0x/contracts-exchange`: Add `SignatureType.WalletOrderValidator` support.

* Ran prettier

* In `@0x/types`: Remove `RevertReason.WalletOrderValidator`.

* Update/fix changelogs in `@0x/contracts-exchange`, `@0x/order-utils`, and `@0x/types`.

* In `@0x/contracts-exchange`: Make `isValidOrderSignature` `external` instead of `public`.

* In `@0x/contracts-exchange`: Change `isValidOrderSignature` back to `public` because passing `calldata` to internal functions isn't supported.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants