编译器
0.6.12+commit.27d51765
文件 1 的 16:Address.sol
pragma solidity >=0.6.2 <0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 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) private 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 的 16:BaseLibEIP712.sol
pragma solidity ^0.6.0;
contract BaseLibEIP712 {
string public constant EIP191_HEADER = "\x19\x01";
string public constant EIP712_DOMAIN_NAME = "Tokenlon";
string public constant EIP712_DOMAIN_VERSION = "v5";
bytes32 public immutable EIP712_DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(EIP712_DOMAIN_NAME)),
keccak256(bytes(EIP712_DOMAIN_VERSION)),
getChainID(),
address(this)
)
);
function getChainID() internal pure returns (uint) {
uint chainId;
assembly {
chainId := chainid()
}
return chainId;
}
}
文件 3 的 16:IERC1271Wallet.sol
pragma solidity ^0.6.0;
interface IERC1271Wallet {
function isValidSignature(
bytes calldata _data,
bytes calldata _signature)
external
view
returns (bytes4 magicValue);
function isValidSignature(
bytes32 _hash,
bytes calldata _signature)
external
view
returns (bytes4 magicValue);
}
文件 4 的 16:IERC20.sol
pragma solidity >=0.6.0 <0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender, address recipient, 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);
}
文件 5 的 16:IPermanentStorage.sol
pragma solidity ^0.6.0;
interface IPermanentStorage {
function wethAddr() external view returns (address);
function getCurvePoolInfo(address _makerAddr, address _takerAssetAddr, address _makerAssetAddr) external view returns (int128 takerAssetIndex, int128 makerAssetIndex, uint16 swapMethod, bool supportGetDx);
function setCurvePoolInfo(address _makerAddr, address[] calldata _underlyingCoins, address[] calldata _coins, bool _supportGetDx) external;
function isTransactionSeen(bytes32 _transactionHash) external view returns (bool);
function isAMMTransactionSeen(bytes32 _transactionHash) external view returns (bool);
function isRFQTransactionSeen(bytes32 _transactionHash) external view returns (bool);
function isRelayerValid(address _relayer) external view returns (bool);
function setTransactionSeen(bytes32 _transactionHash) external;
function setAMMTransactionSeen(bytes32 _transactionHash) external;
function setRFQTransactionSeen(bytes32 _transactionHash) external;
function setRelayersValid(address[] memory _relayers, bool[] memory _isValids) external;
}
文件 6 的 16:IRFQ.sol
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "../utils/RFQLibEIP712.sol";
import "./ISetAllowance.sol";
interface IRFQ is ISetAllowance {
function fill(
RFQLibEIP712.Order memory _order,
bytes memory _mmSignature,
bytes memory _userSignature
) external payable returns (uint256);
}
文件 7 的 16:ISetAllowance.sol
pragma solidity ^0.6.0;
interface ISetAllowance {
function setAllowance(address[] memory tokenList, address spender) external;
function closeAllowance(address[] memory tokenList, address spender) external;
}
文件 8 的 16:ISpender.sol
pragma solidity ^0.6.0;
interface ISpender {
function spendFromUser(address _user, address _tokenAddr, uint256 _amount) external;
function spendFromUserTo(address _user, address _tokenAddr, address _receiverAddr, uint256 _amount) external;
}
文件 9 的 16:IWeth.sol
pragma solidity ^0.6.0;
interface IWETH {
function balanceOf(address account) external view returns (uint256);
function deposit() external payable;
function withdraw(uint256 amount) external;
function transferFrom(address src, address dst, uint wad) external returns (bool);
}
文件 10 的 16:LibBytes.sol
pragma solidity ^0.6.0;
library LibBytes {
using LibBytes for bytes;
function popLastByte(bytes memory b)
internal
pure
returns (bytes1 result)
{
require(
b.length > 0,
"LibBytes#popLastByte: greater than zero length required"
);
result = b[b.length - 1];
assembly {
let newLen := sub(mload(b), 1)
mstore(b, newLen)
}
return result;
}
function readAddress(
bytes memory b,
uint256 index
)
internal
pure
returns (address result)
{
require(
b.length >= index + 20,
"LibBytes#readAddress greater or equal to 20 length required"
);
index += 20;
assembly {
result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
return result;
}
function readBytes32(
bytes memory b,
uint256 index
)
internal
pure
returns (bytes32 result)
{
require(
b.length >= index + 32,
"LibBytes#readBytes32 greater or equal to 32 length required"
);
index += 32;
assembly {
result := mload(add(b, index))
}
return result;
}
function readBytes4(
bytes memory b,
uint256 index
)
internal
pure
returns (bytes4 result)
{
require(
b.length >= index + 4,
"LibBytes#readBytes4 greater or equal to 4 length required"
);
index += 32;
assembly {
result := mload(add(b, index))
result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
}
return result;
}
function readBytes2(
bytes memory b,
uint256 index
)
internal
pure
returns (bytes2 result)
{
require(
b.length >= index + 2,
"LibBytes#readBytes2 greater or equal to 2 length required"
);
index += 32;
assembly {
result := mload(add(b, index))
result := and(result, 0xFFFF000000000000000000000000000000000000000000000000000000000000)
}
return result;
}
}
文件 11 的 16:RFQ.sol
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./interfaces/ISpender.sol";
import "./interfaces/IWeth.sol";
import "./interfaces/IRFQ.sol";
import "./interfaces/IPermanentStorage.sol";
import "./interfaces/IERC1271Wallet.sol";
import "./utils/RFQLibEIP712.sol";
contract RFQ is
ReentrancyGuard,
IRFQ,
RFQLibEIP712,
SignatureValidator
{
using SafeMath for uint256;
using SafeERC20 for IERC20;
using Address for address;
string public constant version = "5.2.0";
uint256 private constant MAX_UINT = 2**256 - 1;
string public constant SOURCE = "RFQ v1";
uint256 private constant BPS_MAX = 10000;
address public immutable userProxy;
IPermanentStorage public immutable permStorage;
IWETH public immutable weth;
address public operator;
ISpender public spender;
struct GroupedVars {
bytes32 orderHash;
bytes32 transactionHash;
}
event TransferOwnership(address newOperator);
event UpgradeSpender(address newSpender);
event AllowTransfer(address spender);
event DisallowTransfer(address spender);
event DepositETH(uint256 ethBalance);
event FillOrder(
string source,
bytes32 indexed transactionHash,
bytes32 indexed orderHash,
address indexed userAddr,
address takerAssetAddr,
uint256 takerAssetAmount,
address makerAddr,
address makerAssetAddr,
uint256 makerAssetAmount,
address receiverAddr,
uint256 settleAmount,
uint16 feeFactor
);
receive() external payable {}
modifier onlyOperator {
require(operator == msg.sender, "RFQ: not operator");
_;
}
modifier onlyUserProxy() {
require(address(userProxy) == msg.sender, "RFQ: not the UserProxy contract");
_;
}
function transferOwnership(address _newOperator) external onlyOperator {
require(_newOperator != address(0), "RFQ: operator can not be zero address");
operator = _newOperator;
emit TransferOwnership(_newOperator);
}
constructor (
address _operator,
address _userProxy,
ISpender _spender,
IPermanentStorage _permStorage,
IWETH _weth
) public {
operator = _operator;
userProxy = _userProxy;
spender = _spender;
permStorage = _permStorage;
weth = _weth;
}
function upgradeSpender(address _newSpender) external onlyOperator {
require(_newSpender != address(0), "RFQ: spender can not be zero address");
spender = ISpender(_newSpender);
emit UpgradeSpender(_newSpender);
}
function setAllowance(address[] calldata _tokenList, address _spender) override external onlyOperator {
for (uint256 i = 0 ; i < _tokenList.length; i++) {
IERC20(_tokenList[i]).safeApprove(_spender, MAX_UINT);
emit AllowTransfer(_spender);
}
}
function closeAllowance(address[] calldata _tokenList, address _spender) override external onlyOperator {
for (uint256 i = 0 ; i < _tokenList.length; i++) {
IERC20(_tokenList[i]).safeApprove(_spender, 0);
emit DisallowTransfer(_spender);
}
}
function depositETH() external onlyOperator {
uint256 balance = address(this).balance;
if (balance > 0) {
weth.deposit{value: balance}();
emit DepositETH(balance);
}
}
function fill(
RFQLibEIP712.Order memory _order,
bytes memory _mmSignature,
bytes memory _userSignature
)
override
payable
external
nonReentrant
onlyUserProxy
returns (uint256)
{
require(_order.deadline >= block.timestamp, "RFQ: expired order");
require(_order.feeFactor < BPS_MAX, "RFQ: invalid fee factor");
GroupedVars memory vars;
vars.orderHash = _getOrderHash(_order);
require(
isValidSignature(
_order.makerAddr,
_getOrderSignDigestFromHash(vars.orderHash),
bytes(""),
_mmSignature
),
"RFQ: invalid MM signature"
);
vars.transactionHash = _getTransactionHash(_order);
require(
isValidSignature(
_order.takerAddr,
_getTransactionSignDigestFromHash(vars.transactionHash),
bytes(""),
_userSignature
),
"RFQ: invalid user signature"
);
permStorage.setRFQTransactionSeen(vars.transactionHash);
if (address(weth) == _order.takerAssetAddr) {
require(
msg.value == _order.takerAssetAmount,
"RFQ: insufficient ETH"
);
weth.deposit{value: msg.value}();
} else {
spender.spendFromUser(_order.takerAddr, _order.takerAssetAddr, _order.takerAssetAmount);
}
spender.spendFromUser(_order.makerAddr, _order.makerAssetAddr, _order.makerAssetAmount);
return _settle(_order, vars);
}
function _settle(
RFQLibEIP712.Order memory _order,
GroupedVars memory _vars
) internal returns(uint256) {
IERC20(_order.takerAssetAddr).safeTransfer(_order.makerAddr, _order.takerAssetAmount);
uint256 settleAmount = _order.makerAssetAmount;
if (_order.feeFactor > 0) {
settleAmount = settleAmount.mul((BPS_MAX).sub(_order.feeFactor)).div(BPS_MAX);
}
if (_order.makerAssetAddr == address(weth)){
weth.withdraw(settleAmount);
payable(_order.receiverAddr).transfer(settleAmount);
} else {
IERC20(_order.makerAssetAddr).safeTransfer(_order.receiverAddr, settleAmount);
}
emit FillOrder(
SOURCE,
_vars.transactionHash,
_vars.orderHash,
_order.takerAddr,
_order.takerAssetAddr,
_order.takerAssetAmount,
_order.makerAddr,
_order.makerAssetAddr,
_order.makerAssetAmount,
_order.receiverAddr,
settleAmount,
uint16(_order.feeFactor)
);
return settleAmount;
}
}
文件 12 的 16:RFQLibEIP712.sol
pragma solidity ^0.6.0;
import "./BaseLibEIP712.sol";
import "./SignatureValidator.sol";
contract RFQLibEIP712 is BaseLibEIP712 {
struct Order {
address takerAddr;
address makerAddr;
address takerAssetAddr;
address makerAssetAddr;
uint256 takerAssetAmount;
uint256 makerAssetAmount;
address receiverAddr;
uint256 salt;
uint256 deadline;
uint256 feeFactor;
}
bytes32 public constant ORDER_TYPEHASH = keccak256(
abi.encodePacked(
"Order(",
"address takerAddr,",
"address makerAddr,",
"address takerAssetAddr,",
"address makerAssetAddr,",
"uint256 takerAssetAmount,",
"uint256 makerAssetAmount,",
"uint256 salt,",
"uint256 deadline,",
"uint256 feeFactor",
")"
)
);
function _getOrderHash(Order memory _order) internal pure returns (bytes32 orderHash) {
orderHash = keccak256(
abi.encode(
ORDER_TYPEHASH,
_order.takerAddr,
_order.makerAddr,
_order.takerAssetAddr,
_order.makerAssetAddr,
_order.takerAssetAmount,
_order.makerAssetAmount,
_order.salt,
_order.deadline,
_order.feeFactor
)
);
}
function _getOrderSignDigest(Order memory _order) internal view returns (bytes32 orderSignDigest) {
orderSignDigest = keccak256(
abi.encodePacked(
EIP191_HEADER,
EIP712_DOMAIN_SEPARATOR,
_getOrderHash(_order)
)
);
}
function _getOrderSignDigestFromHash(bytes32 _orderHash) internal view returns (bytes32 orderSignDigest) {
orderSignDigest = keccak256(
abi.encodePacked(
EIP191_HEADER,
EIP712_DOMAIN_SEPARATOR,
_orderHash
)
);
}
bytes32 public constant FILL_WITH_PERMIT_TYPEHASH = keccak256(
abi.encodePacked(
"fillWithPermit(",
"address makerAddr,",
"address takerAssetAddr,",
"address makerAssetAddr,",
"uint256 takerAssetAmount,",
"uint256 makerAssetAmount,",
"address takerAddr,",
"address receiverAddr,",
"uint256 salt,",
"uint256 deadline,",
"uint256 feeFactor",
")"
)
);
function _getTransactionHash(Order memory _order) internal pure returns(bytes32 transactionHash) {
transactionHash = keccak256(
abi.encode(
FILL_WITH_PERMIT_TYPEHASH,
_order.makerAddr,
_order.takerAssetAddr,
_order.makerAssetAddr,
_order.takerAssetAmount,
_order.makerAssetAmount,
_order.takerAddr,
_order.receiverAddr,
_order.salt,
_order.deadline,
_order.feeFactor
)
);
}
function _getTransactionSignDigest(Order memory _order) internal view returns (bytes32 transactionSignDigest) {
transactionSignDigest = keccak256(
abi.encodePacked(
EIP191_HEADER,
EIP712_DOMAIN_SEPARATOR,
_getTransactionHash(_order)
)
);
}
function _getTransactionSignDigestFromHash(bytes32 _txHash) internal view returns (bytes32 transactionSignDigest) {
transactionSignDigest = keccak256(
abi.encodePacked(
EIP191_HEADER,
EIP712_DOMAIN_SEPARATOR,
_txHash
)
);
}
}
文件 13 的 16:ReentrancyGuard.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 14 的 16:SafeERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
library SafeERC20 {
using SafeMath for uint256;
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).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_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");
}
}
}
文件 15 的 16:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
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) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
文件 16 的 16:SignatureValidator.sol
pragma solidity ^0.6.0;
import "../interfaces/IERC1271Wallet.sol";
import "./LibBytes.sol";
interface IWallet {
function isValidSignature(
bytes32 hash,
bytes memory signature
)
external
view
returns (bool isValid);
}
contract SignatureValidator {
using LibBytes for bytes;
bytes4 constant internal ERC1271_MAGICVALUE = 0x20c13b0b;
bytes4 constant internal ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e;
bytes4 constant internal ERC1271_FALLBACK_MAGICVALUE_BYTES32 = 0xb0671381;
enum SignatureType {
Illegal,
Invalid,
EIP712,
EthSign,
WalletBytes,
WalletBytes32,
Wallet,
NSignatureTypes
}
function isValidSignature(
address _signerAddress,
bytes32 _hash,
bytes memory _data,
bytes memory _sig
)
public
view
returns (bool isValid)
{
require(
_sig.length > 0,
"SignatureValidator#isValidSignature: length greater than 0 required"
);
require(
_signerAddress != address(0x0),
"SignatureValidator#isValidSignature: invalid signer"
);
uint8 signatureTypeRaw = uint8(_sig.popLastByte());
require(
signatureTypeRaw < uint8(SignatureType.NSignatureTypes),
"SignatureValidator#isValidSignature: unsupported signature"
);
SignatureType signatureType = SignatureType(signatureTypeRaw);
uint8 v;
bytes32 r;
bytes32 s;
address recovered;
if (signatureType == SignatureType.Illegal) {
revert("SignatureValidator#isValidSignature: illegal signature");
} else if (signatureType == SignatureType.EIP712) {
require(
_sig.length == 97,
"SignatureValidator#isValidSignature: length 97 required"
);
r = _sig.readBytes32(0);
s = _sig.readBytes32(32);
v = uint8(_sig[64]);
recovered = ecrecover(_hash, v, r, s);
isValid = _signerAddress == recovered;
return isValid;
} else if (signatureType == SignatureType.EthSign) {
require(
_sig.length == 97,
"SignatureValidator#isValidSignature: length 97 required"
);
r = _sig.readBytes32(0);
s = _sig.readBytes32(32);
v = uint8(_sig[64]);
recovered = ecrecover(
keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)),
v,
r,
s
);
isValid = _signerAddress == recovered;
return isValid;
} else if (signatureType == SignatureType.WalletBytes) {
isValid = ERC1271_MAGICVALUE == IERC1271Wallet(_signerAddress).isValidSignature(_data, _sig);
return isValid;
} else if (signatureType == SignatureType.WalletBytes32) {
isValid = ERC1271_MAGICVALUE_BYTES32 == IERC1271Wallet(_signerAddress).isValidSignature(_hash, _sig);
return isValid;
} else if (signatureType == SignatureType.Wallet) {
isValid = isValidWalletSignature(
_hash,
_signerAddress,
_sig
);
return isValid;
}
revert("SignatureValidator#isValidSignature: unsupported signature");
}
function isValidWalletSignature(
bytes32 hash,
address walletAddress,
bytes memory signature
)
internal
view
returns (bool isValid)
{
bytes memory _calldata = abi.encodeWithSelector(
IWallet(walletAddress).isValidSignature.selector,
hash,
signature
);
bytes32 magic_salt = bytes32(bytes4(keccak256("isValidWalletSignature(bytes32,address,bytes)")));
assembly {
if iszero(extcodesize(walletAddress)) {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000000c57414c4c45545f4552524f5200000000000000000000000000000000)
mstore(96, 0)
revert(0, 100)
}
let cdStart := add(_calldata, 32)
let success := staticcall(
gas(),
walletAddress,
cdStart,
mload(_calldata),
cdStart,
32
)
if iszero(eq(returndatasize(), 32)) {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000000c57414c4c45545f4552524f5200000000000000000000000000000000)
mstore(96, 0)
revert(0, 100)
}
switch success
case 0 {
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x0000000c57414c4c45545f4552524f5200000000000000000000000000000000)
mstore(96, 0)
revert(0, 100)
}
case 1 {
isValid := eq(
and(mload(cdStart), 0xffffffff00000000000000000000000000000000000000000000000000000000),
and(magic_salt, 0xffffffff00000000000000000000000000000000000000000000000000000000)
)
}
}
return isValid;
}
}
{
"compilationTarget": {
"contracts/RFQ.sol": "RFQ"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_userProxy","type":"address"},{"internalType":"contract ISpender","name":"_spender","type":"address"},{"internalType":"contract IPermanentStorage","name":"_permStorage","type":"address"},{"internalType":"contract IWETH","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"spender","type":"address"}],"name":"AllowTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ethBalance","type":"uint256"}],"name":"DepositETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"spender","type":"address"}],"name":"DisallowTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"source","type":"string"},{"indexed":true,"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"userAddr","type":"address"},{"indexed":false,"internalType":"address","name":"takerAssetAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"makerAddr","type":"address"},{"indexed":false,"internalType":"address","name":"makerAssetAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiverAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"settleAmount","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"feeFactor","type":"uint16"}],"name":"FillOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOperator","type":"address"}],"name":"TransferOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newSpender","type":"address"}],"name":"UpgradeSpender","type":"event"},{"inputs":[],"name":"EIP191_HEADER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_DOMAIN_NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EIP712_DOMAIN_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FILL_WITH_PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORDER_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SOURCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokenList","type":"address[]"},{"internalType":"address","name":"_spender","type":"address"}],"name":"closeAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"takerAddr","type":"address"},{"internalType":"address","name":"makerAddr","type":"address"},{"internalType":"address","name":"takerAssetAddr","type":"address"},{"internalType":"address","name":"makerAssetAddr","type":"address"},{"internalType":"uint256","name":"takerAssetAmount","type":"uint256"},{"internalType":"uint256","name":"makerAssetAmount","type":"uint256"},{"internalType":"address","name":"receiverAddr","type":"address"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"feeFactor","type":"uint256"}],"internalType":"struct RFQLibEIP712.Order","name":"_order","type":"tuple"},{"internalType":"bytes","name":"_mmSignature","type":"bytes"},{"internalType":"bytes","name":"_userSignature","type":"bytes"}],"name":"fill","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_signerAddress","type":"address"},{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_sig","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permStorage","outputs":[{"internalType":"contract IPermanentStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokenList","type":"address[]"},{"internalType":"address","name":"_spender","type":"address"}],"name":"setAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spender","outputs":[{"internalType":"contract ISpender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSpender","type":"address"}],"name":"upgradeSpender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]