Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SwapTest
Compiler Version
v0.8.6+commit.11564f7e
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import '@openzeppelin/contracts/utils/math/Math.sol';
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/interfaces/IERC1271.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "./OrderEIP712.sol";
import "./interfaces/IWETH.sol";
contract SwapTest is Ownable, ReentrancyGuard, IERC1271, IERC1155Receiver, IERC721Receiver {
using SafeMath for uint256;
bytes4 constant public ETH_ASSET_CLASS = bytes4(keccak256("ETH"));
bytes4 constant public ERC20_ASSET_CLASS = bytes4(keccak256("ERC20"));
bytes4 constant public ERC721_ASSET_CLASS = bytes4(keccak256("ERC721"));
bytes4 constant public ERC1155_ASSET_CLASS = bytes4(keccak256("ERC1155"));
bytes constant public VERSION = bytes("1");
event ErrorHandled(bytes32 hash, string reason);
event NewOrder(
OrderEIP712.OrderSig order,
bytes32 indexed orderHash
);
event ExecuteMatching(
bytes32 indexed orderHash,
uint256 tokenId,
uint256 price,
uint16 currentDeal,
uint256 fee
);
event ExecuteP2PSwap(
address indexed account,
bytes32[] orderHash,
uint256[][] tokensIds,
uint256 buyerFee,
uint256 sellerFee
);
event CancelOrder(
address indexed account,
bytes32 indexed orderHash
);
bytes32 public DOMAIN_SEPARATOR = keccak256(
abi.encode(
OrderEIP712.EIP712DOMAIN_TYPEHASH,
keccak256("Swap"),
keccak256(VERSION),
block.chainid,
address(this)
));
mapping(bytes32 => uint16) public dealsByHash;
mapping(bytes32 => bool) public cancelled;
mapping(address => bool) public operators;
bool public isActive = true;
uint256 public sellerFee = 0;
uint256 public buyerFee = 0; // 200 - 20%; 20 - 2%; 2 - 0.2%
IWETH public weth;
modifier onlyOperators() {
require(operators[msg.sender], "Swap: access denied");
_;
}
constructor(
address wethAddress
) {
setupOperator(msg.sender, true);
setWethAddress(wethAddress);
}
receive() external payable {}
function setupFee(uint256 _sellerFee, uint256 _buyerFee) public onlyOwner {
require(_sellerFee <= 20 && _buyerFee <= 20, 'Swap:fee too much. max 20 (2%)');
sellerFee = _sellerFee;
buyerFee = _buyerFee;
}
function setupOperator(address operator, bool access) public onlyOwner {
operators[operator] = access;
}
function setWethAddress(address wethAddress) public onlyOwner {
weth = IWETH(wethAddress);
}
function setIsActive(bool isActive_) public onlyOwner {
isActive = isActive_;
}
function universalSwap(
OrderEIP712.OrderSig calldata orderWithSig,
address target,
bytes memory callData,
uint256 tokenId,
uint256 tokenPrice
) public onlyOperators nonReentrant returns (bool success){
uint256 startGas = gasleft();
bytes32 orderHash = hashBySig(orderWithSig);
validateOrder(orderWithSig, orderHash, /* ignore check gas price */ false);
uint256 transferGasUsage = getEthFrom(orderWithSig.signer, tokenPrice);
require(orderWithSig.price >= tokenPrice, "Swap:Wrong token price");
require(target != address(0) && target != address(this) && target != address(weth), "Swap:Wrong target address");
(success,) = target.call{value: tokenPrice}(callData);
uint256 fee = 0;
if (success) {
transferTokenToSigner(
orderWithSig.assetClass,
orderWithSig.collection,
tokenId,
address(this),
orderWithSig.signer,
1
);
dealsByHash[orderHash]++;
fee = tokenPrice.div(1000).mul(buyerFee);
emitExecuteOrderEvent(orderWithSig, tokenId, tokenPrice, fee);
} else {
emit ErrorHandled(orderHash, "external market error");
weth.deposit{value: tokenPrice}();
weth.transfer(orderWithSig.signer, tokenPrice);
}
uint256 ethForGasUsageWithFee = (startGas - gasleft())
.add(transferGasUsage)
.add(7000)
.mul(tx.gasprice)
.add(fee);
getEthFrom(orderWithSig.signer, ethForGasUsageWithFee);
(bool transaferSuccess,) = msg.sender.call{value: ethForGasUsageWithFee}('');
require(transaferSuccess, 'Swap:Transfer failed');
}
function p2pSwap(OrderEIP712.OrderSig[] calldata orders, uint256[][] calldata tokenIds) public nonReentrant payable {
require(orders.length > 0 && orders.length == tokenIds.length, 'Swap:wrong items len.');
bytes32[] memory hashes = new bytes32[](orders.length);
uint256 sumOfExchange = 0;
for (uint256 i = 0; i < orders.length; i++) {
OrderEIP712.OrderSig calldata currentOrder = orders[i];
bytes32 currentOrderHash = hashBySig(currentOrder);
hashes[i] = currentOrderHash;
validateOrder(currentOrder, currentOrderHash, /* ignore check gas price */ true);
require(
tokenIds[i].length > 0 &&
tokenIds[i].length <= currentOrder.maxNumberOfDeals - dealsByHash[currentOrderHash],
'Swap: wrong tokens for order deals'
);
uint256 ethResult = 0;
for (uint256 j = 0; j < tokenIds[i].length; j++) {
transferTokenToSigner(
currentOrder.assetClass,
currentOrder.collection,
tokenIds[i][j],
msg.sender,
currentOrder.signer,
1
);
ethResult += currentOrder.price;
dealsByHash[currentOrderHash]++;
uint256 currentOrderFee = currentOrder.price.div(1000).mul(buyerFee);
emitExecuteOrderEvent(currentOrder, tokenIds[i][j], currentOrder.price, currentOrderFee);
}
uint256 fee = ethResult.div(1000).mul(buyerFee);
sumOfExchange += ethResult;
getEthFrom(currentOrder.signer, ethResult.add(fee));
}
uint256 sellerFeeActual = sumOfExchange.div(1000).mul(sellerFee);
uint256 buyerFeeActual = sumOfExchange.div(1000).mul(buyerFee);
require(sellerFeeActual == msg.value, 'Swap:wrong fee');
(bool senderTransaferSuccess,) = msg.sender.call{value: sumOfExchange}(''); // send eth to seller
require(senderTransaferSuccess, 'Swap:Sender transfer failed');
(bool ownerTransaferSuccess,) = owner().call{value: sellerFeeActual.add(buyerFeeActual)}(''); // send all fee to owner
require(ownerTransaferSuccess, 'Swap:Owner transfer failed');
emit ExecuteP2PSwap(msg.sender, hashes, tokenIds, buyerFeeActual, sellerFeeActual);
}
function emitExecuteOrderEvent(OrderEIP712.OrderSig memory order, uint256 tokenId, uint256 price, uint256 fee) internal {
bytes32 currentOrderHash = hashBySig(order);
uint16 dealNumber = dealsByHash[currentOrderHash];
if (dealNumber == 1) { // is new order
emit NewOrder(order, currentOrderHash);
}
emit ExecuteMatching(
currentOrderHash,
tokenId,
price,
dealNumber,
fee
);
}
function cancelOrder(OrderEIP712.OrderSig calldata order) public {
address signer = recoverSigner(order, DOMAIN_SEPARATOR);
require(signer == order.signer && signer == msg.sender, 'Swap:Wrong signer!');
bytes32 orderHash = hashBySig(order);
require(!cancelled[orderHash], 'Swap:Order already canceled!');
cancelled[orderHash] = true;
emit CancelOrder(msg.sender, orderHash);
}
function transferTokenToSigner(
bytes4 assetClass,
address collection,
uint256 tokenId,
address from,
address to,
uint256 value
) internal {
if (assetClass == ERC721_ASSET_CLASS) {
require(IERC721(collection).ownerOf(tokenId) == from, "Swap:wrong owner of token");
IERC721(collection).safeTransferFrom(from, to, tokenId);
} else if (assetClass == ERC1155_ASSET_CLASS) {
require(IERC1155(collection).balanceOf(from, tokenId) > 0, "Swap:wrong owner/count of token");
IERC1155(collection).safeTransferFrom(
from,
to,
tokenId,
value,
""
);
}
}
function recoverSigner(
OrderEIP712.OrderSig calldata _orderWithSig,
bytes32 _domainSeparator
) public pure returns (address){
return recoverSignerSimple(
hashBySig(_orderWithSig),
_orderWithSig.v,
_orderWithSig.r,
_orderWithSig.s,
_domainSeparator
);
}
function recoverSignerSimple(
bytes32 _hash,
uint8 _v,
bytes32 _r,
bytes32 _s,
bytes32 _domainSeparator
) public pure returns (address){
// \x19\x01 is the standardized encoding prefix
// https://eips.ethereum.org/EIPS/eip-712#specification
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", _domainSeparator, _hash));
return ECDSA.recover(digest, _v, _r, _s);
}
function hashBySig(OrderEIP712.OrderSig memory order) public pure returns (bytes32) {
return keccak256(
abi.encode(
OrderEIP712.ORDER_TYPEHASH_V1,
order.nonce,
order.signer,
order.collection,
order.price,
order.maxGasPrice,
order.maxNumberOfDeals,
order.expiration,
order.assetClass
)
);
}
function hash(OrderEIP712.Order memory _order) public pure returns (bytes32) {
return keccak256(
abi.encode(
OrderEIP712.ORDER_TYPEHASH_V1,
_order.nonce,
_order.signer,
_order.collection,
_order.price,
_order.maxGasPrice,
_order.maxNumberOfDeals,
_order.expiration,
_order.assetClass
)
);
}
function getEthFrom(address from, uint256 value) internal returns (uint256){
uint256 startGas = gasleft();
weth.transferFrom(from, address(this), value);
weth.withdraw(value);
return startGas - gasleft();
}
function validateOrder(
OrderEIP712.OrderSig calldata orderWithSig,
bytes32 orderHash,
bool ignoreCheckGas
) public view {
address signer = recoverSigner(orderWithSig, DOMAIN_SEPARATOR);
require(cancelled[orderHash] == false, 'Swap:Order cancelled');
require(
orderWithSig.assetClass == ERC721_ASSET_CLASS || orderWithSig.assetClass == ERC1155_ASSET_CLASS,
"Swap:wrong token type"
);
require(isActive, "Swap:Swap contract deactivated");
require(ignoreCheckGas || orderWithSig.maxGasPrice >= tx.gasprice, 'Swap:Wrong max of gas price!');
require(
dealsByHash[orderHash] < orderWithSig.maxNumberOfDeals ||
orderWithSig.maxNumberOfDeals == 0,
'Swap:Number of deals wrong'
);
require(signer == orderWithSig.signer, 'Swap:Wrong signer!');
require(orderWithSig.expiration == 0 || orderWithSig.expiration > block.timestamp, "Swap:Order expired");
}
function isValidSignature(bytes32 _hash, bytes memory _signature) override public pure returns (bytes4 magicValue) {
magicValue = IERC1271.isValidSignature.selector;
}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) override public pure returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) override public pure returns (bytes4) {
return IERC1155Receiver.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) override public pure returns (bytes4) {
return IERC1155Receiver.onERC1155BatchReceived.selector;
}
function supportsInterface(bytes4 interfaceId) override public pure returns (bool) {
// todo should be check
return true;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
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);
}
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a / b + (a % b == 0 ? 0 : 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../Strings.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} 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");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
// Check the signature length
// - case 65: r,s,v signature (standard)
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
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;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
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);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
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;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
library OrderEIP712 {
bytes32 constant ORDER_TYPEHASH_V1 = keccak256("Order(uint256 nonce,address signer,address collection,uint256 price,uint256 maxGasPrice,uint16 maxNumberOfDeals,uint256 expiration,bytes4 assetClass)");
bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
struct EIP712Domain {
string name;
string version;
uint256 chainId;
address verifyingContract;
}
struct Order {
uint256 nonce;
address signer;
address collection;
uint256 price;
uint256 maxGasPrice;
uint16 maxNumberOfDeals;
uint256 expiration;
bytes4 assetClass;
}
struct OrderSig {
uint256 nonce;
address signer;
address collection;
uint256 price;
uint256 maxGasPrice;
uint16 maxNumberOfDeals;
uint256 expiration;
bytes4 assetClass;
uint8 v;
bytes32 r;
bytes32 s;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
interface IWETH {
function approve(address guy, uint wad) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
function withdraw(uint) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
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);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
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);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed 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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"optimizer": {
"enabled": true,
"runs": 1000000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"wethAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"CancelOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"hash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"ErrorHandled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"currentDeal","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"ExecuteMatching","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32[]","name":"orderHash","type":"bytes32[]"},{"indexed":false,"internalType":"uint256[][]","name":"tokensIds","type":"uint256[][]"},{"indexed":false,"internalType":"uint256","name":"buyerFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sellerFee","type":"uint256"}],"name":"ExecuteP2PSwap","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"indexed":false,"internalType":"struct OrderEIP712.OrderSig","name":"order","type":"tuple"},{"indexed":true,"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"NewOrder","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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC1155_ASSET_CLASS","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC20_ASSET_CLASS","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC721_ASSET_CLASS","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_ASSET_CLASS","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyerFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct OrderEIP712.OrderSig","name":"order","type":"tuple"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"cancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"dealsByHash","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"}],"internalType":"struct OrderEIP712.Order","name":"_order","type":"tuple"}],"name":"hash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct OrderEIP712.OrderSig","name":"order","type":"tuple"}],"name":"hashBySig","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"operators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct OrderEIP712.OrderSig[]","name":"orders","type":"tuple[]"},{"internalType":"uint256[][]","name":"tokenIds","type":"uint256[][]"}],"name":"p2pSwap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct OrderEIP712.OrderSig","name":"_orderWithSig","type":"tuple"},{"internalType":"bytes32","name":"_domainSeparator","type":"bytes32"}],"name":"recoverSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"},{"internalType":"bytes32","name":"_domainSeparator","type":"bytes32"}],"name":"recoverSignerSimple","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellerFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"isActive_","type":"bool"}],"name":"setIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wethAddress","type":"address"}],"name":"setWethAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sellerFee","type":"uint256"},{"internalType":"uint256","name":"_buyerFee","type":"uint256"}],"name":"setupFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"access","type":"bool"}],"name":"setupOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct OrderEIP712.OrderSig","name":"orderWithSig","type":"tuple"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"}],"name":"universalSwap","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"uint16","name":"maxNumberOfDeals","type":"uint16"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes4","name":"assetClass","type":"bytes4"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct OrderEIP712.OrderSig","name":"orderWithSig","type":"tuple"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"bool","name":"ignoreCheckGas","type":"bool"}],"name":"validateOrder","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60016080819052603160f81b60a09081527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e09081527fbce316f0d9d2a3affa97de1d99bb2aac0538e2666d0d8545545ead241ef0ccab610100527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6610120524661014052306101605260c0829052610180604052206002556006805460ff1916909117905560006007819055600855348015620000bd57600080fd5b5060405162003d3138038062003d31833981016040819052620000e09162000246565b620000eb336200010f565b6001808055620000fd9033906200015f565b6200010881620001d9565b5062000278565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b03163314620001ae5760405162461bcd60e51b8152602060048201819052602482015260008051602062003d1183398151915260448201526064015b60405180910390fd5b6001600160a01b03919091166000908152600560205260409020805460ff1916911515919091179055565b6000546001600160a01b03163314620002245760405162461bcd60e51b8152602060048201819052602482015260008051602062003d118339815191526044820152606401620001a5565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6000602082840312156200025957600080fd5b81516001600160a01b03811681146200027157600080fd5b9392505050565b613a8980620002886000396000f3fe6080604052600436106102025760003560e01c8063715018a61161011d578063b4797da2116100b0578063de7ac2ea1161007f578063f23a6e6111610064578063f23a6e6114610724578063f2fde38b1461076a578063ffa1ad741461078a57600080fd5b8063de7ac2ea146106ee578063e1f3d55a1461070e57600080fd5b8063b4797da214610623578063bc197c8114610657578063c214be591461069f578063d5b80870146106d357600080fd5b8063a0b666b2116100ec578063a0b666b2146105a3578063a8db7712146105c3578063a96e2423146105e3578063af90b14d1461060357600080fd5b8063715018a6146105235780637f91077e1461053857806389721671146105585780638da5cb5b1461057857600080fd5b80633644e51511610195578063405bf27511610164578063405bf2751461048557806351f8bfc8146104b95780635de6c42f146104d95780636cd2c30a146104ef57600080fd5b80633644e515146103c65780633a8e4028146103dc5780633b502d33146104205780633fc8cef31461043357600080fd5b80631626ba7e116101d15780631626ba7e1461031857806322f3e2d41461035a5780632750fc78146103745780632ac126221461039657600080fd5b806301ffc9a71461020e5780630927bc1b1461024457806313e7c9d814610272578063150b7a02146102a257600080fd5b3661020957005b600080fd5b34801561021a57600080fd5b5061022f6102293660046131c8565b50600190565b60405190151581526020015b60405180910390f35b34801561025057600080fd5b5061026461025f3660046132e9565b6107e0565b60405190815260200161023b565b34801561027e57600080fd5b5061022f61028d366004612e2c565b60056020526000908152604090205460ff1681565b3480156102ae57600080fd5b506102e76102bd366004612f25565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161023b565b34801561032457600080fd5b506102e761033336600461313b565b507f1626ba7e00000000000000000000000000000000000000000000000000000000919050565b34801561036657600080fd5b5060065461022f9060ff1681565b34801561038057600080fd5b5061039461038f3660046130e8565b6108d9565b005b3480156103a257600080fd5b5061022f6103b1366004613122565b60046020526000908152604090205460ff1681565b3480156103d257600080fd5b5061026460025481565b3480156103e857600080fd5b5061040d6103f7366004613122565b60036020526000908152604090205461ffff1681565b60405161ffff909116815260200161023b565b61039461042e36600461304d565b610990565b34801561043f57600080fd5b506009546104609073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023b565b34801561049157600080fd5b506102e77f973bb64086f173ec8099b7ed3d43da984f4a332e4417a08bc6a286e6402b058681565b3480156104c557600080fd5b506103946104d43660046132a5565b6110b2565b3480156104e557600080fd5b5061026460085481565b3480156104fb57600080fd5b506102e77f8ae85d849167ff996c04040c44924fd364217285e4cad818292c7ac37c0a345b81565b34801561052f57600080fd5b50610394611503565b34801561054457600080fd5b506103946105533660046131e3565b611590565b34801561056457600080fd5b5061039461057336600461347d565b61175b565b34801561058457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610460565b3480156105af57600080fd5b506104606105be366004613278565b61185f565b3480156105cf57600080fd5b506104606105de366004613182565b6118a1565b3480156105ef57600080fd5b506103946105fe366004612e2c565b61190f565b34801561060f57600080fd5b5061039461061e366004613014565b6119d7565b34801561062f57600080fd5b506102e77faaaebeba3810b1e6b70781f14b2d72c1cb89c0b2b320c43bb67ff79f562f5ff481565b34801561066357600080fd5b506102e7610672366004612e66565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b3480156106ab57600080fd5b506102e77f73ad2146b3d3a286642c794379d750360a2d53a3459a11b3e5d6cc900f55f44a81565b3480156106df57600080fd5b5061026461025f36600461339b565b3480156106fa57600080fd5b5061022f610709366004613200565b611aae565b34801561071a57600080fd5b5061026460075481565b34801561073057600080fd5b506102e761073f366004612f98565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b34801561077657600080fd5b50610394610785366004612e2c565b612107565b34801561079657600080fd5b506107d36040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60405161023b9190613646565b60007f0c69e170449ec07dc6f72e9f5f3bbcbec8a37a162e76128a714095e96b7f200e826000015183602001518460400151856060015186608001518760a001518860c001518960e001516040516020016108bc99989796959493929190988952602089019790975273ffffffffffffffffffffffffffffffffffffffff9586166040890152939094166060870152608086019190915260a085015261ffff9190911660c084015260e08301527fffffffff00000000000000000000000000000000000000000000000000000000166101008201526101200190565b604051602081830303815290604052805190602001209050919050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461095f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600260015414156109fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610956565b60026001558215801590610a1057508281145b610a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f537761703a77726f6e67206974656d73206c656e2e00000000000000000000006044820152606401610956565b60008367ffffffffffffffff811115610a9157610a916139f4565b604051908082528060200260200182016040528015610aba578160200160208202803683370190505b5090506000805b85811015610e295736878783818110610adc57610adc6139c5565b9050610160020190506000610afb8280360381019061025f91906132e9565b905080858481518110610b1057610b106139c5565b602002602001018181525050610b28828260016110b2565b6000878785818110610b3c57610b3c6139c5565b9050602002810190610b4e9190613784565b9050118015610bb2575060008181526003602052604090205461ffff16610b7b60c0840160a08501613449565b610b8591906138a6565b61ffff16878785818110610b9b57610b9b6139c5565b9050602002810190610bad9190613784565b905011155b610c3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f537761703a2077726f6e6720746f6b656e7320666f72206f726465722064656160448201527f6c730000000000000000000000000000000000000000000000000000000000006064820152608401610956565b6000805b888886818110610c5457610c546139c5565b9050602002810190610c669190613784565b9050811015610dca57610ce9610c83610100860160e087016131c8565b610c936060870160408801612e2c565b8b8b89818110610ca557610ca56139c5565b9050602002810190610cb79190613784565b85818110610cc757610cc76139c5565b9050602002013533886020016020810190610ce29190612e2c565b6001612237565b610cf7606085013583613816565b6000848152600360205260408120805492945061ffff9092169190610d1b8361390c565b91906101000a81548161ffff021916908361ffff160217905550506000610d5d600854610d576103e8886060013561263d90919063ffffffff16565b90612649565b9050610db7610d71368790038701876132e9565b8b8b89818110610d8357610d836139c5565b9050602002810190610d959190613784565b85818110610da557610da56139c5565b90506020020135876060013584612655565b5080610dc28161392e565b915050610c42565b50600854600090610de190610d57846103e861263d565b9050610ded8287613816565b9550610e11610e026040860160208701612e2c565b610e0c848461270d565b612719565b50505050508080610e219061392e565b915050610ac1565b50600754600090610e4090610d57846103e861263d565b90506000610e5f600854610d576103e88661263d90919063ffffffff16565b9050348214610eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f537761703a77726f6e67206665650000000000000000000000000000000000006044820152606401610956565b604051600090339085908381818185875af1925050503d8060008114610f0c576040519150601f19603f3d011682016040523d82523d6000602084013e610f11565b606091505b5050905080610f7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f537761703a53656e646572207472616e73666572206661696c656400000000006044820152606401610956565b6000805473ffffffffffffffffffffffffffffffffffffffff16610fa0858561270d565b604051600081818185875af1925050503d8060008114610fdc576040519150601f19603f3d011682016040523d82523d6000602084013e610fe1565b606091505b505090508061104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f537761703a4f776e6572207472616e73666572206661696c65640000000000006044820152606401610956565b3373ffffffffffffffffffffffffffffffffffffffff167ff6a5b297a590cc300a0fbb928182a37455a1aff7aab75bb777077a7ee405048a878a8a878960405161109a959493929190613525565b60405180910390a25050600180555050505050505050565b60006110c08460025461185f565b60008481526004602052604090205490915060ff161561113c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f537761703a4f726465722063616e63656c6c65640000000000000000000000006044820152606401610956565b7f73ad21460000000000000000000000000000000000000000000000000000000061116e610100860160e087016131c8565b7fffffffff000000000000000000000000000000000000000000000000000000001614806111ed57507f973bb640000000000000000000000000000000000000000000000000000000006111c9610100860160e087016131c8565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b611253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f537761703a77726f6e6720746f6b656e207479706500000000000000000000006044820152606401610956565b60065460ff166112bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f537761703a5377617020636f6e747261637420646561637469766174656400006044820152606401610956565b81806112cf57503a846080013510155b611335576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f537761703a57726f6e67206d6178206f662067617320707269636521000000006044820152606401610956565b61134560c0850160a08601613449565b60008481526003602052604090205461ffff91821691161080611379575061137360c0850160a08601613449565b61ffff16155b6113df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f537761703a4e756d626572206f66206465616c732077726f6e670000000000006044820152606401610956565b6113ef6040850160208601612e2c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f537761703a57726f6e67207369676e65722100000000000000000000000000006044820152606401610956565b60c084013515806114975750428460c00135115b6114fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f537761703a4f72646572206578706972656400000000000000000000000000006044820152606401610956565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b61158e6000612869565b565b600061159e8260025461185f565b90506115b06040830160208401612e2c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480156115ff575073ffffffffffffffffffffffffffffffffffffffff811633145b611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f537761703a57726f6e67207369676e65722100000000000000000000000000006044820152606401610956565b600061167961025f368590038501856132e9565b60008181526004602052604090205490915060ff16156116f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f537761703a4f7264657220616c72656164792063616e63656c656421000000006044820152606401610956565b60008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551829133917f7b8dc5f614ab474fc886dc13b2af4d505615bd653fd58d7117d91fec5e25b44d9190a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b601482111580156117ee575060148111155b611854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f537761703a66656520746f6f206d7563682e206d6178203230202832252900006044820152606401610956565b600791909155600855565b600061189a61187661025f368690038601866132e9565b6118886101208601610100870161349f565b856101200135866101400135866118a1565b9392505050565b6040517f1901000000000000000000000000000000000000000000000000000000000000602082015260228101829052604281018690526000908190606201604051602081830303815290604052805190602001209050611904818787876128de565b979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b3360009081526005602052604081205460ff16611b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f537761703a206163636573732064656e696564000000000000000000000000006044820152606401610956565b60026001541415611b94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610956565b600260015560005a90506000611bb261025f368a90038a018a6132e9565b9050611bc0888260006110b2565b6000611bdb611bd560408b0160208c01612e2c565b86612719565b90508489606001351015611c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f537761703a57726f6e6720746f6b656e207072696365000000000000000000006044820152606401610956565b73ffffffffffffffffffffffffffffffffffffffff881615801590611c86575073ffffffffffffffffffffffffffffffffffffffff88163014155b8015611cad575060095473ffffffffffffffffffffffffffffffffffffffff898116911614155b611d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f537761703a57726f6e67207461726765742061646472657373000000000000006044820152606401610956565b8773ffffffffffffffffffffffffffffffffffffffff168588604051611d399190613509565b60006040518083038185875af1925050503d8060008114611d76576040519150601f19603f3d011682016040523d82523d6000602084013e611d7b565b606091505b50508094505060008415611e3757611dc2611d9d6101008c0160e08d016131c8565b611dad60608d0160408e01612e2c565b89308e6020016020810190610ce29190612e2c565b6000838152600360205260408120805461ffff1691611de08361390c565b91906101000a81548161ffff021916908361ffff16021790555050611e16600854610d576103e88961263d90919063ffffffff16565b9050611e32611e2a368c90038c018c6132e9565b888884612655565b612000565b7f586e050b392ec4af7264b50cb1b978c1189e3e733ad78c3ad47fd6901e23daa183604051611e9d9181526040602082018190526015908201527f65787465726e616c206d61726b6574206572726f720000000000000000000000606082015260800190565b60405180910390a1600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f0f57600080fd5b505af1158015611f23573d6000803e3d6000fd5b505060095473ffffffffffffffffffffffffffffffffffffffff16925063a9059cbb9150611f59905060408d0160208e01612e2c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101899052604401602060405180830381600087803b158015611fc657600080fd5b505af1158015611fda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ffe9190613105565b505b60006120258261201f3a610d57611b5861201f895a61201f908e6138c9565b9061270d565b905061204061203a60408d0160208e01612e2c565b82612719565b50604051600090339083908381818185875af1925050503d8060008114612083576040519150601f19603f3d011682016040523d82523d6000602084013e612088565b606091505b50509050806120f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f537761703a5472616e73666572206661696c65640000000000000000000000006044820152606401610956565b505060018055509298975050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b73ffffffffffffffffffffffffffffffffffffffff811661222b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610956565b61223481612869565b50565b7fffffffff0000000000000000000000000000000000000000000000000000000086167f73ad2146000000000000000000000000000000000000000000000000000000001415612436576040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8085169190871690636352211e9060240160206040518083038186803b1580156122ec57600080fd5b505afa158015612300573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123249190612e49565b73ffffffffffffffffffffffffffffffffffffffff16146123a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f537761703a77726f6e67206f776e6572206f6620746f6b656e000000000000006044820152606401610956565b6040517f42842e0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018690528616906342842e0e90606401600060405180830381600087803b15801561241957600080fd5b505af115801561242d573d6000803e3d6000fd5b50505050612635565b7fffffffff0000000000000000000000000000000000000000000000000000000086167f973bb640000000000000000000000000000000000000000000000000000000001415612635576040517efdd58e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018690526000919087169062fdd58e9060440160206040518083038186803b1580156124f057600080fd5b505afa158015612504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125289190613464565b1161258f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f537761703a77726f6e67206f776e65722f636f756e74206f6620746f6b656e006044820152606401610956565b6040517ff242432a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018690526064820183905260a06084830152600060a483015286169063f242432a9060c401600060405180830381600087803b15801561261c57600080fd5b505af1158015612630573d6000803e3d6000fd5b505050505b505050505050565b600061189a828461382e565b600061189a8284613869565b6000612660856107e0565b60008181526003602052604090205490915061ffff1660018114156126b857817fee3cce64688f93f221dcfdbb23bd224252db9043cb13a3952371555884f44d80876040516126af9190613697565b60405180910390a25b604080518681526020810186905261ffff83168183015260608101859052905183917ffc65f398f80f1cf5f8259839d65626d5afe627bf9a9a946c840491e60882bd35919081900360800190a2505050505050565b600061189a8284613816565b6000805a6009546040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152306024830152604482018790529293509116906323b872dd90606401602060405180830381600087803b15801561279957600080fd5b505af11580156127ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d19190613105565b506009546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561283e57600080fd5b505af1158015612852573d6000803e3d6000fd5b505050505a61286190826138c9565b949350505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060006128ef87878787612906565b915091506128fc81612a1e565b5095945050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561293d5750600090506003612a15565b8460ff16601b1415801561295557508460ff16601c14155b156129665750600090506004612a15565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129ba573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0e57600060019250925050612a15565b9150600090505b94509492505050565b6000816004811115612a3257612a32613996565b1415612a3b5750565b6001816004811115612a4f57612a4f613996565b1415612ab7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610956565b6002816004811115612acb57612acb613996565b1415612b33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610956565b6003816004811115612b4757612b47613996565b1415612bd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610956565b6004816004811115612be957612be9613996565b1415612234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610956565b8035612c8281613a23565b919050565b60008083601f840112612c9957600080fd5b50813567ffffffffffffffff811115612cb157600080fd5b6020830191508360208260051b8501011115612ccc57600080fd5b9250929050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612c8257600080fd5b60008083601f840112612d1557600080fd5b50813567ffffffffffffffff811115612d2d57600080fd5b602083019150836020828501011115612ccc57600080fd5b600082601f830112612d5657600080fd5b813567ffffffffffffffff80821115612d7157612d716139f4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612db757612db76139f4565b81604052838152866020858801011115612dd057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101608284031215612e0357600080fd5b50919050565b803561ffff81168114612c8257600080fd5b803560ff81168114612c8257600080fd5b600060208284031215612e3e57600080fd5b813561189a81613a23565b600060208284031215612e5b57600080fd5b815161189a81613a23565b60008060008060008060008060a0898b031215612e8257600080fd5b8835612e8d81613a23565b97506020890135612e9d81613a23565b9650604089013567ffffffffffffffff80821115612eba57600080fd5b612ec68c838d01612c87565b909850965060608b0135915080821115612edf57600080fd5b612eeb8c838d01612c87565b909650945060808b0135915080821115612f0457600080fd5b50612f118b828c01612d03565b999c989b5096995094979396929594505050565b600080600080600060808688031215612f3d57600080fd5b8535612f4881613a23565b94506020860135612f5881613a23565b935060408601359250606086013567ffffffffffffffff811115612f7b57600080fd5b612f8788828901612d03565b969995985093965092949392505050565b60008060008060008060a08789031215612fb157600080fd5b8635612fbc81613a23565b95506020870135612fcc81613a23565b94506040870135935060608701359250608087013567ffffffffffffffff811115612ff657600080fd5b61300289828a01612d03565b979a9699509497509295939492505050565b6000806040838503121561302757600080fd5b823561303281613a23565b9150602083013561304281613a45565b809150509250929050565b6000806000806040858703121561306357600080fd5b843567ffffffffffffffff8082111561307b57600080fd5b818701915087601f83011261308f57600080fd5b81358181111561309e57600080fd5b886020610160830285010111156130b457600080fd5b6020928301965094509086013590808211156130cf57600080fd5b506130dc87828801612c87565b95989497509550505050565b6000602082840312156130fa57600080fd5b813561189a81613a45565b60006020828403121561311757600080fd5b815161189a81613a45565b60006020828403121561313457600080fd5b5035919050565b6000806040838503121561314e57600080fd5b82359150602083013567ffffffffffffffff81111561316c57600080fd5b61317885828601612d45565b9150509250929050565b600080600080600060a0868803121561319a57600080fd5b853594506131aa60208701612e1b565b94979496505050506040830135926060810135926080909101359150565b6000602082840312156131da57600080fd5b61189a82612cd3565b600061016082840312156131f657600080fd5b61189a8383612df0565b60008060008060006101e0868803121561321957600080fd5b6132238787612df0565b945061016086013561323481613a23565b935061018086013567ffffffffffffffff81111561325157600080fd5b61325d88828901612d45565b959894975094956101a081013595506101c001359392505050565b600080610180838503121561328c57600080fd5b6132968484612df0565b94610160939093013593505050565b60008060006101a084860312156132bb57600080fd5b6132c58585612df0565b925061016084013591506101808401356132de81613a45565b809150509250925092565b600061016082840312156132fc57600080fd5b6133046137ec565b8235815261331460208401612c77565b602082015261332560408401612c77565b6040820152606083013560608201526080830135608082015261334a60a08401612e09565b60a082015260c083013560c082015261336560e08401612cd3565b60e0820152610100613378818501612e1b565b908201526101208381013590820152610140928301359281019290925250919050565b60006101008083850312156133af57600080fd5b6040519081019067ffffffffffffffff821181831017156133d2576133d26139f4565b8160405283358152602084013591506133ea82613a23565b8160208201526133fc60408501612c77565b6040820152606084013560608201526080840135608082015261342160a08501612e09565b60a082015260c084013560c082015261343c60e08501612cd3565b60e0820152949350505050565b60006020828403121561345b57600080fd5b61189a82612e09565b60006020828403121561347657600080fd5b5051919050565b6000806040838503121561349057600080fd5b50508035926020909101359150565b6000602082840312156134b157600080fd5b61189a82612e1b565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156134ec57600080fd5b8260051b8083602087013760009401602001938452509192915050565b6000825161351b8184602087016138e0565b9190910192915050565b6080808252865190820181905260009060209060a0840190828a01845b8281101561355e57815184529284019290840190600101613542565b50505083810382850152868152818101600588811b830184018a60005b8b811015613627577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18e36030181126135dc57600080fd5b8d01803567ffffffffffffffff8111156135f557600080fd5b80861b36038f131561360657600080fd5b61361385828b85016134ba565b96890196945050509086019060010161357b565b5050604087019890985250505050606090910191909152509392505050565b60208152600082518060208401526136658160408501602087016138e0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b815181526020808301516101608301916136c89084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516136f0604084018273ffffffffffffffffffffffffffffffffffffffff169052565b50606083015160608301526080830151608083015260a083015161371a60a084018261ffff169052565b5060c083015160c083015260e083015161375860e08401827fffffffff00000000000000000000000000000000000000000000000000000000169052565b506101008381015160ff1690830152610120808401519083015261014092830151929091019190915290565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137b957600080fd5b83018035915067ffffffffffffffff8211156137d457600080fd5b6020019150600581901b3603821315612ccc57600080fd5b604051610160810167ffffffffffffffff81118282101715613810576138106139f4565b60405290565b6000821982111561382957613829613967565b500190565b600082613864577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156138a1576138a1613967565b500290565b600061ffff838116908316818110156138c1576138c1613967565b039392505050565b6000828210156138db576138db613967565b500390565b60005b838110156138fb5781810151838201526020016138e3565b838111156114fd5750506000910152565b600061ffff8083168181141561392457613924613967565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561396057613960613967565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461223457600080fd5b801515811461223457600080fdfea26469706673582212202626193b59bdbc4ab9f47424af3e703c008cad46b5f06199af0e229502ff5f5464736f6c634300080600334f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x6080604052600436106102025760003560e01c8063715018a61161011d578063b4797da2116100b0578063de7ac2ea1161007f578063f23a6e6111610064578063f23a6e6114610724578063f2fde38b1461076a578063ffa1ad741461078a57600080fd5b8063de7ac2ea146106ee578063e1f3d55a1461070e57600080fd5b8063b4797da214610623578063bc197c8114610657578063c214be591461069f578063d5b80870146106d357600080fd5b8063a0b666b2116100ec578063a0b666b2146105a3578063a8db7712146105c3578063a96e2423146105e3578063af90b14d1461060357600080fd5b8063715018a6146105235780637f91077e1461053857806389721671146105585780638da5cb5b1461057857600080fd5b80633644e51511610195578063405bf27511610164578063405bf2751461048557806351f8bfc8146104b95780635de6c42f146104d95780636cd2c30a146104ef57600080fd5b80633644e515146103c65780633a8e4028146103dc5780633b502d33146104205780633fc8cef31461043357600080fd5b80631626ba7e116101d15780631626ba7e1461031857806322f3e2d41461035a5780632750fc78146103745780632ac126221461039657600080fd5b806301ffc9a71461020e5780630927bc1b1461024457806313e7c9d814610272578063150b7a02146102a257600080fd5b3661020957005b600080fd5b34801561021a57600080fd5b5061022f6102293660046131c8565b50600190565b60405190151581526020015b60405180910390f35b34801561025057600080fd5b5061026461025f3660046132e9565b6107e0565b60405190815260200161023b565b34801561027e57600080fd5b5061022f61028d366004612e2c565b60056020526000908152604090205460ff1681565b3480156102ae57600080fd5b506102e76102bd366004612f25565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161023b565b34801561032457600080fd5b506102e761033336600461313b565b507f1626ba7e00000000000000000000000000000000000000000000000000000000919050565b34801561036657600080fd5b5060065461022f9060ff1681565b34801561038057600080fd5b5061039461038f3660046130e8565b6108d9565b005b3480156103a257600080fd5b5061022f6103b1366004613122565b60046020526000908152604090205460ff1681565b3480156103d257600080fd5b5061026460025481565b3480156103e857600080fd5b5061040d6103f7366004613122565b60036020526000908152604090205461ffff1681565b60405161ffff909116815260200161023b565b61039461042e36600461304d565b610990565b34801561043f57600080fd5b506009546104609073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023b565b34801561049157600080fd5b506102e77f973bb64086f173ec8099b7ed3d43da984f4a332e4417a08bc6a286e6402b058681565b3480156104c557600080fd5b506103946104d43660046132a5565b6110b2565b3480156104e557600080fd5b5061026460085481565b3480156104fb57600080fd5b506102e77f8ae85d849167ff996c04040c44924fd364217285e4cad818292c7ac37c0a345b81565b34801561052f57600080fd5b50610394611503565b34801561054457600080fd5b506103946105533660046131e3565b611590565b34801561056457600080fd5b5061039461057336600461347d565b61175b565b34801561058457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610460565b3480156105af57600080fd5b506104606105be366004613278565b61185f565b3480156105cf57600080fd5b506104606105de366004613182565b6118a1565b3480156105ef57600080fd5b506103946105fe366004612e2c565b61190f565b34801561060f57600080fd5b5061039461061e366004613014565b6119d7565b34801561062f57600080fd5b506102e77faaaebeba3810b1e6b70781f14b2d72c1cb89c0b2b320c43bb67ff79f562f5ff481565b34801561066357600080fd5b506102e7610672366004612e66565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b3480156106ab57600080fd5b506102e77f73ad2146b3d3a286642c794379d750360a2d53a3459a11b3e5d6cc900f55f44a81565b3480156106df57600080fd5b5061026461025f36600461339b565b3480156106fa57600080fd5b5061022f610709366004613200565b611aae565b34801561071a57600080fd5b5061026460075481565b34801561073057600080fd5b506102e761073f366004612f98565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b34801561077657600080fd5b50610394610785366004612e2c565b612107565b34801561079657600080fd5b506107d36040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60405161023b9190613646565b60007f0c69e170449ec07dc6f72e9f5f3bbcbec8a37a162e76128a714095e96b7f200e826000015183602001518460400151856060015186608001518760a001518860c001518960e001516040516020016108bc99989796959493929190988952602089019790975273ffffffffffffffffffffffffffffffffffffffff9586166040890152939094166060870152608086019190915260a085015261ffff9190911660c084015260e08301527fffffffff00000000000000000000000000000000000000000000000000000000166101008201526101200190565b604051602081830303815290604052805190602001209050919050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461095f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600260015414156109fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610956565b60026001558215801590610a1057508281145b610a76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f537761703a77726f6e67206974656d73206c656e2e00000000000000000000006044820152606401610956565b60008367ffffffffffffffff811115610a9157610a916139f4565b604051908082528060200260200182016040528015610aba578160200160208202803683370190505b5090506000805b85811015610e295736878783818110610adc57610adc6139c5565b9050610160020190506000610afb8280360381019061025f91906132e9565b905080858481518110610b1057610b106139c5565b602002602001018181525050610b28828260016110b2565b6000878785818110610b3c57610b3c6139c5565b9050602002810190610b4e9190613784565b9050118015610bb2575060008181526003602052604090205461ffff16610b7b60c0840160a08501613449565b610b8591906138a6565b61ffff16878785818110610b9b57610b9b6139c5565b9050602002810190610bad9190613784565b905011155b610c3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f537761703a2077726f6e6720746f6b656e7320666f72206f726465722064656160448201527f6c730000000000000000000000000000000000000000000000000000000000006064820152608401610956565b6000805b888886818110610c5457610c546139c5565b9050602002810190610c669190613784565b9050811015610dca57610ce9610c83610100860160e087016131c8565b610c936060870160408801612e2c565b8b8b89818110610ca557610ca56139c5565b9050602002810190610cb79190613784565b85818110610cc757610cc76139c5565b9050602002013533886020016020810190610ce29190612e2c565b6001612237565b610cf7606085013583613816565b6000848152600360205260408120805492945061ffff9092169190610d1b8361390c565b91906101000a81548161ffff021916908361ffff160217905550506000610d5d600854610d576103e8886060013561263d90919063ffffffff16565b90612649565b9050610db7610d71368790038701876132e9565b8b8b89818110610d8357610d836139c5565b9050602002810190610d959190613784565b85818110610da557610da56139c5565b90506020020135876060013584612655565b5080610dc28161392e565b915050610c42565b50600854600090610de190610d57846103e861263d565b9050610ded8287613816565b9550610e11610e026040860160208701612e2c565b610e0c848461270d565b612719565b50505050508080610e219061392e565b915050610ac1565b50600754600090610e4090610d57846103e861263d565b90506000610e5f600854610d576103e88661263d90919063ffffffff16565b9050348214610eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f537761703a77726f6e67206665650000000000000000000000000000000000006044820152606401610956565b604051600090339085908381818185875af1925050503d8060008114610f0c576040519150601f19603f3d011682016040523d82523d6000602084013e610f11565b606091505b5050905080610f7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f537761703a53656e646572207472616e73666572206661696c656400000000006044820152606401610956565b6000805473ffffffffffffffffffffffffffffffffffffffff16610fa0858561270d565b604051600081818185875af1925050503d8060008114610fdc576040519150601f19603f3d011682016040523d82523d6000602084013e610fe1565b606091505b505090508061104c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f537761703a4f776e6572207472616e73666572206661696c65640000000000006044820152606401610956565b3373ffffffffffffffffffffffffffffffffffffffff167ff6a5b297a590cc300a0fbb928182a37455a1aff7aab75bb777077a7ee405048a878a8a878960405161109a959493929190613525565b60405180910390a25050600180555050505050505050565b60006110c08460025461185f565b60008481526004602052604090205490915060ff161561113c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f537761703a4f726465722063616e63656c6c65640000000000000000000000006044820152606401610956565b7f73ad21460000000000000000000000000000000000000000000000000000000061116e610100860160e087016131c8565b7fffffffff000000000000000000000000000000000000000000000000000000001614806111ed57507f973bb640000000000000000000000000000000000000000000000000000000006111c9610100860160e087016131c8565b7fffffffff0000000000000000000000000000000000000000000000000000000016145b611253576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f537761703a77726f6e6720746f6b656e207479706500000000000000000000006044820152606401610956565b60065460ff166112bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f537761703a5377617020636f6e747261637420646561637469766174656400006044820152606401610956565b81806112cf57503a846080013510155b611335576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f537761703a57726f6e67206d6178206f662067617320707269636521000000006044820152606401610956565b61134560c0850160a08601613449565b60008481526003602052604090205461ffff91821691161080611379575061137360c0850160a08601613449565b61ffff16155b6113df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f537761703a4e756d626572206f66206465616c732077726f6e670000000000006044820152606401610956565b6113ef6040850160208601612e2c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f537761703a57726f6e67207369676e65722100000000000000000000000000006044820152606401610956565b60c084013515806114975750428460c00135115b6114fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f537761703a4f72646572206578706972656400000000000000000000000000006044820152606401610956565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b61158e6000612869565b565b600061159e8260025461185f565b90506115b06040830160208401612e2c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480156115ff575073ffffffffffffffffffffffffffffffffffffffff811633145b611665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f537761703a57726f6e67207369676e65722100000000000000000000000000006044820152606401610956565b600061167961025f368590038501856132e9565b60008181526004602052604090205490915060ff16156116f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f537761703a4f7264657220616c72656164792063616e63656c656421000000006044820152606401610956565b60008181526004602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551829133917f7b8dc5f614ab474fc886dc13b2af4d505615bd653fd58d7117d91fec5e25b44d9190a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b601482111580156117ee575060148111155b611854576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f537761703a66656520746f6f206d7563682e206d6178203230202832252900006044820152606401610956565b600791909155600855565b600061189a61187661025f368690038601866132e9565b6118886101208601610100870161349f565b856101200135866101400135866118a1565b9392505050565b6040517f1901000000000000000000000000000000000000000000000000000000000000602082015260228101829052604281018690526000908190606201604051602081830303815290604052805190602001209050611904818787876128de565b979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611990576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b3360009081526005602052604081205460ff16611b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f537761703a206163636573732064656e696564000000000000000000000000006044820152606401610956565b60026001541415611b94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610956565b600260015560005a90506000611bb261025f368a90038a018a6132e9565b9050611bc0888260006110b2565b6000611bdb611bd560408b0160208c01612e2c565b86612719565b90508489606001351015611c4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f537761703a57726f6e6720746f6b656e207072696365000000000000000000006044820152606401610956565b73ffffffffffffffffffffffffffffffffffffffff881615801590611c86575073ffffffffffffffffffffffffffffffffffffffff88163014155b8015611cad575060095473ffffffffffffffffffffffffffffffffffffffff898116911614155b611d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f537761703a57726f6e67207461726765742061646472657373000000000000006044820152606401610956565b8773ffffffffffffffffffffffffffffffffffffffff168588604051611d399190613509565b60006040518083038185875af1925050503d8060008114611d76576040519150601f19603f3d011682016040523d82523d6000602084013e611d7b565b606091505b50508094505060008415611e3757611dc2611d9d6101008c0160e08d016131c8565b611dad60608d0160408e01612e2c565b89308e6020016020810190610ce29190612e2c565b6000838152600360205260408120805461ffff1691611de08361390c565b91906101000a81548161ffff021916908361ffff16021790555050611e16600854610d576103e88961263d90919063ffffffff16565b9050611e32611e2a368c90038c018c6132e9565b888884612655565b612000565b7f586e050b392ec4af7264b50cb1b978c1189e3e733ad78c3ad47fd6901e23daa183604051611e9d9181526040602082018190526015908201527f65787465726e616c206d61726b6574206572726f720000000000000000000000606082015260800190565b60405180910390a1600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611f0f57600080fd5b505af1158015611f23573d6000803e3d6000fd5b505060095473ffffffffffffffffffffffffffffffffffffffff16925063a9059cbb9150611f59905060408d0160208e01612e2c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101899052604401602060405180830381600087803b158015611fc657600080fd5b505af1158015611fda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ffe9190613105565b505b60006120258261201f3a610d57611b5861201f895a61201f908e6138c9565b9061270d565b905061204061203a60408d0160208e01612e2c565b82612719565b50604051600090339083908381818185875af1925050503d8060008114612083576040519150601f19603f3d011682016040523d82523d6000602084013e612088565b606091505b50509050806120f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f537761703a5472616e73666572206661696c65640000000000000000000000006044820152606401610956565b505060018055509298975050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610956565b73ffffffffffffffffffffffffffffffffffffffff811661222b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610956565b61223481612869565b50565b7fffffffff0000000000000000000000000000000000000000000000000000000086167f73ad2146000000000000000000000000000000000000000000000000000000001415612436576040517f6352211e0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8085169190871690636352211e9060240160206040518083038186803b1580156122ec57600080fd5b505afa158015612300573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123249190612e49565b73ffffffffffffffffffffffffffffffffffffffff16146123a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f537761703a77726f6e67206f776e6572206f6620746f6b656e000000000000006044820152606401610956565b6040517f42842e0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018690528616906342842e0e90606401600060405180830381600087803b15801561241957600080fd5b505af115801561242d573d6000803e3d6000fd5b50505050612635565b7fffffffff0000000000000000000000000000000000000000000000000000000086167f973bb640000000000000000000000000000000000000000000000000000000001415612635576040517efdd58e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018690526000919087169062fdd58e9060440160206040518083038186803b1580156124f057600080fd5b505afa158015612504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125289190613464565b1161258f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f537761703a77726f6e67206f776e65722f636f756e74206f6620746f6b656e006044820152606401610956565b6040517ff242432a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301528381166024830152604482018690526064820183905260a06084830152600060a483015286169063f242432a9060c401600060405180830381600087803b15801561261c57600080fd5b505af1158015612630573d6000803e3d6000fd5b505050505b505050505050565b600061189a828461382e565b600061189a8284613869565b6000612660856107e0565b60008181526003602052604090205490915061ffff1660018114156126b857817fee3cce64688f93f221dcfdbb23bd224252db9043cb13a3952371555884f44d80876040516126af9190613697565b60405180910390a25b604080518681526020810186905261ffff83168183015260608101859052905183917ffc65f398f80f1cf5f8259839d65626d5afe627bf9a9a946c840491e60882bd35919081900360800190a2505050505050565b600061189a8284613816565b6000805a6009546040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8781166004830152306024830152604482018790529293509116906323b872dd90606401602060405180830381600087803b15801561279957600080fd5b505af11580156127ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d19190613105565b506009546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90602401600060405180830381600087803b15801561283e57600080fd5b505af1158015612852573d6000803e3d6000fd5b505050505a61286190826138c9565b949350505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060006128ef87878787612906565b915091506128fc81612a1e565b5095945050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561293d5750600090506003612a15565b8460ff16601b1415801561295557508460ff16601c14155b156129665750600090506004612a15565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156129ba573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a0e57600060019250925050612a15565b9150600090505b94509492505050565b6000816004811115612a3257612a32613996565b1415612a3b5750565b6001816004811115612a4f57612a4f613996565b1415612ab7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610956565b6002816004811115612acb57612acb613996565b1415612b33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610956565b6003816004811115612b4757612b47613996565b1415612bd5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610956565b6004816004811115612be957612be9613996565b1415612234576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610956565b8035612c8281613a23565b919050565b60008083601f840112612c9957600080fd5b50813567ffffffffffffffff811115612cb157600080fd5b6020830191508360208260051b8501011115612ccc57600080fd5b9250929050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114612c8257600080fd5b60008083601f840112612d1557600080fd5b50813567ffffffffffffffff811115612d2d57600080fd5b602083019150836020828501011115612ccc57600080fd5b600082601f830112612d5657600080fd5b813567ffffffffffffffff80821115612d7157612d716139f4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612db757612db76139f4565b81604052838152866020858801011115612dd057600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006101608284031215612e0357600080fd5b50919050565b803561ffff81168114612c8257600080fd5b803560ff81168114612c8257600080fd5b600060208284031215612e3e57600080fd5b813561189a81613a23565b600060208284031215612e5b57600080fd5b815161189a81613a23565b60008060008060008060008060a0898b031215612e8257600080fd5b8835612e8d81613a23565b97506020890135612e9d81613a23565b9650604089013567ffffffffffffffff80821115612eba57600080fd5b612ec68c838d01612c87565b909850965060608b0135915080821115612edf57600080fd5b612eeb8c838d01612c87565b909650945060808b0135915080821115612f0457600080fd5b50612f118b828c01612d03565b999c989b5096995094979396929594505050565b600080600080600060808688031215612f3d57600080fd5b8535612f4881613a23565b94506020860135612f5881613a23565b935060408601359250606086013567ffffffffffffffff811115612f7b57600080fd5b612f8788828901612d03565b969995985093965092949392505050565b60008060008060008060a08789031215612fb157600080fd5b8635612fbc81613a23565b95506020870135612fcc81613a23565b94506040870135935060608701359250608087013567ffffffffffffffff811115612ff657600080fd5b61300289828a01612d03565b979a9699509497509295939492505050565b6000806040838503121561302757600080fd5b823561303281613a23565b9150602083013561304281613a45565b809150509250929050565b6000806000806040858703121561306357600080fd5b843567ffffffffffffffff8082111561307b57600080fd5b818701915087601f83011261308f57600080fd5b81358181111561309e57600080fd5b886020610160830285010111156130b457600080fd5b6020928301965094509086013590808211156130cf57600080fd5b506130dc87828801612c87565b95989497509550505050565b6000602082840312156130fa57600080fd5b813561189a81613a45565b60006020828403121561311757600080fd5b815161189a81613a45565b60006020828403121561313457600080fd5b5035919050565b6000806040838503121561314e57600080fd5b82359150602083013567ffffffffffffffff81111561316c57600080fd5b61317885828601612d45565b9150509250929050565b600080600080600060a0868803121561319a57600080fd5b853594506131aa60208701612e1b565b94979496505050506040830135926060810135926080909101359150565b6000602082840312156131da57600080fd5b61189a82612cd3565b600061016082840312156131f657600080fd5b61189a8383612df0565b60008060008060006101e0868803121561321957600080fd5b6132238787612df0565b945061016086013561323481613a23565b935061018086013567ffffffffffffffff81111561325157600080fd5b61325d88828901612d45565b959894975094956101a081013595506101c001359392505050565b600080610180838503121561328c57600080fd5b6132968484612df0565b94610160939093013593505050565b60008060006101a084860312156132bb57600080fd5b6132c58585612df0565b925061016084013591506101808401356132de81613a45565b809150509250925092565b600061016082840312156132fc57600080fd5b6133046137ec565b8235815261331460208401612c77565b602082015261332560408401612c77565b6040820152606083013560608201526080830135608082015261334a60a08401612e09565b60a082015260c083013560c082015261336560e08401612cd3565b60e0820152610100613378818501612e1b565b908201526101208381013590820152610140928301359281019290925250919050565b60006101008083850312156133af57600080fd5b6040519081019067ffffffffffffffff821181831017156133d2576133d26139f4565b8160405283358152602084013591506133ea82613a23565b8160208201526133fc60408501612c77565b6040820152606084013560608201526080840135608082015261342160a08501612e09565b60a082015260c084013560c082015261343c60e08501612cd3565b60e0820152949350505050565b60006020828403121561345b57600080fd5b61189a82612e09565b60006020828403121561347657600080fd5b5051919050565b6000806040838503121561349057600080fd5b50508035926020909101359150565b6000602082840312156134b157600080fd5b61189a82612e1b565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156134ec57600080fd5b8260051b8083602087013760009401602001938452509192915050565b6000825161351b8184602087016138e0565b9190910192915050565b6080808252865190820181905260009060209060a0840190828a01845b8281101561355e57815184529284019290840190600101613542565b50505083810382850152868152818101600588811b830184018a60005b8b811015613627577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086840301855281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18e36030181126135dc57600080fd5b8d01803567ffffffffffffffff8111156135f557600080fd5b80861b36038f131561360657600080fd5b61361385828b85016134ba565b96890196945050509086019060010161357b565b5050604087019890985250505050606090910191909152509392505050565b60208152600082518060208401526136658160408501602087016138e0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b815181526020808301516101608301916136c89084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516136f0604084018273ffffffffffffffffffffffffffffffffffffffff169052565b50606083015160608301526080830151608083015260a083015161371a60a084018261ffff169052565b5060c083015160c083015260e083015161375860e08401827fffffffff00000000000000000000000000000000000000000000000000000000169052565b506101008381015160ff1690830152610120808401519083015261014092830151929091019190915290565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137b957600080fd5b83018035915067ffffffffffffffff8211156137d457600080fd5b6020019150600581901b3603821315612ccc57600080fd5b604051610160810167ffffffffffffffff81118282101715613810576138106139f4565b60405290565b6000821982111561382957613829613967565b500190565b600082613864577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156138a1576138a1613967565b500290565b600061ffff838116908316818110156138c1576138c1613967565b039392505050565b6000828210156138db576138db613967565b500390565b60005b838110156138fb5781810151838201526020016138e3565b838111156114fd5750506000910152565b600061ffff8083168181141561392457613924613967565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561396057613960613967565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461223457600080fd5b801515811461223457600080fdfea26469706673582212202626193b59bdbc4ab9f47424af3e703c008cad46b5f06199af0e229502ff5f5464736f6c63430008060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : wethAddress (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.