Add expirationTimeSeconds to ZeroExTransaction schema throughout codebase
This commit is contained in:
parent
238877b627
commit
6ddaa6f52a
@ -29,16 +29,18 @@ contract LibZeroExTransaction is
|
|||||||
// keccak256(abi.encodePacked(
|
// keccak256(abi.encodePacked(
|
||||||
// "ZeroExTransaction(",
|
// "ZeroExTransaction(",
|
||||||
// "uint256 salt,",
|
// "uint256 salt,",
|
||||||
|
// "uint256 expirationTimeSeconds,"
|
||||||
// "address signerAddress,",
|
// "address signerAddress,",
|
||||||
// "bytes data",
|
// "bytes data",
|
||||||
// ")"
|
// ")"
|
||||||
// ));
|
// ));
|
||||||
bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = 0x213c6f636f3ea94e701c0adf9b2624aa45a6c694f9a292c094f9a81c24b5df4c;
|
bytes32 constant public EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = 0x6b4c70d217b44d0ff0d3bf7aeb18eb8604c5cd06f615a4b497aeefa4f01d2775;
|
||||||
|
|
||||||
struct ZeroExTransaction {
|
struct ZeroExTransaction {
|
||||||
uint256 salt; // Arbitrary number to ensure uniqueness of transaction hash.
|
uint256 salt; // Arbitrary number to ensure uniqueness of transaction hash.
|
||||||
address signerAddress; // Address of transaction signer.
|
uint256 expirationTimeSeconds; // Timestamp in seconds at which transaction expires.
|
||||||
bytes data; // AbiV2 encoded calldata.
|
address signerAddress; // Address of transaction signer.
|
||||||
|
bytes data; // AbiV2 encoded calldata.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.
|
/// @dev Calculates the EIP712 hash of a 0x transaction using the domain separator of the Exchange contract.
|
||||||
@ -65,12 +67,14 @@ contract LibZeroExTransaction is
|
|||||||
bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;
|
bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;
|
||||||
bytes memory data = transaction.data;
|
bytes memory data = transaction.data;
|
||||||
uint256 salt = transaction.salt;
|
uint256 salt = transaction.salt;
|
||||||
|
uint256 expirationTimeSeconds = transaction.expirationTimeSeconds;
|
||||||
address signerAddress = transaction.signerAddress;
|
address signerAddress = transaction.signerAddress;
|
||||||
|
|
||||||
// Assembly for more efficiently computing:
|
// Assembly for more efficiently computing:
|
||||||
// keccak256(abi.encodePacked(
|
// keccak256(abi.encodePacked(
|
||||||
// EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,
|
// EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,
|
||||||
// transaction.salt,
|
// transaction.salt,
|
||||||
|
// transaction.expirationTimeSeconds,
|
||||||
// uint256(transaction.signerAddress),
|
// uint256(transaction.signerAddress),
|
||||||
// keccak256(transaction.data)
|
// keccak256(transaction.data)
|
||||||
// ));
|
// ));
|
||||||
@ -84,11 +88,12 @@ contract LibZeroExTransaction is
|
|||||||
|
|
||||||
mstore(memPtr, schemaHash) // hash of schema
|
mstore(memPtr, schemaHash) // hash of schema
|
||||||
mstore(add(memPtr, 32), salt) // salt
|
mstore(add(memPtr, 32), salt) // salt
|
||||||
mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) // signerAddress
|
mstore(add(memPtr, 64), expirationTimeSeconds) // expirationTimeSeconds
|
||||||
mstore(add(memPtr, 96), dataHash) // hash of data
|
mstore(add(memPtr, 96), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) // signerAddress
|
||||||
|
mstore(add(memPtr, 128), dataHash) // hash of data
|
||||||
|
|
||||||
// Compute hash
|
// Compute hash
|
||||||
result := keccak256(memPtr, 128)
|
result := keccak256(memPtr, 160)
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
|
|||||||
import "../src/LibEIP712ExchangeDomain.sol";
|
import "../src/LibEIP712ExchangeDomain.sol";
|
||||||
import "../src/LibMath.sol";
|
import "../src/LibMath.sol";
|
||||||
import "../src/LibOrder.sol";
|
import "../src/LibOrder.sol";
|
||||||
|
import "../src/LibZeroExTransaction.sol";
|
||||||
import "../src/LibFillResults.sol";
|
import "../src/LibFillResults.sol";
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ contract TestLibs is
|
|||||||
LibEIP712ExchangeDomain,
|
LibEIP712ExchangeDomain,
|
||||||
LibMath,
|
LibMath,
|
||||||
LibOrder,
|
LibOrder,
|
||||||
|
LibZeroExTransaction,
|
||||||
LibFillResults
|
LibFillResults
|
||||||
{
|
{
|
||||||
constructor (uint256 chainId)
|
constructor (uint256 chainId)
|
||||||
|
@ -8,14 +8,14 @@ import {
|
|||||||
web3Wrapper,
|
web3Wrapper,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
|
import { assetDataUtils, orderHashUtils, transactionHashUtils } from '@0x/order-utils';
|
||||||
import { constants as orderConstants } from '@0x/order-utils/lib/src/constants';
|
import { constants as orderConstants } from '@0x/order-utils/lib/src/constants';
|
||||||
import { SignedOrder } from '@0x/types';
|
import { SignedOrder } from '@0x/types';
|
||||||
import { BigNumber, providerUtils } from '@0x/utils';
|
import { BigNumber, providerUtils } from '@0x/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
import { TestLibsContract } from '../generated-wrappers/test_libs';
|
import { TestLibsContract } from '../src';
|
||||||
import { artifacts } from '../src/artifacts';
|
import { artifacts } from '../src/artifacts';
|
||||||
|
|
||||||
import { stringifySchema } from './utils';
|
import { stringifySchema } from './utils';
|
||||||
@ -56,7 +56,6 @@ describe('Exchange libs', () => {
|
|||||||
txDefaults,
|
txDefaults,
|
||||||
new BigNumber(alternateChainId),
|
new BigNumber(alternateChainId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const defaultOrderParams = {
|
const defaultOrderParams = {
|
||||||
...constants.STATIC_ORDER_PARAMS,
|
...constants.STATIC_ORDER_PARAMS,
|
||||||
makerAddress,
|
makerAddress,
|
||||||
@ -154,6 +153,33 @@ describe('Exchange libs', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('LibZeroExTransaction', () => {
|
||||||
|
describe('EIP712ZeroExTransactionSchemaHash', () => {
|
||||||
|
it('should return the correct schema hash', async () => {
|
||||||
|
const schemaHash = await libs.EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH.callAsync();
|
||||||
|
const schemaString =
|
||||||
|
'ZeroExTransaction(uint256 salt,uint256 expirationTimeSeconds,address signerAddress,bytes data)';
|
||||||
|
const expectedSchemaHash = ethUtil.addHexPrefix(ethUtil.bufferToHex(ethUtil.sha3(schemaString)));
|
||||||
|
expect(schemaHash).to.equal(expectedSchemaHash);
|
||||||
|
});
|
||||||
|
it('should return the correct transactionHash', async () => {
|
||||||
|
const transaction = {
|
||||||
|
salt: new BigNumber(0),
|
||||||
|
expirationTimeSeconds: new BigNumber(0),
|
||||||
|
signerAddress: constants.NULL_ADDRESS,
|
||||||
|
data: constants.NULL_BYTES,
|
||||||
|
domain: {
|
||||||
|
verifyingContractAddress: libs.address,
|
||||||
|
chainId,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const transactionHash = await libs.getTransactionHash.callAsync(transaction);
|
||||||
|
const expectedTransactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expect(transactionHash).to.equal(expectedTransactionHash);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('LibEIP712', () => {
|
describe('LibEIP712', () => {
|
||||||
it('should return the correct domain separator schema hash', async () => {
|
it('should return the correct domain separator schema hash', async () => {
|
||||||
const schema = stringifySchema(orderConstants.DEFAULT_DOMAIN_SCHEMA);
|
const schema = stringifySchema(orderConstants.DEFAULT_DOMAIN_SCHEMA);
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
"data": { "$ref": "/hexSchema" },
|
"data": { "$ref": "/hexSchema" },
|
||||||
"signerAddress": { "$ref": "/addressSchema" },
|
"signerAddress": { "$ref": "/addressSchema" },
|
||||||
"salt": { "$ref": "/wholeNumberSchema" },
|
"salt": { "$ref": "/wholeNumberSchema" },
|
||||||
|
"expirationTimeSeconds": { "$ref": "/wholeNumberSchema" },
|
||||||
"domain": { "$ref": "/eip712DomainSchema" }
|
"domain": { "$ref": "/eip712DomainSchema" }
|
||||||
},
|
},
|
||||||
"required": ["data", "salt", "signerAddress", "domain"],
|
"required": ["data", "salt", "expirationTimeSeconds", "signerAddress", "domain"],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ export const constants = {
|
|||||||
name: 'ZeroExTransaction',
|
name: 'ZeroExTransaction',
|
||||||
parameters: [
|
parameters: [
|
||||||
{ name: 'salt', type: 'uint256' },
|
{ name: 'salt', type: 'uint256' },
|
||||||
|
{ name: 'expirationTimeSeconds', type: 'uint256' },
|
||||||
{ name: 'signerAddress', type: 'address' },
|
{ name: 'signerAddress', type: 'address' },
|
||||||
{ name: 'data', type: 'bytes' },
|
{ name: 'data', type: 'bytes' },
|
||||||
],
|
],
|
||||||
|
@ -57,7 +57,8 @@ describe('EIP712 Utils', () => {
|
|||||||
describe('createZeroExTransactionTypedData', () => {
|
describe('createZeroExTransactionTypedData', () => {
|
||||||
it('adds in the EIP712DomainSeparator', () => {
|
it('adds in the EIP712DomainSeparator', () => {
|
||||||
const typedData = eip712Utils.createZeroExTransactionTypedData({
|
const typedData = eip712Utils.createZeroExTransactionTypedData({
|
||||||
salt: new BigNumber('0'),
|
salt: new BigNumber(0),
|
||||||
|
expirationTimeSeconds: new BigNumber(0),
|
||||||
data: constants.NULL_BYTES,
|
data: constants.NULL_BYTES,
|
||||||
signerAddress: constants.NULL_ADDRESS,
|
signerAddress: constants.NULL_ADDRESS,
|
||||||
domain: {
|
domain: {
|
||||||
|
@ -14,12 +14,13 @@ const expect = chai.expect;
|
|||||||
|
|
||||||
describe('0x transaction hashing', () => {
|
describe('0x transaction hashing', () => {
|
||||||
describe('#getTransactionHashHex', () => {
|
describe('#getTransactionHashHex', () => {
|
||||||
const expectedTransactionHash = '0x834125acbd69d6e2e706df216865728e9b63bfd7c8bcecb5987d9d02ea62ecd5';
|
const expectedTransactionHash = '0x9779e4ca195f8c9c6f137f495599e9a1944806310b64748479bfa6c6b1ae7eb4';
|
||||||
const fakeVerifyingContractAddress = '0x5e72914535f202659083db3a02c984188fa26e9f';
|
const fakeVerifyingContractAddress = '0x5e72914535f202659083db3a02c984188fa26e9f';
|
||||||
const fakeChainId = 1337;
|
const fakeChainId = 1337;
|
||||||
const transaction: ZeroExTransaction = {
|
const transaction: ZeroExTransaction = {
|
||||||
signerAddress: constants.NULL_ADDRESS,
|
signerAddress: constants.NULL_ADDRESS,
|
||||||
salt: new BigNumber(0),
|
salt: new BigNumber(0),
|
||||||
|
expirationTimeSeconds: new BigNumber(0),
|
||||||
data: constants.NULL_BYTES,
|
data: constants.NULL_BYTES,
|
||||||
domain: {
|
domain: {
|
||||||
verifyingContractAddress: fakeVerifyingContractAddress,
|
verifyingContractAddress: fakeVerifyingContractAddress,
|
||||||
@ -38,6 +39,7 @@ describe('0x transaction hashing', () => {
|
|||||||
const transactionHash = transactionHashUtils.getTransactionHashHex({
|
const transactionHash = transactionHashUtils.getTransactionHashHex({
|
||||||
...transaction,
|
...transaction,
|
||||||
salt: '0',
|
salt: '0',
|
||||||
|
expirationTimeSeconds: '0',
|
||||||
} as any);
|
} as any);
|
||||||
expect(transactionHash).to.be.equal(expectedTransactionHash);
|
expect(transactionHash).to.be.equal(expectedTransactionHash);
|
||||||
});
|
});
|
||||||
|
@ -55,6 +55,7 @@ export enum MarketOperation {
|
|||||||
*/
|
*/
|
||||||
export interface ZeroExTransaction {
|
export interface ZeroExTransaction {
|
||||||
salt: BigNumber;
|
salt: BigNumber;
|
||||||
|
expirationTimeSeconds: BigNumber;
|
||||||
signerAddress: string;
|
signerAddress: string;
|
||||||
data: string;
|
data: string;
|
||||||
domain: EIP712DomainWithDefaultSchema;
|
domain: EIP712DomainWithDefaultSchema;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user