/* Copyright 2019 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.9; pragma experimental ABIEncoderV2; import "./LibEIP712CoordinatorDomain.sol"; contract LibCoordinatorApproval is LibEIP712CoordinatorDomain { // Hash for the EIP712 Coordinator approval message // keccak256(abi.encodePacked( // "CoordinatorApproval(", // "address txOrigin,", // "bytes32 transactionHash,", // "bytes transactionSignature", // ")" // )); bytes32 constant public EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH = 0xa6511c04ca44625d50986f8c36bedc09366207a17b96e347094053a9f8507168; struct CoordinatorApproval { address txOrigin; // Required signer of Ethereum transaction that is submitting approval. bytes32 transactionHash; // EIP712 hash of the transaction. bytes transactionSignature; // Signature of the 0x transaction. } /// @dev Calculates the EIP712 hash of the Coordinator approval mesasage using the domain /// separator of this contract. /// @param approval Coordinator approval message containing the transaction hash, and transaction /// signature. /// @return approvalHash EIP712 hash of the Coordinator approval message with the domain /// separator of this contract. function getCoordinatorApprovalHash(CoordinatorApproval memory approval) public view returns (bytes32 approvalHash) { approvalHash = _hashEIP712CoordinatorMessage(_hashCoordinatorApproval(approval)); return approvalHash; } /// @dev Calculates the EIP712 hash of the Coordinator approval mesasage with no domain separator. /// @param approval Coordinator approval message containing the transaction hash, and transaction // signature. /// @return result EIP712 hash of the Coordinator approval message with no domain separator. function _hashCoordinatorApproval(CoordinatorApproval memory approval) internal pure returns (bytes32 result) { bytes32 schemaHash = EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH; bytes memory transactionSignature = approval.transactionSignature; address txOrigin = approval.txOrigin; bytes32 transactionHash = approval.transactionHash; // Assembly for more efficiently computing: // keccak256(abi.encodePacked( // EIP712_COORDINATOR_APPROVAL_SCHEMA_HASH, // approval.txOrigin, // approval.transactionHash, // keccak256(approval.transactionSignature) // )); assembly { // Compute hash of transaction signature let transactionSignatureHash := keccak256(add(transactionSignature, 32), mload(transactionSignature)) // Load free memory pointer let memPtr := mload(64) mstore(memPtr, schemaHash) // hash of schema mstore(add(memPtr, 32), txOrigin) // txOrigin mstore(add(memPtr, 64), transactionHash) // transactionHash mstore(add(memPtr, 96), transactionSignatureHash) // transactionSignatureHash // Compute hash result := keccak256(memPtr, 128) } return result; } }