From bca8c5ecccda95f03dae133523e2526be5f26c49 Mon Sep 17 00:00:00 2001 From: "F. Eugene Aumson" Date: Wed, 18 Sep 2019 19:36:06 -0400 Subject: [PATCH] DevUtils.sol: Upgrade for v3 (#2161) * Exhibit bug in getSimulatedOrderTransferResults * Fix getSimulatedOrderTransferResults * dev-utils/package.json: add quantify_bytecode cmd * Fix typo in log message * Reduce compiler optimization runs In order to reduce the EVM bytecode object length of the DevUtils contract to be under the EIP-170 limit of 24 KB. --- contracts/dev-utils/compiler.json | 2 +- .../src/OrderTransferSimulationUtils.sol | 16 ++++++--- contracts/dev-utils/package.json | 3 +- .../dev-utils/test/order_validation_utils.ts | 36 +++++++++++++++++++ .../src/interfaces/IProtocolFees.sol | 12 +++++++ packages/contract-artifacts/src/copy.ts | 2 +- 6 files changed, 64 insertions(+), 7 deletions(-) diff --git a/contracts/dev-utils/compiler.json b/contracts/dev-utils/compiler.json index 6b74c612c2..10160aa539 100644 --- a/contracts/dev-utils/compiler.json +++ b/contracts/dev-utils/compiler.json @@ -7,7 +7,7 @@ "evmVersion": "constantinople", "optimizer": { "enabled": true, - "runs": 1000000, + "runs": 10000, "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true } }, "outputSelection": { diff --git a/contracts/dev-utils/contracts/src/OrderTransferSimulationUtils.sol b/contracts/dev-utils/contracts/src/OrderTransferSimulationUtils.sol index 3c568abee4..b5cc2b12d8 100644 --- a/contracts/dev-utils/contracts/src/OrderTransferSimulationUtils.sol +++ b/contracts/dev-utils/contracts/src/OrderTransferSimulationUtils.sol @@ -24,6 +24,7 @@ import "@0x/contracts-exchange/contracts/src/interfaces/IExchange.sol"; import "@0x/contracts-exchange/contracts/src/libs/LibExchangeRichErrorDecoder.sol"; import "@0x/contracts-exchange-libs/contracts/src/LibExchangeRichErrors.sol"; import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; +import "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol"; import "@0x/contracts-utils/contracts/src/LibBytes.sol"; @@ -66,6 +67,13 @@ contract OrderTransferSimulationUtils is public returns (OrderTransferResults orderTransferResults) { + LibFillResults.FillResults memory fillResults = LibFillResults.calculateFillResults( + order, + takerAssetFillAmount, + _EXCHANGE.protocolFeeMultiplier(), + tx.gasprice + ); + // Create input arrays bytes[] memory assetData = new bytes[](4); address[] memory fromAddresses = new address[](4); @@ -76,25 +84,25 @@ contract OrderTransferSimulationUtils is assetData[0] = order.takerAssetData; fromAddresses[0] = takerAddress; toAddresses[0] = order.makerAddress; - amounts[0] = order.takerAssetAmount; + amounts[0] = takerAssetFillAmount; // Transfer `makerAsset` from maker to taker assetData[1] = order.makerAssetData; fromAddresses[1] = order.makerAddress; toAddresses[1] = takerAddress; - amounts[1] = order.makerAssetAmount; + amounts[1] = fillResults.makerAssetFilledAmount; // Transfer `takerFeeAsset` from taker to feeRecipient assetData[2] = order.takerFeeAssetData; fromAddresses[2] = takerAddress; toAddresses[2] = order.feeRecipientAddress; - amounts[2] = order.takerFee; + amounts[2] = fillResults.takerFeePaid; // Transfer `makerFeeAsset` from maker to feeRecipient assetData[3] = order.makerFeeAssetData; fromAddresses[3] = order.makerAddress; toAddresses[3] = order.feeRecipientAddress; - amounts[3] = order.makerFee; + amounts[3] = fillResults.makerFeePaid; // Encode data for `simulateDispatchTransferFromCalls(assetData, fromAddresses, toAddresses, amounts)` bytes memory simulateDispatchTransferFromCallsData = abi.encodeWithSelector( diff --git a/contracts/dev-utils/package.json b/contracts/dev-utils/package.json index 8ed6627a79..f41f32ce0e 100644 --- a/contracts/dev-utils/package.json +++ b/contracts/dev-utils/package.json @@ -12,7 +12,7 @@ "scripts": { "build": "yarn pre_build && tsc -b", "build:ci": "yarn build", - "pre_build": "run-s compile contracts:gen generate_contract_wrappers", + "pre_build": "run-s compile quantify_bytecode contracts:gen generate_contract_wrappers", "test": "yarn run_mocha", "rebuild_and_test": "run-s build test", "test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov", @@ -32,6 +32,7 @@ "test:circleci": "yarn test", "contracts:gen": "contracts-gen", "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol", + "quantify_bytecode": "echo EVM bytecode object lengths:;for i in ./generated-artifacts/*.json; do node -e \"console.log('$i\t' + (require('$i').compilerOutput.evm.bytecode.object.length - 2) / 2)\"; done", "compile:truffle": "truffle compile" }, "config": { diff --git a/contracts/dev-utils/test/order_validation_utils.ts b/contracts/dev-utils/test/order_validation_utils.ts index 58d2df4eca..0f95e8d2f1 100644 --- a/contracts/dev-utils/test/order_validation_utils.ts +++ b/contracts/dev-utils/test/order_validation_utils.ts @@ -551,6 +551,42 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => { ); expect(orderTransferResults).to.equal(OrderTransferResults.TransfersSuccessful); }); + it('should return TransfersSuccessful for a partial fill when taker has ample assets for the fill but not for the whole order', async () => { + await erc20Token2.setBalance.awaitTransactionSuccessAsync( + takerAddress, + signedOrder.takerAssetAmount.dividedBy(2), + { + from: owner, + }, + ); + await erc20Token2.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.takerAssetAmount, { + from: takerAddress, + }); + await erc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerAssetAmount, { + from: owner, + }); + await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerAssetAmount, { + from: makerAddress, + }); + await feeErc20Token.setBalance.awaitTransactionSuccessAsync(takerAddress, signedOrder.takerFee, { + from: owner, + }); + await feeErc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.takerFee, { + from: takerAddress, + }); + await feeErc20Token.setBalance.awaitTransactionSuccessAsync(makerAddress, signedOrder.makerFee, { + from: owner, + }); + await feeErc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, signedOrder.makerFee, { + from: makerAddress, + }); + const orderTransferResults = await devUtils.getSimulatedOrderTransferResults.callAsync( + signedOrder, + takerAddress, + signedOrder.takerAssetAmount.dividedBy(2), + ); + expect(orderTransferResults).to.equal(OrderTransferResults.TransfersSuccessful); + }); }); describe('getSimulatedOrdersTransferResults', async () => { it('should simulate the transfers of each order independently from one another', async () => { diff --git a/contracts/exchange/contracts/src/interfaces/IProtocolFees.sol b/contracts/exchange/contracts/src/interfaces/IProtocolFees.sol index f437933173..cd0e570c2f 100644 --- a/contracts/exchange/contracts/src/interfaces/IProtocolFees.sol +++ b/contracts/exchange/contracts/src/interfaces/IProtocolFees.sol @@ -36,4 +36,16 @@ contract IProtocolFees { /// @param updatedProtocolFeeCollector The updated protocolFeeCollector contract address. function setProtocolFeeCollectorAddress(address updatedProtocolFeeCollector) external; + + /// @dev Returns the protocolFeeMultiplier + function protocolFeeMultiplier() + external + view + returns (uint256); + + /// @dev Returns the protocolFeeCollector address + function protocolFeeCollector() + external + view + returns (address); } diff --git a/packages/contract-artifacts/src/copy.ts b/packages/contract-artifacts/src/copy.ts index c67b3741f8..dc8f10711c 100644 --- a/packages/contract-artifacts/src/copy.ts +++ b/packages/contract-artifacts/src/copy.ts @@ -41,7 +41,7 @@ if (allArtifactPaths.length < pkgNames.length) { throw new Error( `Expected ${pkgNames.length} artifacts, found ${ allArtifactPaths.length - }. Please ensure artifacts are present in ${contractsPath}/**/generated_artifacts`, + }. Please ensure artifacts are present in ${contractsPath}/**/generated-artifacts`, ); }