forwarder rich errors second pass

This commit is contained in:
Michael Zhu 2019-08-07 17:06:19 -07:00
parent 5879aeac52
commit c9f0c46017
6 changed files with 98 additions and 72 deletions

View File

@ -19,10 +19,12 @@
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "@0x/contracts-erc721/contracts/src/interfaces/IERC721Token.sol";
import "./libs/LibConstants.sol";
import "./libs/LibForwarderRichErrors.sol";
import "./interfaces/IAssets.sol";
@ -63,10 +65,9 @@ contract MixinAssets is
// For now we only care about ERC20, since percentage fees on ERC721 tokens are invalid.
if (proxyId == ERC20_DATA_ID) {
address proxyAddress = EXCHANGE.getAssetProxy(ERC20_DATA_ID);
require(
proxyAddress != address(0),
"UNREGISTERED_ASSET_PROXY"
);
if (proxyAddress == address(0)) {
LibRichErrors._rrevert(LibForwarderRichErrors.UnregisteredAssetProxyError());
}
IERC20Token assetToken = IERC20Token(assetData.readAddress(16));
if (assetToken.allowance(address(this), proxyAddress) != MAX_UINT) {
assetToken.approve(proxyAddress, MAX_UINT);
@ -90,7 +91,9 @@ contract MixinAssets is
} else if (proxyId == ERC721_DATA_ID) {
_transferERC721Token(assetData, amount);
} else {
revert("UNSUPPORTED_ASSET_PROXY");
LibRichErrors._rrevert(LibForwarderRichErrors.UnsupportedAssetProxyError(
proxyId
));
}
}
@ -113,10 +116,9 @@ contract MixinAssets is
msg.sender,
amount
));
require(
success,
"TRANSFER_FAILED"
);
if (!success) {
LibRichErrors._rrevert(LibForwarderRichErrors.TransferFailedError());
}
// Check return data.
// If there is no return data, we assume the token incorrectly
@ -134,10 +136,9 @@ contract MixinAssets is
}
}
}
require(
success,
"TRANSFER_FAILED"
);
if (!success) {
LibRichErrors._rrevert(LibForwarderRichErrors.TransferFailedError());
}
}
/// @dev Decodes ERC721 assetData and transfers given amount to sender.
@ -149,10 +150,11 @@ contract MixinAssets is
)
internal
{
require(
amount == 1,
"INVALID_AMOUNT"
);
if (amount != 1) {
LibRichErrors._rrevert(LibForwarderRichErrors.InvalidErc721AmountError(
amount
));
}
// Decode asset data.
address token = assetData.readAddress(16);
uint256 tokenId = assetData.readUint256(36);

View File

@ -19,11 +19,12 @@
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "./libs/LibConstants.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.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/contracts/src/interfaces/IExchange.sol";
import "./libs/LibForwarderRichErrors.sol";
contract MixinExchangeWrapper is
@ -98,10 +99,12 @@ contract MixinExchangeWrapper is
uint256 ordersLength = orders.length;
for (uint256 i = 0; i != ordersLength; i++) {
require(
orders[i].makerAssetData.equals(orders[0].makerAssetData),
"MAKER_ASSET_MISMATCH"
);
if (!orders[i].makerAssetData.equals(orders[0].makerAssetData)) {
LibRichErrors._rrevert(LibForwarderRichErrors.MakerAssetMismatchError(
orders[0].makerAssetData,
orders[i].makerAssetData
));
}
// The remaining amount of WETH to sell
uint256 remainingTakerAssetFillAmount = _safeSub(
@ -189,10 +192,12 @@ contract MixinExchangeWrapper is
{
uint256 ordersLength = orders.length;
for (uint256 i = 0; i != ordersLength; i++) {
require(
orders[i].makerAssetData.equals(orders[0].makerAssetData),
"MAKER_ASSET_MISMATCH"
);
if (!orders[i].makerAssetData.equals(orders[0].makerAssetData)) {
LibRichErrors._rrevert(LibForwarderRichErrors.MakerAssetMismatchError(
orders[0].makerAssetData,
orders[i].makerAssetData
));
}
// Calculate the remaining amount of takerAsset to sell
uint256 remainingTakerAssetFillAmount = _getPartialAmountCeil(

View File

@ -20,10 +20,12 @@ pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.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 "./libs/LibConstants.sol";
import "./libs/LibForwarderRichErrors.sol";
import "./interfaces/IAssets.sol";
import "./interfaces/IForwarderCore.sol";
import "./MixinAssets.sol";
@ -48,10 +50,9 @@ contract MixinForwarderCore is
public
{
address proxyAddress = EXCHANGE.getAssetProxy(ERC20_DATA_ID);
require(
proxyAddress != address(0),
"UNREGISTERED_ASSET_PROXY"
);
if (proxyAddress == address(0)) {
LibRichErrors._rrevert(LibForwarderRichErrors.UnregisteredAssetProxyError());
}
ETHER_TOKEN.approve(proxyAddress, MAX_UINT);
}

View File

@ -18,8 +18,10 @@
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
import "./libs/LibConstants.sol";
import "./libs/LibForwarderRichErrors.sol";
contract MixinWeth is
@ -31,20 +33,20 @@ contract MixinWeth is
external
payable
{
require(
msg.sender == address(ETHER_TOKEN),
"DEFAULT_FUNCTION_WETH_CONTRACT_ONLY"
);
if (msg.sender != address(ETHER_TOKEN)) {
LibRichErrors._rrevert(LibForwarderRichErrors.DefaultFunctionWethContractOnlyError(
msg.sender
));
}
}
/// @dev Converts message call's ETH value into WETH.
function _convertEthToWeth()
internal
{
require(
msg.value > 0,
"INVALID_MSG_VALUE"
);
if (msg.value <= 0) {
LibRichErrors._rrevert(LibForwarderRichErrors.InvalidMsgValueError());
}
ETHER_TOKEN.deposit.value(msg.value)();
}
@ -61,16 +63,19 @@ contract MixinWeth is
internal
{
// Ensure feePercentage is less than 5%.
require(
feePercentage <= MAX_FEE_PERCENTAGE,
"FEE_PERCENTAGE_TOO_LARGE"
);
if (feePercentage > MAX_FEE_PERCENTAGE) {
LibRichErrors._rrevert(LibForwarderRichErrors.FeePercentageTooLargeError(
feePercentage
));
}
// Ensure that no extra WETH owned by this contract has been sold.
require(
wethSold <= msg.value,
"OVERSOLD_WETH"
);
if (wethSold > msg.value) {
LibRichErrors._rrevert(LibForwarderRichErrors.OversoldWethError(
wethSold,
msg.value
));
}
// Calculate amount of WETH that hasn't been sold.
uint256 wethRemaining = _safeSub(msg.value, wethSold);
@ -83,10 +88,12 @@ contract MixinWeth is
);
// Ensure fee is less than amount of WETH remaining.
require(
ethFee <= wethRemaining,
"INSUFFICIENT_ETH_REMAINING"
);
if (ethFee > wethRemaining) {
LibRichErrors._rrevert(LibForwarderRichErrors.InsufficientEthRemainingError(
ethFee,
wethRemaining
));
}
// Do nothing if no WETH remaining
if (wethRemaining > 0) {

View File

@ -1,10 +0,0 @@
pragma solidity ^0.5.9;
contract IForwarderRichErrors {
enum AssetProxyErrorCodes {
UNREGISTERED_ASSET_PROXY,
UNSUPPORTED_ASSET_PROXY
}
}

View File

@ -19,15 +19,21 @@
pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "./interfaces/IExchangeRichErrors.sol";
library LibExchangeRichErrors {
library LibForwarderRichErrors {
// bytes4(keccak256("AssetProxyError(bytes4)"))
bytes4 internal constant ASEST_PROXY_ERROR_SELECTOR =
0xaa3ff166;
// bytes4(keccak256("UnregisteredAssetProxyError()"))
bytes4 internal constant UNREGISTERED_ASSET_PROXY_ERROR_SELECTOR =
0xf3b96b8d;
// bytes4(keccak256("UnregisteredAssetProxyError()"))
bytes internal constant UNREGISTERED_ASSET_PROXY_ERROR =
hex"f3b96b8d";
// bytes4(keccak256("UnsupportedAssetProxyError(bytes4)"))
bytes4 internal constant UNSUPPORTED_ASSET_PROXY_ERROR_SELECTOR =
0x7996a271;
// bytes4(keccak256("CompleteFillFailedError(uint256,uint256)"))
bytes4 internal constant COMPLETE_FILL_FAILED_ERROR_SELECTOR =
@ -53,6 +59,10 @@ library LibExchangeRichErrors {
bytes4 internal constant TRANSFER_FAILED_ERROR_SELECTOR =
0x570f1df4;
// bytes4(keccak256("TransferFailedError()"))
bytes internal constant TRANSFER_FAILED_ERROR =
hex"570f1df4";
// bytes4(keccak256("DefaultFunctionWethContractOnlyError(address)"))
bytes4 internal constant DEFAULT_FUNCTION_WETH_CONTRACT_ONLY_ERROR_SELECTOR =
0x08b18698;
@ -61,13 +71,24 @@ library LibExchangeRichErrors {
bytes4 internal constant INVALID_MSG_VALUE_ERROR_SELECTOR =
0xb0658a43;
// bytes4(keccak256("InvalidMsgValueError()"))
bytes internal constant INVALID_MSG_VALUE_ERROR =
hex"b0658a43";
// bytes4(keccak256("InvalidErc721AmountError(uint256)"))
bytes4 internal constant INVALID_ERC721_AMOUNT_ERROR_SELECTOR =
0x27ed87bf;
// solhint-disable func-name-mixedcase
function AssetProxyError(
IForwarderRichErrors.AssetProxyErrorCodes errorCode,
function UnregisteredAssetProxyError()
internal
pure
returns (bytes memory)
{
return UNREGISTERED_ASSET_PROXY_ERROR;
}
function UnsupportedAssetProxyError(
bytes4 proxyId
)
internal
@ -75,7 +96,7 @@ library LibExchangeRichErrors {
returns (bytes memory)
{
return abi.encodeWithSelector(
ASSET_PROXY_ERROR_SELECTOR,
UNSUPPORTED_ASSET_PROXY_ERROR_SELECTOR,
proxyId
);
}
@ -158,7 +179,7 @@ library LibExchangeRichErrors {
pure
returns (bytes memory)
{
return TRANSFER_FAILED_ERROR_SELECTOR;
return TRANSFER_FAILED_ERROR;
}
function DefaultFunctionWethContractOnlyError(
@ -179,7 +200,7 @@ library LibExchangeRichErrors {
pure
returns (bytes memory)
{
return INVALID_MSG_VALUE_ERROR_SELECTOR;
return INVALID_MSG_VALUE_ERROR;
}
function InvalidErc721AmountError(