diff options
author | Fabio Berger <me@fabioberger.com> | 2018-06-01 01:45:34 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-06-01 01:45:34 +0800 |
commit | 94ee82e076d85b64063b5c71be13b1ebe0bb8c10 (patch) | |
tree | 53524249da4c5b907e1489d8677a7cc1edf069a2 /packages/contracts/test | |
parent | 0beab9eec45508fb6163bd6c0fd3970f0b61a91d (diff) | |
parent | 5b31d0aa3635ea524fb42d73cd6c713887dfef6a (diff) | |
download | dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.tar dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.tar.gz dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.tar.bz2 dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.tar.lz dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.tar.xz dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.tar.zst dexon-0x-contracts-94ee82e076d85b64063b5c71be13b1ebe0bb8c10.zip |
Merge branch 'v2-prototype' into refactor/order-utils/for-v2
* v2-prototype: (45 commits)
Check length before accessing indices, add awaitTransactionSuccess where needed, and rename function
Add back before/after snapshots for each test
Rename Signer to Wallet, rename GAS_ESTIMATE to GAS_LIMIT
Make preSigned and allowedValidators mappings public
Change names of signature types
Fix formatting and tests
Make AssetProxyId last byte of assetData
Add signer to txHash, allow approveValidator to be used with executeTransaction
Update Whitelist
Fix Exchange interface
Increase block gas limit
Use last byte of signature as signature type
Remove TxOrigin signature type, modify whitelist to use Validator signature type
Update Whitelist contract with comments, also require maker to be whitelisted
Fix build
Add example whitelist contract and minimum tests
Add sample whitelist contract
Add TxOrigin signature type and rearrange order of types
Add approveValidator function
Add Validator signature type
...
# Conflicts:
# packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
# packages/contracts/src/utils/types.ts
# packages/contracts/test/exchange/transactions.ts
# packages/order-utils/src/asset_proxy_utils.ts
Diffstat (limited to 'packages/contracts/test')
-rw-r--r-- | packages/contracts/test/asset_proxy_owner.ts | 6 | ||||
-rw-r--r-- | packages/contracts/test/exchange/core.ts | 5 | ||||
-rw-r--r-- | packages/contracts/test/exchange/libs.ts | 4 | ||||
-rw-r--r-- | packages/contracts/test/exchange/signature_validator.ts | 9 | ||||
-rw-r--r-- | packages/contracts/test/exchange/transactions.ts | 136 | ||||
-rw-r--r-- | packages/contracts/test/libraries/lib_bytes.ts | 31 | ||||
-rw-r--r-- | packages/contracts/test/multi_sig_with_time_lock.ts | 6 | ||||
-rw-r--r-- | packages/contracts/test/token_registry.ts | 1 |
8 files changed, 185 insertions, 13 deletions
diff --git a/packages/contracts/test/asset_proxy_owner.ts b/packages/contracts/test/asset_proxy_owner.ts index db68b5678..43c5da512 100644 --- a/packages/contracts/test/asset_proxy_owner.ts +++ b/packages/contracts/test/asset_proxy_owner.ts @@ -36,6 +36,12 @@ describe('AssetProxyOwner', () => { let multiSigWrapper: MultiSigWrapper; before(async () => { + await blockchainLifecycle.startAsync(); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); + }); + before(async () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); owners = [accounts[0], accounts[1]]; const initialOwner = (authorized = accounts[0]); diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index e8397f8a2..adc57c7a4 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -457,10 +457,11 @@ describe('Exchange core', () => { makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18), }); + const v = ethUtil.toBuffer(signedOrder.signature.slice(0, 4)); const invalidR = ethUtil.sha3('invalidR'); const invalidS = ethUtil.sha3('invalidS'); - const signatureTypeAndV = signedOrder.signature.slice(0, 6); - const invalidSigBuff = Buffer.concat([ethUtil.toBuffer(signatureTypeAndV), invalidR, 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; return expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith( diff --git a/packages/contracts/test/exchange/libs.ts b/packages/contracts/test/exchange/libs.ts index 5f2c24ac0..10cb8b34e 100644 --- a/packages/contracts/test/exchange/libs.ts +++ b/packages/contracts/test/exchange/libs.ts @@ -48,7 +48,6 @@ describe('Exchange libs', () => { beforeEach(async () => { await blockchainLifecycle.startAsync(); - signedOrder = orderFactory.newSignedOrder(); }); afterEach(async () => { await blockchainLifecycle.revertAsync(); @@ -68,7 +67,8 @@ describe('Exchange libs', () => { }); }); describe('getOrderHash', () => { - it('should output the correct order hash', async () => { + it('should output the correct orderHash', async () => { + signedOrder = orderFactory.newSignedOrder(); const orderHashHex = await libs.publicGetOrderHash.callAsync(signedOrder); expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex); }); diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts index a41a19426..194053abc 100644 --- a/packages/contracts/test/exchange/signature_validator.ts +++ b/packages/contracts/test/exchange/signature_validator.ts @@ -53,7 +53,6 @@ describe('MixinSignatureValidator', () => { beforeEach(async () => { await blockchainLifecycle.startAsync(); - signedOrder = orderFactory.newSignedOrder(); }); afterEach(async () => { await blockchainLifecycle.revertAsync(); @@ -75,13 +74,11 @@ describe('MixinSignatureValidator', () => { }); 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 invalidSigBuff = Buffer.concat([ - ethUtil.toBuffer(signedOrder.signature.slice(0, 6)), - invalidR, - 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; const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts index 7ee194aa1..ef7595562 100644 --- a/packages/contracts/test/exchange/transactions.ts +++ b/packages/contracts/test/exchange/transactions.ts @@ -1,5 +1,5 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; -import { assetProxyUtils } from '@0xproject/order-utils'; +import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils'; import { AssetProxyId, Order, OrderWithoutExchangeAddress, SignatureType, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; @@ -9,6 +9,7 @@ import * as Web3 from 'web3'; import { DummyERC20TokenContract } from '../../src/contract_wrappers/generated/dummy_e_r_c20_token'; import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c20_proxy'; import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange'; +import { WhitelistContract } from '../../src/contract_wrappers/generated/whitelist'; import { artifacts } from '../../src/utils/artifacts'; import { chaiSetup } from '../../src/utils/chai_setup'; import { constants } from '../../src/utils/constants'; @@ -49,6 +50,8 @@ describe('Exchange transactions', () => { let defaultMakerTokenAddress: string; let defaultTakerTokenAddress: string; + let makerPrivateKey: Buffer; + let takerPrivateKey: Buffer; before(async () => { await blockchainLifecycle.startAsync(); @@ -92,8 +95,8 @@ describe('Exchange transactions', () => { makerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultMakerTokenAddress), takerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultTakerTokenAddress), }; - const makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; - const takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)]; + makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; + takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)]; orderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams); makerTransactionFactory = new TransactionFactory(makerPrivateKey, exchange.address); takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address); @@ -197,4 +200,131 @@ describe('Exchange transactions', () => { }); }); }); + + describe('Whitelist', () => { + let whitelist: WhitelistContract; + let whitelistOrderFactory: OrderFactory; + + before(async () => { + whitelist = await WhitelistContract.deployFrom0xArtifactAsync( + artifacts.Whitelist, + provider, + txDefaults, + exchange.address, + ); + const isApproved = true; + await web3Wrapper.awaitTransactionSuccessAsync( + await exchange.approveSignatureValidator.sendTransactionAsync(whitelist.address, isApproved, { + from: takerAddress, + }), + ); + const defaultOrderParams = { + ...constants.STATIC_ORDER_PARAMS, + senderAddress: whitelist.address, + exchangeAddress: exchange.address, + makerAddress, + feeRecipientAddress, + makerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultMakerTokenAddress), + takerAssetData: assetProxyUtils.encodeERC20ProxyData(defaultTakerTokenAddress), + }; + whitelistOrderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams); + }); + + beforeEach(async () => { + signedOrder = whitelistOrderFactory.newSignedOrder(); + erc20Balances = await erc20Wrapper.getBalancesAsync(); + }); + + it('should revert if maker has not been whitelisted', async () => { + const isApproved = true; + await web3Wrapper.awaitTransactionSuccessAsync( + await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }), + ); + + orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder); + const takerAssetFillAmount = signedOrder.takerAssetAmount; + const salt = generatePseudoRandomSalt(); + return expect( + whitelist.fillOrderIfWhitelisted.sendTransactionAsync( + orderWithoutExchangeAddress, + takerAssetFillAmount, + salt, + signedOrder.signature, + { from: takerAddress }, + ), + ).to.be.rejectedWith(constants.REVERT); + }); + + it('should revert if taker has not been whitelisted', async () => { + const isApproved = true; + await web3Wrapper.awaitTransactionSuccessAsync( + await whitelist.updateWhitelistStatus.sendTransactionAsync(makerAddress, isApproved, { from: owner }), + ); + + orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder); + const takerAssetFillAmount = signedOrder.takerAssetAmount; + const salt = generatePseudoRandomSalt(); + return expect( + whitelist.fillOrderIfWhitelisted.sendTransactionAsync( + orderWithoutExchangeAddress, + takerAssetFillAmount, + salt, + signedOrder.signature, + { from: takerAddress }, + ), + ).to.be.rejectedWith(constants.REVERT); + }); + + it('should fill the order if maker and taker have been whitelisted', async () => { + const isApproved = true; + await web3Wrapper.awaitTransactionSuccessAsync( + await whitelist.updateWhitelistStatus.sendTransactionAsync(makerAddress, isApproved, { from: owner }), + ); + + await web3Wrapper.awaitTransactionSuccessAsync( + await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }), + ); + + orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder); + const takerAssetFillAmount = signedOrder.takerAssetAmount; + const salt = generatePseudoRandomSalt(); + await web3Wrapper.awaitTransactionSuccessAsync( + await whitelist.fillOrderIfWhitelisted.sendTransactionAsync( + orderWithoutExchangeAddress, + takerAssetFillAmount, + salt, + signedOrder.signature, + { from: takerAddress }, + ), + ); + + const newBalances = await erc20Wrapper.getBalancesAsync(); + + const makerAssetFillAmount = signedOrder.makerAssetAmount; + const makerFeePaid = signedOrder.makerFee; + const takerFeePaid = signedOrder.takerFee; + + expect(newBalances[makerAddress][defaultMakerTokenAddress]).to.be.bignumber.equal( + erc20Balances[makerAddress][defaultMakerTokenAddress].minus(makerAssetFillAmount), + ); + expect(newBalances[makerAddress][defaultTakerTokenAddress]).to.be.bignumber.equal( + erc20Balances[makerAddress][defaultTakerTokenAddress].add(takerAssetFillAmount), + ); + expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal( + erc20Balances[makerAddress][zrxToken.address].minus(makerFeePaid), + ); + expect(newBalances[takerAddress][defaultTakerTokenAddress]).to.be.bignumber.equal( + erc20Balances[takerAddress][defaultTakerTokenAddress].minus(takerAssetFillAmount), + ); + expect(newBalances[takerAddress][defaultMakerTokenAddress]).to.be.bignumber.equal( + erc20Balances[takerAddress][defaultMakerTokenAddress].add(makerAssetFillAmount), + ); + expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal( + erc20Balances[takerAddress][zrxToken.address].minus(takerFeePaid), + ); + expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal( + erc20Balances[feeRecipientAddress][zrxToken.address].add(makerFeePaid.add(takerFeePaid)), + ); + }); + }); }); diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index de4011853..32b319e56 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -21,6 +21,7 @@ describe('LibBytes', () => { let owner: string; let libBytes: TestLibBytesContract; const byteArrayShorterThan32Bytes = '0x012345'; + const byteArrayShorterThan20Bytes = byteArrayShorterThan32Bytes; const byteArrayLongerThan32Bytes = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; const byteArrayLongerThan32BytesFirstBytesSwapped = @@ -59,6 +60,36 @@ describe('LibBytes', () => { await blockchainLifecycle.revertAsync(); }); + describe('popByte', () => { + it('should revert if length is 0', async () => { + return expect(libBytes.publicPopByte.callAsync(constants.NULL_BYTES)).to.be.rejectedWith(constants.REVERT); + }); + + it('should pop the last byte from the input and return it', async () => { + const [newBytes, poppedByte] = await libBytes.publicPopByte.callAsync(byteArrayLongerThan32Bytes); + const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -2); + const expectedPoppedByte = `0x${byteArrayLongerThan32Bytes.slice(-2)}`; + expect(newBytes).to.equal(expectedNewBytes); + expect(poppedByte).to.equal(expectedPoppedByte); + }); + }); + + describe('popAddress', () => { + it('should revert if length is less than 20', async () => { + return expect(libBytes.publicPopAddress.callAsync(byteArrayShorterThan20Bytes)).to.be.rejectedWith( + constants.REVERT, + ); + }); + + it('should pop the last 20 bytes from the input and return it', async () => { + const [newBytes, poppedAddress] = await libBytes.publicPopAddress.callAsync(byteArrayLongerThan32Bytes); + const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -40); + const expectedPoppedAddress = `0x${byteArrayLongerThan32Bytes.slice(-40)}`; + expect(newBytes).to.equal(expectedNewBytes); + expect(poppedAddress).to.equal(expectedPoppedAddress); + }); + }); + describe('areBytesEqual', () => { it('should return true if byte arrays are equal (both arrays < 32 bytes)', async () => { const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts index ace0f0045..7b7885a00 100644 --- a/packages/contracts/test/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -27,6 +27,12 @@ describe('MultiSigWalletWithTimeLock', () => { const SECONDS_TIME_LOCKED = new BigNumber(1000000); before(async () => { + await blockchainLifecycle.startAsync(); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); + }); + before(async () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); owners = [accounts[0], accounts[1]]; }); diff --git a/packages/contracts/test/token_registry.ts b/packages/contracts/test/token_registry.ts index 1cc519c53..7980977c8 100644 --- a/packages/contracts/test/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -23,6 +23,7 @@ describe('TokenRegistry', () => { let notOwner: string; let tokenReg: TokenRegistryContract; let tokenRegWrapper: TokenRegWrapper; + before(async () => { await blockchainLifecycle.startAsync(); }); |