* `@0x/contracts-zero-ex`: Add `CurveLiquidityProvider` and misc refactors * `@0x/asset-swapper`: Fix compiler error on `ILiquidityProvider` call `@0x/protocol-utils`: Add VIP utils. * `@0x/contracts-zero-ex`: Rebase and fix comiler warnings * `@0x/asset-swapper`: Clean up curve VIP integration * `@0x/protocol-utils`: Update changelog * `@0x/protocol-utils`: tsdoc new functions Co-authored-by: Lawrence Forman <me@merklejerk.com>
101 lines
2.9 KiB
Solidity
101 lines
2.9 KiB
Solidity
// 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 "./TestMintableERC20Token.sol";
|
|
|
|
contract TestCurve {
|
|
|
|
event CurveCalled(
|
|
uint256 value,
|
|
bytes4 selector,
|
|
int128 fromCoinIdx,
|
|
int128 toCoinIdx,
|
|
uint256 sellAmount,
|
|
uint256 minBuyAmount
|
|
);
|
|
|
|
// The lower 16 bits of the selector are reserved for flags.
|
|
bytes4 public constant BASE_SWAP_SELECTOR = 0x12340000;
|
|
bytes4 public constant RETURN_BOUGHT_AMOUNT_SELECTOR_FLAG = 0x00000001;
|
|
|
|
int128 public constant SELL_TOKEN_COIN_IDX = 0;
|
|
int128 public constant BUY_TOKEN_COIN_IDX = 1;
|
|
int128 public constant ETH_COIN_IDX = 2;
|
|
|
|
uint256 public buyAmount;
|
|
IERC20TokenV06 public sellToken;
|
|
TestMintableERC20Token public buyToken;
|
|
|
|
constructor(
|
|
IERC20TokenV06 sellToken_,
|
|
TestMintableERC20Token buyToken_,
|
|
uint256 buyAmount_
|
|
)
|
|
public
|
|
payable
|
|
{
|
|
sellToken = sellToken_;
|
|
buyToken = buyToken_;
|
|
buyAmount = buyAmount_;
|
|
}
|
|
|
|
receive() external payable {}
|
|
|
|
fallback() external payable {
|
|
bytes4 selector = abi.decode(msg.data, (bytes4));
|
|
bool shouldReturnBoughtAmount =
|
|
(selector & RETURN_BOUGHT_AMOUNT_SELECTOR_FLAG) != 0x0;
|
|
bytes4 baseSelector = selector & 0xffff0000;
|
|
require(baseSelector == BASE_SWAP_SELECTOR, "TestCurve/REVERT");
|
|
(
|
|
int128 fromCoinIdx,
|
|
int128 toCoinIdx,
|
|
uint256 sellAmount,
|
|
uint256 minBuyAmount
|
|
) = abi.decode(msg.data[4:], (int128, int128, uint256, uint256));
|
|
if (fromCoinIdx == SELL_TOKEN_COIN_IDX) {
|
|
sellToken.transferFrom(msg.sender, address(this), sellAmount);
|
|
}
|
|
if (toCoinIdx == BUY_TOKEN_COIN_IDX) {
|
|
buyToken.mint(msg.sender, buyAmount);
|
|
} else if (toCoinIdx == ETH_COIN_IDX) {
|
|
msg.sender.transfer(buyAmount);
|
|
}
|
|
emit CurveCalled(
|
|
msg.value,
|
|
selector,
|
|
fromCoinIdx,
|
|
toCoinIdx,
|
|
sellAmount,
|
|
minBuyAmount
|
|
);
|
|
if (shouldReturnBoughtAmount) {
|
|
assembly {
|
|
mstore(0, sload(buyAmount_slot))
|
|
return(0, 32)
|
|
}
|
|
}
|
|
assembly { return(0, 0) }
|
|
}
|
|
}
|