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.
This commit is contained in:
F. Eugene Aumson 2019-09-18 19:36:06 -04:00 committed by GitHub
parent 549697dc47
commit bca8c5eccc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 7 deletions

View File

@ -7,7 +7,7 @@
"evmVersion": "constantinople",
"optimizer": {
"enabled": true,
"runs": 1000000,
"runs": 10000,
"details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
},
"outputSelection": {

View File

@ -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(

View File

@ -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": {

View File

@ -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 () => {

View File

@ -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);
}

View File

@ -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`,
);
}