Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
125 lines (103 sloc) 4.36 KB
pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "paradigm-subcontract-sdk/contracts/SubContract.sol";
import "../installed_contracts/0xV2-contracts/contracts/protocol/Exchange/interfaces/IExchangeCore.sol";
import "../installed_contracts/0xV2-contracts/contracts/utils/LibBytes/LibBytes.sol";
contract ZeroExSubContract is SubContract {
using LibBytes for bytes;
IExchangeCore public exchange;
address public zeroExProxy;
constructor(address _exchange, address _proxy, string _makerArguments, string _takerArguments) public {
exchange = IExchangeCore(_exchange);
zeroExProxy = _proxy;
makerArguments = _makerArguments;
takerArguments = _takerArguments;
}
function participate(bytes32[] makerData, bytes32[] takerData) public returns (bool) {
address taker = address(takerData[0]);
uint takerTokenCount = uint(takerData[1]);
bytes memory makerTokenAssetData = abi.encodePacked(
makerData[10],
makerData[11][28],
makerData[11][29],
makerData[11][30],
makerData[11][31]
);
bytes memory takerTokenAssetData = abi.encodePacked(
makerData[12],
makerData[13][28],
makerData[13][29],
makerData[13][30],
makerData[13][31]
);
bytes4 ERC20bytes = bytes4(keccak256("ERC20Token(address)"));
require(makerTokenAssetData.readBytes4(0) == ERC20bytes, "Maker token asset isn't ERC20");
require(takerTokenAssetData.readBytes4(0) == ERC20bytes, "Taker token asset isn't ERC20");
ERC20 makerToken = ERC20(makerTokenAssetData.popLast20Bytes());
ERC20 takerToken = ERC20(takerTokenAssetData.popLast20Bytes());
takerToken.transferFrom(taker, this, takerTokenCount);
takerToken.approve(zeroExProxy, takerTokenCount);
LibFillResults.FillResults memory fillResult = fillOrder(makerData, takerData);
if (fillResult.makerAssetFilledAmount > 0) {
require(makerToken.transfer(taker, fillResult.makerAssetFilledAmount), "Didn't send the goods");
}
if (fillResult.takerAssetFilledAmount < takerTokenCount) {
require(takerToken.transfer(taker, takerTokenCount.sub(fillResult.takerAssetFilledAmount)), "Failed returning excess");
}
return true;
}
function isValid(bytes32[] makerData) public view returns (bool) {
LibOrder.Order memory order = getOrder(makerData);
LibOrder.OrderInfo memory info = exchange.getOrderInfo(order);
return info.orderStatus == uint8(LibOrder.OrderStatus.FILLABLE);
}
function amountRemaining(bytes32[] makerData) public view returns (uint) {
LibOrder.Order memory order = getOrder(makerData);
LibOrder.OrderInfo memory info = exchange.getOrderInfo(order);
return order.takerAssetAmount - info.orderTakerAssetFilledAmount;
}
function fillOrder(bytes32[] makerData, bytes32[] takerData) internal returns (LibFillResults.FillResults) {
LibOrder.Order memory order = getOrder(makerData);
uint take = uint(takerData[1]);
bytes memory signature = abi.encodePacked(
makerData[14],
makerData[15],
makerData[16][30],
makerData[16][31]
);
return exchange.fillOrder(
order,
take,
signature
);
}
function getOrder(bytes32[] makerData) internal returns (LibOrder.Order) {
return LibOrder.Order(
address(makerData[0]),
address(makerData[1]),
address(makerData[2]),
address(makerData[3]),
uint256(makerData[4]),
uint256(makerData[5]),
uint256(makerData[6]),
uint256(makerData[7]),
uint256(makerData[8]),
uint256(makerData[9]),
abi.encodePacked(
makerData[10],
makerData[11][28],
makerData[11][29],
makerData[11][30],
makerData[11][31]
),
abi.encodePacked(abi.encodePacked(
makerData[12],
makerData[13][28],
makerData[13][29],
makerData[13][30],
makerData[13][31]
))
);
}
}
You can’t perform that action at this time.