文件 1 的 34:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 34:AdminController.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
abstract contract AdminController is Context, Ownable {
mapping(address => bool) private _admins;
event AdminSet(address indexed account, bool indexed status);
constructor(address account) {
_setAdmin(account, true);
}
modifier onlyAdmin() {
address sender = _msgSender();
(bool isValid, string memory errorMessage) = _validateAdmin(sender);
require(isValid, errorMessage);
_;
}
modifier onlyAdminOrOwner() {
address sender = _msgSender();
(bool isValid, string memory errorMessage) = _validateAdminOrOwner(
sender
);
require(isValid, errorMessage);
_;
}
function addAdmin(address account) external onlyOwner {
_setAdmin(account, true);
}
function removeAdmin(address account) external onlyAdminOrOwner {
_setAdmin(account, false);
}
function isAdmin(address account) external view returns (bool) {
return _isAdmin(account);
}
function _setAdmin(address account, bool status) internal {
_admins[account] = status;
emit AdminSet(account, status);
}
function _isAdmin(address account) internal view returns (bool) {
return _admins[account];
}
function _isAdminOrOwner(address account) internal view returns (bool) {
return owner() == account || _isAdmin(account);
}
function _validateAdmin(address account)
internal
view
returns (bool, string memory)
{
if (!_isAdmin(account)) {
return (false, "AdminController: admin verification failed");
}
return (true, "");
}
function _validateAdminOrOwner(address account)
internal
view
returns (bool, string memory)
{
if (!_isAdminOrOwner(account)) {
return (
false,
"AdminController: admin or owner verification failed"
);
}
return (true, "");
}
}
文件 3 的 34:AssetLib.sol
pragma solidity ^0.8.0;
library AssetLib {
bytes4 public constant ETH_ASSET_CLASS = bytes4(keccak256("ETH"));
bytes4 public constant ERC20_ASSET_CLASS = bytes4(keccak256("ERC20"));
bytes4 public constant ERC721_ASSET_CLASS = bytes4(keccak256("ERC721"));
bytes4 public constant ERC1155_ASSET_CLASS = bytes4(keccak256("ERC1155"));
bytes4 public constant COLLECTION = bytes4(keccak256("COLLECTION"));
bytes32 constant ASSET_TYPE_TYPEHASH =
keccak256("AssetType(bytes4 assetClass,bytes data)");
bytes32 constant ASSET_TYPEHASH =
keccak256(
"AssetData(AssetType assetType,uint256 value)AssetType(bytes4 assetClass,bytes data)"
);
struct AssetType {
bytes4 assetClass;
bytes data;
}
struct AssetData {
AssetType assetType;
uint256 value;
}
function decodeAssetTypeData(AssetType memory assetType)
internal
pure
returns (address, uint256)
{
if (assetType.assetClass == AssetLib.ERC20_ASSET_CLASS) {
address token = abi.decode(assetType.data, (address));
return (token, 0);
} else if (
assetType.assetClass == AssetLib.ERC721_ASSET_CLASS ||
assetType.assetClass == AssetLib.ERC1155_ASSET_CLASS
) {
(address token, uint256 tokenId) = abi.decode(
assetType.data,
(address, uint256)
);
return (token, tokenId);
}
return (address(0), 0);
}
function hash(AssetType memory assetType) internal pure returns (bytes32) {
return
keccak256(
abi.encode(
ASSET_TYPE_TYPEHASH,
assetType.assetClass,
keccak256(assetType.data)
)
);
}
function hash(AssetData memory asset) internal pure returns (bytes32) {
return
keccak256(
abi.encode(ASSET_TYPEHASH, hash(asset.assetType), asset.value)
);
}
}
文件 4 的 34:BasisPointLib.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
library BasisPointLib {
using SafeMath for uint256;
uint256 constant _BPS_BASE = 10000;
function bp(uint256 value, uint256 bpValue)
internal
pure
returns (uint256)
{
return value.mul(bpValue).div(_BPS_BASE);
}
}
文件 5 的 34:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 6 的 34:ECDSA.sol
pragma solidity ^0.8.0;
import "../Strings.sol";
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 7 的 34:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 8 的 34:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 9 的 34:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 10 的 34:ERC2771Context.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
abstract contract ERC2771Context is Context {
address private _trustedForwarder;
constructor(address trustedForwarder) {
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder)
public
view
virtual
returns (bool)
{
return forwarder == _trustedForwarder;
}
function _msgSender()
internal
view
virtual
override
returns (address sender)
{
if (isTrustedForwarder(msg.sender)) {
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
function _msgData()
internal
view
virtual
override
returns (bytes calldata)
{
if (isTrustedForwarder(msg.sender)) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
}
}
}
文件 11 的 34:ERC721Holder.sol
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 12 的 34:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 13 的 34:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 14 的 34:IERC1271.sol
pragma solidity ^0.8.0;
interface IERC1271 {
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}
文件 15 的 34:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 16 的 34:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 17 的 34:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 18 的 34:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 19 的 34:ITransferProxy.sol
pragma solidity ^0.8.0;
import "../../utils/libraries/AssetLib.sol";
interface ITransferProxy {
function transfer(
AssetLib.AssetData calldata asset,
address from,
address to
) external;
}
文件 20 的 34:MarketBase.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./libraries/OrderLib.sol";
import "./libraries/OrderExtLib.sol";
import "./extensions/ERC2771Context.sol";
import "./extensions/MarketEscrow.sol";
import "./extensions/MarketTxValidatable.sol";
abstract contract MarketBase is
ERC2771Context,
ReentrancyGuard,
MarketEscrow,
MarketTxValidatable
{
using SafeMath for uint256;
constructor(
string memory name,
string memory version,
address trustedForwarder
)
EIP712(name, version)
ERC2771Context(trustedForwarder)
Ownable()
ReentrancyGuard()
AdminController(_msgSender())
{}
function createOrder(
OrderLib.OrderData memory order,
bytes memory signatureLeft,
bytes memory signatureRight
) external payable nonReentrant {
(bool isValid, string memory errorMessage) = _validateFull(
OrderLib.CREATE_ORDER_TYPE,
order,
signatureLeft,
signatureRight
);
require(isValid, errorMessage);
bytes32 orderId = OrderLib.hashKey(order);
_createDeposit(orderId, order.taker, order.takeAsset);
}
function updateOrder(
OrderLib.OrderData memory order,
bytes memory signatureLeft,
bytes memory signatureRight
) external payable nonReentrant {
(bool isValid, string memory errorMessage) = _validateFull(
OrderLib.UPDATE_ORDER_TYPE,
order,
signatureLeft,
signatureRight
);
require(isValid, errorMessage);
bytes32 orderId = OrderLib.hashKey(order);
_updateDeposit(orderId, order.taker, order.takeAsset);
}
function cancelOrder(
OrderLib.OrderData memory order,
bytes memory signatureLeft,
bytes memory signatureRight
) external nonReentrant {
bytes32 orderId = OrderLib.hashKey(order);
AssetLib.AssetData memory asset = getDeposit(orderId);
if (
asset.value != 0 &&
asset.assetType.assetClass != bytes4(0) &&
order.end < block.timestamp
) {
(bool isValid, string memory errorMessage) = _validateOrderAndSig(
OrderLib.CANCEL_ORDER_TYPE,
order,
order.taker,
signatureRight
);
require(isValid, errorMessage);
} else {
(bool isValid, string memory errorMessage) = _validateFull(
OrderLib.CANCEL_ORDER_TYPE,
order,
signatureLeft,
signatureRight
);
require(isValid, errorMessage);
}
_withdraw(orderId, order.taker);
}
function finalizeOrder(
OrderLib.OrderData memory order,
bytes memory signatureLeft,
bytes memory signatureRight
) external payable nonReentrant {
OrderExtLib.OrderExtData memory data = OrderExtLib.decodeOrderExtData(
order.data
);
(bool isValid, string memory errorMessage) = _validateFull(
OrderLib.FINALIZE_ORDER_TYPE,
order,
signatureLeft,
signatureRight
);
require(isValid, errorMessage);
bytes32 orderId = OrderLib.hashKey(order);
_transfer(order.makeAsset, order.maker, order.taker);
_pay(orderId, data.payouts, data.fees);
}
function getVersion() external pure returns (bytes4) {
return OrderExtLib.VERSION;
}
function _msgSender()
internal
view
override(Context, ERC2771Context)
returns (address)
{
return super._msgSender();
}
function _msgData()
internal
view
override(Context, ERC2771Context)
returns (bytes memory)
{
return super._msgData();
}
function _validateFull(
bytes4 orderType,
OrderLib.OrderData memory order,
bytes memory signatureLeft,
bytes memory signatureRight
) internal view returns (bool, string memory) {
(bool isOrderValid, string memory orderErrorMessage) = _validateOrder(
orderType,
order
);
if (!isOrderValid) {
return (isOrderValid, orderErrorMessage);
}
(
bool isMakerSigValid,
string memory makerSigErrorMessage
) = _validateSig(order, order.maker, signatureLeft);
if (!isMakerSigValid) {
return (isMakerSigValid, makerSigErrorMessage);
}
(
bool isTakerSigValid,
string memory takerSigErrorMessage
) = _validateSig(order, order.taker, signatureRight);
if (!isTakerSigValid && orderType != OrderLib.FINALIZE_ORDER_TYPE) {
return (isTakerSigValid, takerSigErrorMessage);
} else if (
!isTakerSigValid && orderType == OrderLib.FINALIZE_ORDER_TYPE
) {
OrderExtLib.OrderExtData memory dataExt = OrderExtLib
.decodeOrderExtData(order.data);
(
bool isForwarderSigValid,
string memory forwarderSigErrorMessage
) = _validateSig(order, dataExt.forwarder, signatureRight);
if (!isForwarderSigValid) {
return (isForwarderSigValid, forwarderSigErrorMessage);
}
}
return (true, "");
}
function _validateOrderAndSig(
bytes4 orderType,
OrderLib.OrderData memory order,
address signer,
bytes memory signature
) internal view returns (bool, string memory) {
(bool isOrderValid, string memory orderErrorMessag) = _validateOrder(
orderType,
order
);
if (!isOrderValid) {
return (isOrderValid, orderErrorMessag);
}
(bool isSigValid, string memory sigErrorMessage) = _validateSig(
order,
signer,
signature
);
if (!isSigValid) {
return (isSigValid, sigErrorMessage);
}
return (true, "");
}
function _validateOrder(bytes4 orderType, OrderLib.OrderData memory order)
private
view
returns (bool, string memory)
{
bool isTargetOrderType = orderType == OrderLib.CREATE_ORDER_TYPE ||
orderType == OrderLib.UPDATE_ORDER_TYPE ||
orderType == OrderLib.FINALIZE_ORDER_TYPE;
if (order.orderType != orderType) {
return (false, "MarketBase: orderType verification failed");
} else if (isTargetOrderType && order.start > block.timestamp) {
return (false, "MarketBase: start verification failed");
} else if (isTargetOrderType && order.end < block.timestamp) {
return (false, "MarketBase: end verification failed");
}
return OrderLib.validate(order);
}
function _validateSig(
OrderLib.OrderData memory order,
address signer,
bytes memory signature
) private view returns (bool, string memory) {
bytes32 hash = OrderLib.hash(order);
(bool isValid, string memory errorMessage) = _validateTx(
signer,
hash,
signature
);
return (isValid, errorMessage);
}
}
文件 21 的 34:MarketEscrow.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../../utils/libraries/AssetLib.sol";
import "../../utils/libraries/BasisPointLib.sol";
import "../../utils/libraries/PartLib.sol";
import "./MarketTransfer.sol";
abstract contract MarketEscrow is MarketTransfer {
using BasisPointLib for uint256;
using SafeMath for uint256;
enum UpdateAssetStatus {
TypeChange,
ValueChangeUp,
ValueChangeDown,
NoChange
}
mapping(bytes32 => AssetLib.AssetData) private _deposits;
mapping(bytes32 => bool) private _completed;
event Deposited(
bytes32 id,
address indexed payee,
AssetLib.AssetData asset
);
event Paid(
bytes32 id,
PartLib.PartData[] payouts,
PartLib.PartData[] fees,
AssetLib.AssetData asset
);
event Withdrawn(
bytes32 id,
address indexed payee,
AssetLib.AssetData asset
);
modifier whenEscrowDeposited(bytes32 id) {
require(
getDeposit(id).value != 0 &&
getDeposit(id).assetType.assetClass != bytes4(0),
"MarketEscrow: escrow already not depositd"
);
_;
}
modifier whenNotEscrowCompleted(bytes32 id) {
require(!getCompleted(id), "MarketEscrow: escrow already completed");
_;
}
function getCompleted(bytes32 id) public view returns (bool) {
return _completed[id];
}
function getDeposit(bytes32 id)
public
view
returns (AssetLib.AssetData memory)
{
return _deposits[id];
}
function _createDeposit(
bytes32 id,
address payee,
AssetLib.AssetData memory asset
) internal whenNotEscrowCompleted(id) {
_setDeposit(id, asset);
_transfer(asset, payee, address(this));
emit Deposited(id, payee, asset);
}
function _updateDeposit(
bytes32 id,
address payee,
AssetLib.AssetData memory newAsset
) internal whenEscrowDeposited(id) whenNotEscrowCompleted(id) {
AssetLib.AssetData memory currentAsset = getDeposit(id);
UpdateAssetStatus status = _matchUpdateAssetStatus(
currentAsset,
newAsset
);
if (status == UpdateAssetStatus.TypeChange) {
_setDeposit(id, newAsset);
_transfer(currentAsset, address(this), payee);
_transfer(newAsset, payee, address(this));
} else if (status == UpdateAssetStatus.ValueChangeDown) {
uint256 diffValue = currentAsset.value.sub(newAsset.value);
_setDeposit(id, newAsset);
_transfer(
AssetLib.AssetData(currentAsset.assetType, diffValue),
address(this),
payee
);
} else if (status == UpdateAssetStatus.ValueChangeUp) {
uint256 diffValue = newAsset.value.sub(currentAsset.value);
_setDeposit(id, newAsset);
_transfer(
AssetLib.AssetData(currentAsset.assetType, diffValue),
payee,
address(this)
);
} else {
revert("MarketEscrow: no asset change");
}
emit Deposited(id, payee, newAsset);
}
function _pay(
bytes32 id,
PartLib.PartData[] memory payouts,
PartLib.PartData[] memory fees
) internal whenEscrowDeposited(id) whenNotEscrowCompleted(id) {
AssetLib.AssetData memory asset = _deposits[id];
_setCompleted(id, true);
uint256 rest = asset.value;
(rest, ) = _transferFees(
asset.assetType,
rest,
asset.value,
address(this),
fees
);
_transferPayouts(asset.assetType, rest, address(this), payouts);
emit Paid(id, payouts, fees, asset);
}
function _withdraw(bytes32 id, address payee)
internal
whenEscrowDeposited(id)
whenNotEscrowCompleted(id)
{
AssetLib.AssetData memory asset = _deposits[id];
_setCompleted(id, true);
_transfer(asset, address(this), payee);
emit Withdrawn(id, payee, asset);
}
function _transferFees(
AssetLib.AssetType memory assetType,
uint256 rest,
uint256 amount,
address from,
PartLib.PartData[] memory fees
) internal returns (uint256 restValue, uint256 totalFees) {
totalFees = 0;
restValue = rest;
for (uint256 i = 0; i < fees.length; i++) {
totalFees = totalFees.add(fees[i].value);
(uint256 newRestValue, uint256 feeValue) = _subFeeInBp(
restValue,
amount,
fees[i].value
);
restValue = newRestValue;
if (feeValue > 0) {
_transfer(
AssetLib.AssetData(assetType, feeValue),
from,
fees[i].account
);
}
}
}
function _transferPayouts(
AssetLib.AssetType memory assetType,
uint256 amount,
address from,
PartLib.PartData[] memory payouts
) internal {
uint256 sumBps = 0;
uint256 restValue = amount;
for (uint256 i = 0; i < payouts.length - 1; i++) {
uint256 currentAmount = amount.bp(payouts[i].value);
sumBps = sumBps.add(payouts[i].value);
if (currentAmount > 0) {
restValue = restValue.sub(currentAmount);
_transfer(
AssetLib.AssetData(assetType, currentAmount),
from,
payouts[i].account
);
}
}
PartLib.PartData memory lastPayout = payouts[payouts.length - 1];
sumBps = sumBps.add(lastPayout.value);
require(
sumBps == 10000,
"MarketEscrow: sum payouts bps not equal 100%"
);
if (restValue > 0) {
_transfer(
AssetLib.AssetData(assetType, restValue),
from,
lastPayout.account
);
}
}
function _matchUpdateAssetStatus(
AssetLib.AssetData memory currentAsset,
AssetLib.AssetData memory newAsset
) internal pure returns (UpdateAssetStatus) {
bool matchAssetClass = currentAsset.assetType.assetClass ==
newAsset.assetType.assetClass;
bool matchToken;
bool matchTokenId;
if (
matchAssetClass &&
currentAsset.assetType.assetClass == AssetLib.ERC20_ASSET_CLASS
) {
(address currentToken, ) = AssetLib.decodeAssetTypeData(
currentAsset.assetType
);
(address newToken, ) = AssetLib.decodeAssetTypeData(
newAsset.assetType
);
matchToken = currentToken == newToken;
} else if (
matchAssetClass &&
(currentAsset.assetType.assetClass == AssetLib.ERC721_ASSET_CLASS ||
currentAsset.assetType.assetClass ==
AssetLib.ERC1155_ASSET_CLASS)
) {
(address currentToken, uint256 currentTokenId) = AssetLib
.decodeAssetTypeData(currentAsset.assetType);
(address newToken, uint256 newTokenId) = AssetLib
.decodeAssetTypeData(newAsset.assetType);
matchToken = currentToken == newToken;
matchTokenId = currentTokenId == newTokenId;
}
if (
!matchAssetClass ||
(!matchToken &&
(currentAsset.assetType.assetClass ==
AssetLib.ERC20_ASSET_CLASS ||
currentAsset.assetType.assetClass ==
AssetLib.ERC721_ASSET_CLASS ||
currentAsset.assetType.assetClass ==
AssetLib.ERC1155_ASSET_CLASS)) ||
(!matchTokenId &&
(currentAsset.assetType.assetClass ==
AssetLib.ERC721_ASSET_CLASS ||
currentAsset.assetType.assetClass ==
AssetLib.ERC1155_ASSET_CLASS))
) {
return UpdateAssetStatus.TypeChange;
} else {
if (currentAsset.value > newAsset.value) {
return UpdateAssetStatus.ValueChangeDown;
} else if (currentAsset.value < newAsset.value) {
return UpdateAssetStatus.ValueChangeUp;
}
return UpdateAssetStatus.NoChange;
}
}
function _setDeposit(bytes32 id, AssetLib.AssetData memory asset) internal {
_deposits[id] = asset;
}
function _setCompleted(bytes32 id, bool status) internal {
_completed[id] = status;
}
function _subFeeInBp(
uint256 value,
uint256 total,
uint256 feeInBp
) internal pure returns (uint256 newValue, uint256 realFee) {
return _subFee(value, total.bp(feeInBp));
}
function _subFee(uint256 value, uint256 fee)
internal
pure
returns (uint256 newValue, uint256 realFee)
{
if (value > fee) {
newValue = value.sub(fee);
realFee = fee;
} else {
newValue = 0;
realFee = value;
}
}
}
文件 22 的 34:MarketTransfer.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "../../transfer-proxy/interfaces/ITransferProxy.sol";
import "../../utils/libraries/AssetLib.sol";
import "./AdminController.sol";
abstract contract MarketTransfer is
ERC721Holder,
ERC1155Holder,
AdminController
{
using Address for address;
using SafeERC20 for IERC20;
mapping(bytes4 => address) private _proxies;
event ProxyUpdated(bytes4 indexed assetType, address proxy);
event Transferred(AssetLib.AssetData asset, address from, address to);
function setTransferProxy(bytes4 assetType, address proxy)
external
onlyAdmin
{
require(
proxy.isContract(),
"MarketTransfer: Address is not a contract"
);
_proxies[assetType] = proxy;
emit ProxyUpdated(assetType, proxy);
}
function getTransferProxy(bytes4 assetType) public view returns (address) {
return _proxies[assetType];
}
function _transfer(
AssetLib.AssetData memory asset,
address from,
address to
) internal {
if (asset.assetType.assetClass == AssetLib.ETH_ASSET_CLASS) {
_ethTransfer(from, to, asset.value);
} else if (asset.assetType.assetClass == AssetLib.ERC20_ASSET_CLASS) {
(address token, ) = AssetLib.decodeAssetTypeData(asset.assetType);
_erc20safeTransferFrom(token, from, to, asset.value);
} else if (asset.assetType.assetClass == AssetLib.ERC721_ASSET_CLASS) {
(address token, uint256 tokenId) = AssetLib.decodeAssetTypeData(
asset.assetType
);
require(asset.value == 1, "MarketTransfer: erc721 value error");
_erc721safeTransferFrom(token, from, to, tokenId);
} else if (asset.assetType.assetClass == AssetLib.ERC1155_ASSET_CLASS) {
(address token, uint256 tokenId) = AssetLib.decodeAssetTypeData(
asset.assetType
);
_erc1155safeTransferFrom(token, from, to, tokenId, asset.value);
} else {
_transferProxyTransfer(asset, from, to);
}
emit Transferred(asset, from, to);
}
function _ethTransfer(
address from,
address to,
uint256 value
) private {
if (from == address(this)) {
require(
address(this).balance >= value,
"MarketTransfer: insufficient balance"
);
} else {
require(msg.value >= value, "MarketTransfer: insufficient balance");
}
if (to != address(this)) {
(bool success, ) = to.call{value: value}("");
require(
success,
"MarketTransfer: unable to send value, recipient may have reverted"
);
}
}
function _erc20safeTransferFrom(
address token,
address from,
address to,
uint256 value
) private {
if (from == address(this)) {
IERC20(token).safeTransfer(to, value);
} else {
IERC20(token).safeTransferFrom(from, to, value);
}
}
function _erc721safeTransferFrom(
address token,
address from,
address to,
uint256 tokenId
) private {
IERC721(token).safeTransferFrom(from, to, tokenId);
}
function _erc1155safeTransferFrom(
address token,
address from,
address to,
uint256 id,
uint256 value
) private {
IERC1155(token).safeTransferFrom(from, to, id, value, "");
}
function _transferProxyTransfer(
AssetLib.AssetData memory asset,
address from,
address to
) private {
ITransferProxy(getTransferProxy(asset.assetType.assetClass)).transfer(
asset,
from,
to
);
}
}
文件 23 的 34:MarketTxValidatable.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
abstract contract MarketTxValidatable is Context, EIP712 {
using SignatureChecker for address;
function _validateTx(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool, string memory) {
if (signature.length == 0) {
address sender = _msgSender();
if (signer != sender) {
return (
false,
"MarketTxValidatable: sender verification failed"
);
}
} else {
if (
!signer.isValidSignatureNow(_hashTypedDataV4(hash), signature)
) {
return (
false,
"MarketTxValidatable: signature verification failed"
);
}
}
return (true, "");
}
}
文件 24 的 34:OrderExtLib.sol
pragma solidity ^0.8.0;
import "../../utils/libraries/AssetLib.sol";
import "../../utils/libraries/PartLib.sol";
library OrderExtLib {
bytes4 public constant VERSION = bytes4(keccak256("V1"));
bytes32 constant ORDER_EXT_TYPEHASH =
keccak256(
"OrderExtData(bytes4 version,address forwarder,PartData[] payouts,PartData[] fees)PartData(address account,uint256 value)"
);
struct OrderExtData {
bytes4 version;
address forwarder;
PartLib.PartData[] payouts;
PartLib.PartData[] fees;
}
function hash(OrderExtData memory orderExt)
internal
pure
returns (bytes32)
{
bytes32[] memory payoutsBytes = new bytes32[](orderExt.payouts.length);
for (uint256 i = 0; i < orderExt.payouts.length; i++) {
payoutsBytes[i] = PartLib.hash(orderExt.payouts[i]);
}
bytes32[] memory feesBytes = new bytes32[](orderExt.fees.length);
for (uint256 i = 0; i < orderExt.fees.length; i++) {
feesBytes[i] = PartLib.hash(orderExt.fees[i]);
}
return
keccak256(
abi.encode(
ORDER_EXT_TYPEHASH,
orderExt.version,
orderExt.forwarder,
keccak256(abi.encodePacked(payoutsBytes)),
keccak256(abi.encodePacked(feesBytes))
)
);
}
function decodeOrderExtData(bytes memory data)
internal
pure
returns (OrderExtData memory)
{
return abi.decode(data, (OrderExtData));
}
function validate(OrderExtData memory orderExt)
internal
pure
returns (bool, string memory)
{
if (orderExt.version != VERSION) {
return (false, "OrderExtLib: version validation failed");
} else if (orderExt.payouts.length == 0) {
return (false, "OrderExtLib: payouts validation failed");
}
return (true, "");
}
}
文件 25 的 34:OrderLib.sol
pragma solidity ^0.8.0;
import "../../utils/libraries/AssetLib.sol";
import "./OrderExtLib.sol";
library OrderLib {
bytes4 public constant CREATE_ORDER_TYPE = bytes4(keccak256("CREATE"));
bytes4 public constant UPDATE_ORDER_TYPE = bytes4(keccak256("UPDATE"));
bytes4 public constant CANCEL_ORDER_TYPE = bytes4(keccak256("CANCEL"));
bytes4 public constant FINALIZE_ORDER_TYPE = bytes4(keccak256("FINALIZE"));
bytes32 constant ORDER_TYPEHASH =
keccak256(
"OrderData(address maker,AssetData makeAsset,address taker,AssetData takeAsset,uint256 salt,uint256 start,uint256 end,bytes4 orderType,bytes data)AssetData(AssetType assetType,uint256 value)AssetType(bytes4 assetClass,bytes data)"
);
struct OrderData {
address maker;
AssetLib.AssetData makeAsset;
address taker;
AssetLib.AssetData takeAsset;
uint256 salt;
uint256 start;
uint256 end;
bytes4 orderType;
bytes data;
}
function hashKey(OrderData memory order) internal pure returns (bytes32) {
return
keccak256(
abi.encode(
order.maker,
order.taker,
order.salt,
order.start,
order.end,
order.data
)
);
}
function hash(OrderData memory order) internal pure returns (bytes32) {
return
keccak256(
abi.encode(
ORDER_TYPEHASH,
order.maker,
AssetLib.hash(order.makeAsset),
order.taker,
AssetLib.hash(order.takeAsset),
order.salt,
order.start,
order.end,
order.orderType,
keccak256(order.data)
)
);
}
function validate(OrderData memory order)
internal
pure
returns (bool, string memory)
{
if (order.maker == address(0)) {
return (false, "OrderLib: maker validation failed");
} else if (
order.makeAsset.value == 0 ||
order.makeAsset.assetType.assetClass == bytes4(0)
) {
return (false, "OrderLib: makeAsset validation failed");
} else if (order.taker == address(0)) {
return (false, "OrderLib: taker validation failed");
} else if (
order.takeAsset.value == 0 ||
order.takeAsset.assetType.assetClass == bytes4(0)
) {
return (false, "OrderLib: takeAsset validation failed");
} else if (order.salt == 0) {
return (false, "OrderLib: salt validation failed");
} else if (order.start == 0) {
return (false, "OrderLib: start validation failed");
} else if (order.end == 0) {
return (false, "OrderLib: end validation failed");
} else if (
!(order.orderType == CREATE_ORDER_TYPE ||
order.orderType == UPDATE_ORDER_TYPE ||
order.orderType == CANCEL_ORDER_TYPE ||
order.orderType == FINALIZE_ORDER_TYPE)
) {
return (false, "OrderLib: orderType validation failed");
}
return OrderExtLib.validate(OrderExtLib.decodeOrderExtData(order.data));
}
}
文件 26 的 34:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 27 的 34:PartLib.sol
pragma solidity ^0.8.0;
import "./BasisPointLib.sol";
library PartLib {
bytes32 public constant TYPE_HASH =
keccak256("PartData(address account,uint256 value)");
struct PartData {
address payable account;
uint256 value;
}
function hash(PartData memory part) internal pure returns (bytes32) {
return keccak256(abi.encode(TYPE_HASH, part.account, part.value));
}
function validate(PartData memory part)
internal
pure
returns (bool, string memory)
{
if (part.account == address(0x0)) {
return (false, "PartLib: account verification failed");
}
if (part.value == 0 || part.value > BasisPointLib._BPS_BASE) {
return (false, "PartLib: value verification failed");
}
return (true, "");
}
}
文件 28 的 34:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 29 的 34:RequestMarketV1.sol
pragma solidity ^0.8.0;
import "./MarketBase.sol";
contract RequestMarketV1 is MarketBase {
constructor(
string memory name,
string memory version,
address trustedForwarder
) MarketBase(name, version, trustedForwarder) {}
}
文件 30 的 34:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 31 的 34:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
文件 32 的 34:SignatureChecker.sol
pragma solidity ^0.8.0;
import "./ECDSA.sol";
import "../Address.sol";
import "../../interfaces/IERC1271.sol";
library SignatureChecker {
function isValidSignatureNow(
address signer,
bytes32 hash,
bytes memory signature
) internal view returns (bool) {
(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
if (error == ECDSA.RecoverError.NoError && recovered == signer) {
return true;
}
(bool success, bytes memory result) = signer.staticcall(
abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
);
return (success && result.length == 32 && abi.decode(result, (bytes4)) == IERC1271.isValidSignature.selector);
}
}
文件 33 的 34:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
文件 34 的 34:draft-EIP712.sol
pragma solidity ^0.8.0;
import "./ECDSA.sol";
abstract contract EIP712 {
bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
uint256 private immutable _CACHED_CHAIN_ID;
address private immutable _CACHED_THIS;
bytes32 private immutable _HASHED_NAME;
bytes32 private immutable _HASHED_VERSION;
bytes32 private immutable _TYPE_HASH;
constructor(string memory name, string memory version) {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
bytes32 typeHash = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
_CACHED_THIS = address(this);
_TYPE_HASH = typeHash;
}
function _domainSeparatorV4() internal view returns (bytes32) {
if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR;
} else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
}
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
}
}
{
"compilationTarget": {
"contracts/market/RequestMarketV1.sol": "RequestMarketV1"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"address","name":"trustedForwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"AdminSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"payee","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"indexed":false,"internalType":"struct AssetLib.AssetData","name":"asset","type":"tuple"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"components":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"indexed":false,"internalType":"struct PartLib.PartData[]","name":"payouts","type":"tuple[]"},{"components":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"indexed":false,"internalType":"struct PartLib.PartData[]","name":"fees","type":"tuple[]"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"indexed":false,"internalType":"struct AssetLib.AssetData","name":"asset","type":"tuple"}],"name":"Paid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"assetType","type":"bytes4"},{"indexed":false,"internalType":"address","name":"proxy","type":"address"}],"name":"ProxyUpdated","type":"event"},{"anonymous":false,"inputs":[{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"indexed":false,"internalType":"struct AssetLib.AssetData","name":"asset","type":"tuple"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Transferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"payee","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"indexed":false,"internalType":"struct AssetLib.AssetData","name":"asset","type":"tuple"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"orderType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct OrderLib.OrderData","name":"order","type":"tuple"},{"internalType":"bytes","name":"signatureLeft","type":"bytes"},{"internalType":"bytes","name":"signatureRight","type":"bytes"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"orderType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct OrderLib.OrderData","name":"order","type":"tuple"},{"internalType":"bytes","name":"signatureLeft","type":"bytes"},{"internalType":"bytes","name":"signatureRight","type":"bytes"}],"name":"createOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"orderType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct OrderLib.OrderData","name":"order","type":"tuple"},{"internalType":"bytes","name":"signatureLeft","type":"bytes"},{"internalType":"bytes","name":"signatureRight","type":"bytes"}],"name":"finalizeOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getDeposit","outputs":[{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"assetType","type":"bytes4"}],"name":"getTransferProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVersion","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"assetType","type":"bytes4"},{"internalType":"address","name":"proxy","type":"address"}],"name":"setTransferProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"maker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"makeAsset","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"components":[{"components":[{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct AssetLib.AssetType","name":"assetType","type":"tuple"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct AssetLib.AssetData","name":"takeAsset","type":"tuple"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"},{"internalType":"bytes4","name":"orderType","type":"bytes4"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct OrderLib.OrderData","name":"order","type":"tuple"},{"internalType":"bytes","name":"signatureLeft","type":"bytes"},{"internalType":"bytes","name":"signatureRight","type":"bytes"}],"name":"updateOrder","outputs":[],"stateMutability":"payable","type":"function"}]