From d46e3f677805c8e3e4b4873fb9b0cec2988a4d63 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 19 Jun 2018 17:20:53 -0700 Subject: Twenty new tests for MixinSignatureValidator. Fixed handling of unsupported types. Fixed trezor prefix. --- .../contracts/test/exchange/signature_validator.ts | 401 ++++++++++++++++++++- 1 file changed, 386 insertions(+), 15 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index c39fd6ee4..8f796361f 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -1,12 +1,16 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; -import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils'; -import { SignedOrder } from '@0xproject/types'; +import { addSignedMessagePrefix, assetProxyUtils, MessagePrefixType, orderHashUtils } from '@0xproject/order-utils'; +import { SignatureType, SignedOrder } from '@0xproject/types'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); +import * as _ from 'lodash'; import { TestSignatureValidatorContract } from '../../src/generated_contract_wrappers/test_signature_validator'; +import { TestValidatorContract } from '../../src/generated_contract_wrappers/test_validator'; +import { TestWalletContract } from '../../src/generated_contract_wrappers/test_wallet'; import { addressUtils } from '../../src/utils/address_utils'; import { artifacts } from '../../src/utils/artifacts'; +import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions'; import { chaiSetup } from '../../src/utils/chai_setup'; import { constants } from '../../src/utils/constants'; import { OrderFactory } from '../../src/utils/order_factory'; @@ -21,6 +25,12 @@ describe('MixinSignatureValidator', () => { let signedOrder: SignedOrder; let orderFactory: OrderFactory; let signatureValidator: TestSignatureValidatorContract; + let testWallet: TestWalletContract; + let testValidator: TestValidatorContract; + let signerAddress: string; + let signerPrivateKey: Buffer; + let notSignerAddress: string; + let notSignerPrivateKey: Buffer; before(async () => { await blockchainLifecycle.startAsync(); @@ -31,11 +41,31 @@ describe('MixinSignatureValidator', () => { before(async () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); const makerAddress = accounts[0]; + signerAddress = makerAddress; + notSignerAddress = accounts[1]; signatureValidator = await TestSignatureValidatorContract.deployFrom0xArtifactAsync( artifacts.TestSignatureValidator, provider, txDefaults, ); + testWallet = await TestWalletContract.deployFrom0xArtifactAsync( + artifacts.TestWallet, + provider, + txDefaults, + signerAddress, + ); + testValidator = await TestValidatorContract.deployFrom0xArtifactAsync( + artifacts.TestValidator, + provider, + txDefaults, + signerAddress, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync(testValidator.address, true, { + from: signerAddress, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); const defaultOrderParams = { ...constants.STATIC_ORDER_PARAMS, @@ -45,8 +75,9 @@ describe('MixinSignatureValidator', () => { makerAssetData: assetProxyUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()), takerAssetData: assetProxyUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()), }; - const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; - orderFactory = new OrderFactory(privateKey, defaultOrderParams); + signerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; + notSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(notSignerAddress)]; + orderFactory = new OrderFactory(signerPrivateKey, defaultOrderParams); }); beforeEach(async () => { @@ -61,29 +92,369 @@ describe('MixinSignatureValidator', () => { signedOrder = orderFactory.newSignedOrder(); }); - it('should return true with a valid signature', async () => { + it('should revert with an empty signature', async () => { + const emptySignature = '0x'; + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + return expectRevertOrAlwaysFailingTransactionAsync( + signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signedOrder.makerAddress, + emptySignature, + ), + ); + }); + + it('should revert with an unsupported signature type', async () => { + const unsupportedSignatureType = SignatureType.NSignatureTypes; + const unsupportedSignatureHex = `0x${unsupportedSignatureType}`; + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + return expectRevertOrAlwaysFailingTransactionAsync( + signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signedOrder.makerAddress, + unsupportedSignatureHex, + ), + ); + }); + + it('should revert when SignatureType=Illegal', async () => { + const unsupportedSignatureHex = `0x${SignatureType.Illegal}`; + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + return expectRevertOrAlwaysFailingTransactionAsync( + signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signedOrder.makerAddress, + unsupportedSignatureHex, + ), + ); + }); + + it('should return false when SignatureType=Invalid and signature has a length of zero', async () => { + const signatureHex = `0x${SignatureType.Invalid}`; + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signedOrder.makerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should revert when SignatureType=Invalid and signature length is non-zero', async () => { + const fillerData = ethUtil.toBuffer('0xdeadbeef'); + const signatureType = ethUtil.toBuffer(`0x${SignatureType.Invalid}`); + const signatureBuffer = Buffer.concat([fillerData, signatureType]); + const signatureHex = ethUtil.bufferToHex(signatureBuffer); + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + return expectRevertOrAlwaysFailingTransactionAsync( + signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signedOrder.makerAddress, + signatureHex, + ), + ); + }); + + it('should return true when SignatureType=EIP712 and signature is valid', async () => { + // Create EIP712 signature const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashBuffer = ethUtil.toBuffer(orderHashHex); + const ecSignature = ethUtil.ecsign(orderHashBuffer, signerPrivateKey); + // Create 0x signature from EIP712 signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.EIP712}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.true(); + }); + + it('should return true when SignatureType=EIP712 and signature is valid', async () => { + // Create EIP712 signature + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashBuffer = ethUtil.toBuffer(orderHashHex); + const ecSignature = ethUtil.ecsign(orderHashBuffer, signerPrivateKey); + // Create 0x signature from EIP712 signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.EIP712}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + notSignerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should return true when SignatureType=EthSign and signature is valid', async () => { + // Create EthSign signature + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashWithEthSignPrefixHex = addSignedMessagePrefix(orderHashHex, MessagePrefixType.EthSign); + const orderHashWithEthSignPrefixBuffer = ethUtil.toBuffer(orderHashWithEthSignPrefixHex); + const ecSignature = ethUtil.ecsign(orderHashWithEthSignPrefixBuffer, signerPrivateKey); + // Create 0x signature from EthSign signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.EthSign}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.true(); + }); + + it('should return true when SignatureType=EthSign and signature is invalid', async () => { + // Create EthSign signature + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashWithEthSignPrefixHex = addSignedMessagePrefix(orderHashHex, MessagePrefixType.EthSign); + const orderHashWithEthSignPrefixBuffer = ethUtil.toBuffer(orderHashWithEthSignPrefixHex); + const ecSignature = ethUtil.ecsign(orderHashWithEthSignPrefixBuffer, signerPrivateKey); + // Create 0x signature from EthSign signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.EthSign}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature. + // This will fail because `signerAddress` signed the message, but we're passing in `notSignerAddress` + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + notSignerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should return true when SignatureType=Caller and signer is caller', async () => { + const signature = ethUtil.toBuffer(`0x${SignatureType.Caller}`); + const signatureHex = ethUtil.bufferToHex(signature); + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + { from: signerAddress }, + ); + expect(isValidSignature).to.be.true(); + }); + + it('should return false when SignatureType=Caller and signer is not caller', async () => { + const signature = ethUtil.toBuffer(`0x${SignatureType.Caller}`); + const signatureHex = ethUtil.bufferToHex(signature); + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + { from: notSignerAddress }, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should return true when SignatureType=Wallet and signature is valid', async () => { + // Create EIP712 signature + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashBuffer = ethUtil.toBuffer(orderHashHex); + const ecSignature = ethUtil.ecsign(orderHashBuffer, signerPrivateKey); + // Create 0x signature from EIP712 signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.Wallet}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + testWallet.address, + signatureHex, + ); + expect(isValidSignature).to.be.true(); + }); + + it('should return false when SignatureType=Wallet and signature is invalid', async () => { + // Create EIP712 signature using a private key that does not belong to the wallet owner. + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashBuffer = ethUtil.toBuffer(orderHashHex); + const notWalletOwnerPrivateKey = notSignerPrivateKey; + const ecSignature = ethUtil.ecsign(orderHashBuffer, notWalletOwnerPrivateKey); + // Create 0x signature from EIP712 signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.Wallet}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + testWallet.address, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should return true when SignatureType=Validator, signature is valid and validator is approved', async () => { + const validatorAddress = ethUtil.toBuffer(`${testValidator.address}`); + const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`); + const signature = Buffer.concat([validatorAddress, signatureType]); + const signatureHex = ethUtil.bufferToHex(signature); + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.true(); + }); + + it('should return false when SignatureType=Validator, signature is invalid and validator is approved', async () => { + const validatorAddress = ethUtil.toBuffer(`${testValidator.address}`); + const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`); + const signature = Buffer.concat([validatorAddress, signatureType]); + const signatureHex = ethUtil.bufferToHex(signature); + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + notSignerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should return false when SignatureType=Validator, signature is valid and validator is not approved', async () => { + // Set approval of signature validator to false + await web3Wrapper.awaitTransactionSuccessAsync( + await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync( + testValidator.address, + false, + { from: signerAddress }, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Validate signature + const validatorAddress = ethUtil.toBuffer(`${testValidator.address}`); + const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`); + const signature = Buffer.concat([validatorAddress, signatureType]); + const signatureHex = ethUtil.bufferToHex(signature); + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + // Set approval of signature validator back to true + await web3Wrapper.awaitTransactionSuccessAsync( + await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync( + testValidator.address, + true, + { from: signerAddress }, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + }); + + it('should return true when SignatureType=Trezor and signature is valid', async () => { + // Create Trezor signature + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashWithTrezorPrefixHex = addSignedMessagePrefix(orderHashHex, MessagePrefixType.Trezor); + const orderHashWithTrezorPrefixBuffer = ethUtil.toBuffer(orderHashWithTrezorPrefixHex); + const ecSignature = ethUtil.ecsign(orderHashWithTrezorPrefixBuffer, signerPrivateKey); + // Create 0x signature from Trezor signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.Trezor}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + signerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.true(); + }); + + it('should return true when SignatureType=Trezor and signature is invalid', async () => { + // Create Trezor signature + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + const orderHashWithTrezorPrefixHex = addSignedMessagePrefix(orderHashHex, MessagePrefixType.Trezor); + const orderHashWithTrezorPrefixBuffer = ethUtil.toBuffer(orderHashWithTrezorPrefixHex); + const ecSignature = ethUtil.ecsign(orderHashWithTrezorPrefixBuffer, signerPrivateKey); + // Create 0x signature from Trezor signature + const signature = Buffer.concat([ + ethUtil.toBuffer(ecSignature.v), + ecSignature.r, + ecSignature.s, + ethUtil.toBuffer(`0x${SignatureType.Trezor}`), + ]); + const signatureHex = ethUtil.bufferToHex(signature); + // Validate signature. + // This will fail because `signerAddress` signed the message, but we're passing in `notSignerAddress` + const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( + orderHashHex, + notSignerAddress, + signatureHex, + ); + expect(isValidSignature).to.be.false(); + }); + + it('should return true when SignatureType=Presigned and signer has presigned hash', async () => { + // Presign hash + const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + await web3Wrapper.awaitTransactionSuccessAsync( + await signatureValidator.preSign.sendTransactionAsync( + orderHashHex, + signedOrder.makerAddress, + signedOrder.signature, + ), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + // Validate presigned signature + const signature = ethUtil.toBuffer(`0x${SignatureType.PreSigned}`); + const signatureHex = ethUtil.bufferToHex(signature); const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, - signedOrder.signature, + signatureHex, ); expect(isValidSignature).to.be.true(); }); - it('should return false with an invalid signature', async () => { - const v = ethUtil.toBuffer(signedOrder.signature.slice(0, 4)); - const invalidR = ethUtil.sha3('invalidR'); - const invalidS = ethUtil.sha3('invalidS'); - const signatureType = ethUtil.toBuffer(`0x${signedOrder.signature.slice(-2)}`); - const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]); - const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`; - signedOrder.signature = invalidSigHex; + it('should return false when SignatureType=Presigned has not presigned hash', async () => { + const signature = ethUtil.toBuffer(`0x${SignatureType.PreSigned}`); + const signatureHex = ethUtil.bufferToHex(signature); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, - signedOrder.signature, + signatureHex, ); expect(isValidSignature).to.be.false(); }); -- cgit v1.2.3 From 8d003dbc30735d72b860e739fd7dc47fad557df9 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 19 Jun 2018 18:26:42 -0700 Subject: Fixed two mislabelled revert reasons + Signature Validator revert tests working on Geth --- packages/contracts/test/exchange/signature_validator.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index 8f796361f..ca6897d7f 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -10,7 +10,7 @@ import { TestValidatorContract } from '../../src/generated_contract_wrappers/tes import { TestWalletContract } from '../../src/generated_contract_wrappers/test_wallet'; import { addressUtils } from '../../src/utils/address_utils'; import { artifacts } from '../../src/utils/artifacts'; -import { expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions'; +import { expectRevertOrOtherErrorAsync, expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions'; import { chaiSetup } from '../../src/utils/chai_setup'; import { constants } from '../../src/utils/constants'; import { OrderFactory } from '../../src/utils/order_factory'; @@ -21,7 +21,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -describe('MixinSignatureValidator', () => { +describe.only('MixinSignatureValidator', () => { let signedOrder: SignedOrder; let orderFactory: OrderFactory; let signatureValidator: TestSignatureValidatorContract; @@ -95,12 +95,13 @@ describe('MixinSignatureValidator', () => { it('should revert with an empty signature', async () => { const emptySignature = '0x'; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectRevertOrOtherErrorAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, emptySignature, ), + constants.EXCHANGE_LENGTH_GREATER_THAN_0_REQUIRED, ); }); @@ -108,24 +109,26 @@ describe('MixinSignatureValidator', () => { const unsupportedSignatureType = SignatureType.NSignatureTypes; const unsupportedSignatureHex = `0x${unsupportedSignatureType}`; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectRevertOrOtherErrorAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, unsupportedSignatureHex, ), + constants.EXCHANGE_SIGNATURE_UNSUPPORTED, ); }); it('should revert when SignatureType=Illegal', async () => { const unsupportedSignatureHex = `0x${SignatureType.Illegal}`; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectRevertOrOtherErrorAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, unsupportedSignatureHex, ), + constants.EXCHANGE_SIGNATURE_ILLEGAL, ); }); @@ -146,12 +149,13 @@ describe('MixinSignatureValidator', () => { const signatureBuffer = Buffer.concat([fillerData, signatureType]); const signatureHex = ethUtil.bufferToHex(signatureBuffer); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); - return expectRevertOrAlwaysFailingTransactionAsync( + return expectRevertOrOtherErrorAsync( signatureValidator.publicIsValidSignature.callAsync( orderHashHex, signedOrder.makerAddress, signatureHex, ), + constants.EXCHANGE_LENGTH_0_REQUIRED, ); }); -- cgit v1.2.3 From d0df25d9e2ced5593a0718ee174eeb833f6599d3 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 19 Jun 2018 18:30:49 -0700 Subject: Remove .only --- packages/contracts/test/exchange/signature_validator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index ca6897d7f..5937dee12 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -21,7 +21,7 @@ const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -describe.only('MixinSignatureValidator', () => { +describe('MixinSignatureValidator', () => { let signedOrder: SignedOrder; let orderFactory: OrderFactory; let signatureValidator: TestSignatureValidatorContract; -- cgit v1.2.3 From 4a136cafda2621b2d539b0d7b406db878586f2ff Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 19 Jun 2018 18:45:57 -0700 Subject: Minor improvements to MixinSignatureValidator tests --- .../contracts/test/exchange/signature_validator.ts | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index 5937dee12..483099c10 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -181,7 +181,7 @@ describe('MixinSignatureValidator', () => { expect(isValidSignature).to.be.true(); }); - it('should return true when SignatureType=EIP712 and signature is valid', async () => { + it('should return false when SignatureType=EIP712 and signature is invalid', async () => { // Create EIP712 signature const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashBuffer = ethUtil.toBuffer(orderHashHex); @@ -194,7 +194,8 @@ describe('MixinSignatureValidator', () => { ethUtil.toBuffer(`0x${SignatureType.EIP712}`), ]); const signatureHex = ethUtil.bufferToHex(signature); - // Validate signature + // Validate signature. + // This will fail because `signerAddress` signed the message, but we're passing in `notSignerAddress` const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( orderHashHex, notSignerAddress, @@ -226,7 +227,7 @@ describe('MixinSignatureValidator', () => { expect(isValidSignature).to.be.true(); }); - it('should return true when SignatureType=EthSign and signature is invalid', async () => { + it('should return false when SignatureType=EthSign and signature is invalid', async () => { // Create EthSign signature const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashWithEthSignPrefixHex = addSignedMessagePrefix(orderHashHex, MessagePrefixType.EthSign); @@ -341,6 +342,8 @@ describe('MixinSignatureValidator', () => { const signature = Buffer.concat([validatorAddress, signatureType]); const signatureHex = ethUtil.bufferToHex(signature); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); + // This will return false because we signed the message with `signerAddress`, but + // are validating against `notSignerAddress` const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync( orderHashHex, notSignerAddress, @@ -371,15 +374,6 @@ describe('MixinSignatureValidator', () => { signatureHex, ); expect(isValidSignature).to.be.false(); - // Set approval of signature validator back to true - await web3Wrapper.awaitTransactionSuccessAsync( - await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync( - testValidator.address, - true, - { from: signerAddress }, - ), - constants.AWAIT_TRANSACTION_MINED_MS, - ); }); it('should return true when SignatureType=Trezor and signature is valid', async () => { @@ -405,7 +399,7 @@ describe('MixinSignatureValidator', () => { expect(isValidSignature).to.be.true(); }); - it('should return true when SignatureType=Trezor and signature is invalid', async () => { + it('should return false when SignatureType=Trezor and signature is invalid', async () => { // Create Trezor signature const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashWithTrezorPrefixHex = addSignedMessagePrefix(orderHashHex, MessagePrefixType.Trezor); @@ -451,7 +445,7 @@ describe('MixinSignatureValidator', () => { expect(isValidSignature).to.be.true(); }); - it('should return false when SignatureType=Presigned has not presigned hash', async () => { + it('should return false when SignatureType=Presigned and signer has not presigned hash', async () => { const signature = ethUtil.toBuffer(`0x${SignatureType.PreSigned}`); const signatureHex = ethUtil.bufferToHex(signature); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); -- cgit v1.2.3 From 322151b0d5d811bf1925f8479de3151316ce44dc Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 19 Jun 2018 18:51:02 -0700 Subject: Changed wording of two tests #nit --- packages/contracts/test/exchange/signature_validator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index 483099c10..0d7722697 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -92,7 +92,7 @@ describe('MixinSignatureValidator', () => { signedOrder = orderFactory.newSignedOrder(); }); - it('should revert with an empty signature', async () => { + it('should revert when signature is empty', async () => { const emptySignature = '0x'; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); return expectRevertOrOtherErrorAsync( @@ -105,7 +105,7 @@ describe('MixinSignatureValidator', () => { ); }); - it('should revert with an unsupported signature type', async () => { + it('should revert when signature type is unsupported', async () => { const unsupportedSignatureType = SignatureType.NSignatureTypes; const unsupportedSignatureHex = `0x${unsupportedSignatureType}`; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); -- cgit v1.2.3 From 491a322ceb6b31d66598ef90a3ce74bf0fbb0b96 Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Wed, 20 Jun 2018 13:51:39 -0700 Subject: Linter --- packages/contracts/test/exchange/signature_validator.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index 0d7722697..2a94ab25a 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -3,14 +3,13 @@ import { addSignedMessagePrefix, assetProxyUtils, MessagePrefixType, orderHashUt import { SignatureType, SignedOrder } from '@0xproject/types'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); -import * as _ from 'lodash'; import { TestSignatureValidatorContract } from '../../src/generated_contract_wrappers/test_signature_validator'; import { TestValidatorContract } from '../../src/generated_contract_wrappers/test_validator'; import { TestWalletContract } from '../../src/generated_contract_wrappers/test_wallet'; import { addressUtils } from '../../src/utils/address_utils'; import { artifacts } from '../../src/utils/artifacts'; -import { expectRevertOrOtherErrorAsync, expectRevertOrAlwaysFailingTransactionAsync } from '../../src/utils/assertions'; +import { expectRevertOrOtherErrorAsync } from '../../src/utils/assertions'; import { chaiSetup } from '../../src/utils/chai_setup'; import { constants } from '../../src/utils/constants'; import { OrderFactory } from '../../src/utils/order_factory'; -- cgit v1.2.3 From 6a073d5f866665c43ab57d7246c7ea693264ed88 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Wed, 20 Jun 2018 14:29:30 -0700 Subject: Add senderAddress to Fill and Cancel logs, add comments to events and types --- packages/contracts/test/exchange/core.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index ea37a1e99..89a1c6492 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -399,6 +399,7 @@ describe('Exchange core', () => { expect(signedOrder.makerAddress).to.be.equal(logArgs.makerAddress); expect(takerAddress).to.be.equal(logArgs.takerAddress); + expect(takerAddress).to.be.equal(logArgs.senderAddress); expect(signedOrder.feeRecipientAddress).to.be.equal(logArgs.feeRecipientAddress); expect(signedOrder.makerAssetData).to.be.equal(logArgs.makerAssetData); expect(signedOrder.takerAssetData).to.be.equal(logArgs.takerAssetData); @@ -577,6 +578,7 @@ describe('Exchange core', () => { const logArgs = log.args; expect(signedOrder.makerAddress).to.be.equal(logArgs.makerAddress); + expect(signedOrder.makerAddress).to.be.equal(logArgs.senderAddress); expect(signedOrder.feeRecipientAddress).to.be.equal(logArgs.feeRecipientAddress); expect(signedOrder.makerAssetData).to.be.equal(logArgs.makerAssetData); expect(signedOrder.takerAssetData).to.be.equal(logArgs.takerAssetData); -- cgit v1.2.3 From b333ed91de8d4f08cd614a52e2b0d602995c2b27 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Thu, 21 Jun 2018 16:08:45 -0700 Subject: Add event to setSignatureValidatorApproval, rename signer => signerAddress accross all contracts --- .../contracts/test/exchange/signature_validator.ts | 52 +++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index 2a94ab25a..8e221e3f1 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -2,9 +2,13 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { addSignedMessagePrefix, assetProxyUtils, MessagePrefixType, orderHashUtils } from '@0xproject/order-utils'; import { SignatureType, SignedOrder } from '@0xproject/types'; import * as chai from 'chai'; +import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); -import { TestSignatureValidatorContract } from '../../src/generated_contract_wrappers/test_signature_validator'; +import { + SignatureValidatorApprovalContractEventArgs, + TestSignatureValidatorContract, +} from '../../src/generated_contract_wrappers/test_signature_validator'; import { TestValidatorContract } from '../../src/generated_contract_wrappers/test_validator'; import { TestWalletContract } from '../../src/generated_contract_wrappers/test_wallet'; import { addressUtils } from '../../src/utils/address_utils'; @@ -12,6 +16,7 @@ import { artifacts } from '../../src/utils/artifacts'; import { expectRevertOrOtherErrorAsync } from '../../src/utils/assertions'; import { chaiSetup } from '../../src/utils/chai_setup'; import { constants } from '../../src/utils/constants'; +import { LogDecoder } from '../../src/utils/log_decoder'; import { OrderFactory } from '../../src/utils/order_factory'; import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper'; @@ -19,7 +24,7 @@ chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); - +// tslint:disable:no-unnecessary-type-assertion describe('MixinSignatureValidator', () => { let signedOrder: SignedOrder; let orderFactory: OrderFactory; @@ -30,6 +35,7 @@ describe('MixinSignatureValidator', () => { let signerPrivateKey: Buffer; let notSignerAddress: string; let notSignerPrivateKey: Buffer; + let signatureValidatorLogDecoder: LogDecoder; before(async () => { await blockchainLifecycle.startAsync(); @@ -59,6 +65,7 @@ describe('MixinSignatureValidator', () => { txDefaults, signerAddress, ); + signatureValidatorLogDecoder = new LogDecoder(web3Wrapper, signatureValidator.address); await web3Wrapper.awaitTransactionSuccessAsync( await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync(testValidator.address, true, { from: signerAddress, @@ -456,4 +463,45 @@ describe('MixinSignatureValidator', () => { expect(isValidSignature).to.be.false(); }); }); + + describe('setSignatureValidatorApproval', () => { + it('should emit a SignatureValidatorApprovalSet with correct args when a validator is approved', async () => { + const approval = true; + const res = await signatureValidatorLogDecoder.getTxWithDecodedLogsAsync( + await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync( + testValidator.address, + approval, + { + from: signerAddress, + }, + ), + ); + expect(res.logs.length).to.equal(1); + const log = res.logs[0] as LogWithDecodedArgs; + const logArgs = log.args; + expect(logArgs.signerAddress).to.equal(signerAddress); + expect(logArgs.validatorAddress).to.equal(testValidator.address); + expect(logArgs.approved).to.equal(approval); + }); + it('should emit a SignatureValidatorApprovalSet with correct args when a validator is disapproved', async () => { + const approval = false; + const res = await signatureValidatorLogDecoder.getTxWithDecodedLogsAsync( + await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync( + testValidator.address, + approval, + { + from: signerAddress, + }, + ), + ); + expect(res.logs.length).to.equal(1); + const log = res.logs[0] as LogWithDecodedArgs; + const logArgs = log.args; + expect(logArgs.signerAddress).to.equal(signerAddress); + expect(logArgs.validatorAddress).to.equal(testValidator.address); + expect(logArgs.approved).to.equal(approval); + }); + }); }); +// tslint:disable:max-file-line-count +// tslint:enable:no-unnecessary-type-assertion -- cgit v1.2.3 From 4012e31115dd0571d742b42a48094f41fd53a460 Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Thu, 21 Jun 2018 19:17:33 -0700 Subject: Use make-promises-safe as a preloader instead of manually importing --- packages/contracts/test/asset_proxy/authorizable.ts | 1 - packages/contracts/test/asset_proxy_owner.ts | 1 - packages/contracts/test/ether_token.ts | 1 - packages/contracts/test/exchange/core.ts | 1 - packages/contracts/test/exchange/wrapper.ts | 1 - packages/contracts/test/multi_sig_with_time_lock.ts | 1 - packages/contracts/test/token_registry.ts | 1 - packages/contracts/test/tutorials/arbitrage.ts | 1 - packages/contracts/test/unlimited_allowance_token.ts | 1 - packages/contracts/test/zrx_token.ts | 1 - 10 files changed, 10 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/asset_proxy/authorizable.ts b/packages/contracts/test/asset_proxy/authorizable.ts index 347d060d6..ed582b63e 100644 --- a/packages/contracts/test/asset_proxy/authorizable.ts +++ b/packages/contracts/test/asset_proxy/authorizable.ts @@ -1,6 +1,5 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import * as chai from 'chai'; -import 'make-promises-safe'; import { MixinAuthorizableContract } from '../../src/generated_contract_wrappers/mixin_authorizable'; import { artifacts } from '../../src/utils/artifacts'; diff --git a/packages/contracts/test/asset_proxy_owner.ts b/packages/contracts/test/asset_proxy_owner.ts index cbe429b12..aa4999e95 100644 --- a/packages/contracts/test/asset_proxy_owner.ts +++ b/packages/contracts/test/asset_proxy_owner.ts @@ -2,7 +2,6 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; -import 'make-promises-safe'; import { AssetProxyOwnerContract, diff --git a/packages/contracts/test/ether_token.ts b/packages/contracts/test/ether_token.ts index e2fc69aee..01093d309 100644 --- a/packages/contracts/test/ether_token.ts +++ b/packages/contracts/test/ether_token.ts @@ -2,7 +2,6 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; -import 'make-promises-safe'; import { WETH9Contract } from '../src/generated_contract_wrappers/weth9'; import { artifacts } from '../src/utils/artifacts'; diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 89a1c6492..ff652d3aa 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -6,7 +6,6 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); -import 'make-promises-safe'; import { DummyERC20TokenContract } from '../../src/generated_contract_wrappers/dummy_e_r_c20_token'; import { DummyERC721TokenContract } from '../../src/generated_contract_wrappers/dummy_e_r_c721_token'; diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index abba1ac4f..703f644b8 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -5,7 +5,6 @@ import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import * as _ from 'lodash'; -import 'make-promises-safe'; import { DummyERC20TokenContract } from '../../src/generated_contract_wrappers/dummy_e_r_c20_token'; import { DummyERC721TokenContract } from '../../src/generated_contract_wrappers/dummy_e_r_c721_token'; diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts index f630743e1..aa82b9edf 100644 --- a/packages/contracts/test/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -2,7 +2,6 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; -import 'make-promises-safe'; import { MultiSigWalletWithTimeLockContract, diff --git a/packages/contracts/test/token_registry.ts b/packages/contracts/test/token_registry.ts index f368fd73d..095cecfce 100644 --- a/packages/contracts/test/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -3,7 +3,6 @@ import { BigNumber, NULL_BYTES } from '@0xproject/utils'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; -import 'make-promises-safe'; import { TokenRegistryContract } from '../src/generated_contract_wrappers/token_registry'; import { artifacts } from '../src/utils/artifacts'; diff --git a/packages/contracts/test/tutorials/arbitrage.ts b/packages/contracts/test/tutorials/arbitrage.ts index 32fcedb43..6851483cc 100644 --- a/packages/contracts/test/tutorials/arbitrage.ts +++ b/packages/contracts/test/tutorials/arbitrage.ts @@ -4,7 +4,6 @@ // import { BigNumber } from '@0xproject/utils'; // import { Web3Wrapper } from '@0xproject/web3-wrapper'; // import * as chai from 'chai'; -// import 'make-promises-safe'; // import ethUtil = require('ethereumjs-util'); // import * as Web3 from 'web3'; diff --git a/packages/contracts/test/unlimited_allowance_token.ts b/packages/contracts/test/unlimited_allowance_token.ts index 0c3f5094b..7132c57bf 100644 --- a/packages/contracts/test/unlimited_allowance_token.ts +++ b/packages/contracts/test/unlimited_allowance_token.ts @@ -1,7 +1,6 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; -import 'make-promises-safe'; import { DummyERC20TokenContract } from '../src/generated_contract_wrappers/dummy_e_r_c20_token'; import { artifacts } from '../src/utils/artifacts'; diff --git a/packages/contracts/test/zrx_token.ts b/packages/contracts/test/zrx_token.ts index 0629c7a88..01ae57d4a 100644 --- a/packages/contracts/test/zrx_token.ts +++ b/packages/contracts/test/zrx_token.ts @@ -2,7 +2,6 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; -import 'make-promises-safe'; import { ZRXTokenContract } from '../src/generated_contract_wrappers/zrx_token'; import { artifacts } from '../src/utils/artifacts'; -- cgit v1.2.3 From 98840c9c5f078d42ea54585dda1645029772db11 Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Thu, 14 Jun 2018 11:49:17 +0200 Subject: Use provided mem in refernce memcpy --- packages/contracts/test/libraries/lib_mem.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/libraries/lib_mem.ts b/packages/contracts/test/libraries/lib_mem.ts index 00f7c4d8b..8cf5cf3a7 100644 --- a/packages/contracts/test/libraries/lib_mem.ts +++ b/packages/contracts/test/libraries/lib_mem.ts @@ -30,8 +30,8 @@ describe('LibMem', () => { const memHex = toHex(memory); // Reference implementation to test against - const refMemcpy = (_mem: Uint8Array, dest: number, source: number, length: number): Uint8Array => - Uint8Array.from(memory).copyWithin(dest, source, source + length); + const refMemcpy = (mem: Uint8Array, dest: number, source: number, length: number): Uint8Array => + Uint8Array.from(mem).copyWithin(dest, source, source + length); // Test vectors: destination, source, length, job description type Tests = Array<[number, number, number, string]>; -- cgit v1.2.3 From 7f84049538af09e7596623158e1364a68bb17a35 Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Wed, 13 Jun 2018 11:36:35 +0200 Subject: Merge LibMem and LibBytes --- packages/contracts/test/asset_proxy/decoder.ts | 1 - packages/contracts/test/libraries/lib_bytes.ts | 171 ++++++++++++++++++++++ packages/contracts/test/libraries/lib_mem.ts | 190 ------------------------- 3 files changed, 171 insertions(+), 191 deletions(-) delete mode 100644 packages/contracts/test/libraries/lib_mem.ts (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/asset_proxy/decoder.ts b/packages/contracts/test/asset_proxy/decoder.ts index 875d55daa..98d18aa38 100644 --- a/packages/contracts/test/asset_proxy/decoder.ts +++ b/packages/contracts/test/asset_proxy/decoder.ts @@ -27,7 +27,6 @@ describe('TestAssetDataDecoders', () => { // Setup accounts & addresses const accounts = await web3Wrapper.getAvailableAddressesAsync(); testAddress = accounts[0]; - // Deploy TestLibMem testAssetProxyDecoder = await TestAssetDataDecodersContract.deployFrom0xArtifactAsync( artifacts.TestAssetDataDecoders, provider, diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index a31a4789c..b378bb036 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -17,6 +17,12 @@ chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); +// BUG: Ideally we would use Buffer.from(memory).toString('hex') +// https://github.com/Microsoft/TypeScript/issues/23155 +const toHex = (buf: Uint8Array): string => buf.reduce((a, v) => a + ('00' + v.toString(16)).slice(-2), '0x'); + +const fromHex = (str: string): Uint8Array => Uint8Array.from(Buffer.from(str.slice(2), 'hex')); + describe('LibBytes', () => { let libBytes: TestLibBytesContract; const byteArrayShorterThan32Bytes = '0x012345'; @@ -617,5 +623,170 @@ describe('LibBytes', () => { ); }); }); + + describe('memCopy', () => { + // Create memory 0x000102...FF + const memSize = 256; + const memory = new Uint8Array(memSize).map((_, i) => i); + const memHex = toHex(memory); + + // Reference implementation to test against + const refMemcpy = (mem: Uint8Array, dest: number, source: number, length: number): Uint8Array => + Uint8Array.from(mem).copyWithin(dest, source, source + length); + + // Test vectors: destination, source, length, job description + type Tests = Array<[number, number, number, string]>; + + const test = (tests: Tests) => + tests.forEach(([dest, source, length, job]) => + it(job, async () => { + const expected = refMemcpy(memory, dest, source, length); + const resultStr = await libBytes.testMemcpy.callAsync( + memHex, + new BigNumber(dest), + new BigNumber(source), + new BigNumber(length), + ); + const result = fromHex(resultStr); + expect(result).to.deep.equal(expected); + }), + ); + + test([[0, 0, 0, 'copies zero bytes with overlap']]); + + describe('copies forward', () => + test([ + [128, 0, 0, 'zero bytes'], + [128, 0, 1, 'one byte'], + [128, 0, 11, 'eleven bytes'], + [128, 0, 31, 'thirty-one bytes'], + [128, 0, 32, 'one word'], + [128, 0, 64, 'two words'], + [128, 0, 96, 'three words'], + [128, 0, 33, 'one word and one byte'], + [128, 0, 72, 'two words and eight bytes'], + [128, 0, 100, 'three words and four bytes'], + ])); + + describe('copies forward within one word', () => + test([ + [16, 0, 0, 'zero bytes'], + [16, 0, 1, 'one byte'], + [16, 0, 11, 'eleven bytes'], + [16, 0, 16, 'sixteen bytes'], + ])); + + describe('copies forward with one byte overlap', () => + test([ + [0, 0, 1, 'one byte'], + [10, 0, 11, 'eleven bytes'], + [30, 0, 31, 'thirty-one bytes'], + [31, 0, 32, 'one word'], + [32, 0, 33, 'one word and one byte'], + [71, 0, 72, 'two words and eight bytes'], + [99, 0, 100, 'three words and four bytes'], + ])); + + describe('copies forward with thirty-one bytes overlap', () => + test([ + [0, 0, 31, 'thirty-one bytes'], + [1, 0, 32, 'one word'], + [2, 0, 33, 'one word and one byte'], + [41, 0, 72, 'two words and eight bytes'], + [69, 0, 100, 'three words and four bytes'], + ])); + + describe('copies forward with one word overlap', () => + test([ + [0, 0, 32, 'one word'], + [1, 0, 33, 'one word and one byte'], + [41, 0, 72, 'two words and eight bytes'], + [69, 0, 100, 'three words and four bytes'], + ])); + + describe('copies forward with one word and one byte overlap', () => + test([ + [0, 0, 33, 'one word and one byte'], + [40, 0, 72, 'two words and eight bytes'], + [68, 0, 100, 'three words and four bytes'], + ])); + + describe('copies forward with two words overlap', () => + test([ + [0, 0, 64, 'two words'], + [8, 0, 72, 'two words and eight bytes'], + [36, 0, 100, 'three words and four bytes'], + ])); + + describe('copies forward within one word and one byte overlap', () => + test([[0, 0, 1, 'one byte'], [10, 0, 11, 'eleven bytes'], [15, 0, 16, 'sixteen bytes']])); + + describe('copies backward', () => + test([ + [0, 128, 0, 'zero bytes'], + [0, 128, 1, 'one byte'], + [0, 128, 11, 'eleven bytes'], + [0, 128, 31, 'thirty-one bytes'], + [0, 128, 32, 'one word'], + [0, 128, 64, 'two words'], + [0, 128, 96, 'three words'], + [0, 128, 33, 'one word and one byte'], + [0, 128, 72, 'two words and eight bytes'], + [0, 128, 100, 'three words and four bytes'], + ])); + + describe('copies backward within one word', () => + test([ + [0, 16, 0, 'zero bytes'], + [0, 16, 1, 'one byte'], + [0, 16, 11, 'eleven bytes'], + [0, 16, 16, 'sixteen bytes'], + ])); + + describe('copies backward with one byte overlap', () => + test([ + [0, 0, 1, 'one byte'], + [0, 10, 11, 'eleven bytes'], + [0, 30, 31, 'thirty-one bytes'], + [0, 31, 32, 'one word'], + [0, 32, 33, 'one word and one byte'], + [0, 71, 72, 'two words and eight bytes'], + [0, 99, 100, 'three words and four bytes'], + ])); + + describe('copies backward with thirty-one bytes overlap', () => + test([ + [0, 0, 31, 'thirty-one bytes'], + [0, 1, 32, 'one word'], + [0, 2, 33, 'one word and one byte'], + [0, 41, 72, 'two words and eight bytes'], + [0, 69, 100, 'three words and four bytes'], + ])); + + describe('copies backward with one word overlap', () => + test([ + [0, 0, 32, 'one word'], + [0, 1, 33, 'one word and one byte'], + [0, 41, 72, 'two words and eight bytes'], + [0, 69, 100, 'three words and four bytes'], + ])); + + describe('copies backward with one word and one byte overlap', () => + test([ + [0, 0, 33, 'one word and one byte'], + [0, 40, 72, 'two words and eight bytes'], + [0, 68, 100, 'three words and four bytes'], + ])); + + describe('copies backward with two words overlap', () => + test([ + [0, 0, 64, 'two words'], + [0, 8, 72, 'two words and eight bytes'], + [0, 36, 100, 'three words and four bytes'], + ])); + + describe('copies forward within one word and one byte overlap', () => + test([[0, 0, 1, 'one byte'], [0, 10, 11, 'eleven bytes'], [0, 15, 16, 'sixteen bytes']])); + }); }); // tslint:disable:max-file-line-count diff --git a/packages/contracts/test/libraries/lib_mem.ts b/packages/contracts/test/libraries/lib_mem.ts deleted file mode 100644 index 8cf5cf3a7..000000000 --- a/packages/contracts/test/libraries/lib_mem.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { BigNumber } from '@0xproject/utils'; -import * as chai from 'chai'; - -import { TestLibMemContract } from '../../src/generated_contract_wrappers/test_lib_mem'; -import { artifacts } from '../../src/utils/artifacts'; -import { chaiSetup } from '../../src/utils/chai_setup'; -import { provider, txDefaults } from '../../src/utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; - -// BUG: Ideally we would use Buffer.from(memory).toString('hex') -// https://github.com/Microsoft/TypeScript/issues/23155 -const toHex = (buf: Uint8Array): string => buf.reduce((a, v) => a + ('00' + v.toString(16)).slice(-2), '0x'); - -const fromHex = (str: string): Uint8Array => Uint8Array.from(Buffer.from(str.slice(2), 'hex')); - -describe('LibMem', () => { - let testLibMem: TestLibMemContract; - - before(async () => { - // Deploy TestLibMem - testLibMem = await TestLibMemContract.deployFrom0xArtifactAsync(artifacts.TestLibMem, provider, txDefaults); - }); - - describe('memCopy', () => { - // Create memory 0x000102...FF - const memSize = 256; - const memory = new Uint8Array(memSize).map((_, i) => i); - const memHex = toHex(memory); - - // Reference implementation to test against - const refMemcpy = (mem: Uint8Array, dest: number, source: number, length: number): Uint8Array => - Uint8Array.from(mem).copyWithin(dest, source, source + length); - - // Test vectors: destination, source, length, job description - type Tests = Array<[number, number, number, string]>; - - const test = (tests: Tests) => - tests.forEach(([dest, source, length, job]) => - it(job, async () => { - const expected = refMemcpy(memory, dest, source, length); - const resultStr = await testLibMem.testMemcpy.callAsync( - memHex, - new BigNumber(dest), - new BigNumber(source), - new BigNumber(length), - ); - const result = fromHex(resultStr); - expect(result).to.deep.equal(expected); - }), - ); - - test([[0, 0, 0, 'copies zero bytes with overlap']]); - - describe('copies forward', () => - test([ - [128, 0, 0, 'zero bytes'], - [128, 0, 1, 'one byte'], - [128, 0, 11, 'eleven bytes'], - [128, 0, 31, 'thirty-one bytes'], - [128, 0, 32, 'one word'], - [128, 0, 64, 'two words'], - [128, 0, 96, 'three words'], - [128, 0, 33, 'one word and one byte'], - [128, 0, 72, 'two words and eight bytes'], - [128, 0, 100, 'three words and four bytes'], - ])); - - describe('copies forward within one word', () => - test([ - [16, 0, 0, 'zero bytes'], - [16, 0, 1, 'one byte'], - [16, 0, 11, 'eleven bytes'], - [16, 0, 16, 'sixteen bytes'], - ])); - - describe('copies forward with one byte overlap', () => - test([ - [0, 0, 1, 'one byte'], - [10, 0, 11, 'eleven bytes'], - [30, 0, 31, 'thirty-one bytes'], - [31, 0, 32, 'one word'], - [32, 0, 33, 'one word and one byte'], - [71, 0, 72, 'two words and eight bytes'], - [99, 0, 100, 'three words and four bytes'], - ])); - - describe('copies forward with thirty-one bytes overlap', () => - test([ - [0, 0, 31, 'thirty-one bytes'], - [1, 0, 32, 'one word'], - [2, 0, 33, 'one word and one byte'], - [41, 0, 72, 'two words and eight bytes'], - [69, 0, 100, 'three words and four bytes'], - ])); - - describe('copies forward with one word overlap', () => - test([ - [0, 0, 32, 'one word'], - [1, 0, 33, 'one word and one byte'], - [41, 0, 72, 'two words and eight bytes'], - [69, 0, 100, 'three words and four bytes'], - ])); - - describe('copies forward with one word and one byte overlap', () => - test([ - [0, 0, 33, 'one word and one byte'], - [40, 0, 72, 'two words and eight bytes'], - [68, 0, 100, 'three words and four bytes'], - ])); - - describe('copies forward with two words overlap', () => - test([ - [0, 0, 64, 'two words'], - [8, 0, 72, 'two words and eight bytes'], - [36, 0, 100, 'three words and four bytes'], - ])); - - describe('copies forward within one word and one byte overlap', () => - test([[0, 0, 1, 'one byte'], [10, 0, 11, 'eleven bytes'], [15, 0, 16, 'sixteen bytes']])); - - describe('copies backward', () => - test([ - [0, 128, 0, 'zero bytes'], - [0, 128, 1, 'one byte'], - [0, 128, 11, 'eleven bytes'], - [0, 128, 31, 'thirty-one bytes'], - [0, 128, 32, 'one word'], - [0, 128, 64, 'two words'], - [0, 128, 96, 'three words'], - [0, 128, 33, 'one word and one byte'], - [0, 128, 72, 'two words and eight bytes'], - [0, 128, 100, 'three words and four bytes'], - ])); - - describe('copies backward within one word', () => - test([ - [0, 16, 0, 'zero bytes'], - [0, 16, 1, 'one byte'], - [0, 16, 11, 'eleven bytes'], - [0, 16, 16, 'sixteen bytes'], - ])); - - describe('copies backward with one byte overlap', () => - test([ - [0, 0, 1, 'one byte'], - [0, 10, 11, 'eleven bytes'], - [0, 30, 31, 'thirty-one bytes'], - [0, 31, 32, 'one word'], - [0, 32, 33, 'one word and one byte'], - [0, 71, 72, 'two words and eight bytes'], - [0, 99, 100, 'three words and four bytes'], - ])); - - describe('copies backward with thirty-one bytes overlap', () => - test([ - [0, 0, 31, 'thirty-one bytes'], - [0, 1, 32, 'one word'], - [0, 2, 33, 'one word and one byte'], - [0, 41, 72, 'two words and eight bytes'], - [0, 69, 100, 'three words and four bytes'], - ])); - - describe('copies backward with one word overlap', () => - test([ - [0, 0, 32, 'one word'], - [0, 1, 33, 'one word and one byte'], - [0, 41, 72, 'two words and eight bytes'], - [0, 69, 100, 'three words and four bytes'], - ])); - - describe('copies backward with one word and one byte overlap', () => - test([ - [0, 0, 33, 'one word and one byte'], - [0, 40, 72, 'two words and eight bytes'], - [0, 68, 100, 'three words and four bytes'], - ])); - - describe('copies backward with two words overlap', () => - test([ - [0, 0, 64, 'two words'], - [0, 8, 72, 'two words and eight bytes'], - [0, 36, 100, 'three words and four bytes'], - ])); - - describe('copies forward within one word and one byte overlap', () => - test([[0, 0, 1, 'one byte'], [0, 10, 11, 'eleven bytes'], [0, 15, 16, 'sixteen bytes']])); - }); -}); -- cgit v1.2.3 From 88982f98ff2ece93831b1442d2c4e1ef0878d919 Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Wed, 13 Jun 2018 17:13:59 +0200 Subject: Rename read/writeBytesWithLength --- packages/contracts/test/libraries/lib_bytes.ts | 58 +++++++++++++------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index b378bb036..3afa2bab4 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -465,10 +465,10 @@ describe('LibBytes', () => { }); }); - describe('readBytes', () => { + describe('readBytesWithLength', () => { it('should successfully read short, nested array of bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); - const bytes = await libBytes.publicReadBytes.callAsync(shortTestBytes, testBytesOffset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(shortTestBytes, testBytesOffset); return expect(bytes).to.be.equal(shortData); }); it('should successfully read short, nested array of bytes when it is offset in the array', async () => { @@ -476,12 +476,12 @@ describe('LibBytes', () => { const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, shortTestBytesAsBuffer]); const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); const testUint256Offset = new BigNumber(prefixByteArrayBuffer.byteLength); - const bytes = await libBytes.publicReadBytes.callAsync(combinedByteArray, testUint256Offset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(combinedByteArray, testUint256Offset); return expect(bytes).to.be.equal(shortData); }); it('should successfully read a nested array of bytes - one word in length - when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); - const bytes = await libBytes.publicReadBytes.callAsync(wordOfTestBytes, testBytesOffset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(wordOfTestBytes, testBytesOffset); return expect(bytes).to.be.equal(wordOfData); }); it('should successfully read a nested array of bytes - one word in length - when it is offset in the array', async () => { @@ -489,12 +489,12 @@ describe('LibBytes', () => { const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, wordOfTestBytesAsBuffer]); const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); const testUint256Offset = new BigNumber(prefixByteArrayBuffer.byteLength); - const bytes = await libBytes.publicReadBytes.callAsync(combinedByteArray, testUint256Offset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(combinedByteArray, testUint256Offset); return expect(bytes).to.be.equal(wordOfData); }); it('should successfully read long, nested array of bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); - const bytes = await libBytes.publicReadBytes.callAsync(longTestBytes, testBytesOffset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(longTestBytes, testBytesOffset); return expect(bytes).to.be.equal(longData); }); it('should successfully read long, nested array of bytes when it is offset in the array', async () => { @@ -502,46 +502,46 @@ describe('LibBytes', () => { const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, longTestBytesAsBuffer]); const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); const testUint256Offset = new BigNumber(prefixByteArrayBuffer.byteLength); - const bytes = await libBytes.publicReadBytes.callAsync(combinedByteArray, testUint256Offset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(combinedByteArray, testUint256Offset); return expect(bytes).to.be.equal(longData); }); it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { // The length of the nested array is 32 bytes. By storing less than 32 bytes, a length cannot be read. const offset = new BigNumber(0); return expectRevertOrOtherErrorAsync( - libBytes.publicReadBytes.callAsync(byteArrayShorterThan32Bytes, offset), + libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, offset), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); it('should fail if we store a nested byte array length, without a nested byte array', async () => { const offset = new BigNumber(0); return expectRevertOrOtherErrorAsync( - libBytes.publicReadBytes.callAsync(testBytes32, offset), + libBytes.publicReadBytesWithLength.callAsync(testBytes32, offset), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength); return expectRevertOrOtherErrorAsync( - libBytes.publicReadBytes.callAsync(byteArrayShorterThan32Bytes, badOffset), + libBytes.publicReadBytesWithLength.callAsync(byteArrayShorterThan32Bytes, badOffset), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); return expectRevertOrOtherErrorAsync( - libBytes.publicReadBytes.callAsync(testBytes32, badOffset), + libBytes.publicReadBytesWithLength.callAsync(testBytes32, badOffset), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); }); - describe('writeBytes', () => { + describe('writeBytesWithLength', () => { it('should successfully write short, nested array of bytes when it takes up the whole array)', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); - const bytesWritten = await libBytes.publicWriteBytes.callAsync(emptyByteArray, testBytesOffset, shortData); - const bytesRead = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); + const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, testBytesOffset, shortData); + const bytesRead = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(shortData); }); it('should successfully write short, nested array of bytes when it is offset in the array', async () => { @@ -552,19 +552,19 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex( new Buffer(prefixDataAsBuffer.byteLength + shortTestBytesAsBuffer.byteLength), ); - let bytesWritten = await libBytes.publicWriteBytes.callAsync(emptyByteArray, prefixOffset, prefixData); + let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, prefixOffset, prefixData); // Write data after prefix const testBytesOffset = new BigNumber(prefixDataAsBuffer.byteLength); - bytesWritten = await libBytes.publicWriteBytes.callAsync(bytesWritten, testBytesOffset, shortData); + bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(bytesWritten, testBytesOffset, shortData); // Read data after prefix and validate - const bytes = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(shortData); }); it('should successfully write a nested array of bytes - one word in length - when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(wordOfTestBytesAsBuffer.byteLength)); - const bytesWritten = await libBytes.publicWriteBytes.callAsync(emptyByteArray, testBytesOffset, wordOfData); - const bytesRead = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); + const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, testBytesOffset, wordOfData); + const bytesRead = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(wordOfData); }); it('should successfully write a nested array of bytes - one word in length - when it is offset in the array', async () => { @@ -575,19 +575,19 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex( new Buffer(prefixDataAsBuffer.byteLength + wordOfTestBytesAsBuffer.byteLength), ); - let bytesWritten = await libBytes.publicWriteBytes.callAsync(emptyByteArray, prefixOffset, prefixData); + let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, prefixOffset, prefixData); // Write data after prefix const testBytesOffset = new BigNumber(prefixDataAsBuffer.byteLength); - bytesWritten = await libBytes.publicWriteBytes.callAsync(bytesWritten, testBytesOffset, wordOfData); + bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(bytesWritten, testBytesOffset, wordOfData); // Read data after prefix and validate - const bytes = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(wordOfData); }); it('should successfully write a long, nested bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(longTestBytesAsBuffer.byteLength)); - const bytesWritten = await libBytes.publicWriteBytes.callAsync(emptyByteArray, testBytesOffset, longData); - const bytesRead = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); + const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, testBytesOffset, longData); + const bytesRead = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(longData); }); it('should successfully write long, nested array of bytes when it is offset in the array', async () => { @@ -598,19 +598,19 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex( new Buffer(prefixDataAsBuffer.byteLength + longTestBytesAsBuffer.byteLength), ); - let bytesWritten = await libBytes.publicWriteBytes.callAsync(emptyByteArray, prefixOffset, prefixData); + let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, prefixOffset, prefixData); // Write data after prefix const testBytesOffset = new BigNumber(prefixDataAsBuffer.byteLength); - bytesWritten = await libBytes.publicWriteBytes.callAsync(bytesWritten, testBytesOffset, longData); + bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(bytesWritten, testBytesOffset, longData); // Read data after prefix and validate - const bytes = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); + const bytes = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(longData); }); it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { const offset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(1)); return expectRevertOrOtherErrorAsync( - libBytes.publicWriteBytes.callAsync(emptyByteArray, offset, longData), + libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, offset, longData), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED, ); }); @@ -618,7 +618,7 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength); return expectRevertOrOtherErrorAsync( - libBytes.publicWriteBytes.callAsync(emptyByteArray, badOffset, shortData), + libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, badOffset, shortData), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED, ); }); -- cgit v1.2.3 From 425af46f98c83e2796aaf0b946d250193393754c Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Wed, 13 Jun 2018 17:46:46 +0200 Subject: Rename bytes.equals --- packages/contracts/test/libraries/lib_bytes.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 3afa2bab4..0c8431a6a 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -129,48 +129,48 @@ describe('LibBytes', () => { }); }); - describe('areBytesEqual', () => { + describe('equals', () => { it('should return true if byte arrays are equal (both arrays < 32 bytes)', async () => { - const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( + const equals = await libBytes.publicEquals.callAsync( byteArrayShorterThan32Bytes, byteArrayShorterThan32Bytes, ); - return expect(areBytesEqual).to.be.true(); + return expect(equals).to.be.true(); }); it('should return true if byte arrays are equal (both arrays > 32 bytes)', async () => { - const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( + const equals = await libBytes.publicEquals.callAsync( byteArrayLongerThan32Bytes, byteArrayLongerThan32Bytes, ); - return expect(areBytesEqual).to.be.true(); + return expect(equals).to.be.true(); }); it('should return false if byte arrays are not equal (first array < 32 bytes, second array > 32 bytes)', async () => { - const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( + const equals = await libBytes.publicEquals.callAsync( byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes, ); - return expect(areBytesEqual).to.be.false(); + return expect(equals).to.be.false(); }); it('should return false if byte arrays are not equal (first array > 32 bytes, second array < 32 bytes)', async () => { - const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( + const equals = await libBytes.publicEquals.callAsync( byteArrayLongerThan32Bytes, byteArrayShorterThan32Bytes, ); - return expect(areBytesEqual).to.be.false(); + return expect(equals).to.be.false(); }); it('should return false if byte arrays are not equal (same length, but a byte in first word differs)', async () => { - const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( + const equals = await libBytes.publicEquals.callAsync( byteArrayLongerThan32BytesFirstBytesSwapped, byteArrayLongerThan32Bytes, ); - return expect(areBytesEqual).to.be.false(); + return expect(equals).to.be.false(); }); it('should return false if byte arrays are not equal (same length, but a byte in last word differs)', async () => { - const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( + const equals = await libBytes.publicEquals.callAsync( byteArrayLongerThan32BytesLastBytesSwapped, byteArrayLongerThan32Bytes, ); - return expect(areBytesEqual).to.be.false(); + return expect(equals).to.be.false(); }); }); -- cgit v1.2.3 From 384cd2f6059bba994a6af2992a7df4909e24897c Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Wed, 13 Jun 2018 18:12:45 +0200 Subject: Add trailing garbage testcase for LibBytes.equals --- packages/contracts/test/libraries/lib_bytes.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 0c8431a6a..5edb5835a 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -172,6 +172,16 @@ describe('LibBytes', () => { ); return expect(equals).to.be.false(); }); + + describe('should ignore trailing data', () => { + it('should return true when both < 32 bytes', async () => { + const equals = await libBytes.publicEqualsPop1.callAsync( + '0x0102', + '0x0103', + ); + return expect(equals).to.be.true(); + }); + }); }); describe('deepCopyBytes', () => { -- cgit v1.2.3 From 943e556f43a328dbb606567b06392851ba4ec3de Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Wed, 13 Jun 2018 18:28:11 +0200 Subject: Refactor LibBytes.readBytes4 for consistency --- packages/contracts/test/libraries/lib_bytes.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 5edb5835a..8dc968ed7 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -459,17 +459,21 @@ describe('LibBytes', () => { }); }); - describe('readFirst4', () => { + describe('readBytes4', () => { // AssertionError: expected promise to be rejected with an error including 'revert' but it was fulfilled with '0x08c379a0' it('should revert if byte array has a length < 4', async () => { const byteArrayLessThan4Bytes = '0x010101'; return expectRevertOrOtherErrorAsync( - libBytes.publicReadFirst4.callAsync(byteArrayLessThan4Bytes), + libBytes.publicReadBytes4.callAsync( + byteArrayLessThan4Bytes, + new BigNumber(0)), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED, ); }); it('should return the first 4 bytes of a byte array of arbitrary length', async () => { - const first4Bytes = await libBytes.publicReadFirst4.callAsync(byteArrayLongerThan32Bytes); + const first4Bytes = await libBytes.publicReadBytes4.callAsync( + byteArrayLongerThan32Bytes, + new BigNumber(0)); const expectedFirst4Bytes = byteArrayLongerThan32Bytes.slice(0, 10); expect(first4Bytes).to.equal(expectedFirst4Bytes); }); -- cgit v1.2.3 From 6a6f98299de5fd67f9162cc57c73583702924a2f Mon Sep 17 00:00:00 2001 From: Remco Bloemen Date: Wed, 13 Jun 2018 20:21:01 +0200 Subject: Move isFunctionRemoveAuthorizedAddress to test --- packages/contracts/test/asset_proxy_owner.ts | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/asset_proxy_owner.ts b/packages/contracts/test/asset_proxy_owner.ts index aa4999e95..a46882828 100644 --- a/packages/contracts/test/asset_proxy_owner.ts +++ b/packages/contracts/test/asset_proxy_owner.ts @@ -10,11 +10,11 @@ import { ExecutionFailureContractEventArgs, SubmissionContractEventArgs, } from '../src/generated_contract_wrappers/asset_proxy_owner'; -import { MixinAuthorizableContract } from '../src/generated_contract_wrappers/mixin_authorizable'; +import { MixinAuthorizableContract } from '../src/generated_contract_wrappers/mixin_authorizable'; +import { TestAssetProxyOwnerContract} from '../src/generated_contract_wrappers/test_asset_proxy_owner'; import { artifacts } from '../src/utils/artifacts'; import { expectRevertOrAlwaysFailingTransactionAsync, - expectRevertOrContractCallFailedAsync, } from '../src/utils/assertions'; import { chaiSetup } from '../src/utils/chai_setup'; import { constants } from '../src/utils/constants'; @@ -35,6 +35,7 @@ describe('AssetProxyOwner', () => { let erc20Proxy: MixinAuthorizableContract; let erc721Proxy: MixinAuthorizableContract; let multiSig: AssetProxyOwnerContract; + let testAssetProxyOwner: TestAssetProxyOwnerContract; let multiSigWrapper: MultiSigWrapper; before(async () => { @@ -68,6 +69,15 @@ describe('AssetProxyOwner', () => { SECONDS_TIME_LOCKED, ); multiSigWrapper = new MultiSigWrapper(multiSig, provider); + testAssetProxyOwner = await TestAssetProxyOwnerContract.deployFrom0xArtifactAsync( + artifacts.TestAssetProxyOwner, + provider, + txDefaults, + owners, + defaultAssetProxyContractAddresses, + REQUIRED_APPROVALS, + SECONDS_TIME_LOCKED, + ); await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }), constants.AWAIT_TRANSACTION_MINED_MS, @@ -118,23 +128,24 @@ describe('AssetProxyOwner', () => { }); describe('isFunctionRemoveAuthorizedAddress', () => { - it('should throw if data is not for removeAuthorizedAddress', async () => { + it('should return false if data is not for removeAuthorizedAddress', async () => { const notRemoveAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData( owners[0], ); - return expectRevertOrContractCallFailedAsync( - multiSig.isFunctionRemoveAuthorizedAddress.callAsync(notRemoveAuthorizedAddressData), + const result = await testAssetProxyOwner.isFunctionRemoveAuthorizedAddress.callAsync( + notRemoveAuthorizedAddressData, ); + expect(result).to.be.false(); }); it('should return true if data is for removeAuthorizedAddress', async () => { const removeAuthorizedAddressData = erc20Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( owners[0], ); - const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.callAsync( + const result = await testAssetProxyOwner.isFunctionRemoveAuthorizedAddress.callAsync( removeAuthorizedAddressData, ); - expect(isFunctionRemoveAuthorizedAddress).to.be.true(); + expect(result).to.be.true(); }); }); -- cgit v1.2.3 From 8ddcb6c841fd97bca2cddffd49a5b773cf53635f Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Thu, 21 Jun 2018 16:25:42 -0700 Subject: Update and add tests --- packages/contracts/test/asset_proxy_owner.ts | 351 +++++++++++++++---------- packages/contracts/test/libraries/lib_bytes.ts | 88 ++++--- 2 files changed, 269 insertions(+), 170 deletions(-) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/asset_proxy_owner.ts b/packages/contracts/test/asset_proxy_owner.ts index a46882828..188cba5a3 100644 --- a/packages/contracts/test/asset_proxy_owner.ts +++ b/packages/contracts/test/asset_proxy_owner.ts @@ -10,11 +10,12 @@ import { ExecutionFailureContractEventArgs, SubmissionContractEventArgs, } from '../src/generated_contract_wrappers/asset_proxy_owner'; -import { MixinAuthorizableContract } from '../src/generated_contract_wrappers/mixin_authorizable'; -import { TestAssetProxyOwnerContract} from '../src/generated_contract_wrappers/test_asset_proxy_owner'; +import { MixinAuthorizableContract } from '../src/generated_contract_wrappers/mixin_authorizable'; +import { TestAssetProxyOwnerContract } from '../src/generated_contract_wrappers/test_asset_proxy_owner'; import { artifacts } from '../src/utils/artifacts'; import { expectRevertOrAlwaysFailingTransactionAsync, + expectRevertOrContractCallFailedAsync, } from '../src/utils/assertions'; import { chaiSetup } from '../src/utils/chai_setup'; import { constants } from '../src/utils/constants'; @@ -34,7 +35,6 @@ describe('AssetProxyOwner', () => { let erc20Proxy: MixinAuthorizableContract; let erc721Proxy: MixinAuthorizableContract; - let multiSig: AssetProxyOwnerContract; let testAssetProxyOwner: TestAssetProxyOwnerContract; let multiSigWrapper: MultiSigWrapper; @@ -59,16 +59,6 @@ describe('AssetProxyOwner', () => { txDefaults, ); const defaultAssetProxyContractAddresses: string[] = []; - multiSig = await AssetProxyOwnerContract.deployFrom0xArtifactAsync( - artifacts.AssetProxyOwner, - provider, - txDefaults, - owners, - defaultAssetProxyContractAddresses, - REQUIRED_APPROVALS, - SECONDS_TIME_LOCKED, - ); - multiSigWrapper = new MultiSigWrapper(multiSig, provider); testAssetProxyOwner = await TestAssetProxyOwnerContract.deployFrom0xArtifactAsync( artifacts.TestAssetProxyOwner, provider, @@ -78,12 +68,17 @@ describe('AssetProxyOwner', () => { REQUIRED_APPROVALS, SECONDS_TIME_LOCKED, ); + multiSigWrapper = new MultiSigWrapper(testAssetProxyOwner, provider); await web3Wrapper.awaitTransactionSuccessAsync( - await erc20Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }), + await erc20Proxy.transferOwnership.sendTransactionAsync(testAssetProxyOwner.address, { + from: initialOwner, + }), constants.AWAIT_TRANSACTION_MINED_MS, ); await web3Wrapper.awaitTransactionSuccessAsync( - await erc721Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }), + await erc721Proxy.transferOwnership.sendTransactionAsync(testAssetProxyOwner.address, { + from: initialOwner, + }), constants.AWAIT_TRANSACTION_MINED_MS, ); }); @@ -127,25 +122,28 @@ describe('AssetProxyOwner', () => { }); }); - describe('isFunctionRemoveAuthorizedAddress', () => { - it('should return false if data is not for removeAuthorizedAddress', async () => { + describe('isFunctionRemoveAuthorizedAddressAtIndex', () => { + it('should return false if data is not for removeAuthorizedAddressAtIndex', async () => { const notRemoveAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData( owners[0], ); - const result = await testAssetProxyOwner.isFunctionRemoveAuthorizedAddress.callAsync( + + const isFunctionRemoveAuthorizedAddressAtIndex = await testAssetProxyOwner.isFunctionRemoveAuthorizedAddressAtIndex.callAsync( notRemoveAuthorizedAddressData, ); - expect(result).to.be.false(); + expect(isFunctionRemoveAuthorizedAddressAtIndex).to.be.false(); }); - it('should return true if data is for removeAuthorizedAddress', async () => { - const removeAuthorizedAddressData = erc20Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( + it('should return true if data is for removeAuthorizedAddressAtIndex', async () => { + const index = new BigNumber(0); + const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( owners[0], + index, ); - const result = await testAssetProxyOwner.isFunctionRemoveAuthorizedAddress.callAsync( - removeAuthorizedAddressData, + const isFunctionRemoveAuthorizedAddressAtIndex = await testAssetProxyOwner.isFunctionRemoveAuthorizedAddressAtIndex.callAsync( + removeAuthorizedAddressAtIndexData, ); - expect(result).to.be.true(); + expect(isFunctionRemoveAuthorizedAddressAtIndex).to.be.true(); }); }); @@ -153,19 +151,21 @@ describe('AssetProxyOwner', () => { it('should throw if not called by multisig', async () => { const isRegistered = true; return expectRevertOrAlwaysFailingTransactionAsync( - multiSig.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, isRegistered, { from: owners[0] }), + testAssetProxyOwner.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, isRegistered, { + from: owners[0], + }), ); }); it('should register an address if called by multisig after timelock', async () => { const addressToRegister = erc20Proxy.address; const isRegistered = true; - const registerAssetProxyData = multiSig.registerAssetProxy.getABIEncodedTransactionData( + const registerAssetProxyData = testAssetProxyOwner.registerAssetProxy.getABIEncodedTransactionData( addressToRegister, isRegistered, ); const submitTxRes = await multiSigWrapper.submitTransactionAsync( - multiSig.address, + testAssetProxyOwner.address, registerAssetProxyData, owners[0], ); @@ -181,19 +181,21 @@ describe('AssetProxyOwner', () => { expect(registerLog.args.assetProxyContract).to.equal(addressToRegister); expect(registerLog.args.isRegistered).to.equal(isRegistered); - const isAssetProxyRegistered = await multiSig.isAssetProxyRegistered.callAsync(addressToRegister); + const isAssetProxyRegistered = await testAssetProxyOwner.isAssetProxyRegistered.callAsync( + addressToRegister, + ); expect(isAssetProxyRegistered).to.equal(isRegistered); }); it('should fail if registering a null address', async () => { const addressToRegister = constants.NULL_ADDRESS; const isRegistered = true; - const registerAssetProxyData = multiSig.registerAssetProxy.getABIEncodedTransactionData( + const registerAssetProxyData = testAssetProxyOwner.registerAssetProxy.getABIEncodedTransactionData( addressToRegister, isRegistered, ); const submitTxRes = await multiSigWrapper.submitTransactionAsync( - multiSig.address, + testAssetProxyOwner.address, registerAssetProxyData, owners[0], ); @@ -207,22 +209,26 @@ describe('AssetProxyOwner', () => { const failureLog = executeTxRes.logs[0] as LogWithDecodedArgs; expect(failureLog.args.transactionId).to.be.bignumber.equal(txId); - const isAssetProxyRegistered = await multiSig.isAssetProxyRegistered.callAsync(addressToRegister); + const isAssetProxyRegistered = await testAssetProxyOwner.isAssetProxyRegistered.callAsync( + addressToRegister, + ); expect(isAssetProxyRegistered).to.equal(false); }); }); - describe('executeRemoveAuthorizedAddress', () => { + describe('Calling removeAuthorizedAddressAtIndex', () => { + const erc20Index = new BigNumber(0); + const erc721Index = new BigNumber(1); before('authorize both proxies and register erc20 proxy', async () => { // Only register ERC20 proxy const addressToRegister = erc20Proxy.address; const isRegistered = true; - const registerAssetProxyData = multiSig.registerAssetProxy.getABIEncodedTransactionData( + const registerAssetProxyData = testAssetProxyOwner.registerAssetProxy.getABIEncodedTransactionData( addressToRegister, isRegistered, ); const registerAssetProxySubmitRes = await multiSigWrapper.submitTransactionAsync( - multiSig.address, + testAssetProxyOwner.address, registerAssetProxyData, owners[0], ); @@ -259,113 +265,180 @@ describe('AssetProxyOwner', () => { await multiSigWrapper.executeTransactionAsync(erc721AddAuthorizedAddressTxId, owners[0]); }); - it('should throw without the required confirmations', async () => { - const removeAuthorizedAddressData = erc20Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( - authorized, - ); - const res = await multiSigWrapper.submitTransactionAsync( - erc20Proxy.address, - removeAuthorizedAddressData, - owners[0], - ); - const log = res.logs[0] as LogWithDecodedArgs; - const txId = log.args.transactionId; - - return expectRevertOrAlwaysFailingTransactionAsync( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ); - }); - - it('should throw if tx destination is not registered', async () => { - const removeAuthorizedAddressData = erc721Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( - authorized, - ); - const res = await multiSigWrapper.submitTransactionAsync( - erc721Proxy.address, - removeAuthorizedAddressData, - owners[0], - ); - const log = res.logs[0] as LogWithDecodedArgs; - const txId = log.args.transactionId; - - await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - - return expectRevertOrAlwaysFailingTransactionAsync( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ); + describe('validRemoveAuthorizedAddressAtIndexTx', () => { + it('should revert if data is not for removeAuthorizedAddressAtIndex and proxy is registered', async () => { + const notRemoveAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData( + authorized, + ); + const submitTxRes = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + notRemoveAuthorizedAddressData, + owners[0], + ); + const log = submitTxRes.logs[0] as LogWithDecodedArgs; + const txId = log.args.transactionId; + return expectRevertOrContractCallFailedAsync( + testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), + ); + }); + + it('should return true if data is for removeAuthorizedAddressAtIndex and proxy is registered', async () => { + const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( + authorized, + erc20Index, + ); + const submitTxRes = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + removeAuthorizedAddressAtIndexData, + owners[0], + ); + const log = submitTxRes.logs[0] as LogWithDecodedArgs; + const txId = log.args.transactionId; + const isValidRemoveAuthorizedAddressAtIndexTx = await testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync( + txId, + ); + expect(isValidRemoveAuthorizedAddressAtIndexTx).to.be.true(); + }); + + it('should revert if data is for removeAuthorizedAddressAtIndex and proxy is not registered', async () => { + const removeAuthorizedAddressAtIndexData = erc721Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( + authorized, + erc721Index, + ); + const submitTxRes = await multiSigWrapper.submitTransactionAsync( + erc721Proxy.address, + removeAuthorizedAddressAtIndexData, + owners[0], + ); + const log = submitTxRes.logs[0] as LogWithDecodedArgs; + const txId = log.args.transactionId; + return expectRevertOrContractCallFailedAsync( + testAssetProxyOwner.testValidRemoveAuthorizedAddressAtIndexTx.callAsync(txId), + ); + }); }); - it('should throw if tx data is not for removeAuthorizedAddress', async () => { - const newAuthorized = owners[1]; - const addAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData( - newAuthorized, - ); - const res = await multiSigWrapper.submitTransactionAsync( - erc20Proxy.address, - addAuthorizedAddressData, - owners[0], - ); - const log = res.logs[0] as LogWithDecodedArgs; - const txId = log.args.transactionId; - - await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - - return expectRevertOrAlwaysFailingTransactionAsync( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ); - }); - - it('should execute removeAuthorizedAddress for registered address if fully confirmed', async () => { - const removeAuthorizedAddressData = erc20Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( - authorized, - ); - const submitRes = await multiSigWrapper.submitTransactionAsync( - erc20Proxy.address, - removeAuthorizedAddressData, - owners[0], - ); - const submitLog = submitRes.logs[0] as LogWithDecodedArgs; - const txId = submitLog.args.transactionId; - - await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - - const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAsync(txId, owners[0]); - const execLog = execRes.logs[0] as LogWithDecodedArgs; - expect(execLog.args.transactionId).to.be.bignumber.equal(txId); - - const tx = await multiSig.transactions.callAsync(txId); - const isExecuted = tx[3]; - expect(isExecuted).to.equal(true); - - const isAuthorized = await erc20Proxy.authorized.callAsync(authorized); - expect(isAuthorized).to.equal(false); - }); - - it('should throw if already executed', async () => { - const removeAuthorizedAddressData = erc20Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( - authorized, - ); - const submitRes = await multiSigWrapper.submitTransactionAsync( - erc20Proxy.address, - removeAuthorizedAddressData, - owners[0], - ); - const submitLog = submitRes.logs[0] as LogWithDecodedArgs; - const txId = submitLog.args.transactionId; - - await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); - - const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAsync(txId, owners[0]); - const execLog = execRes.logs[0] as LogWithDecodedArgs; - expect(execLog.args.transactionId).to.be.bignumber.equal(txId); - - const tx = await multiSig.transactions.callAsync(txId); - const isExecuted = tx[3]; - expect(isExecuted).to.equal(true); - - return expectRevertOrAlwaysFailingTransactionAsync( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ); + describe('executeRemoveAuthorizedAddressAtIndex', () => { + it('should throw without the required confirmations', async () => { + const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( + authorized, + erc20Index, + ); + const res = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + removeAuthorizedAddressAtIndexData, + owners[0], + ); + const log = res.logs[0] as LogWithDecodedArgs; + const txId = log.args.transactionId; + + return expectRevertOrAlwaysFailingTransactionAsync( + testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { + from: owners[1], + }), + ); + }); + + it('should throw if tx destination is not registered', async () => { + const removeAuthorizedAddressAtIndexData = erc721Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( + authorized, + erc721Index, + ); + const res = await multiSigWrapper.submitTransactionAsync( + erc721Proxy.address, + removeAuthorizedAddressAtIndexData, + owners[0], + ); + const log = res.logs[0] as LogWithDecodedArgs; + const txId = log.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + + return expectRevertOrAlwaysFailingTransactionAsync( + testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { + from: owners[1], + }), + ); + }); + + it('should throw if tx data is not for removeAuthorizedAddressAtIndex', async () => { + const newAuthorized = owners[1]; + const addAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData( + newAuthorized, + ); + const res = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + addAuthorizedAddressData, + owners[0], + ); + const log = res.logs[0] as LogWithDecodedArgs; + const txId = log.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + + return expectRevertOrAlwaysFailingTransactionAsync( + testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { + from: owners[1], + }), + ); + }); + + it('should execute removeAuthorizedAddressAtIndex for registered address if fully confirmed', async () => { + const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( + authorized, + erc20Index, + ); + const submitRes = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + removeAuthorizedAddressAtIndexData, + owners[0], + ); + const submitLog = submitRes.logs[0] as LogWithDecodedArgs; + const txId = submitLog.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + + const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAtIndexAsync(txId, owners[0]); + const execLog = execRes.logs[0] as LogWithDecodedArgs; + expect(execLog.args.transactionId).to.be.bignumber.equal(txId); + + const tx = await testAssetProxyOwner.transactions.callAsync(txId); + const isExecuted = tx[3]; + expect(isExecuted).to.equal(true); + + const isAuthorized = await erc20Proxy.authorized.callAsync(authorized); + expect(isAuthorized).to.equal(false); + }); + + it('should throw if already executed', async () => { + const removeAuthorizedAddressAtIndexData = erc20Proxy.removeAuthorizedAddressAtIndex.getABIEncodedTransactionData( + authorized, + erc20Index, + ); + const submitRes = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + removeAuthorizedAddressAtIndexData, + owners[0], + ); + const submitLog = submitRes.logs[0] as LogWithDecodedArgs; + const txId = submitLog.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + + const execRes = await multiSigWrapper.executeRemoveAuthorizedAddressAtIndexAsync(txId, owners[0]); + const execLog = execRes.logs[0] as LogWithDecodedArgs; + expect(execLog.args.transactionId).to.be.bignumber.equal(txId); + + const tx = await testAssetProxyOwner.transactions.callAsync(txId); + const isExecuted = tx[3]; + expect(isExecuted).to.equal(true); + + return expectRevertOrAlwaysFailingTransactionAsync( + testAssetProxyOwner.executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(txId, { + from: owners[1], + }), + ); + }); }); }); }); diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 8dc968ed7..56f1dc2bc 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -131,55 +131,52 @@ describe('LibBytes', () => { describe('equals', () => { it('should return true if byte arrays are equal (both arrays < 32 bytes)', async () => { - const equals = await libBytes.publicEquals.callAsync( + const isEqual = await libBytes.publicEquals.callAsync( byteArrayShorterThan32Bytes, byteArrayShorterThan32Bytes, ); - return expect(equals).to.be.true(); + return expect(isEqual).to.be.true(); }); it('should return true if byte arrays are equal (both arrays > 32 bytes)', async () => { - const equals = await libBytes.publicEquals.callAsync( + const isEqual = await libBytes.publicEquals.callAsync( byteArrayLongerThan32Bytes, byteArrayLongerThan32Bytes, ); - return expect(equals).to.be.true(); + return expect(isEqual).to.be.true(); }); it('should return false if byte arrays are not equal (first array < 32 bytes, second array > 32 bytes)', async () => { - const equals = await libBytes.publicEquals.callAsync( + const isEqual = await libBytes.publicEquals.callAsync( byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes, ); - return expect(equals).to.be.false(); + return expect(isEqual).to.be.false(); }); it('should return false if byte arrays are not equal (first array > 32 bytes, second array < 32 bytes)', async () => { - const equals = await libBytes.publicEquals.callAsync( + const isEqual = await libBytes.publicEquals.callAsync( byteArrayLongerThan32Bytes, byteArrayShorterThan32Bytes, ); - return expect(equals).to.be.false(); + return expect(isEqual).to.be.false(); }); it('should return false if byte arrays are not equal (same length, but a byte in first word differs)', async () => { - const equals = await libBytes.publicEquals.callAsync( + const isEqual = await libBytes.publicEquals.callAsync( byteArrayLongerThan32BytesFirstBytesSwapped, byteArrayLongerThan32Bytes, ); - return expect(equals).to.be.false(); + return expect(isEqual).to.be.false(); }); it('should return false if byte arrays are not equal (same length, but a byte in last word differs)', async () => { - const equals = await libBytes.publicEquals.callAsync( + const isEqual = await libBytes.publicEquals.callAsync( byteArrayLongerThan32BytesLastBytesSwapped, byteArrayLongerThan32Bytes, ); - return expect(equals).to.be.false(); + return expect(isEqual).to.be.false(); }); describe('should ignore trailing data', () => { it('should return true when both < 32 bytes', async () => { - const equals = await libBytes.publicEqualsPop1.callAsync( - '0x0102', - '0x0103', - ); - return expect(equals).to.be.true(); + const isEqual = await libBytes.publicEqualsPop1.callAsync('0x0102', '0x0103'); + return expect(isEqual).to.be.true(); }); }); }); @@ -464,16 +461,12 @@ describe('LibBytes', () => { it('should revert if byte array has a length < 4', async () => { const byteArrayLessThan4Bytes = '0x010101'; return expectRevertOrOtherErrorAsync( - libBytes.publicReadBytes4.callAsync( - byteArrayLessThan4Bytes, - new BigNumber(0)), + libBytes.publicReadBytes4.callAsync(byteArrayLessThan4Bytes, new BigNumber(0)), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_4_LENGTH_REQUIRED, ); }); it('should return the first 4 bytes of a byte array of arbitrary length', async () => { - const first4Bytes = await libBytes.publicReadBytes4.callAsync( - byteArrayLongerThan32Bytes, - new BigNumber(0)); + const first4Bytes = await libBytes.publicReadBytes4.callAsync(byteArrayLongerThan32Bytes, new BigNumber(0)); const expectedFirst4Bytes = byteArrayLongerThan32Bytes.slice(0, 10); expect(first4Bytes).to.equal(expectedFirst4Bytes); }); @@ -554,7 +547,11 @@ describe('LibBytes', () => { it('should successfully write short, nested array of bytes when it takes up the whole array)', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); - const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, testBytesOffset, shortData); + const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + emptyByteArray, + testBytesOffset, + shortData, + ); const bytesRead = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(shortData); }); @@ -566,10 +563,18 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex( new Buffer(prefixDataAsBuffer.byteLength + shortTestBytesAsBuffer.byteLength), ); - let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, prefixOffset, prefixData); + let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + emptyByteArray, + prefixOffset, + prefixData, + ); // Write data after prefix const testBytesOffset = new BigNumber(prefixDataAsBuffer.byteLength); - bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(bytesWritten, testBytesOffset, shortData); + bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + bytesWritten, + testBytesOffset, + shortData, + ); // Read data after prefix and validate const bytes = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(shortData); @@ -577,7 +582,11 @@ describe('LibBytes', () => { it('should successfully write a nested array of bytes - one word in length - when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(wordOfTestBytesAsBuffer.byteLength)); - const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, testBytesOffset, wordOfData); + const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + emptyByteArray, + testBytesOffset, + wordOfData, + ); const bytesRead = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(wordOfData); }); @@ -589,10 +598,18 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex( new Buffer(prefixDataAsBuffer.byteLength + wordOfTestBytesAsBuffer.byteLength), ); - let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, prefixOffset, prefixData); + let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + emptyByteArray, + prefixOffset, + prefixData, + ); // Write data after prefix const testBytesOffset = new BigNumber(prefixDataAsBuffer.byteLength); - bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(bytesWritten, testBytesOffset, wordOfData); + bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + bytesWritten, + testBytesOffset, + wordOfData, + ); // Read data after prefix and validate const bytes = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(wordOfData); @@ -600,7 +617,11 @@ describe('LibBytes', () => { it('should successfully write a long, nested bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(longTestBytesAsBuffer.byteLength)); - const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, testBytesOffset, longData); + const bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + emptyByteArray, + testBytesOffset, + longData, + ); const bytesRead = await libBytes.publicReadBytesWithLength.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(longData); }); @@ -612,7 +633,11 @@ describe('LibBytes', () => { const emptyByteArray = ethUtil.bufferToHex( new Buffer(prefixDataAsBuffer.byteLength + longTestBytesAsBuffer.byteLength), ); - let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(emptyByteArray, prefixOffset, prefixData); + let bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync( + emptyByteArray, + prefixOffset, + prefixData, + ); // Write data after prefix const testBytesOffset = new BigNumber(prefixDataAsBuffer.byteLength); bytesWritten = await libBytes.publicWriteBytesWithLength.callAsync(bytesWritten, testBytesOffset, longData); @@ -641,6 +666,7 @@ describe('LibBytes', () => { describe('memCopy', () => { // Create memory 0x000102...FF const memSize = 256; + // tslint:disable:no-shadowed-variable const memory = new Uint8Array(memSize).map((_, i) => i); const memHex = toHex(memory); -- cgit v1.2.3 From ea8c2b8d6923f37412cefcb8dc8482e009dce104 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Fri, 22 Jun 2018 17:17:55 -0700 Subject: Add modifier and tests for removeAuthorizedAddressAtIndex --- .../contracts/test/asset_proxy/authorizable.ts | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'packages/contracts/test') diff --git a/packages/contracts/test/asset_proxy/authorizable.ts b/packages/contracts/test/asset_proxy/authorizable.ts index ed582b63e..c35dc7882 100644 --- a/packages/contracts/test/asset_proxy/authorizable.ts +++ b/packages/contracts/test/asset_proxy/authorizable.ts @@ -1,4 +1,5 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import { MixinAuthorizableContract } from '../../src/generated_contract_wrappers/mixin_authorizable'; @@ -102,6 +103,74 @@ describe('Authorizable', () => { }); }); + describe('removeAuthorizedAddressAtIndex', () => { + it('should throw if not called by owner', async () => { + await web3Wrapper.awaitTransactionSuccessAsync( + await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const index = new BigNumber(0); + return expectRevertOrAlwaysFailingTransactionAsync( + authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { + from: notOwner, + }), + ); + }); + it('should throw if index is >= authorities.length', async () => { + await web3Wrapper.awaitTransactionSuccessAsync( + await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const index = new BigNumber(1); + return expectRevertOrAlwaysFailingTransactionAsync( + authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { + from: owner, + }), + ); + }); + it('should throw if owner attempts to remove an address that is not authorized', async () => { + const index = new BigNumber(0); + return expectRevertOrAlwaysFailingTransactionAsync( + authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { + from: owner, + }), + ); + }); + it('should throw if address at index does not match target', async () => { + const address1 = address; + const address2 = notOwner; + await web3Wrapper.awaitTransactionSuccessAsync( + await authorizable.addAuthorizedAddress.sendTransactionAsync(address1, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + await web3Wrapper.awaitTransactionSuccessAsync( + await authorizable.addAuthorizedAddress.sendTransactionAsync(address2, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const address1Index = new BigNumber(0); + return expectRevertOrAlwaysFailingTransactionAsync( + authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address2, address1Index, { + from: owner, + }), + ); + }); + it('should allow owner to remove an authorized address', async () => { + await web3Wrapper.awaitTransactionSuccessAsync( + await authorizable.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const index = new BigNumber(0); + await web3Wrapper.awaitTransactionSuccessAsync( + await authorizable.removeAuthorizedAddressAtIndex.sendTransactionAsync(address, index, { + from: owner, + }), + constants.AWAIT_TRANSACTION_MINED_MS, + ); + const isAuthorized = await authorizable.authorized.callAsync(address); + expect(isAuthorized).to.be.false(); + }); + }); + describe('getAuthorizedAddresses', () => { it('should return all authorized addresses', async () => { const initial = await authorizable.getAuthorizedAddresses.callAsync(); -- cgit v1.2.3