diff --git a/contracts/coordinator/CHANGELOG.json b/contracts/coordinator/CHANGELOG.json index 1d4ce3877d..9aae87f350 100644 --- a/contracts/coordinator/CHANGELOG.json +++ b/contracts/coordinator/CHANGELOG.json @@ -4,6 +4,14 @@ "changes": [ { "note": "Created Coordinator package" + }, + { + "note": "Use separate EIP712 domains for transactions and approvals", + "pr": 1705 + }, + { + "note": "Add `SignatureType.Invalid`", + "pr": 1705 } ] } diff --git a/contracts/coordinator/contracts/src/MixinCoordinatorApprovalVerifier.sol b/contracts/coordinator/contracts/src/MixinCoordinatorApprovalVerifier.sol index b0d72f73fd..408fa69b4e 100644 --- a/contracts/coordinator/contracts/src/MixinCoordinatorApprovalVerifier.sol +++ b/contracts/coordinator/contracts/src/MixinCoordinatorApprovalVerifier.sol @@ -125,14 +125,14 @@ contract MixinCoordinatorApprovalVerifier is // Hash approval message and recover signer address bytes32 approvalHash = getCoordinatorApprovalHash(approval); address approvalSignerAddress = getSignerAddress(approvalHash, approvalSignatures[i]); - + // Add approval signer to list of signers approvalSignerAddresses = approvalSignerAddresses.append(approvalSignerAddress); } - + // Ethereum transaction signer gives implicit signature of approval approvalSignerAddresses = approvalSignerAddresses.append(tx.origin); - + uint256 ordersLength = orders.length; for (uint256 i = 0; i != ordersLength; i++) { // Do not check approval if the order's senderAddress is null diff --git a/contracts/coordinator/contracts/src/MixinSignatureValidator.sol b/contracts/coordinator/contracts/src/MixinSignatureValidator.sol index 5134ce5772..6885605c06 100644 --- a/contracts/coordinator/contracts/src/MixinSignatureValidator.sol +++ b/contracts/coordinator/contracts/src/MixinSignatureValidator.sol @@ -59,6 +59,17 @@ contract MixinSignatureValidator is if (signatureType == SignatureType.Illegal) { revert("SIGNATURE_ILLEGAL"); + // Always invalid signature. + // Like Illegal, this is always implicitly available and therefore + // offered explicitly. It can be implicitly created by providing + // a correctly formatted but incorrect signature. + } else if (signatureType == SignatureType.Invalid) { + require( + signature.length == 0, + "LENGTH_0_REQUIRED" + ); + revert("SIGNATURE_INVALID"); + // Signature using EIP712 } else if (signatureType == SignatureType.EIP712) { require( diff --git a/contracts/coordinator/contracts/src/libs/LibCoordinatorApproval.sol b/contracts/coordinator/contracts/src/libs/LibCoordinatorApproval.sol index a8f11074ec..7f9ec9b134 100644 --- a/contracts/coordinator/contracts/src/libs/LibCoordinatorApproval.sol +++ b/contracts/coordinator/contracts/src/libs/LibCoordinatorApproval.sol @@ -50,7 +50,7 @@ contract LibCoordinatorApproval is view returns (bytes32 approvalHash) { - approvalHash = hashEIP712Message(hashCoordinatorApproval(approval)); + approvalHash = hashEIP712CoordinatorMessage(hashCoordinatorApproval(approval)); return approvalHash; } @@ -79,7 +79,7 @@ contract LibCoordinatorApproval is assembly { // Compute hash of transaction signature let transactionSignatureHash := keccak256(add(transactionSignature, 32), mload(transactionSignature)) - + // Load free memory pointer let memPtr := mload(64) diff --git a/contracts/coordinator/contracts/src/libs/LibEIP712Domain.sol b/contracts/coordinator/contracts/src/libs/LibEIP712Domain.sol index 0db46911ec..14502eb897 100644 --- a/contracts/coordinator/contracts/src/libs/LibEIP712Domain.sol +++ b/contracts/coordinator/contracts/src/libs/LibEIP712Domain.sol @@ -18,17 +18,27 @@ pragma solidity ^0.5.5; +import "./LibConstants.sol"; -contract LibEIP712Domain { + +contract LibEIP712Domain is + LibConstants +{ // EIP191 header for EIP712 prefix string constant internal EIP191_HEADER = "\x19\x01"; - // EIP712 Domain Name value - string constant internal EIP712_DOMAIN_NAME = "0x Protocol Coordinator"; + // EIP712 Domain Name value for the Coordinator + string constant internal EIP712_COORDINATOR_DOMAIN_NAME = "0x Protocol Coordinator"; - // EIP712 Domain Version value - string constant internal EIP712_DOMAIN_VERSION = "1.0.0"; + // EIP712 Domain Version value for the Coordinator + string constant internal EIP712_COORDINATOR_DOMAIN_VERSION = "1.0.0"; + + // EIP712 Domain Name value for the Exchange + string constant internal EIP712_EXCHANGE_DOMAIN_NAME = "0x Protocol"; + + // EIP712 Domain Version value for the Exchange + string constant internal EIP712_EXCHANGE_DOMAIN_VERSION = "2"; // Hash of the EIP712 Domain Separator Schema bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked( @@ -39,36 +49,70 @@ contract LibEIP712Domain { ")" )); - // Hash of the EIP712 Domain Separator data + // Hash of the EIP712 Domain Separator data for the Coordinator // solhint-disable-next-line var-name-mixedcase - bytes32 public EIP712_DOMAIN_HASH; + bytes32 public EIP712_COORDINATOR_DOMAIN_HASH; + + // Hash of the EIP712 Domain Separator data for the Exchange + // solhint-disable-next-line var-name-mixedcase + bytes32 public EIP712_EXCHANGE_DOMAIN_HASH; constructor () public { - EIP712_DOMAIN_HASH = keccak256(abi.encodePacked( + EIP712_COORDINATOR_DOMAIN_HASH = keccak256(abi.encodePacked( EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH, - keccak256(bytes(EIP712_DOMAIN_NAME)), - keccak256(bytes(EIP712_DOMAIN_VERSION)), + keccak256(bytes(EIP712_COORDINATOR_DOMAIN_NAME)), + keccak256(bytes(EIP712_COORDINATOR_DOMAIN_VERSION)), uint256(address(this)) )); + + EIP712_EXCHANGE_DOMAIN_HASH = keccak256(abi.encodePacked( + EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH, + keccak256(bytes(EIP712_EXCHANGE_DOMAIN_NAME)), + keccak256(bytes(EIP712_EXCHANGE_DOMAIN_VERSION)), + uint256(address(EXCHANGE)) + )); } - /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain. + /// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain + /// of this contract. /// @param hashStruct The EIP712 hash struct. /// @return EIP712 hash applied to this EIP712 Domain. - function hashEIP712Message(bytes32 hashStruct) + function hashEIP712CoordinatorMessage(bytes32 hashStruct) internal view returns (bytes32 result) { - bytes32 eip712DomainHash = EIP712_DOMAIN_HASH; + return hashEIP712Message(EIP712_COORDINATOR_DOMAIN_HASH, hashStruct); + } + /// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain + /// of the Exchange contract. + /// @param hashStruct The EIP712 hash struct. + /// @return EIP712 hash applied to the Exchange EIP712 Domain. + function hashEIP712ExchangeMessage(bytes32 hashStruct) + internal + view + returns (bytes32 result) + { + return hashEIP712Message(EIP712_EXCHANGE_DOMAIN_HASH, hashStruct); + } + + /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash. + /// @param eip712DomainHash Hash of the domain domain separator data. + /// @param hashStruct The EIP712 hash struct. + /// @return EIP712 hash applied to the Exchange EIP712 Domain. + function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct) + internal + pure + returns (bytes32 result) + { // Assembly for more efficient computing: // keccak256(abi.encodePacked( // EIP191_HEADER, // EIP712_DOMAIN_HASH, - // hashStruct + // hashStruct // )); assembly { diff --git a/contracts/coordinator/contracts/src/libs/LibZeroExTransaction.sol b/contracts/coordinator/contracts/src/libs/LibZeroExTransaction.sol index dd25f12ff2..8d388a55a2 100644 --- a/contracts/coordinator/contracts/src/libs/LibZeroExTransaction.sol +++ b/contracts/coordinator/contracts/src/libs/LibZeroExTransaction.sol @@ -48,8 +48,8 @@ contract LibZeroExTransaction is view returns (bytes32 transactionHash) { - // Note: this transaction hash will differ from the hash produced by the Exchange contract because it utilizes a different domain hash. - transactionHash = hashEIP712Message(hashZeroExTransaction(transaction)); + // Hash the transaction with the domain separator of the Exchange contract. + transactionHash = hashEIP712ExchangeMessage(hashZeroExTransaction(transaction)); return transactionHash; } @@ -77,7 +77,7 @@ contract LibZeroExTransaction is assembly { // Compute hash of data let dataHash := keccak256(add(data, 32), mload(data)) - + // Load free memory pointer let memPtr := mload(64) diff --git a/contracts/coordinator/contracts/src/mixins/MSignatureValidator.sol b/contracts/coordinator/contracts/src/mixins/MSignatureValidator.sol index df75435e4c..d673f2827b 100644 --- a/contracts/coordinator/contracts/src/mixins/MSignatureValidator.sol +++ b/contracts/coordinator/contracts/src/mixins/MSignatureValidator.sol @@ -27,8 +27,9 @@ contract MSignatureValidator is // Allowed signature types. enum SignatureType { Illegal, // 0x00, default value - EIP712, // 0x01 - EthSign, // 0x02 - NSignatureTypes // 0x03, number of signature types. Always leave at end. + Invalid, // 0x01 + EIP712, // 0x02 + EthSign, // 0x03 + NSignatureTypes // 0x04, number of signature types. Always leave at end. } } diff --git a/contracts/coordinator/contracts/test/TestLibs.sol b/contracts/coordinator/contracts/test/TestLibs.sol index 789fd25485..8c615a5d42 100644 --- a/contracts/coordinator/contracts/test/TestLibs.sol +++ b/contracts/coordinator/contracts/test/TestLibs.sol @@ -19,14 +19,22 @@ pragma solidity ^0.5.5; pragma experimental "ABIEncoderV2"; +import "../src/libs/LibConstants.sol"; import "../src/libs/LibCoordinatorApproval.sol"; import "../src/libs/LibZeroExTransaction.sol"; +// solhint-disable no-empty-blocks contract TestLibs is + LibConstants, LibCoordinatorApproval, LibZeroExTransaction { + constructor (address _exchange) + public + LibConstants(_exchange) + {} + /// @dev Calculated the EIP712 hash of the Coordinator approval mesasage using the domain separator of this contract. /// @param approval Coordinator approval message containing the transaction hash, transaction signature, and expiration of the approval. /// @return EIP712 hash of the Coordinator approval message with the domain separator of this contract. @@ -39,9 +47,9 @@ contract TestLibs is return approvalHash; } - /// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of this contract. + /// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract. /// @param transaction 0x transaction containing salt, signerAddress, and data. - /// @return EIP712 hash of the transaction with the domain separator of this contract. + /// @return EIP712 hash of the transaction with the domain separator of the Exchange contract. function publicGetTransactionHash(ZeroExTransaction memory transaction) public view diff --git a/contracts/coordinator/contracts/test/TestMixins.sol b/contracts/coordinator/contracts/test/TestMixins.sol index e547b19fd5..cdadce171c 100644 --- a/contracts/coordinator/contracts/test/TestMixins.sol +++ b/contracts/coordinator/contracts/test/TestMixins.sol @@ -19,12 +19,19 @@ pragma solidity ^0.5.5; pragma experimental "ABIEncoderV2"; +import "../src/libs/LibConstants.sol"; import "../src/MixinSignatureValidator.sol"; import "../src/MixinCoordinatorApprovalVerifier.sol"; // solhint-disable no-empty-blocks contract TestMixins is + LibConstants, MixinSignatureValidator, MixinCoordinatorApprovalVerifier -{} +{ + constructor (address _exchange) + public + LibConstants(_exchange) + {} +} diff --git a/contracts/coordinator/test/libs.ts b/contracts/coordinator/test/libs.ts index 4833a70850..85291d3583 100644 --- a/contracts/coordinator/test/libs.ts +++ b/contracts/coordinator/test/libs.ts @@ -1,5 +1,6 @@ -import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; +import { addressUtils, chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; +import { transactionHashUtils } from '@0x/order-utils'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -11,6 +12,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); describe('Libs tests', () => { let testLibs: TestLibsContract; + const exchangeAddress = addressUtils.generatePseudoRandomAddress(); before(async () => { await blockchainLifecycle.startAsync(); @@ -19,7 +21,12 @@ describe('Libs tests', () => { await blockchainLifecycle.revertAsync(); }); before(async () => { - testLibs = await TestLibsContract.deployFrom0xArtifactAsync(artifacts.TestLibs, provider, txDefaults); + testLibs = await TestLibsContract.deployFrom0xArtifactAsync( + artifacts.TestLibs, + provider, + txDefaults, + exchangeAddress, + ); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -31,12 +38,12 @@ describe('Libs tests', () => { describe('getTransactionHash', () => { it('should return the correct transaction hash', async () => { const tx = { - verifyingContractAddress: testLibs.address, + verifyingContractAddress: exchangeAddress, salt: new BigNumber(0), signerAddress: constants.NULL_ADDRESS, data: '0x1234', }; - const expectedTxHash = hashUtils.getTransactionHashHex(tx); + const expectedTxHash = transactionHashUtils.getTransactionHashHex(tx); const txHash = await testLibs.publicGetTransactionHash.callAsync(tx); expect(expectedTxHash).to.eq(txHash); }); @@ -45,7 +52,7 @@ describe('Libs tests', () => { describe('getApprovalHash', () => { it('should return the correct approval hash', async () => { const signedTx = { - verifyingContractAddress: testLibs.address, + verifyingContractAddress: exchangeAddress, salt: new BigNumber(0), signerAddress: constants.NULL_ADDRESS, data: '0x1234', @@ -55,12 +62,13 @@ describe('Libs tests', () => { const txOrigin = constants.NULL_ADDRESS; const approval = { txOrigin, - transactionHash: hashUtils.getTransactionHashHex(signedTx), + transactionHash: transactionHashUtils.getTransactionHashHex(signedTx), transactionSignature: signedTx.signature, approvalExpirationTimeSeconds, }; const expectedApprovalHash = hashUtils.getApprovalHashHex( signedTx, + testLibs.address, txOrigin, approvalExpirationTimeSeconds, ); diff --git a/contracts/coordinator/test/mixins.ts b/contracts/coordinator/test/mixins.ts index 197c8b8c66..a862791b0f 100644 --- a/contracts/coordinator/test/mixins.ts +++ b/contracts/coordinator/test/mixins.ts @@ -1,28 +1,22 @@ import { + addressUtils, chaiSetup, constants as devConstants, expectContractCallFailedAsync, getLatestBlockTimestampAsync, provider, + TransactionFactory, txDefaults, web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { RevertReason, SignedOrder } from '@0x/types'; +import { transactionHashUtils } from '@0x/order-utils'; +import { RevertReason, SignatureType, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; import * as ethUtil from 'ethereumjs-util'; -import { - ApprovalFactory, - artifacts, - constants, - CoordinatorSignatureType, - CoordinatorTransactionFactory, - exchangeDataEncoder, - hashUtils, - TestMixinsContract, -} from '../src'; +import { ApprovalFactory, artifacts, constants, exchangeDataEncoder, TestMixinsContract } from '../src'; chaiSetup.configure(); const expect = chai.expect; @@ -33,10 +27,12 @@ describe('Mixins tests', () => { let approvalSignerAddress1: string; let approvalSignerAddress2: string; let mixins: TestMixinsContract; - let transactionFactory: CoordinatorTransactionFactory; + let transactionFactory: TransactionFactory; let approvalFactory1: ApprovalFactory; let approvalFactory2: ApprovalFactory; let defaultOrder: SignedOrder; + const exchangeAddress = addressUtils.generatePseudoRandomAddress(); + before(async () => { await blockchainLifecycle.startAsync(); }); @@ -44,7 +40,12 @@ describe('Mixins tests', () => { await blockchainLifecycle.revertAsync(); }); before(async () => { - mixins = await TestMixinsContract.deployFrom0xArtifactAsync(artifacts.TestMixins, provider, txDefaults); + mixins = await TestMixinsContract.deployFrom0xArtifactAsync( + artifacts.TestMixins, + provider, + txDefaults, + exchangeAddress, + ); const accounts = await web3Wrapper.getAvailableAddressesAsync(); [transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 3); defaultOrder = { @@ -67,7 +68,7 @@ describe('Mixins tests', () => { devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(transactionSignerAddress)]; const approvalSignerPrivateKey1 = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress1)]; const approvalSignerPrivateKey2 = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress2)]; - transactionFactory = new CoordinatorTransactionFactory(transactionSignerPrivateKey, mixins.address); + transactionFactory = new TransactionFactory(transactionSignerPrivateKey, exchangeAddress); approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1, mixins.address); approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2, mixins.address); }); @@ -81,47 +82,52 @@ describe('Mixins tests', () => { describe('getSignerAddress', () => { it('should return the correct address using the EthSign signature type', async () => { const data = devConstants.NULL_BYTES; - const transaction = transactionFactory.newSignedCoordinatorTransaction( - data, - CoordinatorSignatureType.EthSign, - ); - const transactionHash = hashUtils.getTransactionHashHex(transaction); + const transaction = transactionFactory.newSignedTransaction(data, SignatureType.EthSign); + const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature); expect(transaction.signerAddress).to.eq(signerAddress); }); it('should return the correct address using the EIP712 signature type', async () => { const data = devConstants.NULL_BYTES; - const transaction = transactionFactory.newSignedCoordinatorTransaction( - data, - CoordinatorSignatureType.EIP712, - ); - const transactionHash = hashUtils.getTransactionHashHex(transaction); + const transaction = transactionFactory.newSignedTransaction(data, SignatureType.EIP712); + const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature); expect(transaction.signerAddress).to.eq(signerAddress); }); it('should revert with with the Illegal signature type', async () => { const data = devConstants.NULL_BYTES; - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); - const illegalSignatureByte = ethUtil.toBuffer(CoordinatorSignatureType.Illegal).toString('hex'); + const transaction = transactionFactory.newSignedTransaction(data); + const illegalSignatureByte = ethUtil.toBuffer(SignatureType.Illegal).toString('hex'); transaction.signature = `${transaction.signature.slice( 0, transaction.signature.length - 2, )}${illegalSignatureByte}`; - const transactionHash = hashUtils.getTransactionHashHex(transaction); + const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); expectContractCallFailedAsync( mixins.getSignerAddress.callAsync(transactionHash, transaction.signature), RevertReason.SignatureIllegal, ); }); + it('should revert with with the Invalid signature type', async () => { + const data = devConstants.NULL_BYTES; + const transaction = transactionFactory.newSignedTransaction(data); + const invalidSignatureByte = ethUtil.toBuffer(SignatureType.Invalid).toString('hex'); + transaction.signature = `0x${invalidSignatureByte}`; + const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); + expectContractCallFailedAsync( + mixins.getSignerAddress.callAsync(transactionHash, transaction.signature), + RevertReason.SignatureInvalid, + ); + }); it("should revert with with a signature type that doesn't exist", async () => { const data = devConstants.NULL_BYTES; - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); - const invalidSignatureByte = '03'; + const transaction = transactionFactory.newSignedTransaction(data); + const invalidSignatureByte = '04'; transaction.signature = `${transaction.signature.slice( 0, transaction.signature.length - 2, )}${invalidSignatureByte}`; - const transactionHash = hashUtils.getTransactionHashHex(transaction); + const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); expectContractCallFailedAsync( mixins.getSignerAddress.callAsync(transactionHash, transaction.signature), RevertReason.SignatureUnsupported, @@ -134,7 +140,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -167,7 +173,7 @@ describe('Mixins tests', () => { }; const orders = [order]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -196,7 +202,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidTransactionOrdersApproval.callAsync( transaction, orders, @@ -220,7 +226,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -249,7 +255,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidTransactionOrdersApproval.callAsync( transaction, orders, @@ -273,7 +279,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid], expiration=[valid]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -309,7 +315,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -344,7 +350,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -387,7 +393,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => { const orders = [defaultOrder, defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -419,7 +425,7 @@ describe('Mixins tests', () => { senderAddress: devConstants.NULL_ADDRESS, })); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -451,7 +457,7 @@ describe('Mixins tests', () => { senderAddress: devConstants.NULL_ADDRESS, })); const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidTransactionOrdersApproval.callAsync( transaction, orders, @@ -473,7 +479,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, senderAddress: devConstants.NULL_ADDRESS }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -502,7 +508,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval1 = approvalFactory1.newSignedApproval( @@ -536,7 +542,7 @@ describe('Mixins tests', () => { it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => { const orders = [defaultOrder, defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidTransactionOrdersApproval.callAsync( transaction, orders, @@ -558,7 +564,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval2 = approvalFactory2.newSignedApproval( @@ -593,7 +599,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => { const orders = [defaultOrder, defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); expectContractCallFailedAsync( mixins.assertValidTransactionOrdersApproval.callAsync( transaction, @@ -621,7 +627,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => { const orders = [defaultOrder, defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval = approvalFactory1.newSignedApproval( @@ -657,7 +663,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval1 = approvalFactory1.newSignedApproval( @@ -698,7 +704,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval2 = approvalFactory2.newSignedApproval( @@ -734,7 +740,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); @@ -775,7 +781,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => { const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER); const approval2 = approvalFactory2.newSignedApproval( @@ -810,7 +816,7 @@ describe('Mixins tests', () => { it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => { const orders = [defaultOrder, defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); const currentTimestamp = await getLatestBlockTimestampAsync(); const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER); const approval1 = approvalFactory1.newSignedApproval( @@ -848,7 +854,7 @@ describe('Mixins tests', () => { it('should allow the tx signer to call `cancelOrders` without approval', async () => { const orders = [defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidCoordinatorApprovals.callAsync( transaction, transactionSignerAddress, @@ -861,7 +867,7 @@ describe('Mixins tests', () => { it('should allow the tx signer to call `batchCancelOrders` without approval', async () => { const orders = [defaultOrder, defaultOrder]; const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidCoordinatorApprovals.callAsync( transaction, transactionSignerAddress, @@ -874,7 +880,7 @@ describe('Mixins tests', () => { it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => { const orders: SignedOrder[] = []; const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders); - const transaction = transactionFactory.newSignedCoordinatorTransaction(data); + const transaction = transactionFactory.newSignedTransaction(data); await mixins.assertValidCoordinatorApprovals.callAsync( transaction, transactionSignerAddress, diff --git a/contracts/coordinator/test/utils/approval_factory.ts b/contracts/coordinator/test/utils/approval_factory.ts index e861214110..f0c5ea145d 100644 --- a/contracts/coordinator/test/utils/approval_factory.ts +++ b/contracts/coordinator/test/utils/approval_factory.ts @@ -1,35 +1,35 @@ -import { SignedZeroExTransaction } from '@0x/types'; +import { signingUtils } from '@0x/contracts-test-utils'; +import { SignatureType, SignedZeroExTransaction } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as ethUtil from 'ethereumjs-util'; -import { CoordinatorSignatureType, hashUtils, SignedCoordinatorApproval, signingUtils } from './index'; +import { hashUtils, SignedCoordinatorApproval } from './index'; export class ApprovalFactory { private readonly _privateKey: Buffer; private readonly _verifyingContractAddress: string; + constructor(privateKey: Buffer, verifyingContractAddress: string) { this._privateKey = privateKey; this._verifyingContractAddress = verifyingContractAddress; } + public newSignedApproval( transaction: SignedZeroExTransaction, txOrigin: string, approvalExpirationTimeSeconds: BigNumber, - signatureType: CoordinatorSignatureType = CoordinatorSignatureType.EthSign, + signatureType: SignatureType = SignatureType.EthSign, ): SignedCoordinatorApproval { - const coordinatorTransaction = { - ...transaction, - verifyingContractAddress: this._verifyingContractAddress, - }; const approvalHashBuff = hashUtils.getApprovalHashBuffer( - coordinatorTransaction, + transaction, + this._verifyingContractAddress, txOrigin, approvalExpirationTimeSeconds, ); const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType); const signedApproval = { txOrigin, - transaction: coordinatorTransaction, + transaction, approvalExpirationTimeSeconds, signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')), }; diff --git a/contracts/coordinator/test/utils/constants.ts b/contracts/coordinator/test/utils/constants.ts index e2fc8bdbae..e83a636418 100644 --- a/contracts/coordinator/test/utils/constants.ts +++ b/contracts/coordinator/test/utils/constants.ts @@ -1,17 +1,6 @@ import { BigNumber } from '@0x/utils'; export const constants = { - COORDINATOR_DOMAIN_NAME: '0x Protocol Coordinator', - COORDINATOR_DOMAIN_VERSION: '1.0.0', - COORDINATOR_APPROVAL_SCHEMA: { - name: 'CoordinatorApproval', - parameters: [ - { name: 'txOrigin', type: 'address' }, - { name: 'transactionHash', type: 'bytes32' }, - { name: 'transactionSignature', type: 'bytes' }, - { name: 'approvalExpirationTimeSeconds', type: 'uint256' }, - ], - }, SINGLE_FILL_FN_NAMES: ['fillOrder', 'fillOrKillOrder', 'fillOrderNoThrow'], BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'], MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'], diff --git a/contracts/coordinator/test/utils/coordinator_transaction_factory.ts b/contracts/coordinator/test/utils/coordinator_transaction_factory.ts deleted file mode 100644 index dd55b56cf3..0000000000 --- a/contracts/coordinator/test/utils/coordinator_transaction_factory.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { generatePseudoRandomSalt } from '@0x/order-utils'; -import { SignedZeroExTransaction } from '@0x/types'; -import * as ethUtil from 'ethereumjs-util'; - -import { CoordinatorSignatureType, hashUtils, signingUtils } from './index'; - -export class CoordinatorTransactionFactory { - private readonly _signerBuff: Buffer; - private readonly _verifyingContractAddress: string; - private readonly _privateKey: Buffer; - constructor(privateKey: Buffer, verifyingContractAddress: string) { - this._privateKey = privateKey; - this._verifyingContractAddress = verifyingContractAddress; - this._signerBuff = ethUtil.privateToAddress(this._privateKey); - } - public newSignedCoordinatorTransaction( - data: string, - signatureType: CoordinatorSignatureType = CoordinatorSignatureType.EthSign, - ): SignedZeroExTransaction { - const transaction = { - verifyingContractAddress: this._verifyingContractAddress, - signerAddress: ethUtil.addHexPrefix(this._signerBuff.toString('hex')), - salt: generatePseudoRandomSalt(), - data, - }; - const transactionHashBuff = hashUtils.getTransactionHashBuffer(transaction); - const signatureBuff = signingUtils.signMessage(transactionHashBuff, this._privateKey, signatureType); - const signedTransaction = { - ...transaction, - signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')), - }; - return signedTransaction; - } -} diff --git a/contracts/coordinator/test/utils/hash_utils.ts b/contracts/coordinator/test/utils/hash_utils.ts index 094b73e7b6..caba4cf3c8 100644 --- a/contracts/coordinator/test/utils/hash_utils.ts +++ b/contracts/coordinator/test/utils/hash_utils.ts @@ -1,23 +1,22 @@ -import { eip712Utils } from '@0x/order-utils'; -import { constants as orderUtilsConstants } from '@0x/order-utils/lib/src/constants'; -import { SignedZeroExTransaction, ZeroExTransaction } from '@0x/types'; +import { eip712Utils, transactionHashUtils } from '@0x/order-utils'; +import { constants } from '@0x/order-utils/lib/src/constants'; +import { SignedZeroExTransaction } from '@0x/types'; import { BigNumber, signTypedDataUtils } from '@0x/utils'; import * as _ from 'lodash'; -import { constants } from './index'; - export const hashUtils = { getApprovalHashBuffer( transaction: SignedZeroExTransaction, + verifyingContractAddress: string, txOrigin: string, approvalExpirationTimeSeconds: BigNumber, ): Buffer { const domain = { name: constants.COORDINATOR_DOMAIN_NAME, version: constants.COORDINATOR_DOMAIN_VERSION, - verifyingContractAddress: transaction.verifyingContractAddress, + verifyingContractAddress, }; - const transactionHash = hashUtils.getTransactionHashHex(transaction); + const transactionHash = transactionHashUtils.getTransactionHashHex(transaction); const approval = { txOrigin, transactionHash, @@ -37,34 +36,13 @@ export const hashUtils = { }, getApprovalHashHex( transaction: SignedZeroExTransaction, + verifyingContractAddress: string, txOrigin: string, approvalExpirationTimeSeconds: BigNumber, ): string { const hashHex = `0x${hashUtils - .getApprovalHashBuffer(transaction, txOrigin, approvalExpirationTimeSeconds) + .getApprovalHashBuffer(transaction, verifyingContractAddress, txOrigin, approvalExpirationTimeSeconds) .toString('hex')}`; return hashHex; }, - getTransactionHashBuffer(transaction: ZeroExTransaction | SignedZeroExTransaction): Buffer { - const domain = { - name: constants.COORDINATOR_DOMAIN_NAME, - version: constants.COORDINATOR_DOMAIN_VERSION, - verifyingContractAddress: transaction.verifyingContractAddress, - }; - const normalizedTransaction = _.mapValues(transaction, value => { - return !_.isString(value) ? value.toString() : value; - }); - const typedData = eip712Utils.createTypedData( - orderUtilsConstants.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.name, - { ZeroExTransaction: orderUtilsConstants.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.parameters }, - normalizedTransaction, - domain, - ); - const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData); - return hashBuffer; - }, - getTransactionHashHex(transaction: ZeroExTransaction | SignedZeroExTransaction): string { - const hashHex = `0x${hashUtils.getTransactionHashBuffer(transaction).toString('hex')}`; - return hashHex; - }, }; diff --git a/contracts/coordinator/test/utils/index.ts b/contracts/coordinator/test/utils/index.ts index 9ffc956f90..83f2013b4b 100644 --- a/contracts/coordinator/test/utils/index.ts +++ b/contracts/coordinator/test/utils/index.ts @@ -1,6 +1,4 @@ export { hashUtils } from './hash_utils'; -export { signingUtils } from './signing_utils'; -export { CoordinatorTransactionFactory } from './coordinator_transaction_factory'; export { ApprovalFactory } from './approval_factory'; export { constants } from './constants'; export { exchangeDataEncoder } from './exchange_data_encoder'; diff --git a/contracts/coordinator/test/utils/signing_utils.ts b/contracts/coordinator/test/utils/signing_utils.ts deleted file mode 100644 index 8515a0b385..0000000000 --- a/contracts/coordinator/test/utils/signing_utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as ethUtil from 'ethereumjs-util'; - -import { CoordinatorSignatureType } from './types'; - -export const signingUtils = { - signMessage(message: Buffer, privateKey: Buffer, signatureType: CoordinatorSignatureType): Buffer { - if (signatureType === CoordinatorSignatureType.EthSign) { - const prefixedMessage = ethUtil.hashPersonalMessage(message); - const ecSignature = ethUtil.ecsign(prefixedMessage, privateKey); - const signature = Buffer.concat([ - ethUtil.toBuffer(ecSignature.v), - ecSignature.r, - ecSignature.s, - ethUtil.toBuffer(signatureType), - ]); - return signature; - } else if (signatureType === CoordinatorSignatureType.EIP712) { - const ecSignature = ethUtil.ecsign(message, privateKey); - const signature = Buffer.concat([ - ethUtil.toBuffer(ecSignature.v), - ecSignature.r, - ecSignature.s, - ethUtil.toBuffer(signatureType), - ]); - return signature; - } else { - throw new Error(`${signatureType} is not a valid signature type`); - } - }, -}; diff --git a/contracts/coordinator/test/utils/types.ts b/contracts/coordinator/test/utils/types.ts index 5db1a847bd..e0a3eafea4 100644 --- a/contracts/coordinator/test/utils/types.ts +++ b/contracts/coordinator/test/utils/types.ts @@ -10,10 +10,3 @@ export interface CoordinatorApproval { export interface SignedCoordinatorApproval extends CoordinatorApproval { signature: string; } - -export enum CoordinatorSignatureType { - Illegal, - EIP712, - EthSign, - NSignatureTypes, -} diff --git a/contracts/test-utils/CHANGELOG.json b/contracts/test-utils/CHANGELOG.json index c9088fbaab..c85059a13b 100644 --- a/contracts/test-utils/CHANGELOG.json +++ b/contracts/test-utils/CHANGELOG.json @@ -14,6 +14,10 @@ { "note": "Set evmVersion to byzantium", "pr": 1678 + }, + { + "note": "Remove Coordinator EIP712 constants. They're now in the `order-utils` package.", + "pr": 1705 } ] }, diff --git a/contracts/test-utils/src/constants.ts b/contracts/test-utils/src/constants.ts index af56912ce3..2e58d764d0 100644 --- a/contracts/test-utils/src/constants.ts +++ b/contracts/test-utils/src/constants.ts @@ -70,14 +70,4 @@ export const constants = { 'CANCEL_ORDERS_UP_TO', 'SET_SIGNATURE_VALIDATOR_APPROVAL', ], - COORDINATOR_DOMAIN_NAME: '0x Protocol Trade Execution Coordinator', - COORDINATOR_DOMAIN_VERSION: '1.0.0', - COORDINATOR_APPROVAL_SCHEMA: { - name: 'COORDINATORApproval', - parameters: [ - { name: 'transactionHash', type: 'bytes32' }, - { name: 'transactionSignature', type: 'bytes' }, - { name: 'approvalExpirationTimeSeconds', type: 'uint256' }, - ], - }, }; diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index 0b2b7791f7..62f4284359 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -2,6 +2,10 @@ { "version": "7.1.0", "changes": [ + { + "note": "Add Coordinator EIP712 constants", + "pr": 1705 + }, { "note": "Added encoding/decoding fdor ERC1155 asset data", "pr": 1661 diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts index 3c93575b3f..30e8cad634 100644 --- a/packages/order-utils/src/constants.ts +++ b/packages/order-utils/src/constants.ts @@ -103,6 +103,17 @@ export const constants = { { name: 'data', type: 'bytes' }, ], }, + COORDINATOR_DOMAIN_NAME: '0x Protocol Coordinator', + COORDINATOR_DOMAIN_VERSION: '1.0.0', + COORDINATOR_APPROVAL_SCHEMA: { + name: 'CoordinatorApproval', + parameters: [ + { name: 'txOrigin', type: 'address' }, + { name: 'transactionHash', type: 'bytes32' }, + { name: 'transactionSignature', type: 'bytes' }, + { name: 'approvalExpirationTimeSeconds', type: 'uint256' }, + ], + }, ERC20_METHOD_ABI, ERC721_METHOD_ABI, MULTI_ASSET_METHOD_ABI, diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts index 68b50cc53f..8bb1bd671e 100644 --- a/packages/order-utils/src/index.ts +++ b/packages/order-utils/src/index.ts @@ -65,6 +65,7 @@ export { ZeroExTransaction, SignedZeroExTransaction, } from '@0x/types'; + export { OrderError, TradeSide, diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 392c7adf15..daa51e24ca 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,6 +1,6 @@ [ { - "version": "2.2.2", + "version": "2.2.0", "changes": [ { "note": "Added ERC1155 revert reasons", @@ -9,24 +9,14 @@ { "note": "Added `ERC1155AssetData`, `ERC1155AssetDataNoProxyId`, and `ERC1155AssetDataAbi`", "pr": 1661 - } - ] - }, - { - "version": "2.2.1", - "changes": [ - { - "note": "Added ERC1155 revert reasons", - "pr": 1657 - } - ] - }, - { - "version": "2.2.0", - "changes": [ + }, { "note": "Add `InvalidOrigin` revert reason", "pr": 1668 + }, + { + "note": "Add `RevertReason.SignatureInvalid` thrown by Coordinator", + "pr": 1705 } ] }, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 23cc118b2e..f694575f6c 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -227,6 +227,7 @@ export enum RevertReason { RoundingError = 'ROUNDING_ERROR', InvalidSignature = 'INVALID_SIGNATURE', SignatureIllegal = 'SIGNATURE_ILLEGAL', + SignatureInvalid = 'SIGNATURE_INVALID', SignatureUnsupported = 'SIGNATURE_UNSUPPORTED', TakerOverpay = 'TAKER_OVERPAY', OrderOverfill = 'ORDER_OVERFILL',