From d86349658f3156c9bf7cfc9af90155f8faeb7743 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:26:23 +0200 Subject: Fix postinstall hook for contracts -> types --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 033cfeeb5..07947271d 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing", "lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing", "comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete.", - "postinstall": "rm -rf `pwd`/packages/0x.js/node_modules/@0xproject; mkdir `pwd`/packages/0x.js/node_modules/@0xproject; ln -s `pwd`/packages/contract-wrappers `pwd`/packages/0x.js/node_modules/@0xproject/contract-wrappers; ln -s `pwd`/packages/order-utils `pwd`/packages/0x.js/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/0x.js/node_modules/@0xproject/types; rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/assert `pwd`/packages/order-utils/node_modules/@0xproject/assert; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; rm -rf `pwd`/packages/fill-scenarios/node_modules/@0xproject; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/json-schemas `pwd`/packages/fill-scenarios/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/contract-wrappers/node_modules/@0xproject; mkdir -p `pwd`/packages/contract-wrappers/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contract-wrappers/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/assert `pwd`/packages/contract-wrappers/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/contract-wrappers/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/contract-wrappers/node_modules/@0xproject/types; ln -s `pwd`/packages/fill-scenarios `pwd`/packages/contract-wrappers/node_modules/@0xproject/fill-scenarios; rm -rf `pwd`/packages/assert/node_modules/@0xproject; mkdir -p `pwd`/packages/assert/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/assert/node_modules/@0xproject/json-schemas; rm -rf `pwd`/packages/order-watcher/node_modules/@0xproject; mkdir `pwd`/packages/order-watcher/node_modules/@0xproject; ln -s `pwd`/packages/assert `pwd`/packages/order-watcher/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-watcher/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/order-watcher/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/order-watcher/node_modules/@0xproject/types; ln -s `pwd`/packages/contract-wrappers `pwd`/packages/order-watcher/node_modules/@0xproject/contract-wrappers; rm -rf `pwd`/packages/contracts/node_modules/@0xproject; mkdir `pwd`/packages/contracts/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contracts/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/migrations/node_modules/@0xproject; mkdir `pwd`/packages/migrations/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/migrations/node_modules/@0xproject/order-utils" + "postinstall": "rm -rf `pwd`/packages/0x.js/node_modules/@0xproject; mkdir `pwd`/packages/0x.js/node_modules/@0xproject; ln -s `pwd`/packages/contract-wrappers `pwd`/packages/0x.js/node_modules/@0xproject/contract-wrappers; ln -s `pwd`/packages/order-utils `pwd`/packages/0x.js/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/0x.js/node_modules/@0xproject/types; rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/assert `pwd`/packages/order-utils/node_modules/@0xproject/assert; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -rf `pwd`/packages/fill-scenarios/node_modules/@0xproject; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/json-schemas `pwd`/packages/fill-scenarios/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/contract-wrappers/node_modules/@0xproject; mkdir -p `pwd`/packages/contract-wrappers/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contract-wrappers/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/assert `pwd`/packages/contract-wrappers/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/contract-wrappers/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/contract-wrappers/node_modules/@0xproject/types; ln -s `pwd`/packages/fill-scenarios `pwd`/packages/contract-wrappers/node_modules/@0xproject/fill-scenarios; rm -rf `pwd`/packages/assert/node_modules/@0xproject; mkdir -p `pwd`/packages/assert/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/assert/node_modules/@0xproject/json-schemas; rm -rf `pwd`/packages/order-watcher/node_modules/@0xproject; mkdir `pwd`/packages/order-watcher/node_modules/@0xproject; ln -s `pwd`/packages/assert `pwd`/packages/order-watcher/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-watcher/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/order-watcher/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/order-watcher/node_modules/@0xproject/types; ln -s `pwd`/packages/contract-wrappers `pwd`/packages/order-watcher/node_modules/@0xproject/contract-wrappers; rm -rf `pwd`/packages/contracts/node_modules/@0xproject; mkdir `pwd`/packages/contracts/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contracts/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; rm -rf `pwd`/packages/migrations/node_modules/@0xproject; mkdir `pwd`/packages/migrations/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/migrations/node_modules/@0xproject/order-utils" }, "config": { "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic" -- cgit v1.2.3 From 6c21ddcedba28f00429b8e57af60459b59ac92df Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:27:34 +0200 Subject: Pass erc721ProxyAddress to fillScenarios --- packages/contract-wrappers/test/exchange_wrapper_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts index 33da19aee..44f8a5680 100644 --- a/packages/contract-wrappers/test/exchange_wrapper_test.ts +++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts @@ -53,7 +53,6 @@ describe('ExchangeWrapper', () => { await blockchainLifecycle.startAsync(); contractWrappers = new ContractWrappers(provider, config); exchangeContractAddress = contractWrappers.exchange.getContractAddress(); - const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); fillScenarios = new FillScenarios( @@ -61,7 +60,8 @@ describe('ExchangeWrapper', () => { userAddresses, zrxTokenAddress, exchangeContractAddress, - erc20ProxyAddress, + contractWrappers.erc20Proxy.getContractAddress(), + contractWrappers.erc721Proxy.getContractAddress(), ); [coinbase, makerAddress, takerAddress, feeRecipient, anotherMakerAddress] = userAddresses; [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); -- cgit v1.2.3 From 4111095da355a940d712800cd45f651f949b89c8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:27:53 +0200 Subject: Don't throw on transferFrom is the sender is an owner --- .../src/contract_wrappers/erc721_token_wrapper.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts index b7e5519c4..6f6b4f716 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts @@ -342,15 +342,17 @@ export class ERC721TokenWrapper extends ContractWrapper { const normalizedSenderAddress = senderAddress.toLowerCase(); const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const ownerAddress = await this.getOwnerOfAsync(tokenAddress, tokenId); - const isApprovedForAll = await this.isApprovedForAllAsync( - normalizedTokenAddress, - ownerAddress, - normalizedSenderAddress, - ); - if (!isApprovedForAll) { - const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId); - if (approvedAddress !== senderAddress) { - throw new Error(ContractWrappersError.ERC721NoApproval); + if (normalizedSenderAddress !== ownerAddress) { + const isApprovedForAll = await this.isApprovedForAllAsync( + normalizedTokenAddress, + ownerAddress, + normalizedSenderAddress, + ); + if (!isApprovedForAll) { + const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId); + if (approvedAddress !== senderAddress) { + throw new Error(ContractWrappersError.ERC721NoApproval); + } } } const txHash = await tokenContract.transferFrom.sendTransactionAsync( -- cgit v1.2.3 From 67e2623d2caf01ab6be584fe10fd03d9d08427f6 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:28:22 +0200 Subject: Remove no-unused-variable rule from tslint as it's buggy and has side-effects --- packages/tslint-config/tslint.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/tslint-config/tslint.json b/packages/tslint-config/tslint.json index fbc71e140..1adb444e2 100644 --- a/packages/tslint-config/tslint.json +++ b/packages/tslint-config/tslint.json @@ -48,7 +48,6 @@ "no-parameter-reassignment": true, "no-redundant-jsdoc": true, "no-return-await": true, - "no-unused-variable": [true, "check-parameters"], "no-string-throw": true, "no-submodule-imports": false, "no-unnecessary-type-assertion": true, -- cgit v1.2.3 From a97ba41b8676d3d9003f9896381737565d418fab Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:28:44 +0200 Subject: Add ERC721 support to fill-scenarios --- packages/fill-scenarios/package.json | 4 +- packages/fill-scenarios/src/artifacts.ts | 6 +- packages/fill-scenarios/src/fill_scenarios.ts | 285 ++++++++++++++++++++++++++ packages/fill-scenarios/src/index.ts | 223 +------------------- 4 files changed, 292 insertions(+), 226 deletions(-) create mode 100644 packages/fill-scenarios/src/fill_scenarios.ts diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json index 12a342415..cc43b4130 100644 --- a/packages/fill-scenarios/package.json +++ b/packages/fill-scenarios/package.json @@ -9,14 +9,14 @@ "build": "yarn pre_build && tsc", "pre_build": "run-s update_artifacts generate_contract_wrappers", "update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/artifacts; done;", - "generate_contract_wrappers": "abi-gen --abis 'lib/artifacts/@(Exchange|ERC20Token).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", + "generate_contract_wrappers": "abi-gen --abis 'lib/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers", "copy_monorepo_scripts": "copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts", "clean": "shx rm -rf lib scripts src/generated_contract_wrappers", "lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*", "manual:postpublish": "yarn build; node ./scripts/postpublish.js" }, "config": { - "contracts": "Exchange ERC20Token" + "contracts": "Exchange DummyERC20Token DummyERC721Token" }, "license": "Apache-2.0", "repository": { diff --git a/packages/fill-scenarios/src/artifacts.ts b/packages/fill-scenarios/src/artifacts.ts index f75374ba2..7f68ae26a 100644 --- a/packages/fill-scenarios/src/artifacts.ts +++ b/packages/fill-scenarios/src/artifacts.ts @@ -1,9 +1,11 @@ import { ContractArtifact } from '@0xproject/sol-compiler'; -import * as ERC20Token from './artifacts/ERC20Token.json'; +import * as DummyERC20Token from './artifacts/DummyERC20Token.json'; +import * as DummyERC721Token from './artifacts/DummyERC721Token.json'; import * as Exchange from './artifacts/Exchange.json'; export const artifacts = { - ERC20Token: (ERC20Token as any) as ContractArtifact, + DummyERC20Token: (DummyERC20Token as any) as ContractArtifact, + DummyERC721Token: (DummyERC721Token as any) as ContractArtifact, Exchange: (Exchange as any) as ContractArtifact, }; diff --git a/packages/fill-scenarios/src/fill_scenarios.ts b/packages/fill-scenarios/src/fill_scenarios.ts new file mode 100644 index 000000000..4905dd596 --- /dev/null +++ b/packages/fill-scenarios/src/fill_scenarios.ts @@ -0,0 +1,285 @@ +import { assetProxyUtils, orderFactory } from '@0xproject/order-utils'; +import { AssetProxyId, ERC721AssetData, OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { artifacts } from './artifacts'; +import { constants } from './constants'; +import { DummyERC20TokenContract } from './generated_contract_wrappers/dummy_erc20_token'; +import { DummyERC721TokenContract } from './generated_contract_wrappers/dummy_erc721_token'; +import { ExchangeContract } from './generated_contract_wrappers/exchange'; + +export class FillScenarios { + private _web3Wrapper: Web3Wrapper; + private _userAddresses: string[]; + private _coinbase: string; + private _zrxTokenAddress: string; + private _exchangeAddress: string; + private _erc20ProxyAddress: string; + private _erc721ProxyAddress: string; + constructor( + provider: Provider, + userAddresses: string[], + zrxTokenAddress: string, + exchangeAddress: string, + erc20ProxyAddress: string, + erc721ProxyAddress: string, + ) { + this._web3Wrapper = new Web3Wrapper(provider); + this._userAddresses = userAddresses; + this._coinbase = userAddresses[0]; + this._zrxTokenAddress = zrxTokenAddress; + this._exchangeAddress = exchangeAddress; + this._erc20ProxyAddress = erc20ProxyAddress; + this._erc721ProxyAddress = erc721ProxyAddress; + } + public async createFillableSignedOrderAsync( + makerAssetData: string, + takerAssetData: string, + makerAddress: string, + takerAddress: string, + fillableAmount: BigNumber, + expirationTimeSeconds?: BigNumber, + ): Promise { + return this.createAsymmetricFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + fillableAmount, + expirationTimeSeconds, + ); + } + public async createFillableSignedOrderWithFeesAsync( + makerAssetData: string, + takerAssetData: string, + makerFee: BigNumber, + takerFee: BigNumber, + makerAddress: string, + takerAddress: string, + fillableAmount: BigNumber, + feeRecepientAddress: string, + expirationTimeSeconds?: BigNumber, + ): Promise { + return this._createAsymmetricFillableSignedOrderWithFeesAsync( + makerAssetData, + takerAssetData, + makerFee, + takerFee, + makerAddress, + takerAddress, + fillableAmount, + fillableAmount, + feeRecepientAddress, + expirationTimeSeconds, + ); + } + public async createAsymmetricFillableSignedOrderAsync( + makerAssetData: string, + takerAssetData: string, + makerAddress: string, + takerAddress: string, + makerFillableAmount: BigNumber, + takerFillableAmount: BigNumber, + expirationTimeSeconds?: BigNumber, + ): Promise { + const makerFee = new BigNumber(0); + const takerFee = new BigNumber(0); + const feeRecepientAddress = constants.NULL_ADDRESS; + return this._createAsymmetricFillableSignedOrderWithFeesAsync( + makerAssetData, + takerAssetData, + makerFee, + takerFee, + makerAddress, + takerAddress, + makerFillableAmount, + takerFillableAmount, + feeRecepientAddress, + expirationTimeSeconds, + ); + } + public async createPartiallyFilledSignedOrderAsync( + makerAssetData: string, + takerAssetData: string, + takerAddress: string, + fillableAmount: BigNumber, + partialFillAmount: BigNumber, + ): Promise { + const [makerAddress] = this._userAddresses; + const signedOrder = await this.createAsymmetricFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + fillableAmount, + ); + const exchangeInstance = new ExchangeContract( + artifacts.Exchange.compilerOutput.abi, + signedOrder.exchangeAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + + const orderWithoutExchangeAddress = _.omit(signedOrder, [ + 'signature', + 'exchangeAddress', + ]) as OrderWithoutExchangeAddress; + + await exchangeInstance.fillOrder.sendTransactionAsync( + orderWithoutExchangeAddress, + partialFillAmount, + signedOrder.signature, + { from: takerAddress }, + ); + return signedOrder; + } + private async _createAsymmetricFillableSignedOrderWithFeesAsync( + makerAssetData: string, + takerAssetData: string, + makerFee: BigNumber, + takerFee: BigNumber, + makerAddress: string, + takerAddress: string, + makerFillableAmount: BigNumber, + takerFillableAmount: BigNumber, + feeRecepientAddress: string, + expirationTimeSeconds?: BigNumber, + ): Promise { + const decodedMakerAssetData = assetProxyUtils.decodeAssetData(makerAssetData); + if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { + await this._increaseERC20BalanceAndAllowanceAsync( + decodedMakerAssetData.tokenAddress, + makerAddress, + makerFillableAmount, + ); + } else { + if (!makerFillableAmount.equals(1)) { + throw new Error(`ERC721 makerFillableAmount should be equal 1. Found: ${makerFillableAmount}`); + } + await this._increaseERC721BalanceAndAllowanceAsync( + decodedMakerAssetData.tokenAddress, + makerAddress, + (decodedMakerAssetData as ERC721AssetData).tokenId, + ); + } + const decodedTakerAssetData = assetProxyUtils.decodeAssetData(takerAssetData); + if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC20) { + const takerTokenAddress = decodedTakerAssetData.tokenAddress; + await this._increaseERC20BalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount); + } else { + if (!takerFillableAmount.equals(1)) { + throw new Error(`ERC721 takerFillableAmount should be equal 1. Found: ${takerFillableAmount}`); + } + await this._increaseERC721BalanceAndAllowanceAsync( + decodedTakerAssetData.tokenAddress, + takerAddress, + (decodedMakerAssetData as ERC721AssetData).tokenId, + ); + } + // Fees + await Promise.all([ + this._increaseERC20BalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee), + this._increaseERC20BalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee), + ]); + const senderAddress = constants.NULL_ADDRESS; + + const signedOrder = await orderFactory.createSignedOrderAsync( + this._web3Wrapper.getProvider(), + makerAddress, + takerAddress, + senderAddress, + makerFee, + takerFee, + makerFillableAmount, + makerAssetData, + takerFillableAmount, + takerAssetData, + this._exchangeAddress, + feeRecepientAddress, + expirationTimeSeconds, + ); + return signedOrder; + } + private async _increaseERC721BalanceAndAllowanceAsync( + tokenAddress: string, + address: string, + tokenId: BigNumber, + ): Promise { + await this._increaseERC721BalanceAsync(tokenAddress, address, tokenId); + await this._increaseERC721AllowanceAsync(tokenAddress, address); + } + private async _increaseERC721AllowanceAsync(tokenAddress: string, address: string): Promise { + const erc721Token = new DummyERC721TokenContract( + artifacts.DummyERC721Token.compilerOutput.abi, + tokenAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + const isApproved = true; + const txHash = await erc721Token.setApprovalForAll.sendTransactionAsync(this._erc721ProxyAddress, isApproved, { + from: address, + }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); + } + private async _increaseERC721BalanceAsync( + tokenAddress: string, + address: string, + tokenId: BigNumber, + ): Promise { + const erc721Token = new DummyERC721TokenContract( + artifacts.DummyERC721Token.compilerOutput.abi, + tokenAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + const txHash = await erc721Token.mint.sendTransactionAsync(address, tokenId, { from: this._coinbase }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); + } + private async _increaseERC20BalanceAndAllowanceAsync( + tokenAddress: string, + address: string, + amount: BigNumber, + ): Promise { + if (amount.isZero() || address === constants.NULL_ADDRESS) { + return; // noop + } + await Promise.all([ + this._increaseERC20BalanceAsync(tokenAddress, address, amount), + this._increaseERC20AllowanceAsync(tokenAddress, address, amount), + ]); + } + private async _increaseERC20BalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise { + const erc20Token = new DummyERC20TokenContract( + artifacts.DummyERC20Token.compilerOutput.abi, + tokenAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + await erc20Token.transfer.sendTransactionAsync(address, amount, { + from: this._coinbase, + }); + } + private async _increaseERC20AllowanceAsync( + tokenAddress: string, + address: string, + amount: BigNumber, + ): Promise { + const erc20Token = new DummyERC20TokenContract( + artifacts.DummyERC20Token.compilerOutput.abi, + tokenAddress, + this._web3Wrapper.getProvider(), + this._web3Wrapper.getContractDefaults(), + ); + const oldMakerAllowance = await erc20Token.allowance.callAsync(address, this._erc20ProxyAddress); + const newMakerAllowance = oldMakerAllowance.plus(amount); + + await erc20Token.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { + from: address, + }); + } +} diff --git a/packages/fill-scenarios/src/index.ts b/packages/fill-scenarios/src/index.ts index f9b69e1f3..c51145cdb 100644 --- a/packages/fill-scenarios/src/index.ts +++ b/packages/fill-scenarios/src/index.ts @@ -1,222 +1 @@ -import { assetProxyUtils, orderFactory } from '@0xproject/order-utils'; -import { OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { Provider } from 'ethereum-types'; -import * as _ from 'lodash'; - -import { artifacts } from './artifacts'; -import { constants } from './constants'; -import { ERC20TokenContract } from './generated_contract_wrappers/erc20_token'; -import { ExchangeContract } from './generated_contract_wrappers/exchange'; - -export class FillScenarios { - private _web3Wrapper: Web3Wrapper; - private _userAddresses: string[]; - private _coinbase: string; - private _zrxTokenAddress: string; - private _exchangeAddress: string; - private _erc20ProxyAddress: string; - constructor( - provider: Provider, - userAddresses: string[], - zrxTokenAddress: string, - exchangeAddress: string, - erc20ProxyAddress: string, - ) { - this._web3Wrapper = new Web3Wrapper(provider); - this._userAddresses = userAddresses; - this._coinbase = userAddresses[0]; - this._zrxTokenAddress = zrxTokenAddress; - this._exchangeAddress = exchangeAddress; - this._erc20ProxyAddress = erc20ProxyAddress; - } - public async createFillableSignedOrderAsync( - makerAssetData: string, - takerAssetData: string, - makerAddress: string, - takerAddress: string, - fillableAmount: BigNumber, - expirationTimeSeconds?: BigNumber, - ): Promise { - return this.createAsymmetricFillableSignedOrderAsync( - makerAssetData, - takerAssetData, - makerAddress, - takerAddress, - fillableAmount, - fillableAmount, - expirationTimeSeconds, - ); - } - public async createFillableSignedOrderWithFeesAsync( - makerAssetData: string, - takerAssetData: string, - makerFee: BigNumber, - takerFee: BigNumber, - makerAddress: string, - takerAddress: string, - fillableAmount: BigNumber, - feeRecepientAddress: string, - expirationTimeSeconds?: BigNumber, - ): Promise { - return this._createAsymmetricFillableSignedOrderWithFeesAsync( - makerAssetData, - takerAssetData, - makerFee, - takerFee, - makerAddress, - takerAddress, - fillableAmount, - fillableAmount, - feeRecepientAddress, - expirationTimeSeconds, - ); - } - public async createAsymmetricFillableSignedOrderAsync( - makerAssetData: string, - takerAssetData: string, - makerAddress: string, - takerAddress: string, - makerFillableAmount: BigNumber, - takerFillableAmount: BigNumber, - expirationTimeSeconds?: BigNumber, - ): Promise { - const makerFee = new BigNumber(0); - const takerFee = new BigNumber(0); - const feeRecepientAddress = constants.NULL_ADDRESS; - return this._createAsymmetricFillableSignedOrderWithFeesAsync( - makerAssetData, - takerAssetData, - makerFee, - takerFee, - makerAddress, - takerAddress, - makerFillableAmount, - takerFillableAmount, - feeRecepientAddress, - expirationTimeSeconds, - ); - } - public async createPartiallyFilledSignedOrderAsync( - makerAssetData: string, - takerAssetData: string, - takerAddress: string, - fillableAmount: BigNumber, - partialFillAmount: BigNumber, - ): Promise { - const [makerAddress] = this._userAddresses; - const signedOrder = await this.createAsymmetricFillableSignedOrderAsync( - makerAssetData, - takerAssetData, - makerAddress, - takerAddress, - fillableAmount, - fillableAmount, - ); - const exchangeInstance = new ExchangeContract( - artifacts.Exchange.compilerOutput.abi, - signedOrder.exchangeAddress, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - - const orderWithoutExchangeAddress = _.omit(signedOrder, [ - 'signature', - 'exchangeAddress', - ]) as OrderWithoutExchangeAddress; - - await exchangeInstance.fillOrder.sendTransactionAsync( - orderWithoutExchangeAddress, - partialFillAmount, - signedOrder.signature, - { from: takerAddress }, - ); - return signedOrder; - } - private async _createAsymmetricFillableSignedOrderWithFeesAsync( - makerAssetData: string, - takerAssetData: string, - makerFee: BigNumber, - takerFee: BigNumber, - makerAddress: string, - takerAddress: string, - makerFillableAmount: BigNumber, - takerFillableAmount: BigNumber, - feeRecepientAddress: string, - expirationTimeSeconds?: BigNumber, - ): Promise { - const makerERC20AssetData = assetProxyUtils.decodeERC20AssetData(makerAssetData); - const makerTokenAddress = makerERC20AssetData.tokenAddress; - const takerERC20AssetData = assetProxyUtils.decodeERC20AssetData(takerAssetData); - const takerTokenAddress = takerERC20AssetData.tokenAddress; - await Promise.all([ - this._increaseERC20BalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount), - this._increaseERC20BalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount), - ]); - await Promise.all([ - this._increaseERC20BalanceAndAllowanceAsync(this._zrxTokenAddress, makerAddress, makerFee), - this._increaseERC20BalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee), - ]); - const senderAddress = constants.NULL_ADDRESS; - - const signedOrder = await orderFactory.createSignedOrderAsync( - this._web3Wrapper.getProvider(), - makerAddress, - takerAddress, - senderAddress, - makerFee, - takerFee, - makerFillableAmount, - makerAssetData, - takerFillableAmount, - takerAssetData, - this._exchangeAddress, - feeRecepientAddress, - expirationTimeSeconds, - ); - return signedOrder; - } - private async _increaseERC20BalanceAndAllowanceAsync( - tokenAddress: string, - address: string, - amount: BigNumber, - ): Promise { - if (amount.isZero() || address === constants.NULL_ADDRESS) { - return; // noop - } - await Promise.all([ - this._increaseERC20BalanceAsync(tokenAddress, address, amount), - this._increaseERC20AllowanceAsync(tokenAddress, address, amount), - ]); - } - private async _increaseERC20BalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise { - const token = new ERC20TokenContract( - artifacts.ERC20Token.compilerOutput.abi, - tokenAddress, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - await token.transfer.sendTransactionAsync(address, amount, { - from: this._coinbase, - }); - } - private async _increaseERC20AllowanceAsync( - tokenAddress: string, - address: string, - amount: BigNumber, - ): Promise { - const tokenInstance = new ERC20TokenContract( - artifacts.ERC20Token.compilerOutput.abi, - tokenAddress, - this._web3Wrapper.getProvider(), - this._web3Wrapper.getContractDefaults(), - ); - const oldMakerAllowance = await tokenInstance.allowance.callAsync(address, this._erc20ProxyAddress); - const newMakerAllowance = oldMakerAllowance.plus(amount); - - await tokenInstance.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { - from: address, - }); - } -} +export { FillScenarios } from './fill_scenarios'; -- cgit v1.2.3 From 4921a83813d31e18bd9377ededc1f7a6e42bbf2a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:29:23 +0200 Subject: Register asset types within collisionResistantAbiDecoder --- packages/order-watcher/src/order_watcher/order_watcher.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index af479f32d..cefead761 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -152,6 +152,20 @@ export class OrderWatcher { this._orderByOrderHash[orderHash] = signedOrder; this._dependentOrderHashesTracker.addToDependentOrderHashes(signedOrder); + + const decodedMakerAssetData = assetProxyUtils.decodeAssetData(signedOrder.makerAssetData); + if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { + this._collisionResistantAbiDecoder.addERC20Token(decodedMakerAssetData.tokenAddress); + } else if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC721) { + this._collisionResistantAbiDecoder.addERC721Token(decodedMakerAssetData.tokenAddress); + } + + const decodedTakerAssetData = assetProxyUtils.decodeAssetData(signedOrder.takerAssetData); + if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC20) { + this._collisionResistantAbiDecoder.addERC20Token(decodedTakerAssetData.tokenAddress); + } else if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC721) { + this._collisionResistantAbiDecoder.addERC721Token(decodedTakerAssetData.tokenAddress); + } } /** * Removes an order from the orderWatcher -- cgit v1.2.3 From 994ccd669455f8736ea1f9c0840ee824f409001a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:29:59 +0200 Subject: Enable downlevelIteration --- packages/order-watcher/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/order-watcher/tsconfig.json b/packages/order-watcher/tsconfig.json index e35816553..ee4363919 100644 --- a/packages/order-watcher/tsconfig.json +++ b/packages/order-watcher/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig", "compilerOptions": { + "downlevelIteration": true, "outDir": "lib" }, "include": ["./src/**/*", "./test/**/*"] -- cgit v1.2.3 From c5ba52910a3716e0e9db65b16e86a129370cdae3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:30:48 +0200 Subject: Add ERC721 tests to order watcher --- .../order-watcher/test/expiration_watcher_test.ts | 4 +- packages/order-watcher/test/order_watcher_test.ts | 64 +++++++++++++++++++++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/packages/order-watcher/test/expiration_watcher_test.ts b/packages/order-watcher/test/expiration_watcher_test.ts index 3c92ddb63..f765e8278 100644 --- a/packages/order-watcher/test/expiration_watcher_test.ts +++ b/packages/order-watcher/test/expiration_watcher_test.ts @@ -43,7 +43,6 @@ describe('ExpirationWatcher', () => { let expirationWatcher: ExpirationWatcher; before(async () => { await blockchainLifecycle.startAsync(); - const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); fillScenarios = new FillScenarios( @@ -51,7 +50,8 @@ describe('ExpirationWatcher', () => { userAddresses, zrxTokenAddress, exchangeContractAddress, - erc20ProxyAddress, + contractWrappers.erc20Proxy.getContractAddress(), + contractWrappers.erc721Proxy.getContractAddress(), ); [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; const [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index 6339505ce..a47dfcd77 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -57,7 +57,6 @@ describe('OrderWatcher', () => { const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals); before(async () => { await blockchainLifecycle.startAsync(); - const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress(); userAddresses = await web3Wrapper.getAvailableAddressesAsync(); zrxTokenAddress = tokenUtils.getProtocolTokenAddress(); exchangeContractAddress = contractWrappers.exchange.getContractAddress(); @@ -66,7 +65,8 @@ describe('OrderWatcher', () => { userAddresses, zrxTokenAddress, exchangeContractAddress, - erc20ProxyAddress, + contractWrappers.erc20Proxy.getContractAddress(), + contractWrappers.erc721Proxy.getContractAddress(), ); [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses; [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); @@ -534,5 +534,65 @@ describe('OrderWatcher', () => { ); })().catch(done); }); + describe('erc721', () => { + let makerErc721AssetData: string; + let makerErc721TokenAddress: string; + const tokenId = new BigNumber(42); + [makerErc721TokenAddress] = tokenUtils.getDummyERC721TokenAddresses(); + makerErc721AssetData = assetProxyUtils.encodeERC721AssetData(makerErc721TokenAddress, tokenId); + const fillableErc721Amount = new BigNumber(1); + it('should emit orderStateInvalid when makerAddress allowance for all set to 0 for watched order', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerErc721AssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableErc721Amount, + ); + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + orderWatcher.addOrder(signedOrder); + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { + expect(orderState.isValid).to.be.false(); + const invalidOrderState = orderState as OrderStateInvalid; + expect(invalidOrderState.orderHash).to.be.equal(orderHash); + expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance); + }); + orderWatcher.subscribe(callback); + const isApproved = false; + await contractWrappers.erc721Token.setProxyApprovalForAllAsync( + makerErc721TokenAddress, + makerAddress, + isApproved, + ); + })().catch(done); + }); + it('should emit orderStateInvalid when makerAddress moves NFT backing watched order', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerErc721AssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableErc721Amount, + ); + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + orderWatcher.addOrder(signedOrder); + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { + expect(orderState.isValid).to.be.false(); + const invalidOrderState = orderState as OrderStateInvalid; + expect(invalidOrderState.orderHash).to.be.equal(orderHash); + expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance); + }); + orderWatcher.subscribe(callback); + await contractWrappers.erc721Token.transferFromAsync( + makerErc721TokenAddress, + coinbase, + makerAddress, + tokenId, + ); + })().catch(done); + }); + }); }); }); // tslint:disable:max-file-line-count -- cgit v1.2.3 From 55f6f02c9b0f3e13ae246b2029fe3d4a36b194c0 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:31:33 +0200 Subject: Import AssetproxyId --- packages/order-watcher/src/order_watcher/order_watcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index cefead761..264b3d18c 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -28,7 +28,7 @@ import { orderHashUtils, OrderStateUtils, } from '@0xproject/order-utils'; -import { ExchangeContractErrs, OrderState, SignedOrder } from '@0xproject/types'; +import { AssetProxyId, ExchangeContractErrs, OrderState, SignedOrder } from '@0xproject/types'; import { errorUtils, intervalUtils } from '@0xproject/utils'; import { BlockParamLiteral, LogEntryEvent, LogWithDecodedArgs, Provider } from 'ethereum-types'; import * as _ from 'lodash'; -- cgit v1.2.3 From 658214a2e24d3f50aacbc078317358d510e9c351 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:31:46 +0200 Subject: Yarn lock changes --- yarn.lock | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/yarn.lock b/yarn.lock index 27d892811..72449b0f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -59,19 +59,6 @@ ethers "3.0.22" lodash "4.17.10" -"@0xproject/fill-scenarios@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@0xproject/fill-scenarios/-/fill-scenarios-0.0.5.tgz#a62a240ae40423b9b73ecc0b1fc2abb58b76621c" - dependencies: - "@0xproject/base-contract" "^0.3.5" - "@0xproject/order-utils" "^0.0.8" - "@0xproject/types" "^0.8.2" - "@0xproject/typescript-typings" "^0.4.2" - "@0xproject/utils" "^0.7.2" - "@0xproject/web3-wrapper" "^0.7.2" - ethers "3.0.22" - lodash "4.17.10" - "@0xproject/json-schemas@0.8.2", "@0xproject/json-schemas@^0.8.2": version "0.8.2" resolved "https://registry.yarnpkg.com/@0xproject/json-schemas/-/json-schemas-0.8.2.tgz#9d3f446e546ce0c959cf7beb45d41ac60476a78c" @@ -2743,7 +2730,7 @@ commander@2.13.0, commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" -commander@2.15.1, commander@^2.12.1, commander@^2.8.1, commander@^2.9.0: +commander@2.15.1, commander@^2.12.1, commander@^2.8.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" @@ -4481,9 +4468,9 @@ ethereumjs-wallet@~0.6.0: utf8 "^2.1.1" uuid "^2.0.1" -ethers@3.0.22: - version "3.0.22" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-3.0.22.tgz#7fab1ea16521705837aa43c15831877b2716b436" +ethers@0xproject/ethers.js#eip-838-reasons, ethers@3.0.22: + version "3.0.18" + resolved "https://codeload.github.com/0xproject/ethers.js/tar.gz/b91342bd200d142af0165d6befddf783c8ae8447" dependencies: aes-js "3.0.0" bn.js "^4.4.0" -- cgit v1.2.3 From 90d72a36834822dd7475ee453e285bc39c1100c4 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 14:54:36 +0200 Subject: Await the promise in order watcher assertion --- packages/order-watcher/src/order_watcher/order_watcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index 264b3d18c..91fa85684 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -145,7 +145,7 @@ export class OrderWatcher { public addOrder(signedOrder: SignedOrder): void { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - assert.isValidSignatureAsync(this._provider, orderHash, signedOrder.signature, signedOrder.makerAddress); + await assert.isValidSignatureAsync(this._provider, orderHash, signedOrder.signature, signedOrder.makerAddress); const expirationUnixTimestampMs = signedOrder.expirationTimeSeconds.times(MILLISECONDS_IN_A_SECOND); this._expirationWatcher.addOrder(orderHash, expirationUnixTimestampMs); -- cgit v1.2.3 From c3bd3437f5c68e96a440da0d1c8160ecb558e900 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 16 Jul 2018 15:14:40 +0200 Subject: Make addOrder async --- .../src/order_watcher/order_watcher.ts | 2 +- packages/order-watcher/test/order_watcher_test.ts | 32 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index 91fa85684..eaa177b6d 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -142,7 +142,7 @@ export class OrderWatcher { * signature is verified. * @param signedOrder The order you wish to start watching. */ - public addOrder(signedOrder: SignedOrder): void { + public async addOrderAsync(signedOrder: SignedOrder): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); await assert.isValidSignatureAsync(this._provider, orderHash, signedOrder.signature, signedOrder.makerAddress); diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index a47dfcd77..c8b723ea6 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -96,7 +96,7 @@ describe('OrderWatcher', () => { fillableAmount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); expect((orderWatcher as any)._orderByOrderHash).to.include({ [orderHash]: signedOrder, }); @@ -156,7 +156,7 @@ describe('OrderWatcher', () => { fillableAmount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; @@ -180,7 +180,7 @@ describe('OrderWatcher', () => { takerAddress, fillableAmount, ); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((_orderState: OrderState) => { throw new Error('OrderState callback fired for irrelevant order'); }); @@ -209,7 +209,7 @@ describe('OrderWatcher', () => { fillableAmount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; @@ -237,7 +237,7 @@ describe('OrderWatcher', () => { fillableAmount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); @@ -263,7 +263,7 @@ describe('OrderWatcher', () => { const makerBalance = await contractWrappers.erc20Token.getBalanceAsync(makerTokenAddress, makerAddress); const fillAmountInBaseUnits = new BigNumber(2); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); @@ -299,7 +299,7 @@ describe('OrderWatcher', () => { takerAddress, ); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); orderWatcher.subscribe(callback); await contractWrappers.erc20Token.setProxyAllowanceAsync( zrxTokenAddress, @@ -323,7 +323,7 @@ describe('OrderWatcher', () => { ); const fillAmountInBaseUnits = Web3Wrapper.toBaseUnitAmount(new BigNumber(2), decimals); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; @@ -351,7 +351,7 @@ describe('OrderWatcher', () => { ); const changedMakerApprovalAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; @@ -388,7 +388,7 @@ describe('OrderWatcher', () => { const remainingAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), decimals); const transferAmount = makerBalance.sub(remainingAmount); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); @@ -429,7 +429,7 @@ describe('OrderWatcher', () => { const remainingTokenAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(4), decimals); const transferTokenAmount = makerFee.sub(remainingTokenAmount); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; @@ -467,7 +467,7 @@ describe('OrderWatcher', () => { feeRecipient, ); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; @@ -495,7 +495,7 @@ describe('OrderWatcher', () => { fillableAmount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); @@ -518,7 +518,7 @@ describe('OrderWatcher', () => { fillableAmount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); @@ -551,7 +551,7 @@ describe('OrderWatcher', () => { fillableErc721Amount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; @@ -577,7 +577,7 @@ describe('OrderWatcher', () => { fillableErc721Amount, ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); - orderWatcher.addOrder(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; -- cgit v1.2.3 From 82ad5f789721312577735fc3ac7227c672903849 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 13:13:05 +0200 Subject: Use normalizedAddress --- .../contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts index 6f6b4f716..1133a4085 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts @@ -350,7 +350,7 @@ export class ERC721TokenWrapper extends ContractWrapper { ); if (!isApprovedForAll) { const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId); - if (approvedAddress !== senderAddress) { + if (approvedAddress !== normalizedSenderAddress) { throw new Error(ContractWrappersError.ERC721NoApproval); } } -- cgit v1.2.3 From 6c2796b433257806efd294318e5f46c8a020184c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 13:16:47 +0200 Subject: Rename decodeAssetData to decodeAssetDataOrThrow --- packages/contracts/test/utils/forwarder_wrapper.ts | 2 +- packages/fill-scenarios/src/fill_scenarios.ts | 4 ++-- packages/order-utils/src/asset_proxy_utils.ts | 2 +- .../order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts | 2 +- .../src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts | 4 ++-- .../src/order_watcher/dependent_order_hashes_tracker.ts | 6 +++--- packages/order-watcher/src/order_watcher/order_watcher.ts | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/contracts/test/utils/forwarder_wrapper.ts b/packages/contracts/test/utils/forwarder_wrapper.ts index d227420ee..2f41efd26 100644 --- a/packages/contracts/test/utils/forwarder_wrapper.ts +++ b/packages/contracts/test/utils/forwarder_wrapper.ts @@ -145,7 +145,7 @@ export class ForwarderWrapper { feeProportion: number, makerAssetFillAmount: BigNumber, ): Promise { - const makerAssetData = assetProxyUtils.decodeAssetData(orders[0].makerAssetData); + const makerAssetData = assetProxyUtils.decodeAssetDataOrThrow(orders[0].makerAssetData); const makerAssetToken = makerAssetData.tokenAddress; const params = formatters.createMarketBuyOrders(orders, makerAssetFillAmount); diff --git a/packages/fill-scenarios/src/fill_scenarios.ts b/packages/fill-scenarios/src/fill_scenarios.ts index 4905dd596..9f5218274 100644 --- a/packages/fill-scenarios/src/fill_scenarios.ts +++ b/packages/fill-scenarios/src/fill_scenarios.ts @@ -150,7 +150,7 @@ export class FillScenarios { feeRecepientAddress: string, expirationTimeSeconds?: BigNumber, ): Promise { - const decodedMakerAssetData = assetProxyUtils.decodeAssetData(makerAssetData); + const decodedMakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(makerAssetData); if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { await this._increaseERC20BalanceAndAllowanceAsync( decodedMakerAssetData.tokenAddress, @@ -167,7 +167,7 @@ export class FillScenarios { (decodedMakerAssetData as ERC721AssetData).tokenId, ); } - const decodedTakerAssetData = assetProxyUtils.decodeAssetData(takerAssetData); + const decodedTakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(takerAssetData); if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC20) { const takerTokenAddress = decodedTakerAssetData.tokenAddress; await this._increaseERC20BalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount); diff --git a/packages/order-utils/src/asset_proxy_utils.ts b/packages/order-utils/src/asset_proxy_utils.ts index 8140ad89d..21acb065a 100644 --- a/packages/order-utils/src/asset_proxy_utils.ts +++ b/packages/order-utils/src/asset_proxy_utils.ts @@ -134,7 +134,7 @@ export const assetProxyUtils = { const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId); return assetProxyId; }, - decodeAssetData(assetData: string): ERC20AssetData | ERC721AssetData { + decodeAssetDataOrThrow(assetData: string): ERC20AssetData | ERC721AssetData { const assetProxyId = assetProxyUtils.decodeAssetDataId(assetData); switch (assetProxyId) { case AssetProxyId.ERC20: diff --git a/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts b/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts index 8235725ed..711bd2173 100644 --- a/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts +++ b/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts @@ -79,7 +79,7 @@ export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProx public deleteAllERC721ProxyAllowance(tokenAddress: string, userAddress: string): void { for (const assetData in this._proxyAllowance) { if (this._proxyAllowance.hasOwnProperty(assetData)) { - const decodedAssetData = assetProxyUtils.decodeAssetData(assetData); + const decodedAssetData = assetProxyUtils.decodeAssetDataOrThrow(assetData); if ( decodedAssetData.assetProxyId === AssetProxyId.ERC721 && decodedAssetData.tokenAddress === tokenAddress && diff --git a/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts b/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts index b1c013928..bfa33c8b9 100644 --- a/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts +++ b/packages/order-watcher/src/fetchers/asset_balance_and_proxy_allowance_fetcher.ts @@ -14,7 +14,7 @@ export class AssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndP this._stateLayer = stateLayer; } public async getBalanceAsync(assetData: string, userAddress: string): Promise { - const decodedAssetData = assetProxyUtils.decodeAssetData(assetData); + const decodedAssetData = assetProxyUtils.decodeAssetDataOrThrow(assetData); if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { const decodedERC20AssetData = decodedAssetData as ERC20AssetData; const balance = await this._erc20Token.getBalanceAsync(decodedERC20AssetData.tokenAddress, userAddress, { @@ -35,7 +35,7 @@ export class AssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndP } } public async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise { - const decodedAssetData = assetProxyUtils.decodeAssetData(assetData); + const decodedAssetData = assetProxyUtils.decodeAssetDataOrThrow(assetData); if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { const decodedERC20AssetData = decodedAssetData as ERC20AssetData; const proxyAllowance = await this._erc20Token.getProxyAllowanceAsync( diff --git a/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts b/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts index ae7d5078c..d639242ac 100644 --- a/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts +++ b/packages/order-watcher/src/order_watcher/dependent_order_hashes_tracker.ts @@ -54,7 +54,7 @@ export class DependentOrderHashesTracker { return dependentOrderHashes; } public getDependentOrderHashesByAssetDataByMaker(makerAddress: string, assetData: string): string[] { - const decodedAssetData = assetProxyUtils.decodeAssetData(assetData); + const decodedAssetData = assetProxyUtils.decodeAssetDataOrThrow(assetData); const dependentOrderHashes = decodedAssetData.assetProxyId === AssetProxyId.ERC20 ? this._getDependentOrderHashesByERC20AssetData(makerAddress, assetData) @@ -62,7 +62,7 @@ export class DependentOrderHashesTracker { return dependentOrderHashes; } public addToDependentOrderHashes(signedOrder: SignedOrder): void { - const decodedMakerAssetData = assetProxyUtils.decodeAssetData(signedOrder.makerAssetData); + const decodedMakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(signedOrder.makerAssetData); if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { this._addToERC20DependentOrderHashes(signedOrder, (decodedMakerAssetData as ERC20AssetData).tokenAddress); } else { @@ -76,7 +76,7 @@ export class DependentOrderHashesTracker { this._addToMakerDependentOrderHashes(signedOrder); } public removeFromDependentOrderHashes(signedOrder: SignedOrder): void { - const decodedMakerAssetData = assetProxyUtils.decodeAssetData(signedOrder.makerAssetData); + const decodedMakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(signedOrder.makerAssetData); if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { this._removeFromERC20DependentOrderhashes( signedOrder, diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index eaa177b6d..de0ff6b87 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -153,14 +153,14 @@ export class OrderWatcher { this._orderByOrderHash[orderHash] = signedOrder; this._dependentOrderHashesTracker.addToDependentOrderHashes(signedOrder); - const decodedMakerAssetData = assetProxyUtils.decodeAssetData(signedOrder.makerAssetData); + const decodedMakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(signedOrder.makerAssetData); if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { this._collisionResistantAbiDecoder.addERC20Token(decodedMakerAssetData.tokenAddress); } else if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC721) { this._collisionResistantAbiDecoder.addERC721Token(decodedMakerAssetData.tokenAddress); } - const decodedTakerAssetData = assetProxyUtils.decodeAssetData(signedOrder.takerAssetData); + const decodedTakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(signedOrder.takerAssetData); if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC20) { this._collisionResistantAbiDecoder.addERC20Token(decodedTakerAssetData.tokenAddress); } else if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC721) { -- cgit v1.2.3 From 28a9a8c3809a63510d2cddf7f9eeaf74635b08ad Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 13:26:49 +0200 Subject: Await transactions in fillScenarios --- packages/fill-scenarios/src/constants.ts | 1 + packages/fill-scenarios/src/fill_scenarios.ts | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/fill-scenarios/src/constants.ts b/packages/fill-scenarios/src/constants.ts index ec2fe744a..5661b059f 100644 --- a/packages/fill-scenarios/src/constants.ts +++ b/packages/fill-scenarios/src/constants.ts @@ -1,3 +1,4 @@ export const constants = { + AWAIT_TRANSACTION_MINED_MS: 0, NULL_ADDRESS: '0x0000000000000000000000000000000000000000', }; diff --git a/packages/fill-scenarios/src/fill_scenarios.ts b/packages/fill-scenarios/src/fill_scenarios.ts index 9f5218274..84c5fbc27 100644 --- a/packages/fill-scenarios/src/fill_scenarios.ts +++ b/packages/fill-scenarios/src/fill_scenarios.ts @@ -130,12 +130,13 @@ export class FillScenarios { 'exchangeAddress', ]) as OrderWithoutExchangeAddress; - await exchangeInstance.fillOrder.sendTransactionAsync( + const txHash = await exchangeInstance.fillOrder.sendTransactionAsync( orderWithoutExchangeAddress, partialFillAmount, signedOrder.signature, { from: takerAddress }, ); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); return signedOrder; } private async _createAsymmetricFillableSignedOrderWithFeesAsync( @@ -224,7 +225,7 @@ export class FillScenarios { const txHash = await erc721Token.setApprovalForAll.sendTransactionAsync(this._erc721ProxyAddress, isApproved, { from: address, }); - await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); } private async _increaseERC721BalanceAsync( tokenAddress: string, @@ -238,7 +239,7 @@ export class FillScenarios { this._web3Wrapper.getContractDefaults(), ); const txHash = await erc721Token.mint.sendTransactionAsync(address, tokenId, { from: this._coinbase }); - await this._web3Wrapper.awaitTransactionSuccessAsync(txHash); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); } private async _increaseERC20BalanceAndAllowanceAsync( tokenAddress: string, @@ -260,9 +261,10 @@ export class FillScenarios { this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); - await erc20Token.transfer.sendTransactionAsync(address, amount, { + const txHash = await erc20Token.transfer.sendTransactionAsync(address, amount, { from: this._coinbase, }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); } private async _increaseERC20AllowanceAsync( tokenAddress: string, @@ -278,8 +280,9 @@ export class FillScenarios { const oldMakerAllowance = await erc20Token.allowance.callAsync(address, this._erc20ProxyAddress); const newMakerAllowance = oldMakerAllowance.plus(amount); - await erc20Token.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { + const txHash = await erc20Token.approve.sendTransactionAsync(this._erc20ProxyAddress, newMakerAllowance, { from: address, }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); } } -- cgit v1.2.3 From 01e617bb831c90f27ca454679f9836cf86235f72 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 13:28:27 +0200 Subject: DRY up the code in order-watcher collision-resistant abi decoder --- .../src/order_watcher/order_watcher.ts | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index de0ff6b87..68ef9fab7 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -153,19 +153,15 @@ export class OrderWatcher { this._orderByOrderHash[orderHash] = signedOrder; this._dependentOrderHashesTracker.addToDependentOrderHashes(signedOrder); - const decodedMakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(signedOrder.makerAssetData); - if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC20) { - this._collisionResistantAbiDecoder.addERC20Token(decodedMakerAssetData.tokenAddress); - } else if (decodedMakerAssetData.assetProxyId === AssetProxyId.ERC721) { - this._collisionResistantAbiDecoder.addERC721Token(decodedMakerAssetData.tokenAddress); - } - - const decodedTakerAssetData = assetProxyUtils.decodeAssetDataOrThrow(signedOrder.takerAssetData); - if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC20) { - this._collisionResistantAbiDecoder.addERC20Token(decodedTakerAssetData.tokenAddress); - } else if (decodedTakerAssetData.assetProxyId === AssetProxyId.ERC721) { - this._collisionResistantAbiDecoder.addERC721Token(decodedTakerAssetData.tokenAddress); - } + const orderAssetDatas = [signedOrder.makerAssetData, signedOrder.takerAssetData]; + _.each(orderAssetDatas, assetData => { + const decodedAssetData = assetProxyUtils.decodeAssetData(assetData); + if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { + this._collisionResistantAbiDecoder.addERC20Token(decodedAssetData.tokenAddress); + } else if (decodedAssetData.assetProxyId === AssetProxyId.ERC721) { + this._collisionResistantAbiDecoder.addERC721Token(decodedAssetData.tokenAddress); + } + }); } /** * Removes an order from the orderWatcher -- cgit v1.2.3 From 96c648c4b49c559bc5f15a0a27937266e4d43d81 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 13:29:59 +0200 Subject: Fix tests descriptions --- packages/order-watcher/test/order_watcher_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index c8b723ea6..8169f61b4 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -541,7 +541,7 @@ describe('OrderWatcher', () => { [makerErc721TokenAddress] = tokenUtils.getDummyERC721TokenAddresses(); makerErc721AssetData = assetProxyUtils.encodeERC721AssetData(makerErc721TokenAddress, tokenId); const fillableErc721Amount = new BigNumber(1); - it('should emit orderStateInvalid when makerAddress allowance for all set to 0 for watched order', (done: DoneCallback) => { + it('should emit orderStateInvalid when maker allowance for all set to 0 for watched order', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( makerErc721AssetData, @@ -567,7 +567,7 @@ describe('OrderWatcher', () => { ); })().catch(done); }); - it('should emit orderStateInvalid when makerAddress moves NFT backing watched order', (done: DoneCallback) => { + it('should emit orderStateInvalid when maker moves NFT backing watched order', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( makerErc721AssetData, -- cgit v1.2.3 From c59cd36da6d16ca89d99e9d44b0577e57a928b7f Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 15:25:20 +0200 Subject: Make downlevelIteration a global config --- packages/order-watcher/tsconfig.json | 1 - packages/subproviders/tsconfig.json | 3 +-- tsconfig.json | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/order-watcher/tsconfig.json b/packages/order-watcher/tsconfig.json index ee4363919..e35816553 100644 --- a/packages/order-watcher/tsconfig.json +++ b/packages/order-watcher/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig", "compilerOptions": { - "downlevelIteration": true, "outDir": "lib" }, "include": ["./src/**/*", "./test/**/*"] diff --git a/packages/subproviders/tsconfig.json b/packages/subproviders/tsconfig.json index 72dfee80b..e35816553 100644 --- a/packages/subproviders/tsconfig.json +++ b/packages/subproviders/tsconfig.json @@ -1,8 +1,7 @@ { "extends": "../../tsconfig", "compilerOptions": { - "outDir": "lib", - "downlevelIteration": true + "outDir": "lib" }, "include": ["./src/**/*", "./test/**/*"] } diff --git a/tsconfig.json b/tsconfig.json index 5ca0267e4..588285140 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "sourceMap": true, "declaration": true, "experimentalDecorators": true, + "downlevelIteration": true, "noImplicitReturns": true, "pretty": true, "skipLibCheck": true, -- cgit v1.2.3 From 2aa729b21244a687b8403af351ed4c033ec42350 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 15:56:10 +0200 Subject: Check if the token doesn't exist before minting in fill scenarios --- packages/fill-scenarios/src/fill_scenarios.ts | 11 +++++++++-- packages/order-watcher/src/order_watcher/order_watcher.ts | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/fill-scenarios/src/fill_scenarios.ts b/packages/fill-scenarios/src/fill_scenarios.ts index 84c5fbc27..afe42fe32 100644 --- a/packages/fill-scenarios/src/fill_scenarios.ts +++ b/packages/fill-scenarios/src/fill_scenarios.ts @@ -238,8 +238,15 @@ export class FillScenarios { this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); - const txHash = await erc721Token.mint.sendTransactionAsync(address, tokenId, { from: this._coinbase }); - await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + try { + const currentOwner = await erc721Token.ownerOf.callAsync(tokenId); + if (currentOwner !== address) { + throw new Error(`Token ${tokenAddress}:${tokenId} is already owner by ${currentOwner}`); + } + } catch (err) { + const txHash = await erc721Token.mint.sendTransactionAsync(address, tokenId, { from: this._coinbase }); + await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); + } } private async _increaseERC20BalanceAndAllowanceAsync( tokenAddress: string, diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index 68ef9fab7..c43887b77 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -155,7 +155,7 @@ export class OrderWatcher { const orderAssetDatas = [signedOrder.makerAssetData, signedOrder.takerAssetData]; _.each(orderAssetDatas, assetData => { - const decodedAssetData = assetProxyUtils.decodeAssetData(assetData); + const decodedAssetData = assetProxyUtils.decodeAssetDataOrThrow(assetData); if (decodedAssetData.assetProxyId === AssetProxyId.ERC20) { this._collisionResistantAbiDecoder.addERC20Token(decodedAssetData.tokenAddress); } else if (decodedAssetData.assetProxyId === AssetProxyId.ERC721) { -- cgit v1.2.3 From b8e69718a1fc12f1604115c9a32aff72a617fd73 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 16:54:25 +0200 Subject: Upgrade sha3 to 1.2.2 to work with node v10 --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2ce7f3abf..e5ec01ea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8174,7 +8174,7 @@ mz@^2.6.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@>=2.5.1, nan@^2.0.5, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0, nan@^2.3.3, nan@^2.6.2: +nan@2.10.0, nan@>=2.5.1, nan@^2.0.8, nan@^2.2.1, nan@^2.3.0, nan@^2.3.3, nan@^2.6.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -10920,10 +10920,10 @@ sha.js@^2.4.0, sha.js@^2.4.8: safe-buffer "^5.0.1" sha3@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.0.tgz#6989f1b70a498705876a373e2c62ace96aa9399a" + version "1.2.2" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.2.tgz#a66c5098de4c25bc88336ec8b4817d005bca7ba9" dependencies: - nan "^2.0.5" + nan "2.10.0" shallowequal@^1.0.1: version "1.0.2" -- cgit v1.2.3 From cca17f70b83d42205b58af9a430fa9c98334bb47 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 18:45:35 +0200 Subject: Use allowance instead of approval for all in fill-scenarios --- packages/fill-scenarios/src/fill_scenarios.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/fill-scenarios/src/fill_scenarios.ts b/packages/fill-scenarios/src/fill_scenarios.ts index afe42fe32..8294657e7 100644 --- a/packages/fill-scenarios/src/fill_scenarios.ts +++ b/packages/fill-scenarios/src/fill_scenarios.ts @@ -212,17 +212,20 @@ export class FillScenarios { tokenId: BigNumber, ): Promise { await this._increaseERC721BalanceAsync(tokenAddress, address, tokenId); - await this._increaseERC721AllowanceAsync(tokenAddress, address); + await this._increaseERC721AllowanceAsync(tokenAddress, address, tokenId); } - private async _increaseERC721AllowanceAsync(tokenAddress: string, address: string): Promise { + private async _increaseERC721AllowanceAsync( + tokenAddress: string, + address: string, + tokenId: BigNumber, + ): Promise { const erc721Token = new DummyERC721TokenContract( artifacts.DummyERC721Token.compilerOutput.abi, tokenAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); - const isApproved = true; - const txHash = await erc721Token.setApprovalForAll.sendTransactionAsync(this._erc721ProxyAddress, isApproved, { + const txHash = await erc721Token.approve.sendTransactionAsync(this._erc721ProxyAddress, tokenId, { from: address, }); await this._web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); -- cgit v1.2.3 From f20b496dca2dceb4f53ae20660798f8b8148a265 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 17 Jul 2018 18:46:58 +0200 Subject: Add a test for ERC721 Allowance --- packages/order-watcher/test/order_watcher_test.ts | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index 8169f61b4..cd2b7bbfe 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -541,6 +541,31 @@ describe('OrderWatcher', () => { [makerErc721TokenAddress] = tokenUtils.getDummyERC721TokenAddresses(); makerErc721AssetData = assetProxyUtils.encodeERC721AssetData(makerErc721TokenAddress, tokenId); const fillableErc721Amount = new BigNumber(1); + it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerErc721AssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableErc721Amount, + ); + const orderHash = orderHashUtils.getOrderHashHex(signedOrder); + await orderWatcher.addOrderAsync(signedOrder); + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { + expect(orderState.isValid).to.be.false(); + const invalidOrderState = orderState as OrderStateInvalid; + expect(invalidOrderState.orderHash).to.be.equal(orderHash); + expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance); + }); + orderWatcher.subscribe(callback); + await contractWrappers.erc721Token.setApprovalAsync( + makerErc721TokenAddress, + constants.NULL_ADDRESS, + tokenId, + ); + })().catch(done); + }); it('should emit orderStateInvalid when maker allowance for all set to 0 for watched order', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( @@ -550,6 +575,17 @@ describe('OrderWatcher', () => { takerAddress, fillableErc721Amount, ); + await contractWrappers.erc721Token.setApprovalAsync( + makerErc721TokenAddress, + constants.NULL_ADDRESS, + tokenId, + ); + let isApproved = true; + await contractWrappers.erc721Token.setProxyApprovalForAllAsync( + makerErc721TokenAddress, + makerAddress, + isApproved, + ); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); await orderWatcher.addOrderAsync(signedOrder); const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { @@ -559,7 +595,7 @@ describe('OrderWatcher', () => { expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance); }); orderWatcher.subscribe(callback); - const isApproved = false; + isApproved = false; await contractWrappers.erc721Token.setProxyApprovalForAllAsync( makerErc721TokenAddress, makerAddress, -- cgit v1.2.3