Compare commits

...

19 Commits

Author SHA1 Message Date
Michael Zhu
4ae56d5876 Assembly optimizations in LibERC721Order 2022-01-19 21:31:25 -08:00
Michael Zhu
fd5d549c43 Add taker callback 2022-01-19 21:31:25 -08:00
Michael Zhu
180110de50 Add IERC721OrdersFeature to IZeroEx 2022-01-19 21:31:25 -08:00
Michael Zhu
d186cddc29 Cancel using just the order nonce 2022-01-19 21:31:25 -08:00
Michael Zhu
fbabd2f264 Add presign support for ERC721 orders 2022-01-19 21:31:25 -08:00
Michael Zhu
35f375a525 Add comments 2022-01-19 21:31:25 -08:00
Michael Zhu
29892db0fd add rich errors for ERC721OrdersFeature 2022-01-19 21:31:25 -08:00
Michael Zhu
2cbb107380 Use SafeMath where necessary 2022-01-19 21:31:25 -08:00
Michael Zhu
599d590fbc Implement matching functions 2022-01-19 21:31:25 -08:00
Michael Zhu
9651b41264 Add missing @return comments 2022-01-19 21:31:25 -08:00
Michael Zhu
b6f118ef32 left/right orders -> sell/buy orders 2022-01-19 21:31:25 -08:00
Michael Zhu
2cc11c87d1 Implement batchBuyERC721s 2022-01-19 21:31:25 -08:00
Michael Zhu
7fa2eb4c2a implement onERC721Received 2022-01-19 21:31:25 -08:00
Michael Zhu
35d839c651 Add isValidERC721OrderSignature to interface 2022-01-19 21:31:25 -08:00
Michael Zhu
a009779a88 Implement basic functionality for ERC721 orders (buy, sell, cancel, etc) 2022-01-19 21:31:25 -08:00
Michael Zhu
9aa7945bc4 Storage lib for ERC721 orders feature 2022-01-19 21:31:25 -08:00
Michael Zhu
e7d198ef16 Add ERC721OrdersFeature interface 2022-01-19 21:31:25 -08:00
Michael Zhu
4e7e6eb634 Add ERC721 interface to vendor/ 2022-01-19 21:31:25 -08:00
Michael Zhu
f745023625 add LibERC721Order.sol 2022-01-19 21:31:25 -08:00
21 changed files with 2343 additions and 27 deletions

View File

@@ -34,6 +34,7 @@ import "./features/interfaces/IBatchFillNativeOrdersFeature.sol";
import "./features/interfaces/IMultiplexFeature.sol";
import "./features/interfaces/IOtcOrdersFeature.sol";
import "./features/interfaces/IFundRecoveryFeature.sol";
import "./features/interfaces/IERC721OrdersFeature.sol";
/// @dev Interface for a fully featured Exchange Proxy.
@@ -50,7 +51,8 @@ interface IZeroEx is
IBatchFillNativeOrdersFeature,
IMultiplexFeature,
IOtcOrdersFeature,
IFundRecoveryFeature
IFundRecoveryFeature,
IERC721OrdersFeature
{
// solhint-disable state-visibility

View File

@@ -0,0 +1,200 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
library LibERC721OrdersRichErrors {
// solhint-disable func-name-mixedcase
function OverspentEthError(
uint256 ethSpent,
uint256 msgValue
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("OverspentEthError(uint256,uint256)")),
ethSpent,
msgValue
);
}
function InsufficientEthError(
uint256 ethAvailable,
uint256 orderAmount
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("InsufficientEthError(uint256,uint256)")),
ethAvailable,
orderAmount
);
}
function ERC721TokenMismatchError(
address token1,
address token2
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("ERC721TokenMismatchError(address,address)")),
token1,
token2
);
}
function ERC20TokenMismatchError(
address token1,
address token2
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("ERC20TokenMismatchError(address,address)")),
token1,
token2
);
}
function NegativeSpreadError(
uint256 sellOrderAmount,
uint256 buyOrderAmount
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("NegativeSpreadError(uint256,uint256)")),
sellOrderAmount,
buyOrderAmount
);
}
function SellOrderFeesExceedSpreadError(
uint256 sellOrderFees,
uint256 spread
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("SellOrderFeesExceedSpreadError(uint256,uint256)")),
sellOrderFees,
spread
);
}
function OnlyTakerError(
address sender,
address taker
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("OnlyTakerError(address,address)")),
sender,
taker
);
}
function InvalidSignerError(
address maker,
address signer
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("InvalidSignerError(address,address)")),
maker,
signer
);
}
function OrderNotFillableError(
address maker,
uint256 nonce,
uint8 orderStatus
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("OrderNotFillableError(address,uint256,uint8)")),
maker,
nonce,
orderStatus
);
}
function ERC721TokenIdMismatchError(
uint256 tokenId,
uint256 orderTokenId
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("ERC721TokenIdMismatchError(uint256,uint256)")),
tokenId,
orderTokenId
);
}
function PropertyValidationFailedError(
address propertyValidator,
address erc721Token,
uint256 erc721TokenId,
bytes memory propertyData,
bytes memory errorData
)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
bytes4(keccak256("PropertyValidationFailedError(address,address,uint256,bytes,bytes)")),
propertyValidator,
erc721Token,
erc721TokenId,
propertyData,
errorData
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -311,7 +311,7 @@ contract OtcOrdersFeature is
// Unwrap WETH
WETH.withdraw(order.makerAmount);
// Transfer ETH to taker
_transferEth(taker, order.makerAmount);
_transferEth(payable(taker), order.makerAmount);
emit OtcOrderFilled(
orderInfo.orderHash,
@@ -622,16 +622,4 @@ contract OtcOrdersFeature is
[txOrigin]
[nonceBucket];
}
function _transferEth(address recipient, uint256 amount)
private
{
// Transfer ETH to recipient
(bool success, bytes memory revertData) =
recipient.call{value: amount}("");
// Revert on failure
if (!success) {
revertData.rrevert();
}
}
}

View File

@@ -0,0 +1,283 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "../libs/LibERC721Order.sol";
import "../libs/LibSignature.sol";
import "../../vendor/IERC721Token.sol";
/// @dev Feature for interacting with ERC721 orders.
interface IERC721OrdersFeature {
/// @dev Emitted whenever an `ERC721Order` is filled.
/// @param direction Whether the order is selling or
/// buying the ERC721 token.
/// @param erc20Token The address of the ERC20 token.
/// @param erc20TokenAmount The amount of ERC20 token
/// to sell or buy.
/// @param erc721Token The address of the ERC721 token.
/// @param erc721TokenId The ID of the ERC721 asset.
/// @param maker The maker of the order.
/// @param taker The taker of the order.
/// @param nonce The unique maker nonce in the order.
event ERC721OrderFilled(
LibERC721Order.TradeDirection direction,
IERC20TokenV06 erc20Token,
uint256 erc20TokenAmount,
IERC721Token erc721Token,
uint256 erc721TokenId,
address maker,
address taker,
uint256 nonce
);
/// @dev Emitted whenever two `ERC721Order`s are matched.
/// @param erc20Token The ERC20 token of the two orders.
/// If `sellOrder.erc20Token` is the native token
/// and `buyOrder.erc20Token` is the wrapped native
/// token, this will be `NATIVE_TOKEN_ADDRESS`.
/// @param erc721Token The address of the ERC721 token.
/// @param erc721TokenId The ID of the ERC721 asset.
/// @param sellOrderMaker The maker of the sell order.
/// @param buyOrderMaker The maker of the buy order.
/// @param sellOrderNonce The nonce of the sell order.
/// @param buyOrderNonce The nonce of the buy order.
/// @param matcher The address that called the `matchERC721Orders`
/// or `batchMatchERC721Orders` function.
/// @param profit The amount of profit earned by the matcher,
/// denominated in `erc20Token`.
event ERC721OrdersMatched(
IERC20TokenV06 erc20Token,
IERC721Token erc721Token,
uint256 erc20TokenAmount,
uint256 erc721TokenId,
address sellOrderMaker,
address buyOrderMaker,
uint256 sellOrderNonce,
uint256 buyOrderNonce,
address matcher,
uint256 profit
);
/// @dev Emitted whenever an `ERC721Order` is cancelled.
/// @param maker The maker of the order.
/// @param nonce The nonce of the order that was cancelled.
event ERC721OrderCancelled(
address maker,
uint256 nonce
);
/// @dev Sells an ERC721 asset to fill the given order.
/// @param order The ERC721 order.
/// @param signature The order signature from the maker.
/// @param erc721TokenId The ID of the ERC721 asset being
/// sold. If the given order specifies properties,
/// the asset must satisfy those properties. Otherwise,
/// it must equal the tokenId in the order.
/// @param unwrapNativeToken If this parameter is true and the
/// ERC20 token of the order is e.g. WETH, unwraps the
/// token before transferring it to the taker.
/// @param callbackData If this parameter is non-zero, invokes
/// `zeroExERC721OrderCallback` on `msg.sender` after
/// the ERC20 tokens have been transferred to `msg.sender`
/// but before transferring the ERC721 asset to the buyer.
function sellERC721(
LibERC721Order.ERC721Order calldata order,
LibSignature.Signature calldata signature,
uint256 erc721TokenId,
bool unwrapNativeToken,
bytes calldata callbackData
)
external;
/// @dev Buys an ERC721 asset by filling the given order.
/// @param order The ERC721 order.
/// @param signature The order signature.
/// @param callbackData If this parameter is non-zero, invokes
/// `zeroExERC721OrderCallback` on `msg.sender` after
/// the ERC721 asset has been transferred to `msg.sender`
/// but before transferring the ERC20 tokens to the seller.
/// Native tokens acquired during the callback can be used
/// to fill the order.
function buyERC721(
LibERC721Order.ERC721Order calldata order,
LibSignature.Signature calldata signature,
bytes calldata callbackData
)
external
payable;
/// @dev Cancel a single ERC721 order by its nonce. The caller
/// should be the maker of the order. Silently succeeds if
/// an order with the same nonce has already been filled or
/// cancelled.
/// @param orderNonce The order nonce.
function cancelERC721Order(uint256 orderNonce)
external;
/// @dev Buys multiple ERC721 assets by filling the
/// given orders.
/// @param orders The ERC721 orders.
/// @param signatures The order signatures.
/// @param revertIfIncomplete If true, reverts if this
/// function fails to fill any individual order.
/// @return successes An array of booleans corresponding to whether
/// each order in `orders` was successfully filled.
function batchBuyERC721s(
LibERC721Order.ERC721Order[] calldata orders,
LibSignature.Signature[] calldata signatures,
bool revertIfIncomplete
)
external
payable
returns (bool[] memory successes);
/// @dev Matches a pair of complementary orders that have
/// a non-negative spread. Each order is filled at
/// their respective price, and the matcher receives
/// a profit denominated in the ERC20 token.
/// @param sellOrder Order selling an ERC721 asset.
/// @param buyOrder Order buying an ERC721 asset.
/// @param sellOrderSignature Signature for the sell order.
/// @param buyOrderSignature Signature for the buy order.
/// @return profit The amount of profit earned by the caller
/// of this function (denominated in the ERC20 token
/// of the matched orders).
function matchERC721Orders(
LibERC721Order.ERC721Order calldata sellOrder,
LibERC721Order.ERC721Order calldata buyOrder,
LibSignature.Signature calldata sellOrderSignature,
LibSignature.Signature calldata buyOrderSignature
)
external
returns (uint256 profit);
/// @dev Matches pairs of complementary orders that have
/// non-negative spreads. Each order is filled at
/// their respective price, and the matcher receives
/// a profit denominated in the ERC20 token.
/// @param sellOrders Orders selling ERC721 assets.
/// @param buyOrders Orders buying ERC721 assets.
/// @param sellOrderSignatures Signatures for the sell orders.
/// @param buyOrderSignatures Signatures for the buy orders.
/// @return profits The amount of profit earned by the caller
/// of this function for each pair of matched orders
/// (denominated in the ERC20 token of the order pair).
/// @return successes An array of booleans corresponding to
/// whether each pair of orders was successfully matched.
function batchMatchERC721Orders(
LibERC721Order.ERC721Order[] calldata sellOrders,
LibERC721Order.ERC721Order[] calldata buyOrders,
LibSignature.Signature[] calldata sellOrderSignatures,
LibSignature.Signature[] calldata buyOrderSignatures
)
external
returns (uint256[] memory profits, bool[] memory successes);
/// @dev Callback for the ERC721 `safeTransferFrom` function.
/// This callback can be used to sell an ERC721 asset if
/// a valid ERC721 order, signature and `unwrapNativeToken`
/// are encoded in `data`. This allows takers to sell their
/// ERC721 asset without first calling `setApprovalForAll`.
/// @param operator The address which called `safeTransferFrom`.
/// @param from The address which previously owned the token.
/// @param tokenId The ID of the asset being transferred.
/// @param data Additional data with no specified format. If a
/// valid ERC721 order, signature and `unwrapNativeToken`
/// are encoded in `data`, this function will try to fill
/// the order using the received asset.
/// @return success The selector of this function (0x150b7a02),
/// indicating that the callback succeeded.
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
)
external
returns (bytes4 success);
/// @dev Approves an ERC721 order hash on-chain. After pre-signing
/// a hash, the `PRESIGNED` signature type will become valid
/// for that order and maker.
/// @param orderHash An ERC721 order hash.
function preSignERC721Order(bytes32 orderHash)
external;
/// @dev Checks whether the given signature is valid for the
/// the given ERC721 order. Reverts if not.
/// @param order The ERC721 order.
/// @param signature The signature to validate.
function validateERC721OrderSignature(
LibERC721Order.ERC721Order calldata order,
LibSignature.Signature calldata signature
)
external
view;
/// @dev If the given order is buying an ERC721 asset, checks
/// whether or not the given token ID satisfies the required
/// properties specified in the order. If the order does not
/// specify any properties, this function instead checks
/// whether the given token ID matches the ID in the order.
/// Reverts if any checks fail, or if the order is selling
/// an ERC721 asset.
/// @param order The ERC721 order.
/// @param erc721TokenId The ID of the ERC721 asset.
function validateERC721OrderProperties(
LibERC721Order.ERC721Order calldata order,
uint256 erc721TokenId
)
external
view;
/// @dev Get the current status of an ERC721 order.
/// @param order The ERC721 order.
/// @return status The status of the order.
function getERC721OrderStatus(LibERC721Order.ERC721Order calldata order)
external
view
returns (LibERC721Order.OrderStatus status);
/// @dev Get the canonical hash of an ERC721 order.
/// @param order The ERC721 order.
/// @return orderHash The order hash.
function getERC721OrderHash(LibERC721Order.ERC721Order calldata order)
external
view
returns (bytes32 orderHash);
/// @dev Get the order status bit vector for the given
/// maker address and nonce range.
/// @param maker The maker of the order.
/// @param nonceRange Order status bit vectors are indexed
/// by maker address and the upper 248 bits of the
/// order nonce. We define `nonceRange` to be these
/// 248 bits.
/// @return bitVector The order status bit vector for the
/// given maker and nonce range.
function getERC721OrderStatusBitVector(address maker, uint248 nonceRange)
external
view
returns (uint256 bitVector);
}

View File

@@ -0,0 +1,269 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../../vendor/IERC721Token.sol";
import "../../vendor/IPropertyValidator.sol";
/// @dev A library for common ERC721 order operations.
library LibERC721Order {
using LibSafeMathV06 for uint256;
using LibRichErrorsV06 for bytes;
enum OrderStatus {
INVALID,
FILLABLE,
UNFILLABLE,
EXPIRED
}
enum TradeDirection {
SELL_721,
BUY_721
}
struct Property {
IPropertyValidator propertyValidator;
bytes propertyData;
}
struct Fee {
address recipient;
uint256 amount;
bytes feeData;
}
/// @dev An ERC721<>ERC20 limit order.
struct ERC721Order {
TradeDirection direction;
IERC20TokenV06 erc20Token;
uint256 erc20TokenAmount;
IERC721Token erc721Token;
uint256 erc721TokenId;
Property[] erc721TokenProperties;
Fee[] fees;
address maker;
address taker;
uint256 expiry;
uint256 nonce;
}
// The type hash for ERC721 orders, which is:
// keccak256(abi.encodePacked(
// "ERC721Order(",
// "uint8 direction,",
// "address erc20Token,",
// "uint256 erc20TokenAmount,",
// "address erc721Token,",
// "uint256 erc721TokenId,",
// "Property[] erc721TokenProperties,",
// "Fee[] fees,",
// "address maker,",
// "address taker,",
// "uint256 expiry,",
// "uint256 nonce",
// ")",
// "Fee(",
// "address recipient,",
// "uint256 amount,",
// "bytes feeData",
// ")",
// "Property(",
// "address propertyValidator,",
// "bytes propertyData",
// ")"
// ))
uint256 private constant _ERC_721_ORDER_TYPEHASH =
0x7af652c2504c5c7d806f4f25edc3762dd8478099f694981f8802db656a9ba9d8;
// keccak256(abi.encodePacked(
// "Fee(",
// "address recipient,",
// "uint256 amount,",
// "bytes feeData",
// ")"
// ))
uint256 private constant _FEE_TYPEHASH =
0xe68c29f1b4e8cce0bbcac76eb1334bdc1dc1f293a517c90e9e532340e1e94115;
// keccak256(abi.encodePacked(
// "Property(",
// "address propertyValidator,",
// "bytes propertyData",
// ")"
// ))
uint256 private constant _PROPERTY_TYPEHASH =
0x6292cf854241cb36887e639065eca63b3af9f7f70270cebeda4c29b6d3bc65e8;
// keccak256("");
bytes32 private constant _EMPTY_ARRAY_KECCAK256 =
0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// keccak256(abi.encodePacked(keccak256(abi.encode(
// _PROPERTY_TYPEHASH,
// address(0),
// keccak256("")
// ))));
bytes32 private constant _NULL_PROPERTY_STRUCT_HASH =
0x720ee400a9024f6a49768142c339bf09d2dd9056ab52d20fbe7165faba6e142d;
uint256 private constant ADDRESS_MASK = (1 << 160) - 1;
/// @dev Get the struct hash of an ERC721 order.
/// @param order The ERC721 order.
/// @return structHash The struct hash of the order.
function getERC721OrderStructHash(ERC721Order memory order)
internal
pure
returns (bytes32 structHash)
{
// We give `order.erc721TokenProperties.length == 0` and
// `order.erc721TokenProperties.length == 1` special treatment
// because we expect these to be the most common.
bytes32 propertiesHash;
if (order.erc721TokenProperties.length == 0) {
propertiesHash = _EMPTY_ARRAY_KECCAK256;
} else if (order.erc721TokenProperties.length == 1) {
Property memory property = order
.erc721TokenProperties[0];
if (
address(property.propertyValidator) == address(0) &&
property.propertyData.length == 0
) {
propertiesHash = _NULL_PROPERTY_STRUCT_HASH;
} else {
// propertiesHash = keccak256(abi.encodePacked(keccak256(abi.encode(
// _PROPERTY_TYPEHASH,
// order.erc721TokenProperties[0].propertyValidator,
// keccak256(order.erc721TokenProperties[0].propertyData)
// ))));
bytes memory data = property.propertyData;
assembly {
// dataHash = keccak256(property.propertyData)
let dataHash := keccak256(add(data, 32), mload(data))
// Load free memory pointer
let mem := mload(64)
mstore(mem, _PROPERTY_TYPEHASH)
// property.propertyValidator
mstore(add(mem, 32), and(ADDRESS_MASK, mload(property)))
// keccak256(property.propertyData)
mstore(add(mem, 64), dataHash)
mstore(mem, keccak256(mem, 96))
propertiesHash := keccak256(mem, 32)
}
}
} else {
bytes32[] memory propertyStructHashArray = new bytes32[](
order.erc721TokenProperties.length
);
for (uint256 i = 0; i < order.erc721TokenProperties.length; i++) {
propertyStructHashArray[i] = keccak256(abi.encode(
_PROPERTY_TYPEHASH,
order.erc721TokenProperties[i].propertyValidator,
keccak256(order.erc721TokenProperties[i].propertyData)
));
}
propertiesHash = keccak256(abi.encodePacked(propertyStructHashArray));
}
// We give `order.fees.length == 0` and
// `order.fees.length == 1` special treatment
// because we expect these to be the most common.
bytes32 feesHash;
if (order.fees.length == 0) {
feesHash = _EMPTY_ARRAY_KECCAK256;
} else if (order.fees.length == 1) {
// feesHash = keccak256(abi.encodePacked(keccak256(abi.encode(
// _FEE_TYPEHASH,
// order.fees[0].recipient,
// order.fees[0].amount,
// keccak256(order.fees[0].feeData)
// ))));
Fee memory fee = order.fees[0];
bytes memory data = fee.feeData;
assembly {
// dataHash = keccak256(fee.feeData)
let dataHash := keccak256(add(data, 32), mload(data))
// Load free memory pointer
let mem := mload(64)
mstore(mem, _FEE_TYPEHASH)
// fee.recipient
mstore(add(mem, 32), and(ADDRESS_MASK, mload(fee)))
// fee.amount
mstore(add(mem, 64), mload(add(fee, 32)))
// keccak256(fee.feeData)
mstore(add(mem, 96), dataHash)
mstore(mem, keccak256(mem, 128))
feesHash := keccak256(mem, 32)
}
} else {
bytes32[] memory feeStructHashArray = new bytes32[](order.fees.length);
for (uint256 i = 0; i < order.fees.length; i++) {
feeStructHashArray[i] = keccak256(abi.encode(
_FEE_TYPEHASH,
order.fees[i].recipient,
order.fees[i].amount,
keccak256(order.fees[i].feeData)
));
}
feesHash = keccak256(abi.encodePacked(feeStructHashArray));
}
// Hash in place, equivalent to:
// return keccak256(abi.encode(
// _ERC_721_ORDER_TYPEHASH,
// order.direction,
// order.erc20Token,
// order.erc20TokenAmount,
// order.erc721Token,
// order.erc721TokenId,
// propertiesHash,
// feesHash,
// order.maker,
// order.taker,
// order.expiry,
// order.nonce
// ));
assembly {
let pos1 := sub(order, 32)
let pos2 := add(order, 160)
let pos3 := add(order, 192)
let temp1 := mload(pos1)
let temp2 := mload(pos2)
let temp3 := mload(pos3)
mstore(pos1, _ERC_721_ORDER_TYPEHASH)
mstore(pos2, propertiesHash)
mstore(pos3, feesHash)
structHash := keccak256(pos1, 384)
mstore(pos1, temp1)
mstore(pos2, temp2)
mstore(pos3, temp3)
}
return structHash;
}
}

View File

@@ -44,7 +44,8 @@ library LibSignature {
ILLEGAL,
INVALID,
EIP712,
ETHSIGN
ETHSIGN,
PRESIGNED
}
/// @dev Encoded EC signature.
@@ -146,6 +147,15 @@ library LibSignature {
).rrevert();
}
// If a feature supports pre-signing, it wouldn't use
// `getSignerOfHash` on a pre-signed order.
if (signature.signatureType == SignatureType.PRESIGNED) {
LibSignatureRichErrors.SignatureValidationError(
LibSignatureRichErrors.SignatureValidationErrorCodes.UNSUPPORTED,
hash
).rrevert();
}
// Solidity should check that the signature type is within enum range for us
// when abi-decoding.
}

View File

@@ -622,15 +622,6 @@ contract MultiplexFeature is
_executeBatchSell(batchSellParams).boughtAmount;
}
// Transfers some amount of ETH to the given recipient and
// reverts if the transfer fails.
function _transferEth(address payable recipient, uint256 amount)
private
{
(bool success,) = recipient.call{value: amount}("");
require(success, "MultiplexFeature::_transferEth/TRANSFER_FAILED");
}
// This function computes the "target" address of hop index `i` within
// a multi-hop sell.
// If `i == 0`, the target is the address which should hold the input

View File

@@ -62,6 +62,18 @@ abstract contract FixinCommon {
_implementation = address(this);
}
/// @dev RichError equivalent of `require`.
/// @param condition If `condition` is false, this function will revert.
/// @param errorData ABI-encoded error data.
function rrequire(bool condition, bytes memory errorData)
internal
pure
{
if (!condition) {
errorData.rrevert();
}
}
/// @dev Registers a function implemented by this feature at `_implementation`.
/// Can and should only be called within a `migrate()`.
/// @param selector The selector of the function whose implementation

View File

@@ -0,0 +1,74 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 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.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../vendor/IERC721Token.sol";
/// @dev Helpers for moving ERC721 assets around.
abstract contract FixinERC721Spender {
// Mask of the lower 20 bytes of a bytes32.
uint256 constant private ADDRESS_MASK = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff;
/// @dev Transfers an ERC721 asset from `owner` to `to`.
/// @param token The address of the ERC721 token contract.
/// @param owner The owner of the asset.
/// @param to The recipient of the asset.
/// @param tokenId The token ID of the asset to transfer.
function _transferERC721AssetFrom(
IERC721Token token,
address owner,
address to,
uint256 tokenId
)
internal
{
require(address(token) != address(this), "FixinERC721Spender/CANNOT_INVOKE_SELF");
assembly {
let ptr := mload(0x40) // free memory pointer
// selector for transferFrom(address,address,uint256)
mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), and(owner, ADDRESS_MASK))
mstore(add(ptr, 0x24), and(to, ADDRESS_MASK))
mstore(add(ptr, 0x44), tokenId)
let success := call(
gas(),
and(token, ADDRESS_MASK),
0,
ptr,
0x64,
ptr,
32
)
let rdsize := returndatasize()
if iszero(success) {
returndatacopy(ptr, 0, rdsize)
revert(ptr, rdsize)
}
}
}
}

View File

@@ -20,7 +20,7 @@
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
@@ -141,6 +141,18 @@ abstract contract FixinTokenSpender {
}
}
/// @dev Transfers some amount of ETH to the given recipient and
/// reverts if the transfer fails.
/// @param recipient The recipient of the ETH.
/// @param amount The amount of ETH to transfer.
function _transferEth(address payable recipient, uint256 amount)
internal
{
(bool success,) = recipient.call{value: amount}("");
require(success, "FixinTokenSpender::_transferEth/TRANSFER_FAILED");
}
/// @dev Gets the maximum amount of an ERC20 token `token` that can be
/// pulled from `owner` by this address.
/// @param token The token to spend.

View File

@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 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.6.5;
pragma experimental ABIEncoderV2;
import "./LibStorage.sol";
/// @dev Storage helpers for `ERC721OrdersFeature`.
library LibERC721OrdersStorage {
/// @dev Storage bucket for this feature.
struct Storage {
// maker => nonce range => order status bit vector
mapping(address => mapping(uint248 => uint256)) orderStatusByMaker;
// order hash => maker => isSigned
mapping(bytes32 => mapping(address => bool)) preSigned;
}
/// @dev Get the storage bucket for this contract.
function getStorage() internal pure returns (Storage storage stor) {
uint256 storageSlot = LibStorage.getStorageSlot(
LibStorage.StorageId.ERC721Orders
);
// Dip into assembly to change the slot pointed to by the local
// variable `stor`.
// See https://solidity.readthedocs.io/en/v0.6.8/assembly.html?highlight=slot#access-to-external-variables-functions-and-libraries
assembly { stor_slot := storageSlot }
}
}

View File

@@ -39,7 +39,8 @@ library LibStorage {
MetaTransactions,
ReentrancyGuard,
NativeOrders,
OtcOrders
OtcOrders,
ERC721Orders
}
/// @dev Get the storage slot given a storage ID. We assign unique, well-spaced

View File

@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
pragma experimental ABIEncoderV2;
interface IERC721OrderCallback {
/// @dev A taker callback function invoked in the ERC721Feature between
/// the maker -> taker transfer and the taker -> maker transfer.
/// @param callbackData Arbitrary data used by this callback.
/// @return success The selector of this function (0x6d46db51),
/// indicating that the callback succeeded.
function zeroExERC721OrderCallback(bytes calldata callbackData)
external
returns (bytes4 success);
}

View File

@@ -0,0 +1,159 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
interface IERC721Token {
/// @dev This emits when ownership of any NFT changes by any mechanism.
/// This event emits when NFTs are created (`from` == 0) and destroyed
/// (`to` == 0). Exception: during contract creation, any number of NFTs
/// may be created and assigned without emitting Transfer. At the time of
/// any transfer, the approved address for that NFT (if any) is reset to none.
event Transfer(
address indexed _from,
address indexed _to,
uint256 indexed _tokenId
);
/// @dev This emits when the approved address for an NFT is changed or
/// reaffirmed. The zero address indicates there is no approved address.
/// When a Transfer event emits, this also indicates that the approved
/// address for that NFT (if any) is reset to none.
event Approval(
address indexed _owner,
address indexed _approved,
uint256 indexed _tokenId
);
/// @dev This emits when an operator is enabled or disabled for an owner.
/// The operator can manage all NFTs of the owner.
event ApprovalForAll(
address indexed _owner,
address indexed _operator,
bool _approved
);
/// @notice Transfers the ownership of an NFT from one address to another address
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// perator, or the approved address for this NFT. Throws if `_from` is
/// not the current owner. Throws if `_to` is the zero address. Throws if
/// `_tokenId` is not a valid NFT. When transfer is complete, this function
/// checks if `_to` is a smart contract (code size > 0). If so, it calls
/// `onERC721Received` on `_to` and throws if the return value is not
/// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
/// @param _data Additional data with no specified format, sent in call to `_to`
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId,
bytes calldata _data
)
external;
/// @notice Transfers the ownership of an NFT from one address to another address
/// @dev This works identically to the other function with an extra data parameter,
/// except this function just sets data to "".
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId
)
external;
/// @notice Change or reaffirm the approved address for an NFT
/// @dev The zero address indicates there is no approved address.
/// Throws unless `msg.sender` is the current NFT owner, or an authorized
/// operator of the current owner.
/// @param _approved The new approved NFT controller
/// @param _tokenId The NFT to approve
function approve(address _approved, uint256 _tokenId)
external;
/// @notice Enable or disable approval for a third party ("operator") to manage
/// all of `msg.sender`'s assets
/// @dev Emits the ApprovalForAll event. The contract MUST allow
/// multiple operators per owner.
/// @param _operator Address to add to the set of authorized operators
/// @param _approved True if the operator is approved, false to revoke approval
function setApprovalForAll(address _operator, bool _approved)
external;
/// @notice Count all NFTs assigned to an owner
/// @dev NFTs assigned to the zero address are considered invalid, and this
/// function throws for queries about the zero address.
/// @param _owner An address for whom to query the balance
/// @return The number of NFTs owned by `_owner`, possibly zero
function balanceOf(address _owner)
external
view
returns (uint256);
/// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
/// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
/// THEY MAY BE PERMANENTLY LOST
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// operator, or the approved address for this NFT. Throws if `_from` is
/// not the current owner. Throws if `_to` is the zero address. Throws if
/// `_tokenId` is not a valid NFT.
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
function transferFrom(
address _from,
address _to,
uint256 _tokenId
)
external;
/// @notice Find the owner of an NFT
/// @dev NFTs assigned to zero address are considered invalid, and queries
/// about them do throw.
/// @param _tokenId The identifier for an NFT
/// @return The address of the owner of the NFT
function ownerOf(uint256 _tokenId)
external
view
returns (address);
/// @notice Get the approved address for a single NFT
/// @dev Throws if `_tokenId` is not a valid NFT.
/// @param _tokenId The NFT to find the approved address for
/// @return The approved address for this NFT, or the zero address if there is none
function getApproved(uint256 _tokenId)
external
view
returns (address);
/// @notice Query if an address is an authorized operator for another address
/// @param _owner The address that owns the NFTs
/// @param _operator The address that acts on behalf of the owner
/// @return True if `_operator` is an approved operator for `_owner`, false otherwise
function isApprovedForAll(address _owner, address _operator)
external
view
returns (bool);
}

View File

@@ -0,0 +1,44 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
pragma experimental ABIEncoderV2;
interface IFeeRecipient {
/// @dev A callback function invoked in the ERC721Feature for each ERC721
/// order fee that get paid. Integrators can make use of this callback
/// to implement arbitrary fee-handling logic, e.g. splitting the fee
/// between multiple parties.
/// @param tokenAddress The address of the token in which the received fee is
/// denominated. `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` indicates
/// that the fee was paid in the native token (e.g. ETH).
/// @param amount The amount of the given token received.
/// @param feeData Arbitrary data encoded in the `Fee` used by this callback.
/// @return success The selector of this function (0x0190805e),
/// indicating that the callback succeeded.
function receiveFeeCallback(
address tokenAddress,
uint256 amount,
bytes calldata feeData
)
external
returns (bytes4 success);
}

View File

@@ -0,0 +1,38 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 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.6.5;
pragma experimental ABIEncoderV2;
interface IPropertyValidator {
/// @dev Checks that the given ERC721/ERC1155 asset satisfies the properties encoded in `propertyData`.
/// Should revert if the asset does not satisfy the specified properties.
/// @param tokenAddress The ERC721/ERC1155 token contract address.
/// @param tokenId The ERC721/ERC1155 tokenId of the asset to check.
/// @param propertyData Encoded properties or auxiliary data needed to perform the check.
function validateProperty(
address tokenAddress,
uint256 tokenId,
bytes calldata propertyData
)
external
view;
}

View File

@@ -43,7 +43,7 @@
"config": {
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IERC721OrderCallback|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibERC721Order|LibERC721OrdersRichErrors|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
},
"repository": {
"type": "git",

View File

@@ -11,11 +11,13 @@ import * as BootstrapFeature from '../test/generated-artifacts/BootstrapFeature.
import * as BridgeAdapter from '../test/generated-artifacts/BridgeAdapter.json';
import * as BridgeProtocols from '../test/generated-artifacts/BridgeProtocols.json';
import * as CurveLiquidityProvider from '../test/generated-artifacts/CurveLiquidityProvider.json';
import * as ERC721OrdersFeature from '../test/generated-artifacts/ERC721OrdersFeature.json';
import * as FeeCollector from '../test/generated-artifacts/FeeCollector.json';
import * as FeeCollectorController from '../test/generated-artifacts/FeeCollectorController.json';
import * as FillQuoteTransformer from '../test/generated-artifacts/FillQuoteTransformer.json';
import * as FixinCommon from '../test/generated-artifacts/FixinCommon.json';
import * as FixinEIP712 from '../test/generated-artifacts/FixinEIP712.json';
import * as FixinERC721Spender from '../test/generated-artifacts/FixinERC721Spender.json';
import * as FixinProtocolFees from '../test/generated-artifacts/FixinProtocolFees.json';
import * as FixinReentrancyGuard from '../test/generated-artifacts/FixinReentrancyGuard.json';
import * as FixinTokenSpender from '../test/generated-artifacts/FixinTokenSpender.json';
@@ -27,7 +29,11 @@ import * as IBootstrapFeature from '../test/generated-artifacts/IBootstrapFeatur
import * as IBridgeAdapter from '../test/generated-artifacts/IBridgeAdapter.json';
import * as IERC20Bridge from '../test/generated-artifacts/IERC20Bridge.json';
import * as IERC20Transformer from '../test/generated-artifacts/IERC20Transformer.json';
import * as IERC721OrderCallback from '../test/generated-artifacts/IERC721OrderCallback.json';
import * as IERC721OrdersFeature from '../test/generated-artifacts/IERC721OrdersFeature.json';
import * as IERC721Token from '../test/generated-artifacts/IERC721Token.json';
import * as IFeature from '../test/generated-artifacts/IFeature.json';
import * as IFeeRecipient from '../test/generated-artifacts/IFeeRecipient.json';
import * as IFlashWallet from '../test/generated-artifacts/IFlashWallet.json';
import * as IFundRecoveryFeature from '../test/generated-artifacts/IFundRecoveryFeature.json';
import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json';
@@ -42,6 +48,7 @@ import * as InitialMigration from '../test/generated-artifacts/InitialMigration.
import * as IOtcOrdersFeature from '../test/generated-artifacts/IOtcOrdersFeature.json';
import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json';
import * as IPancakeSwapFeature from '../test/generated-artifacts/IPancakeSwapFeature.json';
import * as IPropertyValidator from '../test/generated-artifacts/IPropertyValidator.json';
import * as ISimpleFunctionRegistryFeature from '../test/generated-artifacts/ISimpleFunctionRegistryFeature.json';
import * as IStaking from '../test/generated-artifacts/IStaking.json';
import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json';
@@ -55,6 +62,9 @@ import * as IZeroEx from '../test/generated-artifacts/IZeroEx.json';
import * as LibBootstrap from '../test/generated-artifacts/LibBootstrap.json';
import * as LibCommonRichErrors from '../test/generated-artifacts/LibCommonRichErrors.json';
import * as LibERC20Transformer from '../test/generated-artifacts/LibERC20Transformer.json';
import * as LibERC721Order from '../test/generated-artifacts/LibERC721Order.json';
import * as LibERC721OrdersRichErrors from '../test/generated-artifacts/LibERC721OrdersRichErrors.json';
import * as LibERC721OrdersStorage from '../test/generated-artifacts/LibERC721OrdersStorage.json';
import * as LibFeeCollector from '../test/generated-artifacts/LibFeeCollector.json';
import * as LibLiquidityProviderRichErrors from '../test/generated-artifacts/LibLiquidityProviderRichErrors.json';
import * as LibMetaTransactionsRichErrors from '../test/generated-artifacts/LibMetaTransactionsRichErrors.json';
@@ -181,6 +191,7 @@ export const artifacts = {
ZeroEx: ZeroEx as ContractArtifact,
ZeroExOptimized: ZeroExOptimized as ContractArtifact,
LibCommonRichErrors: LibCommonRichErrors as ContractArtifact,
LibERC721OrdersRichErrors: LibERC721OrdersRichErrors as ContractArtifact,
LibLiquidityProviderRichErrors: LibLiquidityProviderRichErrors as ContractArtifact,
LibMetaTransactionsRichErrors: LibMetaTransactionsRichErrors as ContractArtifact,
LibNativeOrdersRichErrors: LibNativeOrdersRichErrors as ContractArtifact,
@@ -201,6 +212,7 @@ export const artifacts = {
TransformerDeployer: TransformerDeployer as ContractArtifact,
BatchFillNativeOrdersFeature: BatchFillNativeOrdersFeature as ContractArtifact,
BootstrapFeature: BootstrapFeature as ContractArtifact,
ERC721OrdersFeature: ERC721OrdersFeature as ContractArtifact,
FundRecoveryFeature: FundRecoveryFeature as ContractArtifact,
LiquidityProviderFeature: LiquidityProviderFeature as ContractArtifact,
MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact,
@@ -214,6 +226,7 @@ export const artifacts = {
UniswapV3Feature: UniswapV3Feature as ContractArtifact,
IBatchFillNativeOrdersFeature: IBatchFillNativeOrdersFeature as ContractArtifact,
IBootstrapFeature: IBootstrapFeature as ContractArtifact,
IERC721OrdersFeature: IERC721OrdersFeature as ContractArtifact,
IFeature: IFeature as ContractArtifact,
IFundRecoveryFeature: IFundRecoveryFeature as ContractArtifact,
ILiquidityProviderFeature: ILiquidityProviderFeature as ContractArtifact,
@@ -229,6 +242,7 @@ export const artifacts = {
ITransformERC20Feature: ITransformERC20Feature as ContractArtifact,
IUniswapFeature: IUniswapFeature as ContractArtifact,
IUniswapV3Feature: IUniswapV3Feature as ContractArtifact,
LibERC721Order: LibERC721Order as ContractArtifact,
LibNativeOrder: LibNativeOrder as ContractArtifact,
LibSignature: LibSignature as ContractArtifact,
MultiplexFeature: MultiplexFeature as ContractArtifact,
@@ -244,6 +258,7 @@ export const artifacts = {
NativeOrdersSettlement: NativeOrdersSettlement as ContractArtifact,
FixinCommon: FixinCommon as ContractArtifact,
FixinEIP712: FixinEIP712 as ContractArtifact,
FixinERC721Spender: FixinERC721Spender as ContractArtifact,
FixinProtocolFees: FixinProtocolFees as ContractArtifact,
FixinReentrancyGuard: FixinReentrancyGuard as ContractArtifact,
FixinTokenSpender: FixinTokenSpender as ContractArtifact,
@@ -253,6 +268,7 @@ export const artifacts = {
InitialMigration: InitialMigration as ContractArtifact,
LibBootstrap: LibBootstrap as ContractArtifact,
LibMigrate: LibMigrate as ContractArtifact,
LibERC721OrdersStorage: LibERC721OrdersStorage as ContractArtifact,
LibMetaTransactionsStorage: LibMetaTransactionsStorage as ContractArtifact,
LibNativeOrdersStorage: LibNativeOrdersStorage as ContractArtifact,
LibOtcOrdersStorage: LibOtcOrdersStorage as ContractArtifact,
@@ -298,8 +314,12 @@ export const artifacts = {
MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
MixinUniswapV3: MixinUniswapV3 as ContractArtifact,
MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
IERC721OrderCallback: IERC721OrderCallback as ContractArtifact,
IERC721Token: IERC721Token as ContractArtifact,
IFeeRecipient: IFeeRecipient as ContractArtifact,
ILiquidityProvider: ILiquidityProvider as ContractArtifact,
IMooniswapPool: IMooniswapPool as ContractArtifact,
IPropertyValidator: IPropertyValidator as ContractArtifact,
IUniswapV2Pair: IUniswapV2Pair as ContractArtifact,
IUniswapV3Pool: IUniswapV3Pool as ContractArtifact,
IERC20Bridge: IERC20Bridge as ContractArtifact,

View File

@@ -9,11 +9,13 @@ export * from '../test/generated-wrappers/bootstrap_feature';
export * from '../test/generated-wrappers/bridge_adapter';
export * from '../test/generated-wrappers/bridge_protocols';
export * from '../test/generated-wrappers/curve_liquidity_provider';
export * from '../test/generated-wrappers/erc721_orders_feature';
export * from '../test/generated-wrappers/fee_collector';
export * from '../test/generated-wrappers/fee_collector_controller';
export * from '../test/generated-wrappers/fill_quote_transformer';
export * from '../test/generated-wrappers/fixin_common';
export * from '../test/generated-wrappers/fixin_e_i_p712';
export * from '../test/generated-wrappers/fixin_erc721_spender';
export * from '../test/generated-wrappers/fixin_protocol_fees';
export * from '../test/generated-wrappers/fixin_reentrancy_guard';
export * from '../test/generated-wrappers/fixin_token_spender';
@@ -25,7 +27,11 @@ export * from '../test/generated-wrappers/i_bootstrap_feature';
export * from '../test/generated-wrappers/i_bridge_adapter';
export * from '../test/generated-wrappers/i_erc20_bridge';
export * from '../test/generated-wrappers/i_erc20_transformer';
export * from '../test/generated-wrappers/i_erc721_order_callback';
export * from '../test/generated-wrappers/i_erc721_orders_feature';
export * from '../test/generated-wrappers/i_erc721_token';
export * from '../test/generated-wrappers/i_feature';
export * from '../test/generated-wrappers/i_fee_recipient';
export * from '../test/generated-wrappers/i_flash_wallet';
export * from '../test/generated-wrappers/i_fund_recovery_feature';
export * from '../test/generated-wrappers/i_liquidity_provider';
@@ -39,6 +45,7 @@ export * from '../test/generated-wrappers/i_native_orders_feature';
export * from '../test/generated-wrappers/i_otc_orders_feature';
export * from '../test/generated-wrappers/i_ownable_feature';
export * from '../test/generated-wrappers/i_pancake_swap_feature';
export * from '../test/generated-wrappers/i_property_validator';
export * from '../test/generated-wrappers/i_simple_function_registry_feature';
export * from '../test/generated-wrappers/i_staking';
export * from '../test/generated-wrappers/i_test_simple_function_registry_feature';
@@ -53,6 +60,9 @@ export * from '../test/generated-wrappers/initial_migration';
export * from '../test/generated-wrappers/lib_bootstrap';
export * from '../test/generated-wrappers/lib_common_rich_errors';
export * from '../test/generated-wrappers/lib_erc20_transformer';
export * from '../test/generated-wrappers/lib_erc721_order';
export * from '../test/generated-wrappers/lib_erc721_orders_rich_errors';
export * from '../test/generated-wrappers/lib_erc721_orders_storage';
export * from '../test/generated-wrappers/lib_fee_collector';
export * from '../test/generated-wrappers/lib_liquidity_provider_rich_errors';
export * from '../test/generated-wrappers/lib_meta_transactions_rich_errors';

View File

@@ -42,11 +42,13 @@
"test/generated-artifacts/BridgeAdapter.json",
"test/generated-artifacts/BridgeProtocols.json",
"test/generated-artifacts/CurveLiquidityProvider.json",
"test/generated-artifacts/ERC721OrdersFeature.json",
"test/generated-artifacts/FeeCollector.json",
"test/generated-artifacts/FeeCollectorController.json",
"test/generated-artifacts/FillQuoteTransformer.json",
"test/generated-artifacts/FixinCommon.json",
"test/generated-artifacts/FixinEIP712.json",
"test/generated-artifacts/FixinERC721Spender.json",
"test/generated-artifacts/FixinProtocolFees.json",
"test/generated-artifacts/FixinReentrancyGuard.json",
"test/generated-artifacts/FixinTokenSpender.json",
@@ -58,7 +60,11 @@
"test/generated-artifacts/IBridgeAdapter.json",
"test/generated-artifacts/IERC20Bridge.json",
"test/generated-artifacts/IERC20Transformer.json",
"test/generated-artifacts/IERC721OrderCallback.json",
"test/generated-artifacts/IERC721OrdersFeature.json",
"test/generated-artifacts/IERC721Token.json",
"test/generated-artifacts/IFeature.json",
"test/generated-artifacts/IFeeRecipient.json",
"test/generated-artifacts/IFlashWallet.json",
"test/generated-artifacts/IFundRecoveryFeature.json",
"test/generated-artifacts/ILiquidityProvider.json",
@@ -72,6 +78,7 @@
"test/generated-artifacts/IOtcOrdersFeature.json",
"test/generated-artifacts/IOwnableFeature.json",
"test/generated-artifacts/IPancakeSwapFeature.json",
"test/generated-artifacts/IPropertyValidator.json",
"test/generated-artifacts/ISimpleFunctionRegistryFeature.json",
"test/generated-artifacts/IStaking.json",
"test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
@@ -86,6 +93,9 @@
"test/generated-artifacts/LibBootstrap.json",
"test/generated-artifacts/LibCommonRichErrors.json",
"test/generated-artifacts/LibERC20Transformer.json",
"test/generated-artifacts/LibERC721Order.json",
"test/generated-artifacts/LibERC721OrdersRichErrors.json",
"test/generated-artifacts/LibERC721OrdersStorage.json",
"test/generated-artifacts/LibFeeCollector.json",
"test/generated-artifacts/LibLiquidityProviderRichErrors.json",
"test/generated-artifacts/LibMetaTransactionsRichErrors.json",