Files
protocol/contracts/zero-ex/contracts/test/TestFillQuoteTransformerExchange.sol
Lawrence Forman 48e7a391c8 Deploy new FQT (#28)
* `@0x/contracts-zero-ex`: Change `ProtocolFeeUnfunded` event in FQT
`@0x/contracts-zero-ex`: Use new PLP interface in FQT.

* `@0x/contract-addresses`: Deploy new FQT

* fix failing FQT test

Co-authored-by: Lawrence Forman <me@merklejerk.com>
2020-11-02 21:47:25 -05:00

148 lines
4.8 KiB
Solidity

/*
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/LibBytesV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../src/vendor/v3/IExchange.sol";
import "./TestMintableERC20Token.sol";
contract TestFillQuoteTransformerExchange {
struct FillBehavior {
// How much of the order is filled, in taker asset amount.
uint256 filledTakerAssetAmount;
// Scaling for maker assets minted, in 1e18.
uint256 makerAssetMintRatio;
}
bytes32 public constant EIP712_EXCHANGE_DOMAIN_HASH = 0xaa81d881b1adbbf115e15b849cb9cdc643cad3c6a90f30eb505954af943247e6;
uint256 private constant PROTOCOL_FEE_MULTIPLIER = 1337;
using LibSafeMathV06 for uint256;
function fillOrder(
IExchange.Order calldata order,
uint256 takerAssetFillAmount,
bytes calldata signature
)
external
payable
returns (IExchange.FillResults memory fillResults)
{
require(
signature.length != 0,
"TestFillQuoteTransformerExchange/INVALID_SIGNATURE"
);
// The signature is the ABI-encoded FillBehavior data.
FillBehavior memory behavior = abi.decode(signature, (FillBehavior));
uint256 protocolFee = PROTOCOL_FEE_MULTIPLIER * tx.gasprice;
require(
msg.value == protocolFee,
"TestFillQuoteTransformerExchange/INSUFFICIENT_PROTOCOL_FEE"
);
// Return excess protocol fee.
msg.sender.transfer(msg.value - protocolFee);
// Take taker tokens.
TestMintableERC20Token takerToken = _getTokenFromAssetData(order.takerAssetData);
takerAssetFillAmount = LibSafeMathV06.min256(
order.takerAssetAmount.safeSub(behavior.filledTakerAssetAmount),
takerAssetFillAmount
);
require(
takerToken.getSpendableAmount(msg.sender, address(this)) >= takerAssetFillAmount,
"TestFillQuoteTransformerExchange/INSUFFICIENT_TAKER_FUNDS"
);
takerToken.transferFrom(msg.sender, order.makerAddress, takerAssetFillAmount);
// Mint maker tokens.
uint256 makerAssetFilledAmount = LibMathV06.getPartialAmountFloor(
takerAssetFillAmount,
order.takerAssetAmount,
order.makerAssetAmount
);
TestMintableERC20Token makerToken = _getTokenFromAssetData(order.makerAssetData);
makerToken.mint(
msg.sender,
LibMathV06.getPartialAmountFloor(
behavior.makerAssetMintRatio,
1e18,
makerAssetFilledAmount
)
);
// Take taker fee.
TestMintableERC20Token takerFeeToken = _getTokenFromAssetData(order.takerFeeAssetData);
uint256 takerFee = LibMathV06.getPartialAmountFloor(
takerAssetFillAmount,
order.takerAssetAmount,
order.takerFee
);
require(
takerFeeToken.getSpendableAmount(msg.sender, address(this)) >= takerFee,
"TestFillQuoteTransformerExchange/INSUFFICIENT_TAKER_FEE_FUNDS"
);
takerFeeToken.transferFrom(msg.sender, order.feeRecipientAddress, takerFee);
fillResults.makerAssetFilledAmount = makerAssetFilledAmount;
fillResults.takerAssetFilledAmount = takerAssetFillAmount;
fillResults.makerFeePaid = uint256(-1);
fillResults.takerFeePaid = takerFee;
fillResults.protocolFeePaid = protocolFee;
}
function encodeBehaviorData(FillBehavior calldata behavior)
external
pure
returns (bytes memory encoded)
{
return abi.encode(behavior);
}
function protocolFeeMultiplier()
external
pure
returns (uint256)
{
return PROTOCOL_FEE_MULTIPLIER;
}
function getAssetProxy(bytes4)
external
view
returns (address)
{
return address(this);
}
function _getTokenFromAssetData(bytes memory assetData)
private
pure
returns (TestMintableERC20Token token)
{
return TestMintableERC20Token(LibBytesV06.readAddress(assetData, 16));
}
}