Added unit tests for LibEIP712
This commit is contained in:
parent
065f46a020
commit
f9292a8fb8
@ -42,6 +42,7 @@ export const constants = {
|
||||
NUM_ERC1155_FUNGIBLE_TOKENS_MINT: 4,
|
||||
NUM_ERC1155_NONFUNGIBLE_TOKENS_MINT: 4,
|
||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
NULL_BYTES32: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
||||
UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
|
||||
TESTRPC_PRIVATE_KEYS: _.map(TESTRPC_PRIVATE_KEYS_STRINGS, privateKeyString => ethUtil.toBuffer(privateKeyString)),
|
||||
INITIAL_ERC20_BALANCE: Web3Wrapper.toBaseUnitAmount(new BigNumber(10000), 18),
|
||||
|
@ -36,6 +36,7 @@
|
||||
"test/TestLibAddress.sol",
|
||||
"test/TestLibAddressArray.sol",
|
||||
"test/TestLibBytes.sol",
|
||||
"test/TestLibEIP712.sol",
|
||||
"test/TestOwnable.sol",
|
||||
"test/TestReentrancyGuard.sol",
|
||||
"test/TestSafeMath.sol"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
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.
|
||||
|
52
contracts/utils/contracts/test/TestLibEIP712.sol
Normal file
52
contracts/utils/contracts/test/TestLibEIP712.sol
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
|
||||
import "../src/LibEIP712.sol";
|
||||
|
||||
|
||||
contract TestLibEIP712 is
|
||||
LibEIP712
|
||||
{
|
||||
function externalHashEIP712DomainSeperator(
|
||||
string calldata name,
|
||||
string calldata version,
|
||||
uint256 chainid,
|
||||
address verifyingcontractaddress
|
||||
)
|
||||
external
|
||||
pure
|
||||
returns (bytes32)
|
||||
{
|
||||
return _hashEIP712Domain(
|
||||
name,
|
||||
version,
|
||||
chainid,
|
||||
verifyingcontractaddress
|
||||
);
|
||||
}
|
||||
|
||||
function externalHashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)
|
||||
external
|
||||
pure
|
||||
returns (bytes32)
|
||||
{
|
||||
return _hashEIP712Message(eip712DomainHash, hashStruct);
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@
|
||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./generated-artifacts/@(IOwnable|LibAddress|LibBytes|LibEIP1271|LibEIP712|Ownable|ReentrancyGuard|SafeMath|TestConstants|TestLibAddress|TestLibAddressArray|TestLibBytes|TestOwnable|TestReentrancyGuard|TestSafeMath).json",
|
||||
"abis": "./generated-artifacts/@(IOwnable|LibAddress|LibBytes|LibEIP1271|LibEIP712|Ownable|ReentrancyGuard|SafeMath|TestConstants|TestLibAddress|TestLibAddressArray|TestLibBytes|TestLibEIP712|TestOwnable|TestReentrancyGuard|TestSafeMath).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
@ -17,6 +17,7 @@ import * as TestConstants from '../generated-artifacts/TestConstants.json';
|
||||
import * as TestLibAddress from '../generated-artifacts/TestLibAddress.json';
|
||||
import * as TestLibAddressArray from '../generated-artifacts/TestLibAddressArray.json';
|
||||
import * as TestLibBytes from '../generated-artifacts/TestLibBytes.json';
|
||||
import * as TestLibEIP712 from '../generated-artifacts/TestLibEIP712.json';
|
||||
import * as TestOwnable from '../generated-artifacts/TestOwnable.json';
|
||||
import * as TestReentrancyGuard from '../generated-artifacts/TestReentrancyGuard.json';
|
||||
import * as TestSafeMath from '../generated-artifacts/TestSafeMath.json';
|
||||
@ -33,6 +34,7 @@ export const artifacts = {
|
||||
TestLibAddress: TestLibAddress as ContractArtifact,
|
||||
TestLibAddressArray: TestLibAddressArray as ContractArtifact,
|
||||
TestLibBytes: TestLibBytes as ContractArtifact,
|
||||
TestLibEIP712: TestLibEIP712 as ContractArtifact,
|
||||
TestOwnable: TestOwnable as ContractArtifact,
|
||||
TestReentrancyGuard: TestReentrancyGuard as ContractArtifact,
|
||||
TestSafeMath: TestSafeMath as ContractArtifact,
|
||||
|
@ -15,6 +15,7 @@ export * from '../generated-wrappers/test_constants';
|
||||
export * from '../generated-wrappers/test_lib_address';
|
||||
export * from '../generated-wrappers/test_lib_address_array';
|
||||
export * from '../generated-wrappers/test_lib_bytes';
|
||||
export * from '../generated-wrappers/test_lib_e_i_p712';
|
||||
export * from '../generated-wrappers/test_ownable';
|
||||
export * from '../generated-wrappers/test_reentrancy_guard';
|
||||
export * from '../generated-wrappers/test_safe_math';
|
||||
|
107
contracts/utils/test/lib_eip712.ts
Normal file
107
contracts/utils/test/lib_eip712.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import { chaiSetup, constants, hexConcat, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
|
||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||
import { BigNumber, signTypedDataUtils } from '@0x/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts, TestLibEIP712Contract } from '../src';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
/**
|
||||
* Tests a specific instance of EIP712 domain hashing.
|
||||
* @param lib The LibEIP712 contract to call.
|
||||
* @param name The name of the domain.
|
||||
* @param version The version of the domain.
|
||||
* @param chainId The chain id of the domain.
|
||||
* @param verifyingContractAddress The verifying contract address of the domain.
|
||||
*/
|
||||
async function testHashEIP712DomainAsync(
|
||||
lib: TestLibEIP712Contract,
|
||||
name: string,
|
||||
version: string,
|
||||
chainId: number,
|
||||
verifyingContractAddress: string,
|
||||
): Promise<void> {
|
||||
const expectedHash = signTypedDataUtils.generateDomainHash({
|
||||
name,
|
||||
version,
|
||||
chainId,
|
||||
verifyingContractAddress,
|
||||
});
|
||||
const actualHash = await lib.externalHashEIP712DomainSeperator.callAsync(
|
||||
name,
|
||||
version,
|
||||
new BigNumber(chainId),
|
||||
verifyingContractAddress,
|
||||
);
|
||||
expect(actualHash).to.be.eq(hexConcat(expectedHash));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a specific instance of EIP712 message hashing.
|
||||
* @param lib The LibEIP712 contract to call.
|
||||
* @param domainHash The hash of the EIP712 domain of this instance.
|
||||
* @param hashStruct The hash of the struct of this instance.
|
||||
*/
|
||||
async function testHashEIP712MessageAsync(
|
||||
lib: TestLibEIP712Contract,
|
||||
domainHash: string,
|
||||
hashStruct: string,
|
||||
): Promise<void> {
|
||||
const input = '0x1901'.concat(domainHash.slice(2, domainHash.length).concat(hashStruct.slice(2, hashStruct.length)));
|
||||
const expectedHash = '0x'.concat(ethUtil.sha3(input).toString('hex'));
|
||||
const actualHash = await lib.externalHashEIP712Message.callAsync(
|
||||
domainHash,
|
||||
hashStruct,
|
||||
);
|
||||
expect(actualHash).to.be.eq(expectedHash);
|
||||
}
|
||||
|
||||
describe('LibEIP712', () => {
|
||||
let lib: TestLibEIP712Contract;
|
||||
|
||||
before(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
// Deploy SafeMath
|
||||
lib = await TestLibEIP712Contract.deployFrom0xArtifactAsync(
|
||||
artifacts.TestLibEIP712,
|
||||
provider,
|
||||
txDefaults,
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
|
||||
describe('_hashEIP712Domain', async () => {
|
||||
it('should correctly hash empty input', async () => {
|
||||
await testHashEIP712DomainAsync(
|
||||
lib,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
constants.NULL_ADDRESS,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_hashEIP712Message', () => {
|
||||
it('should correctly hash empty input', async () => {
|
||||
/*
|
||||
const expectedHash = hashEIP712Message(constants.NULL_BYTES32, constants.NULL_BYTES32);
|
||||
const actualHash = await lib.externalHashEIP712Message.callAsync(constants.NULL_BYTES32, constants.NULL_BYTES32);
|
||||
expect(actualHash).to.be.eq(expectedHash);
|
||||
*/
|
||||
await testHashEIP712MessageAsync(
|
||||
lib,
|
||||
constants.NULL_BYTES32,
|
||||
constants.NULL_BYTES32,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
@ -15,6 +15,7 @@
|
||||
"generated-artifacts/TestLibAddress.json",
|
||||
"generated-artifacts/TestLibAddressArray.json",
|
||||
"generated-artifacts/TestLibBytes.json",
|
||||
"generated-artifacts/TestLibEIP712.json",
|
||||
"generated-artifacts/TestOwnable.json",
|
||||
"generated-artifacts/TestReentrancyGuard.json",
|
||||
"generated-artifacts/TestSafeMath.json"
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { EIP712Object, EIP712ObjectValue, EIP712TypedData, EIP712Types } from '@0x/types';
|
||||
import { EIP712DomainWithDefaultSchema, EIP712Object, EIP712ObjectValue, EIP712TypedData, EIP712Types } from '@0x/types';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as ethers from 'ethers';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { BigNumber } from './configured_bignumber';
|
||||
|
||||
|
||||
export const signTypedDataUtils = {
|
||||
/**
|
||||
* Generates the EIP712 Typed Data hash for signing
|
||||
@ -20,6 +21,28 @@ export const signTypedDataUtils = {
|
||||
]),
|
||||
);
|
||||
},
|
||||
/**
|
||||
* Generates the hash of a EIP712 Domain with the default schema
|
||||
* @param domain An EIP712 domain with the default schema containing a name, version, chain id,
|
||||
* and verifying address.
|
||||
* @return A buffer that contains the hash of the domain.
|
||||
*/
|
||||
generateDomainHash(domain: EIP712Object): Buffer {
|
||||
return signTypedDataUtils._structHash(
|
||||
'EIP712Domain',
|
||||
domain,
|
||||
// HACK(jalextowle): When we consolidate our testing packages into test-utils, we can use a constant
|
||||
// to eliminate code duplication. At the moment, there isn't a good way to do that because of cyclic-dependencies.
|
||||
{
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContractAddress', type: 'address' },
|
||||
]
|
||||
} as EIP712Types,
|
||||
);
|
||||
},
|
||||
_findDependencies(primaryType: string, types: EIP712Types, found: string[] = []): string[] {
|
||||
if (found.includes(primaryType) || types[primaryType] === undefined) {
|
||||
return found;
|
||||
|
Loading…
x
Reference in New Issue
Block a user