Refactor EIP712 contracts to reduce code duplication.

This commit is contained in:
Lawrence Forman
2019-03-21 13:49:12 -04:00
committed by Amir Bandeali
parent 4bbaa6b41c
commit 64b4158bad
11 changed files with 212 additions and 127 deletions

View File

@@ -19,8 +19,8 @@
pragma solidity ^0.5.5;
pragma experimental "ABIEncoderV2";
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712.sol";
import "./libs/LibConstants.sol";
import "./libs/LibEIP712Domain.sol";
import "./MixinSignatureValidator.sol";
import "./MixinCoordinatorApprovalVerifier.sol";
import "./MixinCoordinatorCore.sol";
@@ -29,7 +29,7 @@ import "./MixinCoordinatorCore.sol";
// solhint-disable no-empty-blocks
contract Coordinator is
LibConstants,
LibEIP712Domain,
LibEIP712,
MixinSignatureValidator,
MixinCoordinatorApprovalVerifier,
MixinCoordinatorCore
@@ -38,6 +38,7 @@ contract Coordinator is
/// @param _chainId Chain ID of the network this contract is deployed on.
constructor (address _exchange, uint256 _chainId)
public
LibConstants(_exchange, _chainId)
LibConstants(_exchange)
LibEIP712(_chainId)
{}
}

View File

@@ -26,15 +26,11 @@ contract LibConstants {
// The 0x Exchange contract.
ITransactions internal EXCHANGE;
// The numerical ID of the network this contract is deployed on.
uint256 internal CHAIN_ID;
/// @param _exchange Address of the 0x Exchange contract.
/// @param _chainId Chain ID of the network this contract is deployed on.
constructor (address _exchange, uint256 _chainId)
constructor (address _exchange)
public
{
EXCHANGE = ITransactions(_exchange);
CHAIN_ID = _chainId;
}
}

View File

@@ -18,63 +18,33 @@
pragma solidity ^0.5.5;
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712.sol";
import "./LibConstants.sol";
// solhint-disable var-name-mixedcase
contract LibEIP712Domain is
LibConstants
LibConstants,
LibEIP712
{
// EIP191 header for EIP712 prefix
string constant internal EIP191_HEADER = "\x19\x01";
// EIP712 Domain Name value for the Coordinator
string constant internal EIP712_COORDINATOR_DOMAIN_NAME = "0x Protocol Coordinator";
// 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 = "3.0.0";
// 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 verifyingContract",
")"
));
// Hash of the EIP712 Domain Separator data for the Coordinator
bytes32 public EIP712_COORDINATOR_DOMAIN_HASH;
// Hash of the EIP712 Domain Separator data for the Exchange
bytes32 public EIP712_EXCHANGE_DOMAIN_HASH;
constructor ()
public
{
EIP712_COORDINATOR_DOMAIN_HASH = keccak256(abi.encodePacked(
EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,
keccak256(bytes(EIP712_COORDINATOR_DOMAIN_NAME)),
keccak256(bytes(EIP712_COORDINATOR_DOMAIN_VERSION)),
CHAIN_ID,
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)),
CHAIN_ID,
uint256(address(EXCHANGE))
));
EIP712_COORDINATOR_DOMAIN_HASH = hashEIP712Domain(
EIP712_COORDINATOR_DOMAIN_NAME,
EIP712_COORDINATOR_DOMAIN_VERSION,
address(this)
);
}
/// @dev Calculates EIP712 encoding for a hash struct in the EIP712 domain
@@ -100,34 +70,4 @@ contract LibEIP712Domain is
{
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
// ));
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

@@ -0,0 +1,64 @@
/*
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 "@0x/contracts-exchange-libs/contracts/src/LibEIP712.sol";
import "../src/libs/LibConstants.sol";
import "../src/libs/LibCoordinatorApproval.sol";
import "../src/libs/LibZeroExTransaction.sol";
// solhint-disable no-empty-blocks
contract TestLibs is
LibConstants,
LibEIP712,
LibCoordinatorApproval,
LibZeroExTransaction
{
constructor (address _exchange, uint256 _chainId)
public
LibConstants(_exchange)
LibEIP712(_chainId)
{}
/// @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.
function publicGetCoordinatorApprovalHash(CoordinatorApproval memory approval)
public
view
returns (bytes32 approvalHash)
{
approvalHash = getCoordinatorApprovalHash(approval);
return approvalHash;
}
/// @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 the Exchange contract.
function publicGetTransactionHash(ZeroExTransaction memory transaction)
public
view
returns (bytes32 transactionHash)
{
transactionHash = getTransactionHash(transaction);
return transactionHash;
}
}

View File

@@ -0,0 +1,40 @@
/*
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 "@0x/contracts-exchange-libs/contracts/src/LibEIP712.sol";
import "../src/libs/LibConstants.sol";
import "../src/MixinSignatureValidator.sol";
import "../src/MixinCoordinatorApprovalVerifier.sol";
// solhint-disable no-empty-blocks
contract TestMixins is
LibConstants,
LibEIP712,
MixinSignatureValidator,
MixinCoordinatorApprovalVerifier
{
constructor (address _exchange, uint256 _chainId)
public
LibConstants(_exchange)
LibEIP712(_chainId)
{}
}