Refactor EIP712 libraries

This commit is contained in:
Amir Bandeali
2019-04-02 16:16:21 -07:00
parent c195629a77
commit 308ff15adc
26 changed files with 85 additions and 84 deletions

View File

@@ -27,10 +27,11 @@
"src/LibAbiEncoder.sol",
"src/LibAssetProxyErrors.sol",
"src/LibConstants.sol",
"src/LibEIP712.sol",
"src/LibEIP712ExchangeDomain.sol",
"src/LibFillResults.sol",
"src/LibMath.sol",
"src/LibOrder.sol",
"src/LibZeroExTransaction.sol",
"test/TestLibs.sol"
]
}

View File

@@ -1,88 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.5;
contract LibEIP712 {
// Hash of the EIP712 Domain Separator Schema
bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked(
"EIP712Domain(",
"string name,",
"string version,",
"uint256 chainId,",
"address verifyingContractAddress",
")"
));
/// @dev Calculates a EIP712 domain separator.
/// @param name The EIP712 domain name.
/// @param version The EIP712 domain version.
/// @param verifyingContractAddress The EIP712 verifying contract.
/// @return EIP712 domain separator.
function hashEIP712Domain(
string memory name,
string memory version,
uint256 chainId,
address verifyingContractAddress
)
internal
view
returns (bytes32 result)
{
return keccak256(abi.encodePacked(
EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
keccak256(bytes(name)),
keccak256(bytes(version)),
chainId,
uint256(verifyingContractAddress)
));
}
/// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.
/// @param eip712DomainHash Hash of the domain domain separator data, computed
/// with getDomainHash().
/// @param hashStruct The EIP712 hash struct.
/// @return EIP712 hash applied to the given 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
// ));
assembly {
// Load free memory pointer
let memPtr := mload(64)
mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header
mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash
mstore(add(memPtr, 34), hashStruct) // Hash of struct
// Compute hash
result := keccak256(memPtr, 66)
}
return result;
}
}

View File

@@ -18,27 +18,32 @@
pragma solidity ^0.5.5;
import "./LibEIP712.sol";
import "./LibEIP712ExchangeDomainConstants.sol";
import "@0x/contracts-utils/contracts/src/LibEIP712.sol";
contract LibEIP712ExchangeDomain is
LibEIP712,
LibEIP712ExchangeDomainConstants
LibEIP712
{
// EIP712 Exchange Domain Name value
string constant internal EIP712_EXCHANGE_DOMAIN_NAME = "0x Protocol";
// EIP712 Exchange Domain Version value
string constant internal EIP712_EXCHANGE_DOMAIN_VERSION = "3.0.0";
// Hash of the EIP712 Domain Separator data
// solhint-disable-next-line var-name-mixedcase
bytes32 internal EIP712_EXCHANGE_DOMAIN_HASH;
/// @param chainId Chain ID of the network this contract is deployed on.
constructor (uint256 chainId)
/// @param verifyingContractAddress Address of the verifying contract (null if the address of this contract)
constructor (uint256 chainId, address verifyingContractAddress)
public
{
EIP712_EXCHANGE_DOMAIN_HASH = hashEIP712Domain(
EIP712_EXCHANGE_DOMAIN_NAME,
EIP712_EXCHANGE_DOMAIN_VERSION,
chainId,
address(this)
verifyingContractAddress == address(0) ? address(this) : verifyingContractAddress
);
}

View File

@@ -1,29 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.5;
contract LibEIP712ExchangeDomainConstants {
// EIP712 Exchange Domain Name value
string constant internal EIP712_EXCHANGE_DOMAIN_NAME = "0x Protocol";
// EIP712 Exchange Domain Version value
string constant internal EIP712_EXCHANGE_DOMAIN_VERSION = "3.0.0";
}

View File

@@ -17,6 +17,7 @@
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
import "./LibEIP712ExchangeDomain.sol";
@@ -81,7 +82,7 @@ contract LibOrder is
/// @param order The order structure.
/// @return Keccak-256 EIP712 hash of the order.
function getOrderHash(Order memory order)
internal
public
view
returns (bytes32 orderHash)
{

View File

@@ -0,0 +1,95 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
import "./LibEIP712ExchangeDomain.sol";
contract LibZeroExTransaction is
LibEIP712ExchangeDomain
{
// Hash for the EIP712 0x transaction schema
// keccak256(abi.encodePacked(
// "ZeroExTransaction(",
// "uint256 salt,",
// "address signerAddress,",
// "bytes data",
// ")"
// ));
bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = 0x213c6f636f3ea94e701c0adf9b2624aa45a6c694f9a292c094f9a81c24b5df4c;
struct ZeroExTransaction {
uint256 salt; // Arbitrary number to ensure uniqueness of transaction hash.
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.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @return EIP712 hash of the transaction with the domain separator of this contract.
function getTransactionHash(ZeroExTransaction memory transaction)
public
view
returns (bytes32 transactionHash)
{
// Hash the transaction with the domain separator of the Exchange contract.
transactionHash = hashEIP712ExchangeMessage(hashZeroExTransaction(transaction));
return transactionHash;
}
/// @dev Calculates EIP712 hash of the 0x transaction with no domain separator.
/// @param transaction 0x transaction containing salt, signerAddress, and data.
/// @return EIP712 hash of the transaction with no domain separator.
function hashZeroExTransaction(ZeroExTransaction memory transaction)
internal
pure
returns (bytes32 result)
{
bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;
bytes memory data = transaction.data;
uint256 salt = transaction.salt;
address signerAddress = transaction.signerAddress;
// Assembly for more efficiently computing:
// keccak256(abi.encodePacked(
// EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH,
// transaction.salt,
// uint256(transaction.signerAddress),
// keccak256(transaction.data)
// ));
assembly {
// Compute hash of data
let dataHash := keccak256(add(data, 32), mload(data))
// Load free memory pointer
let memPtr := mload(64)
mstore(memPtr, schemaHash) // hash of schema
mstore(add(memPtr, 32), salt) // salt
mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) // signerAddress
mstore(add(memPtr, 96), dataHash) // hash of data
// Compute hash
result := keccak256(memPtr, 128)
}
return result;
}
}

View File

@@ -36,7 +36,7 @@ contract TestLibs is
{
constructor (uint256 chainId)
public
LibEIP712ExchangeDomain(chainId)
LibEIP712ExchangeDomain(chainId, address(0))
{}
function publicAbiEncodeFillOrder(

View File

@@ -34,7 +34,7 @@
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
},
"config": {
"abis": "./generated-artifacts/@(LibAbiEncoder|LibAssetProxyErrors|LibConstants|LibEIP712|LibEIP712ExchangeDomainConstants|LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|TestLibs).json",
"abis": "./generated-artifacts/@(LibAbiEncoder|LibAssetProxyErrors|LibConstants|LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibs).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {

View File

@@ -8,18 +8,20 @@ import { ContractArtifact } from 'ethereum-types';
import * as LibAbiEncoder from '../generated-artifacts/LibAbiEncoder.json';
import * as LibAssetProxyErrors from '../generated-artifacts/LibAssetProxyErrors.json';
import * as LibConstants from '../generated-artifacts/LibConstants.json';
import * as LibEIP712 from '../generated-artifacts/LibEIP712.json';
import * as LibEIP712ExchangeDomain from '../generated-artifacts/LibEIP712ExchangeDomain.json';
import * as LibFillResults from '../generated-artifacts/LibFillResults.json';
import * as LibMath from '../generated-artifacts/LibMath.json';
import * as LibOrder from '../generated-artifacts/LibOrder.json';
import * as LibZeroExTransaction from '../generated-artifacts/LibZeroExTransaction.json';
import * as TestLibs from '../generated-artifacts/TestLibs.json';
export const artifacts = {
LibAbiEncoder: LibAbiEncoder as ContractArtifact,
LibAssetProxyErrors: LibAssetProxyErrors as ContractArtifact,
LibConstants: LibConstants as ContractArtifact,
LibEIP712: LibEIP712 as ContractArtifact,
LibFillResults: LibFillResults as ContractArtifact,
LibMath: LibMath as ContractArtifact,
LibOrder: LibOrder as ContractArtifact,
LibZeroExTransaction: LibZeroExTransaction as ContractArtifact,
LibEIP712ExchangeDomain: LibEIP712ExchangeDomain as ContractArtifact,
TestLibs: TestLibs as ContractArtifact,
};

View File

@@ -6,8 +6,9 @@
export * from '../generated-wrappers/lib_abi_encoder';
export * from '../generated-wrappers/lib_asset_proxy_errors';
export * from '../generated-wrappers/lib_constants';
export * from '../generated-wrappers/lib_e_i_p712';
export * from '../generated-wrappers/lib_e_i_p712_exchange_domain';
export * from '../generated-wrappers/lib_fill_results';
export * from '../generated-wrappers/lib_math';
export * from '../generated-wrappers/lib_order';
export * from '../generated-wrappers/lib_zero_ex_transaction';
export * from '../generated-wrappers/test_libs';

View File

@@ -6,10 +6,11 @@
"generated-artifacts/LibAbiEncoder.json",
"generated-artifacts/LibAssetProxyErrors.json",
"generated-artifacts/LibConstants.json",
"generated-artifacts/LibEIP712.json",
"generated-artifacts/LibEIP712ExchangeDomain.json",
"generated-artifacts/LibFillResults.json",
"generated-artifacts/LibMath.json",
"generated-artifacts/LibOrder.json",
"generated-artifacts/LibZeroExTransaction.json",
"generated-artifacts/TestLibs.json"
],
"exclude": ["./deploy/solc/solc_bin"]