diff options
author | Fabio Berger <me@fabioberger.com> | 2018-05-26 06:39:02 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-05-26 06:39:02 +0800 |
commit | 790af0fd72754314025c2c396a785167671f8bb6 (patch) | |
tree | 38a1d2dd86316268f6afcc2e01c4afaf3ee03c49 /packages/contracts/test | |
parent | 4e5bfae332279acbb58d76a32102b5a27dde069d (diff) | |
parent | c7f5e77b3fe7c1805202a5b1e1e1ce1e9d31a6b0 (diff) | |
download | dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.tar dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.tar.gz dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.tar.bz2 dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.tar.lz dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.tar.xz dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.tar.zst dexon-sol-tools-790af0fd72754314025c2c396a785167671f8bb6.zip |
Merge branch 'v2-prototype' into refactor/order-utils/for-v2
* v2-prototype:
Fix imports in order_utils
Use web3-wrapper instead of 0x.js, update logDecoder
Cleanup tests
Add errMsg when throwing on unrecognized error
Move readFirst4 to LibBytes
Add old MultiSig to previous contracts, cleanup file structure
Fix build
Address feedback, rename contract to AssetProxyOwner
Update multisig tests and utils
Update MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress to use a mapping of registered proxies
Implement design for relayers with no volume or tokens
Diffstat (limited to 'packages/contracts/test')
-rw-r--r-- | packages/contracts/test/asset_proxy_owner.ts | 345 | ||||
-rw-r--r-- | packages/contracts/test/exchange/core.ts | 9 | ||||
-rw-r--r-- | packages/contracts/test/libraries/lib_bytes.ts | 14 | ||||
-rw-r--r-- | packages/contracts/test/multi_sig_with_time_lock.ts | 150 | ||||
-rw-r--r-- | packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts | 205 |
5 files changed, 404 insertions, 319 deletions
diff --git a/packages/contracts/test/asset_proxy_owner.ts b/packages/contracts/test/asset_proxy_owner.ts new file mode 100644 index 000000000..db68b5678 --- /dev/null +++ b/packages/contracts/test/asset_proxy_owner.ts @@ -0,0 +1,345 @@ +import { BlockchainLifecycle } from '@0xproject/dev-utils'; +import { LogWithDecodedArgs } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as chai from 'chai'; +import * as _ from 'lodash'; +import 'make-promises-safe'; +import * as Web3 from 'web3'; + +import { + AssetProxyOwnerContract, + AssetProxyRegistrationContractEventArgs, + ExecutionContractEventArgs, + ExecutionFailureContractEventArgs, + SubmissionContractEventArgs, +} from '../src/contract_wrappers/generated/asset_proxy_owner'; +import { MixinAuthorizableContract } from '../src/contract_wrappers/generated/mixin_authorizable'; +import { artifacts } from '../src/utils/artifacts'; +import { chaiSetup } from '../src/utils/chai_setup'; +import { constants } from '../src/utils/constants'; +import { MultiSigWrapper } from '../src/utils/multi_sig_wrapper'; +import { provider, txDefaults, web3Wrapper } from '../src/utils/web3_wrapper'; + +chaiSetup.configure(); +const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); + +describe('AssetProxyOwner', () => { + let owners: string[]; + let authorized: string; + const REQUIRED_APPROVALS = new BigNumber(2); + const SECONDS_TIME_LOCKED = new BigNumber(1000000); + + let erc20Proxy: MixinAuthorizableContract; + let erc721Proxy: MixinAuthorizableContract; + let multiSig: AssetProxyOwnerContract; + let multiSigWrapper: MultiSigWrapper; + + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + owners = [accounts[0], accounts[1]]; + const initialOwner = (authorized = accounts[0]); + erc20Proxy = await MixinAuthorizableContract.deployFrom0xArtifactAsync( + artifacts.MixinAuthorizable, + provider, + txDefaults, + ); + erc721Proxy = await MixinAuthorizableContract.deployFrom0xArtifactAsync( + artifacts.MixinAuthorizable, + provider, + txDefaults, + ); + const defaultAssetProxyContractAddresses: string[] = []; + multiSig = await AssetProxyOwnerContract.deployFrom0xArtifactAsync( + artifacts.AssetProxyOwner, + provider, + txDefaults, + owners, + defaultAssetProxyContractAddresses, + REQUIRED_APPROVALS, + SECONDS_TIME_LOCKED, + ); + multiSigWrapper = new MultiSigWrapper(multiSig, provider); + await erc20Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }); + await erc721Proxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner }); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + + describe('constructor', () => { + it('should register passed in assetProxyContracts', async () => { + const assetProxyContractAddresses = [erc20Proxy.address, erc721Proxy.address]; + const newMultiSig = await AssetProxyOwnerContract.deployFrom0xArtifactAsync( + artifacts.AssetProxyOwner, + provider, + txDefaults, + owners, + assetProxyContractAddresses, + REQUIRED_APPROVALS, + SECONDS_TIME_LOCKED, + ); + const isErc20ProxyRegistered = await newMultiSig.isAssetProxyRegistered.callAsync(erc20Proxy.address); + const isErc721ProxyRegistered = await newMultiSig.isAssetProxyRegistered.callAsync(erc721Proxy.address); + expect(isErc20ProxyRegistered).to.equal(true); + expect(isErc721ProxyRegistered).to.equal(true); + }); + it('should throw if a null address is included in assetProxyContracts', async () => { + const assetProxyContractAddresses = [erc20Proxy.address, constants.NULL_ADDRESS]; + return expect( + AssetProxyOwnerContract.deployFrom0xArtifactAsync( + artifacts.AssetProxyOwner, + provider, + txDefaults, + owners, + assetProxyContractAddresses, + REQUIRED_APPROVALS, + SECONDS_TIME_LOCKED, + ), + ).to.be.rejectedWith(constants.REVERT); + }); + }); + + describe('isFunctionRemoveAuthorizedAddress', () => { + it('should throw if data is not for removeAuthorizedAddress', async () => { + const notRemoveAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData( + owners[0], + ); + return expect( + multiSig.isFunctionRemoveAuthorizedAddress.callAsync(notRemoveAuthorizedAddressData), + ).to.be.rejectedWith(constants.REVERT); + }); + + it('should return true if data is for removeAuthorizedAddress', async () => { + const removeAuthorizedAddressData = erc20Proxy.removeAuthorizedAddress.getABIEncodedTransactionData( + owners[0], + ); + const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.callAsync( + removeAuthorizedAddressData, + ); + expect(isFunctionRemoveAuthorizedAddress).to.be.true(); + }); + }); + + describe('registerAssetProxy', () => { + it('should throw if not called by multisig', async () => { + const isRegistered = true; + return expect( + multiSig.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, isRegistered, { from: owners[0] }), + ).to.be.rejectedWith(constants.REVERT); + }); + + it('should register an address if called by multisig after timelock', async () => { + const addressToRegister = erc20Proxy.address; + const isRegistered = true; + const registerAssetProxyData = multiSig.registerAssetProxy.getABIEncodedTransactionData( + addressToRegister, + isRegistered, + ); + const submitTxRes = await multiSigWrapper.submitTransactionAsync( + multiSig.address, + registerAssetProxyData, + owners[0], + ); + const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + await web3Wrapper.increaseTimeAsync(SECONDS_TIME_LOCKED.toNumber()); + + const executeTxRes = await multiSigWrapper.executeTransactionAsync(txId, owners[0]); + const registerLog = executeTxRes.logs[0] as LogWithDecodedArgs<AssetProxyRegistrationContractEventArgs>; + expect(registerLog.args.assetProxyContract).to.equal(addressToRegister); + expect(registerLog.args.isRegistered).to.equal(isRegistered); + + const isAssetProxyRegistered = await multiSig.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( + addressToRegister, + isRegistered, + ); + const submitTxRes = await multiSigWrapper.submitTransactionAsync( + multiSig.address, + registerAssetProxyData, + owners[0], + ); + const log = submitTxRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + await web3Wrapper.increaseTimeAsync(SECONDS_TIME_LOCKED.toNumber()); + + const executeTxRes = await multiSigWrapper.executeTransactionAsync(txId, owners[0]); + const failureLog = executeTxRes.logs[0] as LogWithDecodedArgs<ExecutionFailureContractEventArgs>; + expect(failureLog.args.transactionId).to.be.bignumber.equal(txId); + + const isAssetProxyRegistered = await multiSig.isAssetProxyRegistered.callAsync(addressToRegister); + expect(isAssetProxyRegistered).to.equal(false); + }); + }); + + describe('executeRemoveAuthorizedAddress', () => { + 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( + addressToRegister, + isRegistered, + ); + const registerAssetProxySubmitRes = await multiSigWrapper.submitTransactionAsync( + multiSig.address, + registerAssetProxyData, + owners[0], + ); + const registerAssetProxySubmitLog = registerAssetProxySubmitRes.logs[0] as LogWithDecodedArgs< + SubmissionContractEventArgs + >; + const registerAssetProxyTxId = registerAssetProxySubmitLog.args.transactionId; + await multiSigWrapper.confirmTransactionAsync(registerAssetProxyTxId, owners[1]); + + const addAuthorizedAddressData = erc20Proxy.addAuthorizedAddress.getABIEncodedTransactionData(authorized); + const erc20AddAuthorizedAddressSubmitRes = await multiSigWrapper.submitTransactionAsync( + erc20Proxy.address, + addAuthorizedAddressData, + owners[0], + ); + const erc721AddAuthorizedAddressSubmitRes = await multiSigWrapper.submitTransactionAsync( + erc721Proxy.address, + addAuthorizedAddressData, + owners[0], + ); + const erc20AddAuthorizedAddressSubmitLog = erc20AddAuthorizedAddressSubmitRes.logs[0] as LogWithDecodedArgs< + SubmissionContractEventArgs + >; + const erc721AddAuthorizedAddressSubmitLog = erc721AddAuthorizedAddressSubmitRes + .logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const erc20AddAuthorizedAddressTxId = erc20AddAuthorizedAddressSubmitLog.args.transactionId; + const erc721AddAuthorizedAddressTxId = erc721AddAuthorizedAddressSubmitLog.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(erc20AddAuthorizedAddressTxId, owners[1]); + await multiSigWrapper.confirmTransactionAsync(erc721AddAuthorizedAddressTxId, owners[1]); + await web3Wrapper.increaseTimeAsync(SECONDS_TIME_LOCKED.toNumber()); + await multiSigWrapper.executeTransactionAsync(registerAssetProxyTxId, owners[0]); + await multiSigWrapper.executeTransactionAsync(erc20AddAuthorizedAddressTxId, owners[0]); + 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<SubmissionContractEventArgs>; + const txId = log.args.transactionId; + + return expect( + multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), + ).to.be.rejectedWith(constants.REVERT); + }); + + 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<SubmissionContractEventArgs>; + const txId = log.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + + return expect( + multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), + ).to.be.rejectedWith(constants.REVERT); + }); + + 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<SubmissionContractEventArgs>; + const txId = log.args.transactionId; + + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + + return expect( + multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), + ).to.be.rejectedWith(constants.REVERT); + }); + + 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<SubmissionContractEventArgs>; + 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<ExecutionContractEventArgs>; + 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<SubmissionContractEventArgs>; + 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<ExecutionContractEventArgs>; + 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 expect( + multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), + ).to.be.rejectedWith(constants.REVERT); + }); + }); +}); diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index f5cae7c7c..be8d14cb0 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -127,11 +127,6 @@ describe('Exchange core', () => { afterEach(async () => { await blockchainLifecycle.revertAsync(); }); - describe('internal functions', () => { - it('should include transferViaTokenTransferProxy', () => { - expect((exchange as any).transferViaTokenTransferProxy).to.be.undefined(); - }); - }); describe('fillOrder', () => { beforeEach(async () => { @@ -708,7 +703,7 @@ describe('Exchange core', () => { // Create 3 orders with makerEpoch values: 0,1,2,3 // Since we cancelled with makerEpoch=1, orders with makerEpoch<=1 will not be processed erc20Balances = await erc20Wrapper.getBalancesAsync(); - const signedOrders = await Promise.all([ + const signedOrders = [ orderFactory.newSignedOrder({ makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(9), 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(9), 18), @@ -729,7 +724,7 @@ describe('Exchange core', () => { takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(7979), 18), salt: new BigNumber(3), }), - ]); + ]; await exchangeWrapper.batchFillOrdersNoThrowAsync(signedOrders, takerAddress); const newBalances = await erc20Wrapper.getBalancesAsync(); diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index ce3adbdae..968bac300 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -248,4 +248,18 @@ describe('LibBytes', () => { it('should fail if the length between the offset and end of the byte array is too short to hold a uint256)', async () => {}); }); */ + + describe('readFirst4', () => { + it('should revert if byte array has a length < 4', async () => { + const byteArrayLessThan4Bytes = '0x010101'; + return expect(libBytes.publicReadFirst4.callAsync(byteArrayLessThan4Bytes)).to.be.rejectedWith( + constants.REVERT, + ); + }); + it('should return the first 4 bytes of a byte array of arbitrary length', async () => { + const first4Bytes = await libBytes.publicReadFirst4.callAsync(byteArrayLongerThan32Bytes); + const expectedFirst4Bytes = byteArrayLongerThan32Bytes.slice(0, 10); + expect(first4Bytes).to.equal(expectedFirst4Bytes); + }); + }); }); diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts index 732077df2..ace0f0045 100644 --- a/packages/contracts/test/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -1,40 +1,39 @@ import { BlockchainLifecycle, web3Factory } from '@0xproject/dev-utils'; import { LogWithDecodedArgs } from '@0xproject/types'; -import { AbiDecoder, BigNumber } from '@0xproject/utils'; +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 * as Web3 from 'web3'; -import * as multiSigWalletJSON from '../../build/contracts/MultiSigWalletWithTimeLock.json'; -import { MultiSigWalletContract } from '../src/contract_wrappers/generated/multi_sig_wallet'; -import { MultiSigWalletWithTimeLockContract } from '../src/contract_wrappers/generated/multi_sig_wallet_with_time_lock'; +import { + MultiSigWalletWithTimeLockContract, + SubmissionContractEventArgs, +} from '../src/contract_wrappers/generated/multi_sig_wallet_with_time_lock'; import { artifacts } from '../src/utils/artifacts'; import { chaiSetup } from '../src/utils/chai_setup'; import { constants } from '../src/utils/constants'; import { MultiSigWrapper } from '../src/utils/multi_sig_wrapper'; -import { SubmissionContractEventArgs } from '../src/utils/types'; import { provider, txDefaults, web3Wrapper } from '../src/utils/web3_wrapper'; -const MULTI_SIG_ABI = artifacts.MultiSigWalletWithTimeLock.compilerOutput.abi; chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -const abiDecoder = new AbiDecoder([MULTI_SIG_ABI]); describe('MultiSigWalletWithTimeLock', () => { let owners: string[]; + const REQUIRED_APPROVALS = new BigNumber(2); + const SECONDS_TIME_LOCKED = new BigNumber(1000000); + before(async () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); owners = [accounts[0], accounts[1]]; }); - const SIGNATURES_REQUIRED = new BigNumber(2); - const SECONDS_TIME_LOCKED = new BigNumber(10000); let multiSig: MultiSigWalletWithTimeLockContract; let multiSigWrapper: MultiSigWrapper; - let txId: BigNumber; - let initialSecondsTimeLocked: number; + beforeEach(async () => { await blockchainLifecycle.startAsync(); }); @@ -51,19 +50,18 @@ describe('MultiSigWalletWithTimeLock', () => { await blockchainLifecycle.revertAsync(); }); before('deploy a wallet', async () => { + const secondsTimeLocked = new BigNumber(0); multiSig = await MultiSigWalletWithTimeLockContract.deployFrom0xArtifactAsync( artifacts.MultiSigWalletWithTimeLock, provider, txDefaults, owners, - SIGNATURES_REQUIRED, - new BigNumber(0), + REQUIRED_APPROVALS, + secondsTimeLocked, ); - multiSigWrapper = new MultiSigWrapper((multiSig as any) as MultiSigWalletContract); - - const secondsTimeLocked = await multiSig.secondsTimeLocked.callAsync(); - initialSecondsTimeLocked = secondsTimeLocked.toNumber(); + multiSigWrapper = new MultiSigWrapper(multiSig, provider); }); + it('should throw when not called by wallet', async () => { return expect( multiSig.changeTimeLock.sendTransactionAsync(SECONDS_TIME_LOCKED, { from: owners[0] }), @@ -72,22 +70,11 @@ describe('MultiSigWalletWithTimeLock', () => { it('should throw without enough confirmations', async () => { const destination = multiSig.address; - const from = owners[0]; - const dataParams = { - name: 'changeTimeLock', - abi: MULTI_SIG_ABI, - args: [SECONDS_TIME_LOCKED.toNumber()], - }; - const txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, - ); - const log = abiDecoder.tryToDecodeLogOrNoop(txReceipt.logs[0]) as LogWithDecodedArgs< - SubmissionContractEventArgs - >; + const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(SECONDS_TIME_LOCKED); + const res = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); + const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = log.args.transactionId; - txId = log.args.transactionId; return expect( multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), ).to.be.rejectedWith(constants.REVERT); @@ -95,28 +82,13 @@ describe('MultiSigWalletWithTimeLock', () => { it('should set confirmation time with enough confirmations', async () => { const destination = multiSig.address; - const from = owners[0]; - const dataParams = { - name: 'changeTimeLock', - abi: MULTI_SIG_ABI, - args: [SECONDS_TIME_LOCKED.toNumber()], - }; - let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, - ); - const log = abiDecoder.tryToDecodeLogOrNoop(txReceipt.logs[0]) as LogWithDecodedArgs< - SubmissionContractEventArgs - >; + const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(SECONDS_TIME_LOCKED); + const subRes = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); + const subLog = subRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = subLog.args.transactionId; - txId = log.args.transactionId; - txHash = await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const res = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, - ); - expect(res.logs).to.have.length(2); + const confirmRes = await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + expect(confirmRes.logs).to.have.length(2); const blockNum = await web3Wrapper.getBlockNumberAsync(); const blockInfo = await web3Wrapper.getBlockAsync(blockNum); @@ -128,33 +100,13 @@ describe('MultiSigWalletWithTimeLock', () => { it('should be executable with enough confirmations and secondsTimeLocked of 0', async () => { const destination = multiSig.address; - const from = owners[0]; - const dataParams = { - name: 'changeTimeLock', - abi: MULTI_SIG_ABI, - args: [SECONDS_TIME_LOCKED.toNumber()], - }; - let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, - ); - const log = abiDecoder.tryToDecodeLogOrNoop(txReceipt.logs[0]) as LogWithDecodedArgs< - SubmissionContractEventArgs - >; - - txId = log.args.transactionId; - txHash = await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - - expect(initialSecondsTimeLocked).to.be.equal(0); + const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(SECONDS_TIME_LOCKED); + const subRes = await multiSigWrapper.submitTransactionAsync(destination, changeTimeLockData, owners[0]); + const subLog = subRes.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; + const txId = subLog.args.transactionId; - txHash = await multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }); - const res = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, - ); - expect(res.logs).to.have.length(2); + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); + await multiSigWrapper.executeTransactionAsync(txId, owners[1]); const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.callAsync()); expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED); @@ -167,45 +119,29 @@ describe('MultiSigWalletWithTimeLock', () => { after(async () => { await blockchainLifecycle.revertAsync(); }); - before('deploy a wallet', async () => { + let txId: BigNumber; + const newSecondsTimeLocked = new BigNumber(0); + before('deploy a wallet, submit transaction to change timelock, and confirm the transaction', async () => { multiSig = await MultiSigWalletWithTimeLockContract.deployFrom0xArtifactAsync( artifacts.MultiSigWalletWithTimeLock, provider, txDefaults, owners, - SIGNATURES_REQUIRED, + REQUIRED_APPROVALS, SECONDS_TIME_LOCKED, ); - multiSigWrapper = new MultiSigWrapper((multiSig as any) as MultiSigWalletContract); + multiSigWrapper = new MultiSigWrapper(multiSig, provider); - const secondsTimeLocked = await multiSig.secondsTimeLocked.callAsync(); - initialSecondsTimeLocked = secondsTimeLocked.toNumber(); - const destination = multiSig.address; - const from = owners[0]; - const dataParams = { - name: 'changeTimeLock', - abi: MULTI_SIG_ABI, - args: [newSecondsTimeLocked], - }; - let txHash = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams); - let txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, + const changeTimeLockData = multiSig.changeTimeLock.getABIEncodedTransactionData(newSecondsTimeLocked); + const res = await multiSigWrapper.submitTransactionAsync( + multiSig.address, + changeTimeLockData, + owners[0], ); - const log = abiDecoder.tryToDecodeLogOrNoop(txReceipt.logs[0]) as LogWithDecodedArgs< - SubmissionContractEventArgs - >; + const log = res.logs[0] as LogWithDecodedArgs<SubmissionContractEventArgs>; txId = log.args.transactionId; - txHash = await multiSig.confirmTransaction.sendTransactionAsync(txId, { - from: owners[1], - }); - txReceipt = await web3Wrapper.awaitTransactionSuccessAsync( - txHash, - constants.AWAIT_TRANSACTION_MINED_MS, - ); - expect(txReceipt.logs).to.have.length(2); + await multiSigWrapper.confirmTransactionAsync(txId, owners[1]); }); - const newSecondsTimeLocked = 0; it('should throw if it has enough confirmations but is not past the time lock', async () => { return expect( multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }), diff --git a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts deleted file mode 100644 index dcd206b1c..000000000 --- a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts +++ /dev/null @@ -1,205 +0,0 @@ -/* - * - * @TODO: Before deploying, the MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress contract must be updated - * to have a mapping of all approved addresses. These tests must be updated appropriately. - * For now, these tests have been commented out by @hysz (greg@0xproject.com). - * -import { LogWithDecodedArgs, ZeroEx } from '0x.js'; -import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; -import { AbiDecoder, BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as chai from 'chai'; -import 'make-promises-safe'; -import * as Web3 from 'web3'; - -import { MultiSigWalletContract } from '../src/contract_wrappers/generated/multi_sig_wallet'; -import { MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract } from '../src/contract_wrappers/generated/multi_sig_wallet_with_time_lock_except_remove_authorized_address'; -import { TokenTransferProxyContract } from '../src/contract_wrappers/generated/token_transfer_proxy'; -import { artifacts } from '../src/utils/artifacts'; -import { constants } from '../src/utils/constants'; -import { crypto } from '../src/utils/crypto'; -import { MultiSigWrapper } from '../src/utils/multi_sig_wrapper'; -import { ContractName, SubmissionContractEventArgs, TransactionDataParams } from '../src/utils/types'; - -import { chaiSetup } from './utils/chai_setup'; - -import { provider, txDefaults, web3Wrapper } from './utils/web3_wrapper'; - -const PROXY_ABI = artifacts.TokenTransferProxy.compilerOutput.abi; -const MUTISIG_WALLET_WITH_TIME_LOCK_EXCEPT_REMOVE_AUTHORIZED_ADDRESS_ABI = - artifacts.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.compilerOutput.abi; - -chaiSetup.configure(); -const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); -const abiDecoder = new AbiDecoder([MUTISIG_WALLET_WITH_TIME_LOCK_EXCEPT_REMOVE_AUTHORIZED_ADDRESS_ABI]); - -describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { - const zeroEx = new ZeroEx(provider, { networkId: constants.TESTRPC_NETWORK_ID }); - let owners: string[]; - const requiredApprovals = new BigNumber(2); - const SECONDS_TIME_LOCKED = new BigNumber(1000000); - - // initialize fake addresses - let authorizedAddress: string; - let unauthorizedAddress: string; - - let tokenTransferProxy: TokenTransferProxyContract; - let multiSig: MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract; - let multiSigWrapper: MultiSigWrapper; - - let validDestination: string; - before(async () => { - const accounts = await web3Wrapper.getAvailableAddressesAsync(); - owners = [accounts[0], accounts[1]]; - [authorizedAddress, unauthorizedAddress] = accounts; - const initialOwner = accounts[0]; - tokenTransferProxy = await TokenTransferProxyContract.deployFrom0xArtifactAsync( - artifacts.TokenTransferProxy, - provider, - txDefaults, - ); - await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(authorizedAddress, { - from: initialOwner, - }); - multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract.deployFrom0xArtifactAsync( - artifacts.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress, - provider, - txDefaults, - owners, - requiredApprovals, - SECONDS_TIME_LOCKED, - tokenTransferProxy.address, - ); - await tokenTransferProxy.transferOwnership.sendTransactionAsync(multiSig.address, { - from: initialOwner, - }); - multiSigWrapper = new MultiSigWrapper((multiSig as any) as MultiSigWalletContract); - validDestination = tokenTransferProxy.address; - }); - beforeEach(async () => { - await blockchainLifecycle.startAsync(); - }); - afterEach(async () => { - await blockchainLifecycle.revertAsync(); - }); - - describe('isFunctionRemoveAuthorizedAddress', () => { - it('should throw if data is not for removeAuthorizedAddress', async () => { - const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]); - return expect(multiSig.isFunctionRemoveAuthorizedAddress.callAsync(data)).to.be.rejectedWith( - constants.REVERT, - ); - }); - - it('should return true if data is for removeAuthorizedAddress', async () => { - const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]); - const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.callAsync(data); - expect(isFunctionRemoveAuthorizedAddress).to.be.true(); - }); - }); - - describe('executeRemoveAuthorizedAddress', () => { - it('should throw without the required confirmations', async () => { - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const res = await zeroEx.awaitTransactionMinedAsync(txHash); - const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; - const txId = log.args.transactionId; - - return expect( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ).to.be.rejectedWith(constants.REVERT); - }); - - it('should throw if tx destination is not the tokenTransferProxy', async () => { - const invalidTokenTransferProxy = await TokenTransferProxyContract.deployFrom0xArtifactAsync( - artifacts.TokenTransferProxy, - provider, - txDefaults, - ); - const invalidDestination = invalidTokenTransferProxy.address; - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const txHash = await multiSigWrapper.submitTransactionAsync(invalidDestination, owners[0], dataParams); - const res = await zeroEx.awaitTransactionMinedAsync(txHash); - const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; - const txId = log.args.transactionId; - await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.callAsync(txId); - expect(isConfirmed).to.be.true(); - - return expect( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ).to.be.rejectedWith(constants.REVERT); - }); - - it('should throw if tx data is not for removeAuthorizedAddress', async () => { - const dataParams: TransactionDataParams = { - name: 'addAuthorizedAddress', - abi: PROXY_ABI, - args: [unauthorizedAddress], - }; - const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const res = await zeroEx.awaitTransactionMinedAsync(txHash); - const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; - const txId = log.args.transactionId; - await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.callAsync(txId); - expect(isConfirmed).to.be.true(); - - return expect( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ).to.be.rejectedWith(constants.REVERT); - }); - - it('should execute removeAuthorizedAddress for valid tokenTransferProxy if fully confirmed', async () => { - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const res = await zeroEx.awaitTransactionMinedAsync(txHash); - const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; - const txId = log.args.transactionId; - await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.callAsync(txId); - expect(isConfirmed).to.be.true(); - await multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }); - const isAuthorized = await tokenTransferProxy.authorized.callAsync(authorizedAddress); - expect(isAuthorized).to.be.false(); - }); - - it('should throw if already executed', async () => { - const dataParams: TransactionDataParams = { - name: 'removeAuthorizedAddress', - abi: PROXY_ABI, - args: [authorizedAddress], - }; - const txHash = await multiSigWrapper.submitTransactionAsync(validDestination, owners[0], dataParams); - const res = await zeroEx.awaitTransactionMinedAsync(txHash); - const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<SubmissionContractEventArgs>; - const txId = log.args.transactionId; - await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed.callAsync(txId); - expect(isConfirmed).to.be.true(); - await multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }); - const tx = await multiSig.transactions.callAsync(txId); - const isExecuted = tx[3]; - expect(isExecuted).to.be.true(); - return expect( - multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }), - ).to.be.rejectedWith(constants.REVERT); - }); - }); -}); - -*/ |