Files
protocol/packages/contracts/contracts/extensions/CompliantForwarder/CompliantForwarder.sol
Greg Hysen 989b5b0a98 Ran linter
2018-12-18 13:36:05 -08:00

101 lines
4.7 KiB
Solidity

/*
Copyright 2018 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.4.24;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/interfaces/IExchange.sol";
import "../../tokens/ERC721Token/IERC721Token.sol";
import "../../utils/LibBytes/LibBytes.sol";
contract CompliantForwarder {
using LibBytes for bytes;
bytes4 constant internal EXCHANGE_FILL_ORDER_SELECTOR = bytes4(keccak256("fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)"));
IExchange internal EXCHANGE;
IERC721Token internal COMPLIANCE_TOKEN;
constructor(address exchange, address complianceToken)
public
{
EXCHANGE = IExchange(exchange);
COMPLIANCE_TOKEN = IERC721Token(complianceToken);
}
function fillOrder(
uint256 salt,
address signerAddress,
bytes signedFillOrderTransaction,
bytes signature
)
public
{
// Validate `signedFillOrderTransaction`
bytes4 selector = signedFillOrderTransaction.readBytes4(0);
if (selector != EXCHANGE_FILL_ORDER_SELECTOR) {
revert("EXCHANGE_TRANSACTION_NOT_FILL_ORDER");
}
// Extract maker address from fill order transaction
// Below is the table of calldata offsets into a fillOrder transaction.
/**
### parameters
0x00 ptr<order>
0x20 takerAssetFillAmount
0x40 ptr<signature>
### order
0x60 makerAddress
0x80 takerAddress
0xa0 feeRecipientAddress
0xc0 senderAddress
0xe0 makerAssetAmount
0x100 takerAssetAmount
0x120 makerFee
0x140 takerFee
0x160 expirationTimeSeconds
0x180 salt
0x1a0 ptr<makerAssetData>
0x1c0 ptr<takerAssetData>
0x1e0 makerAssetData
* takerAssetData
* signature
------------------------------
* Context-dependent offsets; unknown at compile time.
*/
// Add 0x4 to a given offset to account for the fillOrder selector prepended to `signedFillOrderTransaction`.
// Add 0xc to the makerAddress since abi-encoded addresses are left padded with 12 bytes.
// Putting this together: makerAddress = 0x60 + 0x4 + 0xc = 0x70
address makerAddress = signedFillOrderTransaction.readAddress(0x70);
// Verify maker/taker have been verified by the compliance token.
if (COMPLIANCE_TOKEN.balanceOf(makerAddress) == 0) {
revert("MAKER_UNVERIFIED");
} else if (COMPLIANCE_TOKEN.balanceOf(signerAddress) == 0) {
revert("TAKER_UNVERIFIED");
}
// All entities are verified. Execute fillOrder.
EXCHANGE.executeTransaction(
salt,
signerAddress,
signedFillOrderTransaction,
signature
);
}
}