diff options
author | Jacob Evans <jacob@dekz.net> | 2018-06-18 18:59:23 +0800 |
---|---|---|
committer | Jacob Evans <jacob@dekz.net> | 2018-06-18 19:46:05 +0800 |
commit | d4ee0e862297c16f8ee62efccd31f1193052c64e (patch) | |
tree | 4b3f8a4a75dfb9ed73bccc850a01ac789363c830 /packages/contracts | |
parent | a8d328bfc926a62d61830334fadc43fc5d013e0e (diff) | |
download | dexon-0x-contracts-d4ee0e862297c16f8ee62efccd31f1193052c64e.tar.gz dexon-0x-contracts-d4ee0e862297c16f8ee62efccd31f1193052c64e.tar.zst dexon-0x-contracts-d4ee0e862297c16f8ee62efccd31f1193052c64e.zip |
Rebase and update feedback
Cache the domain separator data with address this
Use the EIP712Types enum for types everywhere
Rename EIP712 struct ExecuteTransaction to ZeroExTransaction
Diffstat (limited to 'packages/contracts')
4 files changed, 85 insertions, 81 deletions
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol index e3f6b2b2b..9bdaa0f8f 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinTransactions.sol @@ -37,28 +37,31 @@ contract MixinTransactions is // Address of current transaction signer address public currentContextAddress; - bytes32 constant EXECUTE_TRANSACTION_SCHEMA_HASH = keccak256( - "ExecuteTransaction(", + // Hash for the EIP712 ZeroEx Transaction Schema + bytes32 constant EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked( + "ZeroExTransaction(", "uint256 salt,", "address signer,", "bytes data", ")" - ); + )); - function getExecuteTransactionHash(uint256 salt, address signer, bytes data) + /// @dev Calculates EIP712 hash of the Transaction. + /// @param salt Arbitrary number to ensure uniqueness of transaction hash. + /// @param signer Address of transaction signer. + /// @param data AbiV2 encoded calldata. + /// @return EIP712 hash of the Transaction. + function hashZeroExTransaction(uint256 salt, address signer, bytes data) internal view - returns (bytes32 executeTransactionHash) + returns (bytes32) { - executeTransactionHash = createEIP712Message( - keccak256( - EXECUTE_TRANSACTION_SCHEMA_HASH, - salt, - bytes32(signer), - keccak256(data) - ) - ); - return executeTransactionHash; + return keccak256(abi.encodePacked( + EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH, + salt, + bytes32(signer), + keccak256(abi.encodePacked(data)) + )); } /// @dev Executes an exchange method call in the context of signer. @@ -80,7 +83,7 @@ contract MixinTransactions is REENTRANCY_ILLEGAL ); - bytes32 transactionHash = getExecuteTransactionHash(salt, signer, data); + bytes32 transactionHash = hashEIP712Message(hashZeroExTransaction(salt, signer, data)); // Validate transaction has not been executed require( diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibEIP712.sol b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibEIP712.sol index 7704e3db4..991137f32 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibEIP712.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibEIP712.sol @@ -19,44 +19,37 @@ pragma solidity ^0.4.24; contract LibEIP712 { - string public constant EIP191_HEADER = "\x19\x01"; - - bytes32 public constant EIP712_DOMAIN_SEPARATOR_NAME_HASH = keccak256("0x Protocol"); - - bytes32 public constant EIP712_DOMAIN_SEPARATOR_VERSION_HASH = keccak256("2"); - - bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256( - abi.encodePacked( - "DomainSeparator(", - "string name,", - "string version,", - "address contract", - ")" - ) - ); + // EIP191 header for EIP712 prefix + string constant EIP191_HEADER = "\x19\x01"; + + // Hash of the EIP712 Domain Separator Schema + bytes32 public constant EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked( + "EIP712Domain(", + "string name,", + "string version,", + "address verifyingContract", + ")" + )); + + // Hash of the EIP712 Domain Separator data + bytes32 public EIP712_DOMAIN_HASH; + + constructor () + public + { + EIP712_DOMAIN_HASH = keccak256(abi.encodePacked( + EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH, + keccak256(abi.encodePacked("0x Protocol")), + keccak256(abi.encodePacked("2")), + bytes32(address(this)) + )); + } - function createEIP712Message(bytes32 hashStruct) + function hashEIP712Message(bytes32 hashStruct) internal view - returns (bytes32 message) + returns (bytes32) { - // TODO: EIP712 is not finalized yet - // Source: https://github.com/ethereum/EIPs/pull/712 - // TODO: Cache the Domain Separator - message = keccak256( - abi.encodePacked( - EIP191_HEADER, - keccak256( - abi.encodePacked( - EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH, - EIP712_DOMAIN_SEPARATOR_NAME_HASH, - EIP712_DOMAIN_SEPARATOR_VERSION_HASH, - bytes32(address(this)) - ) - ), - hashStruct - ) - ); - return message; + return keccak256(abi.encodePacked(EIP191_HEADER, EIP712_DOMAIN_HASH, hashStruct)); } -}
\ No newline at end of file +} diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibOrder.sol b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibOrder.sol index ed532fd59..04374f1d0 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibOrder.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibOrder.sol @@ -24,8 +24,8 @@ contract LibOrder is LibEIP712 { - bytes32 constant EIP712_ORDER_SCHEMA_HASH = keccak256( - abi.encodePacked( + // Hash for the EIP712 Order Schema + bytes32 constant EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked( "Order(", "address makerAddress,", "address takerAddress,", @@ -40,7 +40,8 @@ contract LibOrder is "bytes makerAssetData,", "bytes takerAssetData", ")" - )); + ) + ); // A valid order remains fillable until it is expired, fully filled, or cancelled. // An order's state is unaffected by external factors, like account balances. @@ -86,25 +87,32 @@ contract LibOrder is view returns (bytes32 orderHash) { - orderHash = createEIP712Message( - keccak256( - abi.encodePacked( - EIP712_ORDER_SCHEMA_HASH, - bytes32(order.makerAddress), - bytes32(order.takerAddress), - bytes32(order.feeRecipientAddress), - bytes32(order.senderAddress), - order.makerAssetAmount, - order.takerAssetAmount, - order.makerFee, - order.takerFee, - order.expirationTimeSeconds, - order.salt, - keccak256(abi.encodePacked(order.makerAssetData)), - keccak256(abi.encodePacked(order.takerAssetData)) - ) - ) - ); + orderHash = hashEIP712Message(hashOrder(order)); return orderHash; } + + /// @dev Calculates EIP712 hash of the order. + /// @param order The order structure. + /// @return EIP712 hash of the order. + function hashOrder(Order memory order) + internal + pure + returns (bytes32) + { + return keccak256(abi.encodePacked( + EIP712_ORDER_SCHEMA_HASH, + bytes32(order.makerAddress), + bytes32(order.takerAddress), + bytes32(order.feeRecipientAddress), + bytes32(order.senderAddress), + order.makerAssetAmount, + order.takerAssetAmount, + order.makerFee, + order.takerFee, + order.expirationTimeSeconds, + order.salt, + keccak256(abi.encodePacked(order.makerAssetData)), + keccak256(abi.encodePacked(order.takerAssetData)) + )); + } } diff --git a/packages/contracts/src/utils/transaction_factory.ts b/packages/contracts/src/utils/transaction_factory.ts index bb15a0309..c0a32b83a 100644 --- a/packages/contracts/src/utils/transaction_factory.ts +++ b/packages/contracts/src/utils/transaction_factory.ts @@ -1,16 +1,16 @@ -import { crypto, EIP712Schema, EIP712Utils, generatePseudoRandomSalt } from '@0xproject/order-utils'; +import { crypto, EIP712Schema, EIP712Types, EIP712Utils, generatePseudoRandomSalt } from '@0xproject/order-utils'; import { SignatureType } from '@0xproject/types'; import * as ethUtil from 'ethereumjs-util'; import { signingUtils } from './signing_utils'; import { SignedTransaction } from './types'; -const EIP712_EXECUTE_TRANSACTION_SCHEMA: EIP712Schema = { - name: 'ExecuteTransaction', +const EIP712_ZEROEX_TRANSACTION_SCHEMA: EIP712Schema = { + name: 'ZeroExTransaction', parameters: [ - { name: 'salt', type: 'uint256' }, - { name: 'signer', type: 'address' }, - { name: 'data', type: 'bytes' }, + { name: 'salt', type: EIP712Types.Uint256 }, + { name: 'signer', type: EIP712Types.Address }, + { name: 'data', type: EIP712Types.Bytes }, ], }; @@ -24,7 +24,7 @@ export class TransactionFactory { this._signerBuff = ethUtil.privateToAddress(this._privateKey); } public newSignedTransaction(data: string, signatureType: SignatureType = SignatureType.EthSign): SignedTransaction { - const executeTransactionSchemaHashBuff = EIP712Utils.compileSchema(EIP712_EXECUTE_TRANSACTION_SCHEMA); + const executeTransactionSchemaHashBuff = EIP712Utils.compileSchema(EIP712_ZEROEX_TRANSACTION_SCHEMA); const salt = generatePseudoRandomSalt(); const signer = `0x${this._signerBuff.toString('hex')}`; const executeTransactionData = { @@ -33,7 +33,7 @@ export class TransactionFactory { data, }; const executeTransactionHashBuff = EIP712Utils.structHash( - EIP712_EXECUTE_TRANSACTION_SCHEMA, + EIP712_ZEROEX_TRANSACTION_SCHEMA, executeTransactionData, ); const txHash = EIP712Utils.createEIP712Message(executeTransactionHashBuff, this._exchangeAddress); |