add multiplex TokenForEth functions to metatransactions
This commit is contained in:
parent
90b826da61
commit
2507028612
@ -15,6 +15,7 @@
|
||||
pragma solidity ^0.6.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
@ -92,6 +93,9 @@ contract MetaTransactionsFeature is
|
||||
")"
|
||||
);
|
||||
|
||||
/// @dev The WETH token contract.
|
||||
IEtherTokenV06 private immutable WETH;
|
||||
|
||||
/// @dev Refunds up to `msg.value` leftover ETH at the end of the call.
|
||||
modifier refundsAttachedEth() {
|
||||
_;
|
||||
@ -109,7 +113,12 @@ contract MetaTransactionsFeature is
|
||||
require(initialBalance <= address(this).balance, "MetaTransactionsFeature/ETH_LEAK");
|
||||
}
|
||||
|
||||
constructor(address zeroExAddress) public FixinCommon() FixinEIP712(zeroExAddress) {}
|
||||
constructor(
|
||||
address zeroExAddress,
|
||||
IEtherTokenV06 weth
|
||||
) public FixinCommon() FixinEIP712(zeroExAddress) {
|
||||
WETH = weth;
|
||||
}
|
||||
|
||||
/// @dev Initialize and register this feature.
|
||||
/// Should be delegatecalled by `Migrate.migrate()`.
|
||||
@ -248,8 +257,12 @@ contract MetaTransactionsFeature is
|
||||
returnResult = _executeFillRfqOrderCall(state);
|
||||
} else if (state.selector == IMultiplexFeature.multiplexBatchSellTokenForToken.selector) {
|
||||
returnResult = _executeMultiplexBatchSellTokenForTokenCall(state);
|
||||
} else if (state.selector == IMultiplexFeature.multiplexBatchSellTokenForEth.selector) {
|
||||
returnResult = _executeMultiplexBatchSellTokenForEthCall(state);
|
||||
} else if (state.selector == IMultiplexFeature.multiplexMultiHopSellTokenForToken.selector) {
|
||||
returnResult = _executeMultiplexMultiHopSellTokenForTokenCall(state);
|
||||
} else if (state.selector == IMultiplexFeature.multiplexMultiHopSellTokenForEth.selector) {
|
||||
returnResult = _executeMultiplexMultiHopSellTokenForEthCall(state);
|
||||
} else {
|
||||
LibMetaTransactionsRichErrors.MetaTransactionUnsupportedFunctionError(state.hash, state.selector).rrevert();
|
||||
}
|
||||
@ -497,6 +510,46 @@ contract MetaTransactionsFeature is
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Execute a `IMultiplexFeature.multiplexBatchSellTokenForEth()` meta-transaction
|
||||
/// call by decoding the call args and translating the call to the internal
|
||||
/// `IMultiplexFeature._multiplexBatchSellTokenForEth()` variant, where we can override the
|
||||
/// msgSender address.
|
||||
function _executeMultiplexBatchSellTokenForEthCall(ExecuteState memory state) private returns (bytes memory returnResult) {
|
||||
IERC20TokenV06 inputToken;
|
||||
IMultiplexFeature.BatchSellSubcall[] memory calls;
|
||||
uint256 sellAmount;
|
||||
uint256 minBuyAmount;
|
||||
|
||||
bytes memory args = _extractArgumentsFromCallData(state.mtx.callData);
|
||||
(inputToken, calls, sellAmount, minBuyAmount) = abi.decode(
|
||||
args,
|
||||
(IERC20TokenV06, IMultiplexFeature.BatchSellSubcall[], uint256, uint256)
|
||||
);
|
||||
|
||||
returnResult = _callSelf(
|
||||
state.hash,
|
||||
abi.encodeWithSelector(
|
||||
IMultiplexFeature._multiplexBatchSell.selector,
|
||||
IMultiplexFeature.BatchSellParams({
|
||||
inputToken: inputToken,
|
||||
outputToken: IERC20TokenV06(WETH),
|
||||
sellAmount: sellAmount,
|
||||
calls: calls,
|
||||
useSelfBalance: false,
|
||||
recipient: address(this),
|
||||
msgSender: state.mtx.signer
|
||||
}),
|
||||
minBuyAmount
|
||||
),
|
||||
state.mtx.value
|
||||
);
|
||||
|
||||
// Unwrap and transfer WETH
|
||||
uint256 boughtAmount = abi.decode(returnResult, (uint256));
|
||||
WETH.withdraw(boughtAmount);
|
||||
_transferEth(state.mtx.signer, boughtAmount);
|
||||
}
|
||||
|
||||
/// @dev Execute a `IMultiplexFeature.multiplexMultiHopSellTokenForToken()` meta-transaction
|
||||
/// call by decoding the call args and translating the call to the internal
|
||||
/// `IMultiplexFeature._multiplexMultiHopSell()` variant, where we can override the
|
||||
@ -532,6 +585,50 @@ contract MetaTransactionsFeature is
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Execute a `IMultiplexFeature.multiplexMultiHopSellTokenForEth()` meta-transaction
|
||||
/// call by decoding the call args and translating the call to the internal
|
||||
/// `IMultiplexFeature._multiplexMultiHopSellTokenForEth()` variant, where we can override the
|
||||
/// msgSender address.
|
||||
function _executeMultiplexMultiHopSellTokenForEthCall(ExecuteState memory state) private returns (bytes memory returnResult) {
|
||||
address[] memory tokens;
|
||||
IMultiplexFeature.MultiHopSellSubcall[] memory calls;
|
||||
uint256 sellAmount;
|
||||
uint256 minBuyAmount;
|
||||
|
||||
bytes memory args = _extractArgumentsFromCallData(state.mtx.callData);
|
||||
(tokens, calls, sellAmount, minBuyAmount) = abi.decode(
|
||||
args,
|
||||
(address[], IMultiplexFeature.MultiHopSellSubcall[], uint256, uint256)
|
||||
);
|
||||
|
||||
require(
|
||||
tokens[tokens.length - 1] == address(WETH),
|
||||
"MetaTransactionsFeature::multiplexMultiHopSellTokenForEth/NOT_WETH"
|
||||
);
|
||||
|
||||
returnResult = _callSelf(
|
||||
state.hash,
|
||||
abi.encodeWithSelector(
|
||||
IMultiplexFeature._multiplexMultiHopSell.selector,
|
||||
IMultiplexFeature.MultiHopSellParams({
|
||||
tokens: tokens,
|
||||
sellAmount: sellAmount,
|
||||
calls: calls,
|
||||
useSelfBalance: false,
|
||||
recipient: address(this),
|
||||
msgSender: state.mtx.signer
|
||||
}),
|
||||
minBuyAmount
|
||||
),
|
||||
state.mtx.value
|
||||
);
|
||||
|
||||
// Unwrap and transfer WETH
|
||||
uint256 boughtAmount = abi.decode(returnResult, (uint256));
|
||||
WETH.withdraw(boughtAmount);
|
||||
_transferEth(state.mtx.signer, boughtAmount);
|
||||
}
|
||||
|
||||
/// @dev Make an arbitrary internal, meta-transaction call.
|
||||
/// Warning: Do not let unadulterated `callData` into this function.
|
||||
function _callSelf(bytes32 hash, bytes memory callData, uint256 value) private returns (bytes memory returnResult) {
|
||||
|
@ -331,9 +331,7 @@ contract MultiplexFeature is
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Executes a multi-hop sell and checks that at least
|
||||
/// `minBuyAmount` of output tokens were bought. Internal
|
||||
/// variant.
|
||||
/// @dev Executes a multi-hop sell. Internal variant.
|
||||
/// @param params Multi-hop sell parameters.
|
||||
/// @param minBuyAmount The minimum amount of output tokens that
|
||||
/// must be bought for this function to not revert.
|
||||
|
Loading…
x
Reference in New Issue
Block a user