Remove LibAbiEncoder
This commit is contained in:
@@ -21,17 +21,17 @@ pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./libs/LibConstants.sol";
|
||||
import "./mixins/MExchangeWrapper.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibAbiEncoder.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
|
||||
import "@0x/contracts-exchange-libs/contracts/src/LibExchangeSelectors.sol";
|
||||
|
||||
|
||||
contract MixinExchangeWrapper is
|
||||
LibAbiEncoder,
|
||||
LibFillResults,
|
||||
LibMath,
|
||||
LibConstants,
|
||||
LibExchangeSelectors,
|
||||
MExchangeWrapper
|
||||
{
|
||||
/// @dev Fills the input order.
|
||||
@@ -49,7 +49,8 @@ contract MixinExchangeWrapper is
|
||||
returns (FillResults memory fillResults)
|
||||
{
|
||||
// ABI encode calldata for `fillOrder`
|
||||
bytes memory fillOrderCalldata = _abiEncodeFillOrder(
|
||||
bytes memory fillOrderCalldata = abi.encodeWithSelector(
|
||||
FILL_ORDER_SELECTOR,
|
||||
order,
|
||||
takerAssetFillAmount,
|
||||
signature
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
}
|
||||
},
|
||||
"contracts": [
|
||||
"src/LibAbiEncoder.sol",
|
||||
"src/LibConstants.sol",
|
||||
"src/LibEIP712ExchangeDomain.sol",
|
||||
"src/LibFillResults.sol",
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "./LibOrder.sol";
|
||||
|
||||
|
||||
contract LibAbiEncoder {
|
||||
|
||||
/// @dev ABI encodes calldata for `fillOrder`.
|
||||
/// @param order Order struct containing order specifications.
|
||||
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
|
||||
/// @param signature Proof that order has been created by maker.
|
||||
/// @return ABI encoded calldata for `fillOrder`.
|
||||
function _abiEncodeFillOrder(
|
||||
LibOrder.Order memory order,
|
||||
uint256 takerAssetFillAmount,
|
||||
bytes memory signature
|
||||
)
|
||||
internal
|
||||
pure
|
||||
returns (bytes memory fillOrderCalldata)
|
||||
{
|
||||
// We need to call MExchangeCore.fillOrder using a delegatecall in
|
||||
// assembly so that we can intercept a call that throws. For this, we
|
||||
// need the input encoded in memory in the Ethereum ABIv2 format [1].
|
||||
|
||||
// | Area | Offset | Length | Contents |
|
||||
// | -------- |--------|---------|-------------------------------------------- |
|
||||
// | Header | 0x00 | 4 | function selector |
|
||||
// | Params | | 3 * 32 | function parameters: |
|
||||
// | | 0x00 | | 1. offset to order (*) |
|
||||
// | | 0x20 | | 2. takerAssetFillAmount |
|
||||
// | | 0x40 | | 3. offset to signature (*) |
|
||||
// | Data | | 12 * 32 | order: |
|
||||
// | | 0x000 | | 1. senderAddress |
|
||||
// | | 0x020 | | 2. makerAddress |
|
||||
// | | 0x040 | | 3. takerAddress |
|
||||
// | | 0x060 | | 4. feeRecipientAddress |
|
||||
// | | 0x080 | | 5. makerAssetAmount |
|
||||
// | | 0x0A0 | | 6. takerAssetAmount |
|
||||
// | | 0x0C0 | | 7. makerFeeAmount |
|
||||
// | | 0x0E0 | | 8. takerFeeAmount |
|
||||
// | | 0x100 | | 9. expirationTimeSeconds |
|
||||
// | | 0x120 | | 10. salt |
|
||||
// | | 0x140 | | 11. Offset to makerAssetData (*) |
|
||||
// | | 0x160 | | 12. Offset to takerAssetData (*) |
|
||||
// | | 0x180 | 32 | makerAssetData Length |
|
||||
// | | 0x1A0 | ** | makerAssetData Contents |
|
||||
// | | 0x1C0 | 32 | takerAssetData Length |
|
||||
// | | 0x1E0 | ** | takerAssetData Contents |
|
||||
// | | 0x200 | 32 | signature Length |
|
||||
// | | 0x220 | ** | signature Contents |
|
||||
|
||||
// * Offsets are calculated from the beginning of the current area: Header, Params, Data:
|
||||
// An offset stored in the Params area is calculated from the beginning of the Params section.
|
||||
// An offset stored in the Data area is calculated from the beginning of the Data section.
|
||||
|
||||
// ** The length of dynamic array contents are stored in the field immediately preceeding the contents.
|
||||
|
||||
// [1]: https://solidity.readthedocs.io/en/develop/abi-spec.html
|
||||
|
||||
assembly {
|
||||
|
||||
// Areas below may use the following variables:
|
||||
// 1. <area>Start -- Start of this area in memory
|
||||
// 2. <area>End -- End of this area in memory. This value may
|
||||
// be precomputed (before writing contents),
|
||||
// or it may be computed as contents are written.
|
||||
// 3. <area>Offset -- Current offset into area. If an area's End
|
||||
// is precomputed, this variable tracks the
|
||||
// offsets of contents as they are written.
|
||||
|
||||
/////// Setup Header Area ///////
|
||||
// Load free memory pointer
|
||||
fillOrderCalldata := mload(0x40)
|
||||
// bytes4(keccak256("fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)"))
|
||||
// = 0xb4be83d5
|
||||
// Leave 0x20 bytes to store the length
|
||||
mstore(add(fillOrderCalldata, 0x20), 0xb4be83d500000000000000000000000000000000000000000000000000000000)
|
||||
let headerAreaEnd := add(fillOrderCalldata, 0x24)
|
||||
|
||||
/////// Setup Params Area ///////
|
||||
// This area is preallocated and written to later.
|
||||
// This is because we need to fill in offsets that have not yet been calculated.
|
||||
let paramsAreaStart := headerAreaEnd
|
||||
let paramsAreaEnd := add(paramsAreaStart, 0x60)
|
||||
let paramsAreaOffset := paramsAreaStart
|
||||
|
||||
/////// Setup Data Area ///////
|
||||
let dataAreaStart := paramsAreaEnd
|
||||
let dataAreaEnd := dataAreaStart
|
||||
|
||||
// Offset from the source data we're reading from
|
||||
let sourceOffset := order
|
||||
// arrayLenBytes and arrayLenWords track the length of a dynamically-allocated bytes array.
|
||||
let arrayLenBytes := 0
|
||||
let arrayLenWords := 0
|
||||
|
||||
/////// Write order Struct ///////
|
||||
// Write memory location of Order, relative to the start of the
|
||||
// parameter list, then increment the paramsAreaOffset respectively.
|
||||
mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))
|
||||
paramsAreaOffset := add(paramsAreaOffset, 0x20)
|
||||
|
||||
// Write values for each field in the order
|
||||
// It would be nice to use a loop, but we save on gas by writing
|
||||
// the stores sequentially.
|
||||
mstore(dataAreaEnd, mload(sourceOffset)) // makerAddress
|
||||
mstore(add(dataAreaEnd, 0x20), mload(add(sourceOffset, 0x20))) // takerAddress
|
||||
mstore(add(dataAreaEnd, 0x40), mload(add(sourceOffset, 0x40))) // feeRecipientAddress
|
||||
mstore(add(dataAreaEnd, 0x60), mload(add(sourceOffset, 0x60))) // senderAddress
|
||||
mstore(add(dataAreaEnd, 0x80), mload(add(sourceOffset, 0x80))) // makerAssetAmount
|
||||
mstore(add(dataAreaEnd, 0xA0), mload(add(sourceOffset, 0xA0))) // takerAssetAmount
|
||||
mstore(add(dataAreaEnd, 0xC0), mload(add(sourceOffset, 0xC0))) // makerFeeAmount
|
||||
mstore(add(dataAreaEnd, 0xE0), mload(add(sourceOffset, 0xE0))) // takerFeeAmount
|
||||
mstore(add(dataAreaEnd, 0x100), mload(add(sourceOffset, 0x100))) // expirationTimeSeconds
|
||||
mstore(add(dataAreaEnd, 0x120), mload(add(sourceOffset, 0x120))) // salt
|
||||
mstore(add(dataAreaEnd, 0x140), mload(add(sourceOffset, 0x140))) // Offset to makerAssetData
|
||||
mstore(add(dataAreaEnd, 0x160), mload(add(sourceOffset, 0x160))) // Offset to takerAssetData
|
||||
dataAreaEnd := add(dataAreaEnd, 0x180)
|
||||
sourceOffset := add(sourceOffset, 0x180)
|
||||
|
||||
// Write offset to <order.makerAssetData>
|
||||
mstore(add(dataAreaStart, mul(10, 0x20)), sub(dataAreaEnd, dataAreaStart))
|
||||
|
||||
// Calculate length of <order.makerAssetData>
|
||||
sourceOffset := mload(add(order, 0x140)) // makerAssetData
|
||||
arrayLenBytes := mload(sourceOffset)
|
||||
sourceOffset := add(sourceOffset, 0x20)
|
||||
arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)
|
||||
|
||||
// Write length of <order.makerAssetData>
|
||||
mstore(dataAreaEnd, arrayLenBytes)
|
||||
dataAreaEnd := add(dataAreaEnd, 0x20)
|
||||
|
||||
// Write contents of <order.makerAssetData>
|
||||
for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {
|
||||
mstore(dataAreaEnd, mload(sourceOffset))
|
||||
dataAreaEnd := add(dataAreaEnd, 0x20)
|
||||
sourceOffset := add(sourceOffset, 0x20)
|
||||
}
|
||||
|
||||
// Write offset to <order.takerAssetData>
|
||||
mstore(add(dataAreaStart, mul(11, 0x20)), sub(dataAreaEnd, dataAreaStart))
|
||||
|
||||
// Calculate length of <order.takerAssetData>
|
||||
sourceOffset := mload(add(order, 0x160)) // takerAssetData
|
||||
arrayLenBytes := mload(sourceOffset)
|
||||
sourceOffset := add(sourceOffset, 0x20)
|
||||
arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)
|
||||
|
||||
// Write length of <order.takerAssetData>
|
||||
mstore(dataAreaEnd, arrayLenBytes)
|
||||
dataAreaEnd := add(dataAreaEnd, 0x20)
|
||||
|
||||
// Write contents of <order.takerAssetData>
|
||||
for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {
|
||||
mstore(dataAreaEnd, mload(sourceOffset))
|
||||
dataAreaEnd := add(dataAreaEnd, 0x20)
|
||||
sourceOffset := add(sourceOffset, 0x20)
|
||||
}
|
||||
|
||||
/////// Write takerAssetFillAmount ///////
|
||||
mstore(paramsAreaOffset, takerAssetFillAmount)
|
||||
paramsAreaOffset := add(paramsAreaOffset, 0x20)
|
||||
|
||||
/////// Write signature ///////
|
||||
// Write offset to paramsArea
|
||||
mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart))
|
||||
|
||||
// Calculate length of signature
|
||||
sourceOffset := signature
|
||||
arrayLenBytes := mload(sourceOffset)
|
||||
sourceOffset := add(sourceOffset, 0x20)
|
||||
arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20)
|
||||
|
||||
// Write length of signature
|
||||
mstore(dataAreaEnd, arrayLenBytes)
|
||||
dataAreaEnd := add(dataAreaEnd, 0x20)
|
||||
|
||||
// Write contents of signature
|
||||
for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} {
|
||||
mstore(dataAreaEnd, mload(sourceOffset))
|
||||
dataAreaEnd := add(dataAreaEnd, 0x20)
|
||||
sourceOffset := add(sourceOffset, 0x20)
|
||||
}
|
||||
|
||||
// Set length of calldata
|
||||
mstore(fillOrderCalldata, sub(dataAreaEnd, add(fillOrderCalldata, 0x20)))
|
||||
|
||||
// Increment free memory pointer
|
||||
mstore(0x40, dataAreaEnd)
|
||||
}
|
||||
|
||||
return fillOrderCalldata;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import "../src/LibEIP712ExchangeDomain.sol";
|
||||
import "../src/LibMath.sol";
|
||||
import "../src/LibOrder.sol";
|
||||
import "../src/LibFillResults.sol";
|
||||
import "../src/LibAbiEncoder.sol";
|
||||
|
||||
|
||||
// solhint-disable no-empty-blocks
|
||||
@@ -31,31 +30,13 @@ contract TestLibs is
|
||||
LibEIP712ExchangeDomain,
|
||||
LibMath,
|
||||
LibOrder,
|
||||
LibFillResults,
|
||||
LibAbiEncoder
|
||||
LibFillResults
|
||||
{
|
||||
constructor (uint256 chainId)
|
||||
public
|
||||
LibEIP712ExchangeDomain(chainId, address(0))
|
||||
{}
|
||||
|
||||
function abiEncodeFillOrder(
|
||||
Order memory order,
|
||||
uint256 takerAssetFillAmount,
|
||||
bytes memory signature
|
||||
)
|
||||
public
|
||||
pure
|
||||
returns (bytes memory fillOrderCalldata)
|
||||
{
|
||||
fillOrderCalldata = _abiEncodeFillOrder(
|
||||
order,
|
||||
takerAssetFillAmount,
|
||||
signature
|
||||
);
|
||||
return fillOrderCalldata;
|
||||
}
|
||||
|
||||
function getPartialAmountFloor(
|
||||
uint256 numerator,
|
||||
uint256 denominator,
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./generated-artifacts/@(LibAbiEncoder|LibAssetProxyErrors|LibConstants|LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibs).json",
|
||||
"abis": "./generated-artifacts/@(LibAssetProxyErrors|LibConstants|LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibs).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as LibAbiEncoder from '../generated-artifacts/LibAbiEncoder.json';
|
||||
import * as LibConstants from '../generated-artifacts/LibConstants.json';
|
||||
import * as LibEIP712ExchangeDomain from '../generated-artifacts/LibEIP712ExchangeDomain.json';
|
||||
import * as LibFillResults from '../generated-artifacts/LibFillResults.json';
|
||||
@@ -14,7 +13,6 @@ import * as LibOrder from '../generated-artifacts/LibOrder.json';
|
||||
import * as LibZeroExTransaction from '../generated-artifacts/LibZeroExTransaction.json';
|
||||
import * as TestLibs from '../generated-artifacts/TestLibs.json';
|
||||
export const artifacts = {
|
||||
LibAbiEncoder: LibAbiEncoder as ContractArtifact,
|
||||
LibConstants: LibConstants as ContractArtifact,
|
||||
LibFillResults: LibFillResults as ContractArtifact,
|
||||
LibMath: LibMath as ContractArtifact,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../generated-wrappers/lib_abi_encoder';
|
||||
export * from '../generated-wrappers/lib_constants';
|
||||
export * from '../generated-wrappers/lib_e_i_p712_exchange_domain';
|
||||
export * from '../generated-wrappers/lib_fill_results';
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||
"files": [
|
||||
"generated-artifacts/LibAbiEncoder.json",
|
||||
"generated-artifacts/LibConstants.json",
|
||||
"generated-artifacts/LibEIP712ExchangeDomain.json",
|
||||
"generated-artifacts/LibFillResults.json",
|
||||
|
||||
@@ -33,7 +33,7 @@ contract MixinWrapperFunctions is
|
||||
ReentrancyGuard,
|
||||
LibMath,
|
||||
LibFillResults,
|
||||
LibAbiEncoder,
|
||||
LibExchangeSelectors,
|
||||
MExchangeCore,
|
||||
MWrapperFunctions,
|
||||
MExchangeRichErrors
|
||||
|
||||
@@ -431,8 +431,6 @@ export class FillOrderCombinatorialUtils {
|
||||
lazyStore,
|
||||
fillRevertReasonIfExists,
|
||||
);
|
||||
|
||||
await this._abiEncodeFillOrderAndAssertOutcomeAsync(signedOrder, takerAssetFillAmount);
|
||||
}
|
||||
private async _fillOrderAndAssertOutcomeAsync(
|
||||
signedOrder: SignedOrder,
|
||||
@@ -609,19 +607,6 @@ export class FillOrderCombinatorialUtils {
|
||||
'ZRXAssetBalanceOfFeeRecipient',
|
||||
);
|
||||
}
|
||||
private async _abiEncodeFillOrderAndAssertOutcomeAsync(
|
||||
signedOrder: SignedOrder,
|
||||
takerAssetFillAmount: BigNumber,
|
||||
): Promise<void> {
|
||||
const params = orderUtils.createFill(signedOrder, takerAssetFillAmount);
|
||||
const abiDataEncodedByContract = await this.testLibsContract.abiEncodeFillOrder.callAsync(
|
||||
params.order,
|
||||
params.takerAssetFillAmount,
|
||||
params.signature,
|
||||
);
|
||||
const paramsDecodedByClient = this.exchangeWrapper.abiDecodeFillOrder(abiDataEncodedByContract);
|
||||
expect(paramsDecodedByClient).to.be.deep.equal(params, 'ABIEncodedFillOrderData');
|
||||
}
|
||||
private async _getTakerAssetFillAmountAsync(
|
||||
signedOrder: SignedOrder,
|
||||
takerAssetFillAmountScenario: TakerAssetFillAmountScenario,
|
||||
|
||||
Reference in New Issue
Block a user