Files
protocol/contracts/zero-ex/contracts/test/TestCurve.sol
Lawrence Forman a74a3450eb @0x/contracts-zero-ex: Add CurveLiquidityProvider and misc refactors (#127)
* `@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>
2021-02-11 19:13:17 -05:00

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) }
}
}