Add signature validator tests
This commit is contained in:
parent
99aeaddf42
commit
bebcd99b3b
@ -16,5 +16,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"contracts": ["TEC", "TestLibs", "MixinSignatureValidator"]
|
"contracts": ["src/MixinSignatureValidator.sol", "src/TEC.sol", "test/TestLibs.sol"]
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@
|
|||||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "generated-artifacts/@(TEC|TestLibs|TestInternals).json"
|
"abis": "./generated-artifacts/@(MixinSignatureValidator|TEC|TestLibs).json",
|
||||||
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -78,6 +79,7 @@
|
|||||||
"@0x/typescript-typings": "^4.0.0",
|
"@0x/typescript-typings": "^4.0.0",
|
||||||
"@0x/utils": "^4.1.0",
|
"@0x/utils": "^4.1.0",
|
||||||
"@0x/web3-wrapper": "^5.0.0",
|
"@0x/web3-wrapper": "^5.0.0",
|
||||||
|
"ethereumjs-util": "^5.1.1",
|
||||||
"ethereum-types": "^2.0.0",
|
"ethereum-types": "^2.0.0",
|
||||||
"lodash": "^4.17.11"
|
"lodash": "^4.17.11"
|
||||||
},
|
},
|
||||||
|
15
contracts/tec/src/artifacts.ts
Normal file
15
contracts/tec/src/artifacts.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
import { ContractArtifact } from 'ethereum-types';
|
||||||
|
|
||||||
|
import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
|
||||||
|
import * as TEC from '../generated-artifacts/TEC.json';
|
||||||
|
import * as TestLibs from '../generated-artifacts/TestLibs.json';
|
||||||
|
export const artifacts = {
|
||||||
|
TEC: TEC as ContractArtifact,
|
||||||
|
TestLibs: TestLibs as ContractArtifact,
|
||||||
|
MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
|
||||||
|
};
|
@ -1,11 +0,0 @@
|
|||||||
import { ContractArtifact } from 'ethereum-types';
|
|
||||||
|
|
||||||
import * as TEC from '../../generated-artifacts/TEC.json';
|
|
||||||
import * as TestInternals from '../../generated-artifacts/TestInternals.json';
|
|
||||||
import * as TestLibs from '../../generated-artifacts/TestLibs.json';
|
|
||||||
|
|
||||||
export const artifacts = {
|
|
||||||
TEC: TEC as ContractArtifact,
|
|
||||||
TestLibs: TestLibs as ContractArtifact,
|
|
||||||
TestInternals: TestInternals as ContractArtifact,
|
|
||||||
};
|
|
8
contracts/tec/src/wrappers.ts
Normal file
8
contracts/tec/src/wrappers.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
export * from '../generated-wrappers/mixin_signature_validator';
|
||||||
|
export * from '../generated-wrappers/tec';
|
||||||
|
export * from '../generated-wrappers/test_libs';
|
@ -1,3 +0,0 @@
|
|||||||
export * from '../../generated-wrappers/tec';
|
|
||||||
export * from '../../generated-wrappers/test_libs';
|
|
||||||
export * from '../../generated-wrappers/test_internals';
|
|
@ -1,56 +0,0 @@
|
|||||||
import { chaiSetup, constants, provider, TransactionFactory, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
|
|
||||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
|
||||||
import { transactionHashUtils } from '@0x/order-utils';
|
|
||||||
import { BigNumber } from '@0x/utils';
|
|
||||||
import * as chai from 'chai';
|
|
||||||
|
|
||||||
import { artifacts, TestInternalsContract } from '../src';
|
|
||||||
|
|
||||||
chaiSetup.configure();
|
|
||||||
const expect = chai.expect;
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
|
||||||
|
|
||||||
describe('Internals tests', () => {
|
|
||||||
let transactionSignerAddress: string;
|
|
||||||
let approvalSignerAddress: string;
|
|
||||||
let testInternals: TestInternalsContract;
|
|
||||||
let transactionFactory: TransactionFactory;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
|
||||||
});
|
|
||||||
after(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
before(async () => {
|
|
||||||
testInternals = await TestInternalsContract.deployFrom0xArtifactAsync(
|
|
||||||
artifacts.TestInternals,
|
|
||||||
provider,
|
|
||||||
txDefaults,
|
|
||||||
);
|
|
||||||
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
|
||||||
[transactionSignerAddress, approvalSignerAddress] = accounts.slice(0, 2);
|
|
||||||
const transactionSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[0];
|
|
||||||
const approvalSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[1];
|
|
||||||
transactionFactory = new TransactionFactory(transactionSignerPrivateKey, testInternals.address);
|
|
||||||
});
|
|
||||||
beforeEach(async () => {
|
|
||||||
await blockchainLifecycle.startAsync();
|
|
||||||
});
|
|
||||||
afterEach(async () => {
|
|
||||||
await blockchainLifecycle.revertAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getSignerAddress', () => {
|
|
||||||
it('should return the correct address', async () => {
|
|
||||||
const data = constants.NULL_BYTES;
|
|
||||||
const transaction = transactionFactory.newSignedTransaction(data);
|
|
||||||
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
|
||||||
const signerAddress = await testInternals.publicGetSignerAddress.callAsync(
|
|
||||||
transactionHash,
|
|
||||||
transaction.signature,
|
|
||||||
);
|
|
||||||
expect(transaction.signerAddress).to.eq(signerAddress);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
103
contracts/tec/test/mixins.ts
Normal file
103
contracts/tec/test/mixins.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
chaiSetup,
|
||||||
|
constants,
|
||||||
|
expectContractCallFailedAsync,
|
||||||
|
provider,
|
||||||
|
txDefaults,
|
||||||
|
web3Wrapper,
|
||||||
|
} from '@0x/contracts-test-utils';
|
||||||
|
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||||
|
import { transactionHashUtils } from '@0x/order-utils';
|
||||||
|
import { RevertReason } from '@0x/types';
|
||||||
|
import { BigNumber } from '@0x/utils';
|
||||||
|
import * as chai from 'chai';
|
||||||
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
|
import { artifacts, MixinSignatureValidatorContract, TECSignatureType, TECTransactionFactory } from '../src';
|
||||||
|
|
||||||
|
chaiSetup.configure();
|
||||||
|
const expect = chai.expect;
|
||||||
|
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||||
|
|
||||||
|
describe('Mixins tests', () => {
|
||||||
|
let transactionSignerAddress: string;
|
||||||
|
let approvalSignerAddress: string;
|
||||||
|
let signatureValidator: MixinSignatureValidatorContract;
|
||||||
|
let transactionFactory: TECTransactionFactory;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await blockchainLifecycle.startAsync();
|
||||||
|
});
|
||||||
|
after(async () => {
|
||||||
|
await blockchainLifecycle.revertAsync();
|
||||||
|
});
|
||||||
|
before(async () => {
|
||||||
|
signatureValidator = await MixinSignatureValidatorContract.deployFrom0xArtifactAsync(
|
||||||
|
artifacts.MixinSignatureValidator,
|
||||||
|
provider,
|
||||||
|
txDefaults,
|
||||||
|
);
|
||||||
|
const accounts = await web3Wrapper.getAvailableAddressesAsync();
|
||||||
|
[transactionSignerAddress, approvalSignerAddress] = accounts.slice(0, 2);
|
||||||
|
const transactionSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[0];
|
||||||
|
const approvalSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[1];
|
||||||
|
transactionFactory = new TECTransactionFactory(transactionSignerPrivateKey, signatureValidator.address);
|
||||||
|
});
|
||||||
|
beforeEach(async () => {
|
||||||
|
await blockchainLifecycle.startAsync();
|
||||||
|
});
|
||||||
|
afterEach(async () => {
|
||||||
|
await blockchainLifecycle.revertAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSignerAddress', () => {
|
||||||
|
it('should return the correct address using the EthSign signature type', async () => {
|
||||||
|
const data = constants.NULL_BYTES;
|
||||||
|
const transaction = transactionFactory.newSignedTECTransaction(data, TECSignatureType.EthSign);
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
const signerAddress = await signatureValidator.getSignerAddress.callAsync(
|
||||||
|
transactionHash,
|
||||||
|
transaction.signature,
|
||||||
|
);
|
||||||
|
expect(transaction.signerAddress).to.eq(signerAddress);
|
||||||
|
});
|
||||||
|
it('should return the correct address using the EIP712 signature type', async () => {
|
||||||
|
const data = constants.NULL_BYTES;
|
||||||
|
const transaction = transactionFactory.newSignedTECTransaction(data, TECSignatureType.EIP712);
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
const signerAddress = await signatureValidator.getSignerAddress.callAsync(
|
||||||
|
transactionHash,
|
||||||
|
transaction.signature,
|
||||||
|
);
|
||||||
|
expect(transaction.signerAddress).to.eq(signerAddress);
|
||||||
|
});
|
||||||
|
it('should revert with with the Illegal signature type', async () => {
|
||||||
|
const data = constants.NULL_BYTES;
|
||||||
|
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||||
|
const illegalSignatureByte = ethUtil.toBuffer(TECSignatureType.Illegal).toString('hex');
|
||||||
|
transaction.signature = `${transaction.signature.slice(
|
||||||
|
0,
|
||||||
|
transaction.signature.length - 2,
|
||||||
|
)}${illegalSignatureByte}`;
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expectContractCallFailedAsync(
|
||||||
|
signatureValidator.getSignerAddress.callAsync(transactionHash, transaction.signature),
|
||||||
|
RevertReason.SignatureIllegal,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it("should revert with with a signature type that doesn't exist", async () => {
|
||||||
|
const data = constants.NULL_BYTES;
|
||||||
|
const transaction = transactionFactory.newSignedTECTransaction(data);
|
||||||
|
const invalidSignatureByte = '03';
|
||||||
|
transaction.signature = `${transaction.signature.slice(
|
||||||
|
0,
|
||||||
|
transaction.signature.length - 2,
|
||||||
|
)}${invalidSignatureByte}`;
|
||||||
|
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
|
||||||
|
expectContractCallFailedAsync(
|
||||||
|
signatureValidator.getSignerAddress.callAsync(transactionHash, transaction.signature),
|
||||||
|
RevertReason.SignatureUnsupported,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1 +1,3 @@
|
|||||||
export { approvalHashUtils } from './approval_hash';
|
export { approvalHashUtils } from './approval_hash';
|
||||||
|
export { TECTransactionFactory } from './tec_transaction_factory';
|
||||||
|
export * from './types';
|
||||||
|
31
contracts/tec/test/utils/tec_transaction_factory.ts
Normal file
31
contracts/tec/test/utils/tec_transaction_factory.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { TransactionFactory } from '@0x/contracts-test-utils';
|
||||||
|
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
|
||||||
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
|
import { TECSignatureType } from './types';
|
||||||
|
|
||||||
|
export class TECTransactionFactory extends TransactionFactory {
|
||||||
|
constructor(privateKey: Buffer, exchangeAddress: string) {
|
||||||
|
super(privateKey, exchangeAddress);
|
||||||
|
}
|
||||||
|
public newSignedTECTransaction(
|
||||||
|
data: string,
|
||||||
|
signatureType: TECSignatureType = TECSignatureType.EthSign,
|
||||||
|
): SignedZeroExTransaction {
|
||||||
|
let exchangeSignatureType;
|
||||||
|
if (signatureType === TECSignatureType.EthSign) {
|
||||||
|
exchangeSignatureType = SignatureType.EthSign;
|
||||||
|
} else if (signatureType === TECSignatureType.EIP712) {
|
||||||
|
exchangeSignatureType = SignatureType.EIP712;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Error: ${signatureType} not a valid signature type`);
|
||||||
|
}
|
||||||
|
const signedTransaction = super.newSignedTransaction(data, exchangeSignatureType);
|
||||||
|
const tecSignatureTypeByte = ethUtil.toBuffer(signatureType).toString('hex');
|
||||||
|
signedTransaction.signature = `${signedTransaction.signature.slice(
|
||||||
|
0,
|
||||||
|
signedTransaction.signature.length - 2,
|
||||||
|
)}${tecSignatureTypeByte}`;
|
||||||
|
return signedTransaction;
|
||||||
|
}
|
||||||
|
}
|
@ -5,3 +5,10 @@ export interface TECApproval {
|
|||||||
transactionSignature: string;
|
transactionSignature: string;
|
||||||
approvalExpirationTimeSeconds: BigNumber;
|
approvalExpirationTimeSeconds: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum TECSignatureType {
|
||||||
|
Illegal,
|
||||||
|
EIP712,
|
||||||
|
EthSign,
|
||||||
|
NSignatureTypes,
|
||||||
|
}
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig",
|
"extends": "../../tsconfig",
|
||||||
"compilerOptions": {
|
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||||
"outDir": "lib",
|
|
||||||
"rootDir": ".",
|
|
||||||
"resolveJsonModule": true
|
|
||||||
},
|
|
||||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||||
"files": [
|
"files": [
|
||||||
"./generated-artifacts/TEC.json",
|
"generated-artifacts/MixinSignatureValidator.json",
|
||||||
"./generated-artifacts/TestLibs.json",
|
"generated-artifacts/TEC.json",
|
||||||
"./generated-artifacts/TestInternals.json"
|
"generated-artifacts/TestLibs.json"
|
||||||
],
|
],
|
||||||
"exclude": ["./deploy/solc/solc_bin"]
|
"exclude": ["./deploy/solc/solc_bin"]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user