diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/contracts/src/utils/exchange_wrapper.ts | 10 | ||||
-rw-r--r-- | packages/contracts/src/utils/formatters.ts | 10 | ||||
-rw-r--r-- | packages/contracts/src/utils/log_decoder.ts | 29 | ||||
-rw-r--r-- | packages/contracts/src/utils/signed_order_utils.ts (renamed from packages/contracts/util/signed_order_utils.ts) | 5 | ||||
-rw-r--r-- | packages/contracts/test/exchange/core.ts | 248 |
5 files changed, 158 insertions, 144 deletions
diff --git a/packages/contracts/src/utils/exchange_wrapper.ts b/packages/contracts/src/utils/exchange_wrapper.ts index 75b452b04..daab002b3 100644 --- a/packages/contracts/src/utils/exchange_wrapper.ts +++ b/packages/contracts/src/utils/exchange_wrapper.ts @@ -20,10 +20,7 @@ export class ExchangeWrapper { from: string, opts: { takerTokenFillAmount?: BigNumber } = {}, ): Promise<TransactionReceiptWithDecodedLogs> { - const params = signedOrderUtils.createFill( - signedOrder, - opts.takerTokenFillAmount, - ); + const params = signedOrderUtils.createFill(signedOrder, opts.takerTokenFillAmount); const txHash = await this._exchange.fillOrder.sendTransactionAsync( params.orderAddresses, params.orderValues, @@ -60,10 +57,7 @@ export class ExchangeWrapper { from: string, opts: { takerTokenFillAmount?: BigNumber } = {}, ): Promise<TransactionReceiptWithDecodedLogs> { - const params = signedOrderUtils.createFill( - signedOrder, - opts.takerTokenFillAmount, - ); + const params = signedOrderUtils.createFill(signedOrder, opts.takerTokenFillAmount); const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync( params.orderAddresses, params.orderValues, diff --git a/packages/contracts/src/utils/formatters.ts b/packages/contracts/src/utils/formatters.ts index 88e12a6b4..48c77fea1 100644 --- a/packages/contracts/src/utils/formatters.ts +++ b/packages/contracts/src/utils/formatters.ts @@ -5,10 +5,7 @@ import * as _ from 'lodash'; import { BatchCancelOrders, BatchFillOrders, MarketFillOrders } from './types'; export const formatters = { - createBatchFill( - signedOrders: SignedOrder[], - takerTokenFillAmounts: BigNumber[] = [], - ) { + createBatchFill(signedOrders: SignedOrder[], takerTokenFillAmounts: BigNumber[] = []) { const batchFill: BatchFillOrders = { orderAddresses: [], orderValues: [], @@ -42,10 +39,7 @@ export const formatters = { }); return batchFill; }, - createMarketFillOrders( - signedOrders: SignedOrder[], - takerTokenFillAmount: BigNumber, - ) { + createMarketFillOrders(signedOrders: SignedOrder[], takerTokenFillAmount: BigNumber) { const marketFillOrders: MarketFillOrders = { orderAddresses: [], orderValues: [], diff --git a/packages/contracts/src/utils/log_decoder.ts b/packages/contracts/src/utils/log_decoder.ts new file mode 100644 index 000000000..98dd8eab6 --- /dev/null +++ b/packages/contracts/src/utils/log_decoder.ts @@ -0,0 +1,29 @@ +import { LogWithDecodedArgs, RawLog } from '@0xproject/types'; +import { AbiDecoder } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import { artifacts } from './artifacts'; +import { Artifact } from './types'; + +export class LogDecoder { + private _abiDecoder: AbiDecoder; + constructor(networkId: number) { + if (_.isUndefined(networkId)) { + throw new Error('networkId not specified'); + } + const abiArrays: Web3.AbiDefinition[][] = []; + _.forEach(artifacts, (artifact: Artifact) => { + const network = artifact.networks[networkId]; + if (_.isUndefined(network)) { + throw new Error(`Artifact does not exist on network ${networkId}`); + } + abiArrays.push(network.abi); + }); + this._abiDecoder = new AbiDecoder(abiArrays); + } + public tryToDecodeLogOrNoop<ArgsType>(log: Web3.LogEntry): LogWithDecodedArgs<ArgsType> | RawLog { + const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log); + return logWithDecodedArgs; + } +} diff --git a/packages/contracts/util/signed_order_utils.ts b/packages/contracts/src/utils/signed_order_utils.ts index 3e5d2f226..6122748b4 100644 --- a/packages/contracts/util/signed_order_utils.ts +++ b/packages/contracts/src/utils/signed_order_utils.ts @@ -7,10 +7,7 @@ import * as _ from 'lodash'; import { crypto } from './crypto'; export const signedOrderUtils = { - createFill: ( - signedOrder: SignedOrder, - takerTokenFillAmount?: BigNumber, - ) => { + createFill: (signedOrder: SignedOrder, takerTokenFillAmount?: BigNumber) => { const fill = { ...signedOrderUtils.getOrderAddressesAndValues(signedOrder), takerTokenFillAmount: takerTokenFillAmount || signedOrder.takerTokenAmount, diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index a1758457b..ae136816e 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -19,6 +19,7 @@ import { Balances } from '../../src/utils/balances'; import { constants } from '../../src/utils/constants'; import { crypto } from '../../src/utils/crypto'; import { ExchangeWrapper } from '../../src/utils/exchange_wrapper'; +import { LogDecoder } from '../../src/utils/log_decoder'; import { OrderFactory } from '../../src/utils/order_factory'; import { BalancesByOwner, ContractName, ExchangeContractErrs } from '../../src/utils/types'; import { chaiSetup } from '../utils/chai_setup'; @@ -28,6 +29,7 @@ import { provider, web3Wrapper } from '../utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); +const logDecoder = new LogDecoder(constants.TESTRPC_NETWORK_ID); describe('Exchange', () => { let maker: string; @@ -392,7 +394,7 @@ describe('Exchange', () => { const res = await exWrapper.fillOrderAsync(signedOrder, taker, { takerTokenFillAmount: signedOrder.takerTokenAmount, }); - const log = res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogFillContractEventArgs>; expect(log.args.takerTokenFilledAmount).to.be.bignumber.equal( signedOrder.takerTokenAmount.minus(takerTokenFillAmount), ); @@ -428,7 +430,8 @@ describe('Exchange', () => { }); expect(res.logs).to.have.length(1); - const logArgs = (res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>).args; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogFillContractEventArgs>; + const logArgs = log.args; const expectedFilledMakerTokenAmount = signedOrder.makerTokenAmount.div(divisor); const expectedFilledTakerTokenAmount = signedOrder.takerTokenAmount.div(divisor); const expectedFeeMPaid = signedOrder.makerFee.div(divisor); @@ -458,7 +461,8 @@ describe('Exchange', () => { }); expect(res.logs).to.have.length(1); - const logArgs = (res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>).args; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogFillContractEventArgs>; + const logArgs = log.args; const expectedFilledMakerTokenAmount = signedOrder.makerTokenAmount.div(divisor); const expectedFilledTakerTokenAmount = signedOrder.takerTokenAmount.div(divisor); const expectedFeeMPaid = new BigNumber(0); @@ -524,19 +528,18 @@ describe('Exchange', () => { ).to.be.rejectedWith(constants.REVERT); }); - it('should not change balances if maker balances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - signedOrder = await orderFactory.newSignedOrderAsync({ - makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18), - }); + // it('should not change balances if maker balances are too low to fill order and \ + // shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // signedOrder = await orderFactory.newSignedOrderAsync({ + // makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18), + // }); - await exWrapper.fillOrderAsync(signedOrder, taker); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); - it('should throw if maker balances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = true', async () => { + it('should throw if maker balances are too low to fill order', async () => { signedOrder = await orderFactory.newSignedOrderAsync({ makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18), }); @@ -544,19 +547,18 @@ describe('Exchange', () => { return expect(exWrapper.fillOrderAsync(signedOrder, taker)).to.be.rejectedWith(constants.REVERT); }); - it('should not change balances if taker balances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - signedOrder = await orderFactory.newSignedOrderAsync({ - takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18), - }); + // it('should not change balances if taker balances are too low to fill order and \ + // shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // signedOrder = await orderFactory.newSignedOrderAsync({ + // takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18), + // }); - await exWrapper.fillOrderAsync(signedOrder, taker); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); - it('should throw if taker balances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = true', async () => { + it('should throw if taker balances are too low to fill order', async () => { signedOrder = await orderFactory.newSignedOrderAsync({ takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18), }); @@ -564,20 +566,19 @@ describe('Exchange', () => { return expect(exWrapper.fillOrderAsync(signedOrder, taker)).to.be.rejectedWith(constants.REVERT); }); - it('should not change balances if maker allowances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - await rep.approve.sendTransactionAsync(tokenTransferProxy.address, new BigNumber(0), { from: maker }); - await exWrapper.fillOrderAsync(signedOrder, taker); - await rep.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { - from: maker, - }); + // it('should not change balances if maker allowances are too low to fill order and \ + // shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // await rep.approve.sendTransactionAsync(tokenTransferProxy.address, new BigNumber(0), { from: maker }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // await rep.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { + // from: maker, + // }); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); - it('should throw if maker allowances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = true', async () => { + it('should throw if maker allowances are too low to fill order', async () => { await rep.approve.sendTransactionAsync(tokenTransferProxy.address, new BigNumber(0), { from: maker }); expect(exWrapper.fillOrderAsync(signedOrder, taker)).to.be.rejectedWith(constants.REVERT); await rep.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { @@ -585,20 +586,19 @@ describe('Exchange', () => { }); }); - it('should not change balances if taker allowances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - await dgd.approve.sendTransactionAsync(tokenTransferProxy.address, new BigNumber(0), { from: taker }); - await exWrapper.fillOrderAsync(signedOrder, taker); - await dgd.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { - from: taker, - }); + // it('should not change balances if taker allowances are too low to fill order and \ + // shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // await dgd.approve.sendTransactionAsync(tokenTransferProxy.address, new BigNumber(0), { from: taker }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // await dgd.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { + // from: taker, + // }); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); - it('should throw if taker allowances are too low to fill order and \ - shouldThrowOnInsufficientBalanceOrAllowance = true', async () => { + it('should throw if taker allowances are too low to fill order', async () => { await dgd.approve.sendTransactionAsync(tokenTransferProxy.address, new BigNumber(0), { from: taker }); expect(exWrapper.fillOrderAsync(signedOrder, taker)).to.be.rejectedWith(constants.REVERT); await dgd.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { @@ -606,71 +606,71 @@ describe('Exchange', () => { }); }); - it('should not change balances if makerTokenAddress is ZRX, makerTokenAmount + makerFee > maker balance, \ - and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const makerZRXBalance = new BigNumber(balances[maker][zrx.address]); - signedOrder = await orderFactory.newSignedOrderAsync({ - makerTokenAddress: zrx.address, - makerTokenAmount: makerZRXBalance, - makerFee: new BigNumber(1), - }); - await exWrapper.fillOrderAsync(signedOrder, taker); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); - - it('should not change balances if makerTokenAddress is ZRX, makerTokenAmount + makerFee > maker allowance, \ - and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const makerZRXAllowance = await zrx.allowance.callAsync(maker, tokenTransferProxy.address); - signedOrder = await orderFactory.newSignedOrderAsync({ - makerTokenAddress: zrx.address, - makerTokenAmount: new BigNumber(makerZRXAllowance), - makerFee: new BigNumber(1), - }); - await exWrapper.fillOrderAsync(signedOrder, taker); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); - - it('should not change balances if takerTokenAddress is ZRX, takerTokenAmount + takerFee > taker balance, \ - and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const takerZRXBalance = new BigNumber(balances[taker][zrx.address]); - signedOrder = await orderFactory.newSignedOrderAsync({ - takerTokenAddress: zrx.address, - takerTokenAmount: takerZRXBalance, - takerFee: new BigNumber(1), - }); - await exWrapper.fillOrderAsync(signedOrder, taker); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); - - it('should not change balances if takerTokenAddress is ZRX, takerTokenAmount + takerFee > taker allowance, \ - and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const takerZRXAllowance = await zrx.allowance.callAsync(taker, tokenTransferProxy.address); - signedOrder = await orderFactory.newSignedOrderAsync({ - takerTokenAddress: zrx.address, - takerTokenAmount: new BigNumber(takerZRXAllowance), - takerFee: new BigNumber(1), - }); - await exWrapper.fillOrderAsync(signedOrder, taker); - const newBalances = await dmyBalances.getAsync(); - expect(newBalances).to.be.deep.equal(balances); - }); - - it('should throw if getBalance or getAllowance attempts to change state and \ - shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const maliciousToken = await deployer.deployAsync(ContractName.MaliciousToken); - await maliciousToken.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { - from: taker, - }); - - signedOrder = await orderFactory.newSignedOrderAsync({ - takerTokenAddress: maliciousToken.address, - }); - - return expect(exWrapper.fillOrderAsync(signedOrder, taker)).to.be.rejectedWith(constants.REVERT); - }); + // it('should not change balances if makerTokenAddress is ZRX, makerTokenAmount + makerFee > maker balance, \ + // and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // const makerZRXBalance = new BigNumber(balances[maker][zrx.address]); + // signedOrder = await orderFactory.newSignedOrderAsync({ + // makerTokenAddress: zrx.address, + // makerTokenAmount: makerZRXBalance, + // makerFee: new BigNumber(1), + // }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); + + // it('should not change balances if makerTokenAddress is ZRX, makerTokenAmount + makerFee > maker allowance, \ + // and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // const makerZRXAllowance = await zrx.allowance(maker, tokenTransferProxy.address); + // signedOrder = await orderFactory.newSignedOrderAsync({ + // makerTokenAddress: zrx.address, + // makerTokenAmount: new BigNumber(makerZRXAllowance), + // makerFee: new BigNumber(1), + // }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); + + // it('should not change balances if takerTokenAddress is ZRX, takerTokenAmount + takerFee > taker balance, \ + // and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // const takerZRXBalance = new BigNumber(balances[taker][zrx.address]); + // signedOrder = await orderFactory.newSignedOrderAsync({ + // takerTokenAddress: zrx.address, + // takerTokenAmount: takerZRXBalance, + // takerFee: new BigNumber(1), + // }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); + + // it('should not change balances if takerTokenAddress is ZRX, takerTokenAmount + takerFee > taker allowance, \ + // and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // const takerZRXAllowance = await zrx.allowance(taker, tokenTransferProxy.address); + // signedOrder = await orderFactory.newSignedOrderAsync({ + // takerTokenAddress: zrx.address, + // takerTokenAmount: new BigNumber(takerZRXAllowance), + // takerFee: new BigNumber(1), + // }); + // await exWrapper.fillOrderAsync(signedOrder, taker); + // const newBalances = await dmyBalances.getAsync(); + // expect(newBalances).to.be.deep.equal(balances); + // }); + + // it('should throw if getBalance or getAllowance attempts to change state and \ + // shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { + // const maliciousToken = await deployer.deployAsync(ContractName.MaliciousToken); + // await maliciousToken.approve.sendTransactionAsync(tokenTransferProxy.address, INITIAL_ALLOWANCE, { + // from: taker, + // }); + + // signedOrder = await orderFactory.newSignedOrderAsync({ + // takerTokenAddress: maliciousToken.address, + // }); + + // return expect(exWrapper.fillOrderAsync(signedOrder, taker)).to.be.rejectedWith(constants.REVERT); + // }); it('should not change balances if an order is expired', async () => { signedOrder = await orderFactory.newSignedOrderAsync({ @@ -689,8 +689,8 @@ describe('Exchange', () => { const res = await exWrapper.fillOrderAsync(signedOrder, taker); expect(res.logs).to.have.length(1); - const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; - const errCode = log.args.errorId; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED); }); @@ -700,8 +700,8 @@ describe('Exchange', () => { const res = await exWrapper.fillOrderAsync(signedOrder, taker); expect(res.logs).to.have.length(1); - const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; - const errCode = log.args.errorId; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED); }); }); @@ -761,7 +761,7 @@ describe('Exchange', () => { const res = await exWrapper.fillOrderAsync(signedOrder, taker, { takerTokenFillAmount: signedOrder.takerTokenAmount, }); - const log = res.logs[0] as LogWithDecodedArgs<LogFillContractEventArgs>; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogFillContractEventArgs>; expect(log.args.takerTokenFilledAmount).to.be.bignumber.equal( signedOrder.takerTokenAmount.minus(takerTokenCancelAmount), ); @@ -806,7 +806,7 @@ describe('Exchange', () => { }); expect(res.logs).to.have.length(1); - const log = res.logs[0] as LogWithDecodedArgs<LogCancelContractEventArgs>; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogCancelContractEventArgs>; const logArgs = log.args; const expectedCancelledMakerTokenAmount = signedOrder.makerTokenAmount.div(divisor); const expectedCancelledTakerTokenAmount = signedOrder.takerTokenAmount.div(divisor); @@ -827,8 +827,8 @@ describe('Exchange', () => { const res = await exWrapper.cancelOrderAsync(signedOrder, maker); expect(res.logs).to.have.length(1); - const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; - const errCode = log.args.errorId; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED); }); @@ -839,8 +839,8 @@ describe('Exchange', () => { const res = await exWrapper.cancelOrderAsync(signedOrder, maker); expect(res.logs).to.have.length(1); - const log = res.logs[0] as LogWithDecodedArgs<LogErrorContractEventArgs>; - const errCode = log.args.errorId; + const log = logDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs<LogErrorContractEventArgs>; + const errCode = log.args.errorId.toNumber(); expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED); }); }); |