Latest 21 from a total of 21 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Buy Now | 15818179 | 1239 days ago | IN | 0 ETH | 0.00693169 | ||||
| Add Listing | 15817706 | 1239 days ago | IN | 0 ETH | 0.00304154 | ||||
| Remove Listing | 15803112 | 1241 days ago | IN | 0 ETH | 0.00195356 | ||||
| Remove Listing | 15766027 | 1247 days ago | IN | 0 ETH | 0.00037779 | ||||
| Remove Listing | 15766026 | 1247 days ago | IN | 0 ETH | 0.00129003 | ||||
| Add Listing | 15766018 | 1247 days ago | IN | 0 ETH | 0.00274109 | ||||
| Add Listing | 15719037 | 1253 days ago | IN | 0 ETH | 0.00887446 | ||||
| Add Listing | 15558400 | 1276 days ago | IN | 0 ETH | 0.00068311 | ||||
| Add Listing | 15558351 | 1276 days ago | IN | 0 ETH | 0.00068311 | ||||
| Add Listing | 15558323 | 1276 days ago | IN | 0 ETH | 0.00068311 | ||||
| Add Listing | 15525629 | 1281 days ago | IN | 0 ETH | 0.00128552 | ||||
| Buy Now | 15439665 | 1294 days ago | IN | 0 ETH | 0.00325192 | ||||
| Add Listing | 15439627 | 1294 days ago | IN | 0 ETH | 0.00346569 | ||||
| Remove Listing | 15439514 | 1294 days ago | IN | 0 ETH | 0.00134678 | ||||
| Add Listing | 15439504 | 1294 days ago | IN | 0 ETH | 0.00222121 | ||||
| Remove Listing | 15439048 | 1295 days ago | IN | 0 ETH | 0.0003856 | ||||
| Remove Listing | 15439046 | 1295 days ago | IN | 0 ETH | 0.00123315 | ||||
| Add Listing | 15439033 | 1295 days ago | IN | 0 ETH | 0.00346221 | ||||
| Remove Listing | 15439025 | 1295 days ago | IN | 0 ETH | 0.00144476 | ||||
| Add Listing | 15434450 | 1295 days ago | IN | 0 ETH | 0.00549094 | ||||
| Update Fee Rate | 15415117 | 1298 days ago | IN | 0 ETH | 0.00041732 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Loobr
Compiler Version
v0.8.1+commit.df193b15
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2022-08-25
*/
// SPDX-License-Identifier: MIT
//** Marketplace Contract trade by ERC20 token(USDT on Ethereum) */
//** Author Ishanshahzad: LooBr Marketplace Contract 2022.8 */
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File @openzeppelin/contracts/utils/Address.sol@v4.5.0
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.5.0
// 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);
}
// File @openzeppelin/contracts/utils/introspection/ERC165.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File contracts/interfaces/IERC2981.sol
pragma solidity ^0.8.0;
///
/// @dev Interface for the NFT Royalty Standard
///
interface IERC2981 is IERC165 {
/// ERC165 bytes to add to interface array - set in parent contract
/// implementing this standard
///
/// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
/// bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
/// _registerInterface(_INTERFACE_ID_ERC2981);
/// @notice Called with the sale price to determine how much royalty
// is owed and to whom.
/// @param _tokenId - the NFT asset queried for royalty information
/// @param _salePrice - the sale price of the NFT asset specified by _tokenId
/// @return receiver - address of who should be sent the royalty payment
/// @return royaltyAmount - the royalty payment amount for _salePrice
function royaltyInfo(
uint256 _tokenId,
uint256 _salePrice
) external view returns (
address receiver,
uint256 royaltyAmount
);
}
// File @openzeppelin/contracts/utils/Context.sol@v4.5.0
// 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;
}
}
// File @openzeppelin/contracts/access/Ownable.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @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);
}
}
// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
// File @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol@v4.5.0
// 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);
}
// File @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
// File @openzeppelin/contracts/utils/Strings.sol@v4.5.0
// 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);
}
}
// File @openzeppelin/contracts/token/ERC721/ERC721.sol@v4.5.0
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @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.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
// File @openzeppelin/contracts/token/ERC1155/IERC1155.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
/**
* @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;
}
// File @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol@v4.5.0
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
/**
* @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);
}
// File @openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}
// File @openzeppelin/contracts/token/ERC1155/ERC1155.sol@v4.5.0
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.0;
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri_) {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `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 memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - 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[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* 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 _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `from`
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}
// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.5.0
// 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;
}
}
// File contracts/interfaces/IMRConfig.sol
pragma solidity ^0.8.0;
interface IMRConfig {
function getRevenueAddress() external view returns (address);
function getMrNftAddress() external view returns (address);
function getRoyalityFeeRate() external view returns (uint256);
function getMinDuration() external view returns (uint256);
function getMaxDuration() external view returns (uint256);
}
// File contracts/MRContractBase.sol
//** Marketplace Base Contract, other marketplace contract will
//** inherit this contract */
//** Author ishanshahzad : Loobr Marketplace Base Contract 2022.5 */
pragma solidity ^0.8.0;
/// The contract is abstract so it cannnot be deployed.
abstract contract MRContractBase is Ownable, ReentrancyGuard, IERC721Receiver {
enum SellMode {
FixedPrice,
Auction
}
event ListingPlaced(
bytes32 indexed listingId,
address indexed sender,
address indexed hostContract,
uint256 tokenId,
uint256 copyIndex,
SellMode sellMode,
uint256 _price,
uint256 startTime,
uint256 duration
);
event ListingRemoved(bytes32 indexed listingId, address indexed sender);
event BiddingRemoved(bytes32 indexed biddingId, address indexed sender);
event BiddingPlaced(bytes32 indexed biddingId, bytes32 listingId, uint256 price);
event BuyNow(bytes32 indexed listingId, address indexed buyer, uint256 price);
event ClaimNFT(bytes32 indexed listingId, bytes32 indexed biddingId, address indexed buyer);
event RoyaltiesPaid(
address indexed hostContract,
uint256 indexed tokenId,
uint256 royaltiesAmount
);
event RoyaltiesFeePaid(
address indexed hostContract,
uint256 indexed tokenId,
uint256 royaltiesFeeAmount
);
// https://eips.ethereum.org/EIPS/eip-2981
bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
// listing detail
struct listing {
address seller; // The owner of the NFT who want to sell it
address hostContract; // The source of the contract
uint256 tokenId; // The NFT token ID
SellMode sellMode; // The sell mode the NFT, fixed price, auction or dutch auction
uint256 price; // In fixed price sell mode, it is the fixed price, in auction mode, it is the start price
uint256 startTime; // The timestamp of the listing creation
uint256 duration; // The duration of the biddings, in seconds
bytes32 biddingId; // last valid bidding Id with highest bidding price
}
// bidding detail
struct bidding {
address bidder; // User who submit the bidding
bytes32 listingId; // The target listing id
uint256 price; // The bidder price
uint256 timestamp; // The timestamp user create the bidding
}
mapping(bytes32 => listing) public listingRegistry; // The mapping of `listing Id` to `listing detail`
mapping(address => bytes32[]) public addrListingIds; // The mapping of `seller address` to `array of listing Id`
mapping(bytes32 => bidding) public biddingRegistry; // The mapping of `bidding Id` to `bidding detail`
mapping(address => bytes32[]) public addrBiddingIds; // The mapping of `bidder address` to `array of bidding Id`
uint256 public operationNonce;
uint256 public constant MAXIMUM_FEE_RATE = 5000;
uint256 public constant FEE_RATE_BASE = 10000;
uint256 public feeRate;
// maximum charge 50% royalty fee
uint256 public constant MAXIMUM_ROYALTIES_FEE_RATE = 5000;
IMRConfig public mrConfig;
// Total revenue amount
uint256 public revenueAmount;
mapping(address => uint256) public addrTokens;
uint256 public totalEscrowAmount;
constructor(address _owner, IMRConfig _mrConfig) {
require(_owner != address(0), "Invalid owner address");
_transferOwnership(_owner);
mrConfig = _mrConfig;
feeRate = 250; // 2.5%
}
/// @notice Checks if NFT contract implements the ERC-2981 interface
/// @param _contract - the address of the NFT contract to query
/// @return true if ERC-2981 interface is supported, false otherwise
function _checkRoyalties(address _contract) internal view returns (bool) {
bool success = ERC721(_contract).supportsInterface(_INTERFACE_ID_ERC2981);
return success;
}
/*
* @notice Add NFT to marketplace, Support auction(Price increasing), buyNow (Fixed price) and dutch auction (Price decreasing).
* @dev Only the token owner can call, because need to transfer the ownership of the token to marketplace contract.
*/
function _addListing(
address _hostContract,
uint256 _tokenId,
uint256 _copies,
SellMode _sellMode,
uint256 _price,
uint256 _startTime,
uint256 _duration
) internal {
// Fixed price no need to check start time and duration.
if (_sellMode != SellMode.FixedPrice) {
require(_startTime >= block.timestamp, "Listing auction start time past already");
require(
_duration >= mrConfig.getMinDuration() && _duration <= mrConfig.getMaxDuration(),
"Invalid duration"
);
}
require(_copies > 0, "The NFT copies should larger than 0");
if (_sellMode == SellMode.FixedPrice) {
require(_price > 0, "Invalid fixed price");
} else if (_sellMode == SellMode.Auction) {
require(_price > 0, "Invalid auction start price");
}
_depositNft(msg.sender, _hostContract, _tokenId, _copies);
for (uint256 index = 0; index < _copies; ++index) {
bytes32 listingId = keccak256(
abi.encodePacked(operationNonce, _hostContract, _tokenId)
);
listingRegistry[listingId].seller = msg.sender;
listingRegistry[listingId].hostContract = _hostContract;
listingRegistry[listingId].tokenId = _tokenId;
listingRegistry[listingId].sellMode = _sellMode;
listingRegistry[listingId].price = _price;
listingRegistry[listingId].startTime = _startTime;
listingRegistry[listingId].duration = _duration;
operationNonce++;
addrListingIds[msg.sender].push(listingId);
emit ListingPlaced(
listingId,
msg.sender,
_hostContract,
_tokenId,
index,
_sellMode,
_price,
_startTime,
_duration
);
}
}
function _placeBid(bytes32 listingId, uint256 price) internal {
listing storage lst = listingRegistry[listingId];
require(lst.sellMode == SellMode.Auction, "Can only bid for listing on auction");
require(block.timestamp >= lst.startTime, "The auction hasn't started yet");
require(lst.startTime + lst.duration >= block.timestamp, "The auction already expired");
require(msg.sender != lst.seller, "Bidder cannot be seller");
uint256 minPrice = lst.price;
if (lst.biddingId != 0) {
minPrice = biddingRegistry[lst.biddingId].price;
}
require(price > minPrice, "Bid price too low");
// this is a lower price bid before, need to return Token back to the buyer
if (lst.biddingId != 0) {
address olderBidder = biddingRegistry[lst.biddingId].bidder;
_transferToken(olderBidder, olderBidder, biddingRegistry[lst.biddingId].price);
_removeBidding(lst.biddingId, olderBidder);
}
_depositToken(price);
bytes32 biddingId = keccak256(
abi.encodePacked(operationNonce, lst.hostContract, lst.tokenId)
);
biddingRegistry[biddingId].bidder = msg.sender;
biddingRegistry[biddingId].listingId = listingId;
biddingRegistry[biddingId].price = price;
biddingRegistry[biddingId].timestamp = block.timestamp;
operationNonce++;
lst.biddingId = biddingId;
addrBiddingIds[msg.sender].push(biddingId);
emit BiddingPlaced(biddingId, listingId, price);
}
function _deduceRoyalties(
address _contract,
uint256 tokenId,
uint256 grossSaleValue
) internal returns (uint256 netSaleAmount) {
// Get amount of royalties to pays and recipient
(address royaltiesReceiver, uint256 royaltiesAmount) = IERC2981(_contract).royaltyInfo(
tokenId,
grossSaleValue
);
// Deduce royalties from sale value
uint256 netSaleValue = grossSaleValue - royaltiesAmount;
// Transfer royalties to rightholder if not zero
if (royaltiesAmount > 0) {
uint256 royaltyFee = (royaltiesAmount * mrConfig.getRoyalityFeeRate()) / FEE_RATE_BASE;
if (royaltyFee > 0) {
_transferToken(msg.sender, mrConfig.getRevenueAddress(), royaltyFee);
revenueAmount += royaltyFee;
emit RoyaltiesFeePaid(_contract, tokenId, royaltyFee);
}
uint256 payToReceiver = royaltiesAmount - royaltyFee;
_transferToken(msg.sender, royaltiesReceiver, payToReceiver);
// Broadcast royalties payment
emit RoyaltiesPaid(_contract, tokenId, payToReceiver);
}
return netSaleValue;
}
function _buyNow(bytes32 listingId, uint256 price) internal returns (address hostContract) {
listing storage lst = listingRegistry[listingId];
require(lst.sellMode != SellMode.Auction, "Auction not support buy now");
require(msg.sender != lst.seller, "Buyer cannot be seller");
hostContract = lst.hostContract;
_processFee(price);
// Deposit the tokens to market place contract.
_depositToken(price);
uint256 sellerAmount = price;
if (_checkRoyalties(lst.hostContract)) {
sellerAmount = _deduceRoyalties(lst.hostContract, lst.tokenId, price);
}
_transferToken(msg.sender, lst.seller, sellerAmount);
_transferNft(msg.sender, lst.hostContract, lst.tokenId);
emit BuyNow(listingId, msg.sender, price);
_removeListing(listingId, lst.seller);
}
function _claimNft(
bytes32 biddingId,
bidding storage bid,
listing storage lst
) internal {
_processFee(bid.price);
_transferNft(msg.sender, lst.hostContract, lst.tokenId);
uint256 sellerAmount = bid.price;
if (_checkRoyalties(lst.hostContract)) {
sellerAmount = _deduceRoyalties(lst.hostContract, lst.tokenId, bid.price);
}
_transferToken(msg.sender, lst.seller, sellerAmount);
emit ClaimNFT(bid.listingId, biddingId, msg.sender);
_removeListing(bid.listingId, lst.seller);
_removeBidding(biddingId, bid.bidder);
}
function listingOfAddr(address addr) public view returns (bytes32[] memory) {
return addrListingIds[addr];
}
/*
* @notice Get the price of Dutch auction and fixed price item.
* @dev Not support auction item which need to get from the lastest bid.
* @param listingId: the listing item id.
*/
function getPrice(bytes32 listingId) public view returns (uint256) {
listing storage lst = listingRegistry[listingId];
require(lst.price > 0, "The listing doesn't exist");
return lst.price;
}
/*
* @notice Get all the biddings of an address.
* @param addr: the address want to get.
*/
function biddingOfAddr(address addr) public view returns (bytes32[] memory) {
return addrBiddingIds[addr];
}
function _removeItemFromArray(bytes32 listingId, bytes32[] storage arrayOfIds) internal {
uint256 length = arrayOfIds.length;
for (uint256 index = 0; index < length; ++index) {
// Move the last element to the index need to remove
if (arrayOfIds[index] == listingId && index != length - 1) {
arrayOfIds[index] = arrayOfIds[length - 1];
}
}
// Remove the last element
arrayOfIds.pop();
}
function _removeListing(bytes32 listingId, address seller) internal {
_removeItemFromArray(listingId, addrListingIds[seller]);
// Delete from the mapping
delete listingRegistry[listingId];
emit ListingRemoved(listingId, seller);
}
function _removeBidding(bytes32 biddingId, address bidder) internal {
_removeItemFromArray(biddingId, addrBiddingIds[bidder]);
// Delete from the mapping
delete biddingRegistry[biddingId];
emit BiddingRemoved(biddingId, bidder);
}
/*
* @notice Remove a listing from the marketplace, can only remove if the duration finished and
* the item didn't receive any bid(For auction item).
* @param listingId: the listing want to remove.
*/
function removeListing(bytes32 listingId) external nonReentrant {
listing storage lst = listingRegistry[listingId];
// For fixed price sell, there is no duration limit,
// so user should be remove it any time before it is sold.
if (lst.sellMode != SellMode.FixedPrice) {
require(lst.startTime + lst.duration < block.timestamp, "The listing haven't expired");
}
require(lst.seller == msg.sender, "Only seller can remove");
require(lst.biddingId == 0, "Already received bidding, cannot close");
// return the NFT to seller
_transferNft(msg.sender, lst.hostContract, lst.tokenId);
_removeListing(listingId, lst.seller);
}
function _depositNft(
address from,
address _hostContract,
uint256 _tokenId,
uint256 _copies
) internal {
if (IERC165(_hostContract).supportsInterface(type(IERC721).interfaceId)) {
require(_copies == 1, "ERC721 doesn't support copies");
ERC721 nftContract = ERC721(_hostContract);
nftContract.safeTransferFrom(from, address(this), _tokenId);
} else if (IERC165(_hostContract).supportsInterface(type(IERC1155).interfaceId)) {
ERC1155 nftContract = ERC1155(_hostContract);
nftContract.safeTransferFrom(from, address(this), _tokenId, _copies, "0x0");
}
}
function _transferNft(
address to,
address _hostContract,
uint256 _tokenId
) internal {
if (IERC165(_hostContract).supportsInterface(type(IERC721).interfaceId)) {
ERC721 nftContract = ERC721(_hostContract);
nftContract.safeTransferFrom(address(this), to, _tokenId);
} else if (IERC165(_hostContract).supportsInterface(type(IERC1155).interfaceId)) {
ERC1155 nftContract = ERC1155(_hostContract);
nftContract.safeTransferFrom(address(this), to, _tokenId, 1, "0x0");
}
}
/**
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
/**
* Always returns `IERC1155Receiver.onERC1155Received.selector`.
*/
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) public pure returns (bytes4) {
return this.onERC1155Received.selector;
}
/*
* @notice Update the transaction fee rate and royalties fee rate
* @dev Only callable by owner.
* @param _feeRate: the fee rate the contract charge.
* @param _royaltiesFeeRate: the royalties fee rate the contract charge.
*/
function updateFeeRate(uint256 _feeRate) external onlyOwner {
require(_feeRate <= MAXIMUM_FEE_RATE, "Invalid fee rate");
feeRate = _feeRate;
}
/*
* @notice Process fee which is the revenue, some will burn if using LFG token.
* @param _price: The price of buy or bidding.
*/
function _processFee(uint256 _price) internal virtual;
/*
* @notice User deposit the token for bidding, which will under escrow
* @param _amount: The amount to deposit.
*/
function _depositToken(uint256 _amount) internal virtual;
/*
* @notice Transfer token from one address to another address, if they
are the same, means refund the escrowed token
* @param _from: The token transfer from.
* @param _to: The token transfer to.
* @param _from: The amount to transfer.
*/
function _transferToken(
address _from,
address _to,
uint256 _amount
) internal virtual;
}
// File contracts/MRContract.sol
pragma solidity ^0.8.0;
contract Loobr is MRContractBase {
IERC20 public USDT;
constructor(
address _owner,
IERC20 _tokenAddr,
IMRConfig _mrConfig
) MRContractBase(_owner, _mrConfig) {
USDT = _tokenAddr;
feeRate = 250; // 2.5%
}
/*
* @notice Place bidding for the listing item, only support normal auction.
* @dev The bidding price must higher than previous price.
*/
function placeBid(bytes32 listingId, uint256 price) external nonReentrant {
_placeBid(listingId, price);
}
/*
* @notice Add NFT to marketplace, Support auction(Price increasing), buyNow (Fixed price) and dutch auction (Price decreasing).
* @dev Only the token owner can call, because need to transfer the ownership to marketplace contract.
*/
function addListing(
address _hostContract,
uint256 _tokenId,
uint256 _copies,
SellMode _sellMode,
uint256 _price,
uint256 _startTime,
uint256 _duration
) external nonReentrant {
_addListing(
_hostContract,
_tokenId,
_copies,
_sellMode,
_price,
_startTime,
_duration
);
}
/*
* @notice Immediately buy the NFT.
* @dev If it is dutch auction, then the price is dutch auction price, if normal auction, then the price is buyNowPrice.
*/
function buyNow(bytes32 listingId) external nonReentrant {
uint256 price = getPrice(listingId);
_buyNow(listingId, price);
}
/*
* @notice The highest bidder claim the NFT he bought.
* @dev Can only claim after the auction period finished.
*/
function claimNft(bytes32 biddingId) external nonReentrant {
bidding storage bid = biddingRegistry[biddingId];
require(bid.bidder == msg.sender, "Only bidder can claim NFT");
listing storage lst = listingRegistry[bid.listingId];
require(
lst.duration < block.timestamp,
"The bidding period haven't complete"
);
// Use the bid.price before _claimNft, because the bid will be deleted in _claimNft.
_claimNft(biddingId, bid, lst);
}
/// Check base function definition
function _processFee(uint256 price) internal override {
uint256 fee = (price * feeRate) / FEE_RATE_BASE;
uint256 revenue = fee;
SafeERC20.safeTransferFrom(USDT, msg.sender, mrConfig.getRevenueAddress(), revenue);
revenueAmount += revenue;
}
/// Check base function definition
function _depositToken(uint256 _amount) internal override {
// Using USDT.safeTransferFrom(addr, address(this), _amount) will increase
// contract size for 0.13KB, which will make the contract no deployable.
SafeERC20.safeTransferFrom(USDT, msg.sender, address(this), _amount);
addrTokens[msg.sender] += _amount;
totalEscrowAmount += _amount;
}
/// Check base function definition
function _transferToken(
address from,
address to,
uint256 _amount
) internal override {
require(addrTokens[from] >= _amount, "The locked amount is not enough");
SafeERC20.safeTransfer(USDT, to, _amount);
addrTokens[from] -= _amount;
totalEscrowAmount -= _amount;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract IERC20","name":"_tokenAddr","type":"address"},{"internalType":"contract IMRConfig","name":"_mrConfig","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"biddingId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"listingId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"BiddingPlaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"biddingId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"BiddingRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"listingId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"BuyNow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"listingId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"biddingId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"}],"name":"ClaimNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"listingId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"hostContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"copyIndex","type":"uint256"},{"indexed":false,"internalType":"enum MRContractBase.SellMode","name":"sellMode","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"_price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"ListingPlaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"listingId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"ListingRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hostContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"royaltiesFeeAmount","type":"uint256"}],"name":"RoyaltiesFeePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hostContract","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"royaltiesAmount","type":"uint256"}],"name":"RoyaltiesPaid","type":"event"},{"inputs":[],"name":"FEE_RATE_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_FEE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_ROYALTIES_FEE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hostContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_copies","type":"uint256"},{"internalType":"enum MRContractBase.SellMode","name":"_sellMode","type":"uint8"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"addListing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"addrBiddingIds","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"addrListingIds","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addrTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"biddingOfAddr","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"biddingRegistry","outputs":[{"internalType":"address","name":"bidder","type":"address"},{"internalType":"bytes32","name":"listingId","type":"bytes32"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"listingId","type":"bytes32"}],"name":"buyNow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"biddingId","type":"bytes32"}],"name":"claimNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"listingId","type":"bytes32"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"listingOfAddr","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"listingRegistry","outputs":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"address","name":"hostContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"enum MRContractBase.SellMode","name":"sellMode","type":"uint8"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"bytes32","name":"biddingId","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mrConfig","outputs":[{"internalType":"contract IMRConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operationNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"listingId","type":"bytes32"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"placeBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"listingId","type":"bytes32"}],"name":"removeListing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revenueAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalEscrowAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeRate","type":"uint256"}],"name":"updateFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162002e1838038062002e1883398101604081905262000034916200011e565b82816200004a62000044620000ca565b620000ce565b600180556001600160a01b038216620000805760405162461bcd60e51b8152600401620000779062000171565b60405180910390fd5b6200008b82620000ce565b600880546001600160a01b039283166001600160a01b03199182161790915560fa600755600c80549590921694169390931790925550620001c1915050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060006060848603121562000133578283fd5b83516200014081620001a8565b60208501519093506200015381620001a8565b60408501519092506200016681620001a8565b809150509250925092565b60208082526015908201527f496e76616c6964206f776e657220616464726573730000000000000000000000604082015260600190565b6001600160a01b0381168114620001be57600080fd5b50565b612c4780620001d16000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80637b84fda5116100f9578063bca1aaa311610097578063d7ad493111610071578063d7ad493114610373578063e050763814610386578063f23a6e6114610399578063f2fde38b146103ac576101c4565b8063bca1aaa314610345578063c4d83cd314610358578063c54e44eb1461036b576101c4565b8063978bbdb9116100d3578063978bbdb91461030f578063ae91639714610317578063af4d349c1461031f578063b444691a14610332576101c4565b80637b84fda5146102f457806385fcba5e1461023c5780638da5cb5b14610307576101c4565b80634d7e112711610166578063569063e111610140578063569063e1146102c957806361c3efb1146102dc57806370f43d64146102e4578063715018a6146102ec576101c4565b80634d7e1127146102975780634e3f1002146102ac578063550ee133146102b4576101c4565b8063254e5c94116101a2578063254e5c941461023c57806327a0a92f1461025157806330f2a3d31461026457806331d98b3f14610284576101c4565b806307183fa8146101c9578063097584e2146101f5578063150b7a021461021c575b600080fd5b6101dc6101d7366004612286565b6103bf565b6040516101ec9493929190612416565b60405180910390f35b610208610203366004612286565b6103f0565b6040516101ec98979695949392919061238b565b61022f61022a3660046120bc565b610446565b6040516101ec91906124b0565b610244610457565b6040516101ec9190612499565b61024461025f366004612084565b61045d565b610277610272366004612084565b61046f565b6040516101ec9190612455565b610244610292366004612286565b6104db565b61029f61051d565b6040516101ec9190612353565b61024461052c565b6102c76102c2366004612286565b610532565b005b6102776102d7366004612084565b610654565b6102446106be565b6102446106c4565b6102c76106ca565b6102c7610302366004612286565b610715565b61029f61077b565b61024461078a565b610244610790565b61024461032d3660046121a7565b610796565b6102c76103403660046121ff565b6107c7565b6102c761035336600461229e565b61080b565b6102446103663660046121a7565b61083d565b61029f610859565b6102c7610381366004612286565b610868565b6102c7610394366004612286565b6108b0565b61022f6103a736600461212d565b610950565b6102c76103ba366004612084565b610962565b60046020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909184565b6002602081905260009182526040909120805460018201549282015460038301546004840154600585015460068601546007909601546001600160a01b039586169790951695939460ff90931693919290919088565b630a85bd0160e11b95945050505050565b61138881565b600a6020526000908152604090205481565b6001600160a01b0381166000908152600560209081526040918290208054835181840281018401909452808452606093928301828280156104cf57602002820191906000526020600020905b8154815260200190600101908083116104bb575b50505050509050919050565b600081815260026020526040812060048101546105135760405162461bcd60e51b815260040161050a906126ca565b60405180910390fd5b6004015492915050565b6008546001600160a01b031681565b60065481565b600260015414156105555760405162461bcd60e51b815260040161050a90612a8b565b6002600181905560008281526020919091526040812090600382015460ff16600181111561059357634e487b7160e01b600052602160045260246000fd5b146105ca5742816006015482600501546105ad9190612b31565b106105ca5760405162461bcd60e51b815260040161050a90612616565b80546001600160a01b031633146105f35760405162461bcd60e51b815260040161050a90612908565b6007810154156106155760405162461bcd60e51b815260040161050a90612738565b600181015460028201546106369133916001600160a01b03909116906109d3565b805461064c9083906001600160a01b0316610bbb565b505060018055565b6001600160a01b0381166000908152600360209081526040918290208054835181840281018401909452808452606093928301828280156104cf57602002820191906000526020600020908154815260200190600101908083116104bb5750505050509050919050565b61271081565b60095481565b6106d2610c6f565b6001600160a01b03166106e361077b565b6001600160a01b0316146107095760405162461bcd60e51b815260040161050a906127ec565b6107136000610c73565b565b61071d610c6f565b6001600160a01b031661072e61077b565b6001600160a01b0316146107545760405162461bcd60e51b815260040161050a906127ec565b6113888111156107765760405162461bcd60e51b815260040161050a90612821565b600755565b6000546001600160a01b031690565b60075481565b600b5481565b600360205281600052604060002081815481106107b257600080fd5b90600052602060002001600091509150505481565b600260015414156107ea5760405162461bcd60e51b815260040161050a90612a8b565b60026001556107fe87878787878787610cc3565b5050600180555050505050565b6002600154141561082e5760405162461bcd60e51b815260040161050a90612a8b565b600260015561064c82826110d2565b600560205281600052604060002081815481106107b257600080fd5b600c546001600160a01b031681565b6002600154141561088b5760405162461bcd60e51b815260040161050a90612a8b565b6002600155600061089b826104db565b90506108a78282611340565b50506001805550565b600260015414156108d35760405162461bcd60e51b815260040161050a90612a8b565b6002600155600081815260046020526040902080546001600160a01b0316331461090f5760405162461bcd60e51b815260040161050a90612ac2565b60018101546000908152600260205260409020600681015442116109455760405162461bcd60e51b815260040161050a9061296f565b6108a78383836114b8565b63f23a6e6160e01b9695505050505050565b61096a610c6f565b6001600160a01b031661097b61077b565b6001600160a01b0316146109a15760405162461bcd60e51b815260040161050a906127ec565b6001600160a01b0381166109c75760405162461bcd60e51b815260040161050a906125a6565b6109d081610c73565b50565b6040516301ffc9a760e01b81526001600160a01b038316906301ffc9a790610a06906380ac58cd60e01b906004016124b0565b60206040518083038186803b158015610a1e57600080fd5b505afa158015610a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a569190612266565b15610ac557604051632142170760e11b815282906001600160a01b038216906342842e0e90610a8d90309088908790600401612367565b600060405180830381600087803b158015610aa757600080fd5b505af1158015610abb573d6000803e3d6000fd5b5050505050610bb6565b6040516301ffc9a760e01b81526001600160a01b038316906301ffc9a790610af890636cdb3d1360e11b906004016124b0565b60206040518083038186803b158015610b1057600080fd5b505afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b489190612266565b15610bb657604051637921219560e11b815282906001600160a01b0382169063f242432a90610b82903090889087906001906004016123dd565b600060405180830381600087803b158015610b9c57600080fd5b505af1158015610bb0573d6000803e3d6000fd5b50505050505b505050565b6001600160a01b0381166000908152600360205260409020610bde9083906115ac565b600082815260026020819052604080832080546001600160a01b03199081168255600182018054909116905591820183905560038201805460ff191690556004820183905560058201839055600682018390556007909101829055516001600160a01b0383169184917f06db153d35c91ecb23cb1a8436fa463ac549aecc38ae907f1e5330fea11980c69190a35050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000846001811115610ce557634e487b7160e01b600052602160045260246000fd5b14610e405742821015610d0a5760405162461bcd60e51b815260040161050a906124f8565b600860009054906101000a90046001600160a01b03166001600160a01b031663034d501b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d5857600080fd5b505afa158015610d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9091906122bf565b8110158015610e245750600860009054906101000a90046001600160a01b03166001600160a01b031663b49a2db96040518163ffffffff1660e01b815260040160206040518083038186803b158015610de857600080fd5b505afa158015610dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2091906122bf565b8111155b610e405760405162461bcd60e51b815260040161050a906125ec565b60008511610e605760405162461bcd60e51b815260040161050a906128c5565b6000846001811115610e8257634e487b7160e01b600052602160045260246000fd5b1415610ead5760008311610ea85760405162461bcd60e51b815260040161050a90612a5e565b610ef5565b6001846001811115610ecf57634e487b7160e01b600052602160045260246000fd5b1415610ef55760008311610ef55760405162461bcd60e51b815260040161050a90612701565b610f01338888886116ad565b60005b85811015610bb05760006006548989604051602001610f259392919061232b565b604051602081830303815290604052805190602001209050336002600083815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550886002600083815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550876002600083815260200190815260200160002060020181905550856002600083815260200190815260200160002060030160006101000a81548160ff0219169083600181111561101457634e487b7160e01b600052602160045260246000fd5b021790555060008181526002602052604081206004810187905560058101869055600690810185905580549161104983612bcb565b909155505033600081815260036020908152604080832080546001810182559084529190922001839055516001600160a01b038b16919083907fb3c6a00319684483d74f44afa50e07c0580b811b1ffbdc29e915c1005e181db5906110b9908d9088908d908d908d908d90612af9565b60405180910390a4506110cb81612bcb565b9050610f04565b60008281526002602052604090206001600382015460ff16600181111561110957634e487b7160e01b600052602160045260246000fd5b146111265760405162461bcd60e51b815260040161050a9061284b565b806005015442101561114a5760405162461bcd60e51b815260040161050a906127b5565b428160060154826005015461115f9190612b31565b101561117d5760405162461bcd60e51b815260040161050a90612938565b80546001600160a01b03163314156111a75760405162461bcd60e51b815260040161050a9061256f565b60048101546007820154156111cf575060078101546000908152600460205260409020600201545b8083116111ee5760405162461bcd60e51b815260040161050a906129e9565b60078201541561123c576007820154600090815260046020526040902080546002909101546001600160a01b039091169061122c90829081906118b4565b61123a83600701548261194e565b505b611245836119d8565b600654600183015460028401546040516000936112729390926001600160a01b039091169160200161232b565b60408051601f1981840301815291815281516020928301206000818152600490935290822080546001600160a01b031916331781556001810188905560028101879055426003909101556006805491935090916112ce83612bcb565b909155505060078301819055336000908152600560209081526040808320805460018101825590845291909220018290555181907f3a2718516bf8de6760fe7647dd13c596fe6a2beb8a15697aeee3f3ca6ddedda69061133190889088906124a2565b60405180910390a25050505050565b60008281526002602052604081206001600382015460ff16600181111561137757634e487b7160e01b600052602160045260246000fd5b14156113955760405162461bcd60e51b815260040161050a9061277e565b80546001600160a01b03163314156113bf5760405162461bcd60e51b815260040161050a9061253f565b60018101546001600160a01b031691506113d883611a30565b6113e1836119d8565b600181015483906113fa906001600160a01b0316611af3565b15611420576001820154600283015461141d916001600160a01b03169086611b82565b90505b81546114379033906001600160a01b0316836118b4565b600182015460028301546114589133916001600160a01b03909116906109d3565b336001600160a01b0316857f166e1788ade6bdaa98c1822ed449cd9cf405f106815607aa3cec15b5c7cb16fb866040516114929190612499565b60405180910390a381546114b09086906001600160a01b0316610bbb565b505092915050565b6114c58260020154611a30565b600181015460028201546114e69133916001600160a01b03909116906109d3565b60028201546001820154611502906001600160a01b0316611af3565b1561152d5760018201546002808401549085015461152a926001600160a01b03169190611b82565b90505b81546115449033906001600160a01b0316836118b4565b6001830154604051339186917f3b51ddb79624307cce37f8ba22985a23f6e050a1f7a26aab1eb7ef7af3255b1890600090a46001830154825461159091906001600160a01b0316610bbb565b82546115a69085906001600160a01b031661194e565b50505050565b805460005b8181101561167357838382815481106115da57634e487b7160e01b600052603260045260246000fd5b90600052602060002001541480156115fc57506115f8600183612b88565b8114155b15611663578261160d600184612b88565b8154811061162b57634e487b7160e01b600052603260045260246000fd5b906000526020600020015483828154811061165657634e487b7160e01b600052603260045260246000fd5b6000918252602090912001555b61166c81612bcb565b90506115b1565b508180548061169257634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055505050565b6040516301ffc9a760e01b81526001600160a01b038416906301ffc9a7906116e0906380ac58cd60e01b906004016124b0565b60206040518083038186803b1580156116f857600080fd5b505afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117309190612266565b156117bf57806001146117555760405162461bcd60e51b815260040161050a9061264d565b604051632142170760e11b815283906001600160a01b038216906342842e0e9061178790889030908890600401612367565b600060405180830381600087803b1580156117a157600080fd5b505af11580156117b5573d6000803e3d6000fd5b50505050506115a6565b6040516301ffc9a760e01b81526001600160a01b038416906301ffc9a7906117f290636cdb3d1360e11b906004016124b0565b60206040518083038186803b15801561180a57600080fd5b505afa15801561181e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118429190612266565b156115a657604051637921219560e11b815283906001600160a01b0382169063f242432a9061187b9088903090889088906004016123dd565b600060405180830381600087803b15801561189557600080fd5b505af11580156118a9573d6000803e3d6000fd5b505050505050505050565b6001600160a01b0383166000908152600a60205260409020548111156118ec5760405162461bcd60e51b815260040161050a9061288e565b600c54611903906001600160a01b03168383611e18565b6001600160a01b0383166000908152600a60205260408120805483929061192b908490612b88565b9250508190555080600b60008282546119449190612b88565b9091555050505050565b6001600160a01b03811660009081526005602052604090206119719083906115ac565b60008281526004602052604080822080546001600160a01b03191681556001810183905560028101839055600301829055516001600160a01b0383169184917fbb5d40441e7aee8a4ab754e8fc0b8511e576dcfd271af8996e537654dbe4913a9190a35050565b600c546119f0906001600160a01b0316333084611e6e565b336000908152600a602052604081208054839290611a0f908490612b31565b9250508190555080600b6000828254611a289190612b31565b909155505050565b600061271060075483611a439190612b69565b611a4d9190612b49565b600c54600854604080516378d1c86d60e01b815290519394508493611ae1936001600160a01b039081169333939116916378d1c86d91600480820192602092909190829003018186803b158015611aa357600080fd5b505afa158015611ab7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adb91906120a0565b84611e6e565b80600960008282546119449190612b31565b6040516301ffc9a760e01b815260009081906001600160a01b038416906301ffc9a790611b2b9063152a902d60e11b906004016124b0565b60206040518083038186803b158015611b4357600080fd5b505afa158015611b57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7b9190612266565b9392505050565b6000806000856001600160a01b0316632a55205a86866040518363ffffffff1660e01b8152600401611bb59291906124a2565b604080518083038186803b158015611bcc57600080fd5b505afa158015611be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0491906121d2565b90925090506000611c158286612b88565b90508115611e0e576000612710600860009054906101000a90046001600160a01b03166001600160a01b0316635801771e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c7057600080fd5b505afa158015611c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca891906122bf565b611cb29085612b69565b611cbc9190612b49565b90508015611db057611d5433600860009054906101000a90046001600160a01b03166001600160a01b03166378d1c86d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d1657600080fd5b505afa158015611d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4e91906120a0565b836118b4565b8060096000828254611d669190612b31565b9250508190555086886001600160a01b03167f5e322778c7e97750a93b7ef4d26e80a14c466530a586e67c0d8394021498010383604051611da79190612499565b60405180910390a35b6000611dbc8285612b88565b9050611dc93386836118b4565b87896001600160a01b03167f7a474f3ea7966b6a336a0169253a863c5bbe817379d3570951736f604adbe26983604051611e039190612499565b60405180910390a350505b9695505050505050565b610bb68363a9059cbb60e01b8484604051602401611e3792919061243c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611e8f565b6115a6846323b872dd60e01b858585604051602401611e3793929190612367565b6000611ee4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611f1e9092919063ffffffff16565b805190915015610bb65780806020019051810190611f029190612266565b610bb65760405162461bcd60e51b815260040161050a90612a14565b6060611f2d8484600085611f35565b949350505050565b606082471015611f575760405162461bcd60e51b815260040161050a90612684565b611f6085611ff5565b611f7c5760405162461bcd60e51b815260040161050a906129b2565b600080866001600160a01b03168587604051611f98919061230f565b60006040518083038185875af1925050503d8060008114611fd5576040519150601f19603f3d011682016040523d82523d6000602084013e611fda565b606091505b5091509150611fea828286612004565b979650505050505050565b6001600160a01b03163b151590565b60608315612013575081611b7b565b8251156120235782518084602001fd5b8160405162461bcd60e51b815260040161050a91906124c5565b60008083601f84011261204e578182fd5b50813567ffffffffffffffff811115612065578182fd5b60208301915083602082850101111561207d57600080fd5b9250929050565b600060208284031215612095578081fd5b8135611b7b81612bfc565b6000602082840312156120b1578081fd5b8151611b7b81612bfc565b6000806000806000608086880312156120d3578081fd5b85356120de81612bfc565b945060208601356120ee81612bfc565b935060408601359250606086013567ffffffffffffffff811115612110578182fd5b61211c8882890161203d565b969995985093965092949392505050565b60008060008060008060a08789031215612145578081fd5b863561215081612bfc565b9550602087013561216081612bfc565b94506040870135935060608701359250608087013567ffffffffffffffff811115612189578182fd5b61219589828a0161203d565b979a9699509497509295939492505050565b600080604083850312156121b9578182fd5b82356121c481612bfc565b946020939093013593505050565b600080604083850312156121e4578182fd5b82516121ef81612bfc565b6020939093015192949293505050565b600080600080600080600060e0888a031215612219578081fd5b873561222481612bfc565b96506020880135955060408801359450606088013560028110612245578182fd5b9699959850939660808101359560a0820135955060c0909101359350915050565b600060208284031215612277578081fd5b81518015158114611b7b578182fd5b600060208284031215612297578081fd5b5035919050565b600080604083850312156122b0578182fd5b50508035926020909101359150565b6000602082840312156122d0578081fd5b5051919050565b600281106122f557634e487b7160e01b600052602160045260246000fd5b9052565b600381526203078360ec1b602082015260400190565b60008251612321818460208701612b9f565b9190910192915050565b92835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038981168252881660208201526040810187905261010081016123b860608301886122d7565b8560808301528460a08301528360c08301528260e08301529998505050505050505050565b6001600160a01b03858116825284166020820152604081018390526060810182905260a060808201819052600090611e0e9083016122f9565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561248d57835183529284019291840191600101612471565b50909695505050505050565b90815260200190565b918252602082015260400190565b6001600160e01b031991909116815260200190565b60006020825282518060208401526124e4816040850160208701612b9f565b601f01601f19169190910160400192915050565b60208082526027908201527f4c697374696e672061756374696f6e2073746172742074696d65207061737420604082015266616c726561647960c81b606082015260800190565b602080825260169082015275213abcb2b91031b0b73737ba1031329039b2b63632b960511b604082015260600190565b60208082526017908201527f4269646465722063616e6e6f742062652073656c6c6572000000000000000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526010908201526f24b73b30b634b210323ab930ba34b7b760811b604082015260600190565b6020808252601b908201527f546865206c697374696e6720686176656e277420657870697265640000000000604082015260600190565b6020808252601d908201527f45524337323120646f65736e277420737570706f727420636f70696573000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b60208082526019908201527f546865206c697374696e6720646f65736e277420657869737400000000000000604082015260600190565b6020808252601b908201527f496e76616c69642061756374696f6e2073746172742070726963650000000000604082015260600190565b60208082526026908201527f416c72656164792072656365697665642062696464696e672c2063616e6e6f7460408201526520636c6f736560d01b606082015260800190565b6020808252601b908201527f41756374696f6e206e6f7420737570706f727420627579206e6f770000000000604082015260600190565b6020808252601e908201527f5468652061756374696f6e206861736e27742073746172746564207965740000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f496e76616c696420666565207261746560801b604082015260600190565b60208082526023908201527f43616e206f6e6c792062696420666f72206c697374696e67206f6e206175637460408201526234b7b760e91b606082015260800190565b6020808252601f908201527f546865206c6f636b656420616d6f756e74206973206e6f7420656e6f75676800604082015260600190565b60208082526023908201527f546865204e465420636f706965732073686f756c64206c61726765722074686160408201526206e20360ec1b606082015260800190565b6020808252601690820152754f6e6c792073656c6c65722063616e2072656d6f766560501b604082015260600190565b6020808252601b908201527f5468652061756374696f6e20616c726561647920657870697265640000000000604082015260600190565b60208082526023908201527f5468652062696464696e6720706572696f6420686176656e277420636f6d706c60408201526265746560e81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526011908201527042696420707269636520746f6f206c6f7760781b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b602080825260139082015272496e76616c696420666978656420707269636560681b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526019908201527f4f6e6c79206269646465722063616e20636c61696d204e465400000000000000604082015260600190565b8681526020810186905260c08101612b1460408301876122d7565b8460608301528360808301528260a0830152979650505050505050565b60008219821115612b4457612b44612be6565b500190565b600082612b6457634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612b8357612b83612be6565b500290565b600082821015612b9a57612b9a612be6565b500390565b60005b83811015612bba578181015183820152602001612ba2565b838111156115a65750506000910152565b6000600019821415612bdf57612bdf612be6565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146109d057600080fdfea26469706673582212207233f7f733935f04e5f8f6f22b8c54296d3edfa64ead46abcdaab7c73943371064736f6c6343000801003300000000000000000000000079003a1052658f3b664cc080a001875d501be4b1000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000e9e65e22edcdfbba43e71ff3ba9f382429a34d8e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80637b84fda5116100f9578063bca1aaa311610097578063d7ad493111610071578063d7ad493114610373578063e050763814610386578063f23a6e6114610399578063f2fde38b146103ac576101c4565b8063bca1aaa314610345578063c4d83cd314610358578063c54e44eb1461036b576101c4565b8063978bbdb9116100d3578063978bbdb91461030f578063ae91639714610317578063af4d349c1461031f578063b444691a14610332576101c4565b80637b84fda5146102f457806385fcba5e1461023c5780638da5cb5b14610307576101c4565b80634d7e112711610166578063569063e111610140578063569063e1146102c957806361c3efb1146102dc57806370f43d64146102e4578063715018a6146102ec576101c4565b80634d7e1127146102975780634e3f1002146102ac578063550ee133146102b4576101c4565b8063254e5c94116101a2578063254e5c941461023c57806327a0a92f1461025157806330f2a3d31461026457806331d98b3f14610284576101c4565b806307183fa8146101c9578063097584e2146101f5578063150b7a021461021c575b600080fd5b6101dc6101d7366004612286565b6103bf565b6040516101ec9493929190612416565b60405180910390f35b610208610203366004612286565b6103f0565b6040516101ec98979695949392919061238b565b61022f61022a3660046120bc565b610446565b6040516101ec91906124b0565b610244610457565b6040516101ec9190612499565b61024461025f366004612084565b61045d565b610277610272366004612084565b61046f565b6040516101ec9190612455565b610244610292366004612286565b6104db565b61029f61051d565b6040516101ec9190612353565b61024461052c565b6102c76102c2366004612286565b610532565b005b6102776102d7366004612084565b610654565b6102446106be565b6102446106c4565b6102c76106ca565b6102c7610302366004612286565b610715565b61029f61077b565b61024461078a565b610244610790565b61024461032d3660046121a7565b610796565b6102c76103403660046121ff565b6107c7565b6102c761035336600461229e565b61080b565b6102446103663660046121a7565b61083d565b61029f610859565b6102c7610381366004612286565b610868565b6102c7610394366004612286565b6108b0565b61022f6103a736600461212d565b610950565b6102c76103ba366004612084565b610962565b60046020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909184565b6002602081905260009182526040909120805460018201549282015460038301546004840154600585015460068601546007909601546001600160a01b039586169790951695939460ff90931693919290919088565b630a85bd0160e11b95945050505050565b61138881565b600a6020526000908152604090205481565b6001600160a01b0381166000908152600560209081526040918290208054835181840281018401909452808452606093928301828280156104cf57602002820191906000526020600020905b8154815260200190600101908083116104bb575b50505050509050919050565b600081815260026020526040812060048101546105135760405162461bcd60e51b815260040161050a906126ca565b60405180910390fd5b6004015492915050565b6008546001600160a01b031681565b60065481565b600260015414156105555760405162461bcd60e51b815260040161050a90612a8b565b6002600181905560008281526020919091526040812090600382015460ff16600181111561059357634e487b7160e01b600052602160045260246000fd5b146105ca5742816006015482600501546105ad9190612b31565b106105ca5760405162461bcd60e51b815260040161050a90612616565b80546001600160a01b031633146105f35760405162461bcd60e51b815260040161050a90612908565b6007810154156106155760405162461bcd60e51b815260040161050a90612738565b600181015460028201546106369133916001600160a01b03909116906109d3565b805461064c9083906001600160a01b0316610bbb565b505060018055565b6001600160a01b0381166000908152600360209081526040918290208054835181840281018401909452808452606093928301828280156104cf57602002820191906000526020600020908154815260200190600101908083116104bb5750505050509050919050565b61271081565b60095481565b6106d2610c6f565b6001600160a01b03166106e361077b565b6001600160a01b0316146107095760405162461bcd60e51b815260040161050a906127ec565b6107136000610c73565b565b61071d610c6f565b6001600160a01b031661072e61077b565b6001600160a01b0316146107545760405162461bcd60e51b815260040161050a906127ec565b6113888111156107765760405162461bcd60e51b815260040161050a90612821565b600755565b6000546001600160a01b031690565b60075481565b600b5481565b600360205281600052604060002081815481106107b257600080fd5b90600052602060002001600091509150505481565b600260015414156107ea5760405162461bcd60e51b815260040161050a90612a8b565b60026001556107fe87878787878787610cc3565b5050600180555050505050565b6002600154141561082e5760405162461bcd60e51b815260040161050a90612a8b565b600260015561064c82826110d2565b600560205281600052604060002081815481106107b257600080fd5b600c546001600160a01b031681565b6002600154141561088b5760405162461bcd60e51b815260040161050a90612a8b565b6002600155600061089b826104db565b90506108a78282611340565b50506001805550565b600260015414156108d35760405162461bcd60e51b815260040161050a90612a8b565b6002600155600081815260046020526040902080546001600160a01b0316331461090f5760405162461bcd60e51b815260040161050a90612ac2565b60018101546000908152600260205260409020600681015442116109455760405162461bcd60e51b815260040161050a9061296f565b6108a78383836114b8565b63f23a6e6160e01b9695505050505050565b61096a610c6f565b6001600160a01b031661097b61077b565b6001600160a01b0316146109a15760405162461bcd60e51b815260040161050a906127ec565b6001600160a01b0381166109c75760405162461bcd60e51b815260040161050a906125a6565b6109d081610c73565b50565b6040516301ffc9a760e01b81526001600160a01b038316906301ffc9a790610a06906380ac58cd60e01b906004016124b0565b60206040518083038186803b158015610a1e57600080fd5b505afa158015610a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a569190612266565b15610ac557604051632142170760e11b815282906001600160a01b038216906342842e0e90610a8d90309088908790600401612367565b600060405180830381600087803b158015610aa757600080fd5b505af1158015610abb573d6000803e3d6000fd5b5050505050610bb6565b6040516301ffc9a760e01b81526001600160a01b038316906301ffc9a790610af890636cdb3d1360e11b906004016124b0565b60206040518083038186803b158015610b1057600080fd5b505afa158015610b24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b489190612266565b15610bb657604051637921219560e11b815282906001600160a01b0382169063f242432a90610b82903090889087906001906004016123dd565b600060405180830381600087803b158015610b9c57600080fd5b505af1158015610bb0573d6000803e3d6000fd5b50505050505b505050565b6001600160a01b0381166000908152600360205260409020610bde9083906115ac565b600082815260026020819052604080832080546001600160a01b03199081168255600182018054909116905591820183905560038201805460ff191690556004820183905560058201839055600682018390556007909101829055516001600160a01b0383169184917f06db153d35c91ecb23cb1a8436fa463ac549aecc38ae907f1e5330fea11980c69190a35050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000846001811115610ce557634e487b7160e01b600052602160045260246000fd5b14610e405742821015610d0a5760405162461bcd60e51b815260040161050a906124f8565b600860009054906101000a90046001600160a01b03166001600160a01b031663034d501b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d5857600080fd5b505afa158015610d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9091906122bf565b8110158015610e245750600860009054906101000a90046001600160a01b03166001600160a01b031663b49a2db96040518163ffffffff1660e01b815260040160206040518083038186803b158015610de857600080fd5b505afa158015610dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2091906122bf565b8111155b610e405760405162461bcd60e51b815260040161050a906125ec565b60008511610e605760405162461bcd60e51b815260040161050a906128c5565b6000846001811115610e8257634e487b7160e01b600052602160045260246000fd5b1415610ead5760008311610ea85760405162461bcd60e51b815260040161050a90612a5e565b610ef5565b6001846001811115610ecf57634e487b7160e01b600052602160045260246000fd5b1415610ef55760008311610ef55760405162461bcd60e51b815260040161050a90612701565b610f01338888886116ad565b60005b85811015610bb05760006006548989604051602001610f259392919061232b565b604051602081830303815290604052805190602001209050336002600083815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550886002600083815260200190815260200160002060010160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550876002600083815260200190815260200160002060020181905550856002600083815260200190815260200160002060030160006101000a81548160ff0219169083600181111561101457634e487b7160e01b600052602160045260246000fd5b021790555060008181526002602052604081206004810187905560058101869055600690810185905580549161104983612bcb565b909155505033600081815260036020908152604080832080546001810182559084529190922001839055516001600160a01b038b16919083907fb3c6a00319684483d74f44afa50e07c0580b811b1ffbdc29e915c1005e181db5906110b9908d9088908d908d908d908d90612af9565b60405180910390a4506110cb81612bcb565b9050610f04565b60008281526002602052604090206001600382015460ff16600181111561110957634e487b7160e01b600052602160045260246000fd5b146111265760405162461bcd60e51b815260040161050a9061284b565b806005015442101561114a5760405162461bcd60e51b815260040161050a906127b5565b428160060154826005015461115f9190612b31565b101561117d5760405162461bcd60e51b815260040161050a90612938565b80546001600160a01b03163314156111a75760405162461bcd60e51b815260040161050a9061256f565b60048101546007820154156111cf575060078101546000908152600460205260409020600201545b8083116111ee5760405162461bcd60e51b815260040161050a906129e9565b60078201541561123c576007820154600090815260046020526040902080546002909101546001600160a01b039091169061122c90829081906118b4565b61123a83600701548261194e565b505b611245836119d8565b600654600183015460028401546040516000936112729390926001600160a01b039091169160200161232b565b60408051601f1981840301815291815281516020928301206000818152600490935290822080546001600160a01b031916331781556001810188905560028101879055426003909101556006805491935090916112ce83612bcb565b909155505060078301819055336000908152600560209081526040808320805460018101825590845291909220018290555181907f3a2718516bf8de6760fe7647dd13c596fe6a2beb8a15697aeee3f3ca6ddedda69061133190889088906124a2565b60405180910390a25050505050565b60008281526002602052604081206001600382015460ff16600181111561137757634e487b7160e01b600052602160045260246000fd5b14156113955760405162461bcd60e51b815260040161050a9061277e565b80546001600160a01b03163314156113bf5760405162461bcd60e51b815260040161050a9061253f565b60018101546001600160a01b031691506113d883611a30565b6113e1836119d8565b600181015483906113fa906001600160a01b0316611af3565b15611420576001820154600283015461141d916001600160a01b03169086611b82565b90505b81546114379033906001600160a01b0316836118b4565b600182015460028301546114589133916001600160a01b03909116906109d3565b336001600160a01b0316857f166e1788ade6bdaa98c1822ed449cd9cf405f106815607aa3cec15b5c7cb16fb866040516114929190612499565b60405180910390a381546114b09086906001600160a01b0316610bbb565b505092915050565b6114c58260020154611a30565b600181015460028201546114e69133916001600160a01b03909116906109d3565b60028201546001820154611502906001600160a01b0316611af3565b1561152d5760018201546002808401549085015461152a926001600160a01b03169190611b82565b90505b81546115449033906001600160a01b0316836118b4565b6001830154604051339186917f3b51ddb79624307cce37f8ba22985a23f6e050a1f7a26aab1eb7ef7af3255b1890600090a46001830154825461159091906001600160a01b0316610bbb565b82546115a69085906001600160a01b031661194e565b50505050565b805460005b8181101561167357838382815481106115da57634e487b7160e01b600052603260045260246000fd5b90600052602060002001541480156115fc57506115f8600183612b88565b8114155b15611663578261160d600184612b88565b8154811061162b57634e487b7160e01b600052603260045260246000fd5b906000526020600020015483828154811061165657634e487b7160e01b600052603260045260246000fd5b6000918252602090912001555b61166c81612bcb565b90506115b1565b508180548061169257634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055505050565b6040516301ffc9a760e01b81526001600160a01b038416906301ffc9a7906116e0906380ac58cd60e01b906004016124b0565b60206040518083038186803b1580156116f857600080fd5b505afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117309190612266565b156117bf57806001146117555760405162461bcd60e51b815260040161050a9061264d565b604051632142170760e11b815283906001600160a01b038216906342842e0e9061178790889030908890600401612367565b600060405180830381600087803b1580156117a157600080fd5b505af11580156117b5573d6000803e3d6000fd5b50505050506115a6565b6040516301ffc9a760e01b81526001600160a01b038416906301ffc9a7906117f290636cdb3d1360e11b906004016124b0565b60206040518083038186803b15801561180a57600080fd5b505afa15801561181e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118429190612266565b156115a657604051637921219560e11b815283906001600160a01b0382169063f242432a9061187b9088903090889088906004016123dd565b600060405180830381600087803b15801561189557600080fd5b505af11580156118a9573d6000803e3d6000fd5b505050505050505050565b6001600160a01b0383166000908152600a60205260409020548111156118ec5760405162461bcd60e51b815260040161050a9061288e565b600c54611903906001600160a01b03168383611e18565b6001600160a01b0383166000908152600a60205260408120805483929061192b908490612b88565b9250508190555080600b60008282546119449190612b88565b9091555050505050565b6001600160a01b03811660009081526005602052604090206119719083906115ac565b60008281526004602052604080822080546001600160a01b03191681556001810183905560028101839055600301829055516001600160a01b0383169184917fbb5d40441e7aee8a4ab754e8fc0b8511e576dcfd271af8996e537654dbe4913a9190a35050565b600c546119f0906001600160a01b0316333084611e6e565b336000908152600a602052604081208054839290611a0f908490612b31565b9250508190555080600b6000828254611a289190612b31565b909155505050565b600061271060075483611a439190612b69565b611a4d9190612b49565b600c54600854604080516378d1c86d60e01b815290519394508493611ae1936001600160a01b039081169333939116916378d1c86d91600480820192602092909190829003018186803b158015611aa357600080fd5b505afa158015611ab7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adb91906120a0565b84611e6e565b80600960008282546119449190612b31565b6040516301ffc9a760e01b815260009081906001600160a01b038416906301ffc9a790611b2b9063152a902d60e11b906004016124b0565b60206040518083038186803b158015611b4357600080fd5b505afa158015611b57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b7b9190612266565b9392505050565b6000806000856001600160a01b0316632a55205a86866040518363ffffffff1660e01b8152600401611bb59291906124a2565b604080518083038186803b158015611bcc57600080fd5b505afa158015611be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c0491906121d2565b90925090506000611c158286612b88565b90508115611e0e576000612710600860009054906101000a90046001600160a01b03166001600160a01b0316635801771e6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c7057600080fd5b505afa158015611c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca891906122bf565b611cb29085612b69565b611cbc9190612b49565b90508015611db057611d5433600860009054906101000a90046001600160a01b03166001600160a01b03166378d1c86d6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d1657600080fd5b505afa158015611d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4e91906120a0565b836118b4565b8060096000828254611d669190612b31565b9250508190555086886001600160a01b03167f5e322778c7e97750a93b7ef4d26e80a14c466530a586e67c0d8394021498010383604051611da79190612499565b60405180910390a35b6000611dbc8285612b88565b9050611dc93386836118b4565b87896001600160a01b03167f7a474f3ea7966b6a336a0169253a863c5bbe817379d3570951736f604adbe26983604051611e039190612499565b60405180910390a350505b9695505050505050565b610bb68363a9059cbb60e01b8484604051602401611e3792919061243c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611e8f565b6115a6846323b872dd60e01b858585604051602401611e3793929190612367565b6000611ee4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611f1e9092919063ffffffff16565b805190915015610bb65780806020019051810190611f029190612266565b610bb65760405162461bcd60e51b815260040161050a90612a14565b6060611f2d8484600085611f35565b949350505050565b606082471015611f575760405162461bcd60e51b815260040161050a90612684565b611f6085611ff5565b611f7c5760405162461bcd60e51b815260040161050a906129b2565b600080866001600160a01b03168587604051611f98919061230f565b60006040518083038185875af1925050503d8060008114611fd5576040519150601f19603f3d011682016040523d82523d6000602084013e611fda565b606091505b5091509150611fea828286612004565b979650505050505050565b6001600160a01b03163b151590565b60608315612013575081611b7b565b8251156120235782518084602001fd5b8160405162461bcd60e51b815260040161050a91906124c5565b60008083601f84011261204e578182fd5b50813567ffffffffffffffff811115612065578182fd5b60208301915083602082850101111561207d57600080fd5b9250929050565b600060208284031215612095578081fd5b8135611b7b81612bfc565b6000602082840312156120b1578081fd5b8151611b7b81612bfc565b6000806000806000608086880312156120d3578081fd5b85356120de81612bfc565b945060208601356120ee81612bfc565b935060408601359250606086013567ffffffffffffffff811115612110578182fd5b61211c8882890161203d565b969995985093965092949392505050565b60008060008060008060a08789031215612145578081fd5b863561215081612bfc565b9550602087013561216081612bfc565b94506040870135935060608701359250608087013567ffffffffffffffff811115612189578182fd5b61219589828a0161203d565b979a9699509497509295939492505050565b600080604083850312156121b9578182fd5b82356121c481612bfc565b946020939093013593505050565b600080604083850312156121e4578182fd5b82516121ef81612bfc565b6020939093015192949293505050565b600080600080600080600060e0888a031215612219578081fd5b873561222481612bfc565b96506020880135955060408801359450606088013560028110612245578182fd5b9699959850939660808101359560a0820135955060c0909101359350915050565b600060208284031215612277578081fd5b81518015158114611b7b578182fd5b600060208284031215612297578081fd5b5035919050565b600080604083850312156122b0578182fd5b50508035926020909101359150565b6000602082840312156122d0578081fd5b5051919050565b600281106122f557634e487b7160e01b600052602160045260246000fd5b9052565b600381526203078360ec1b602082015260400190565b60008251612321818460208701612b9f565b9190910192915050565b92835260609190911b6bffffffffffffffffffffffff19166020830152603482015260540190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038981168252881660208201526040810187905261010081016123b860608301886122d7565b8560808301528460a08301528360c08301528260e08301529998505050505050505050565b6001600160a01b03858116825284166020820152604081018390526060810182905260a060808201819052600090611e0e9083016122f9565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561248d57835183529284019291840191600101612471565b50909695505050505050565b90815260200190565b918252602082015260400190565b6001600160e01b031991909116815260200190565b60006020825282518060208401526124e4816040850160208701612b9f565b601f01601f19169190910160400192915050565b60208082526027908201527f4c697374696e672061756374696f6e2073746172742074696d65207061737420604082015266616c726561647960c81b606082015260800190565b602080825260169082015275213abcb2b91031b0b73737ba1031329039b2b63632b960511b604082015260600190565b60208082526017908201527f4269646465722063616e6e6f742062652073656c6c6572000000000000000000604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526010908201526f24b73b30b634b210323ab930ba34b7b760811b604082015260600190565b6020808252601b908201527f546865206c697374696e6720686176656e277420657870697265640000000000604082015260600190565b6020808252601d908201527f45524337323120646f65736e277420737570706f727420636f70696573000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b60208082526019908201527f546865206c697374696e6720646f65736e277420657869737400000000000000604082015260600190565b6020808252601b908201527f496e76616c69642061756374696f6e2073746172742070726963650000000000604082015260600190565b60208082526026908201527f416c72656164792072656365697665642062696464696e672c2063616e6e6f7460408201526520636c6f736560d01b606082015260800190565b6020808252601b908201527f41756374696f6e206e6f7420737570706f727420627579206e6f770000000000604082015260600190565b6020808252601e908201527f5468652061756374696f6e206861736e27742073746172746564207965740000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526010908201526f496e76616c696420666565207261746560801b604082015260600190565b60208082526023908201527f43616e206f6e6c792062696420666f72206c697374696e67206f6e206175637460408201526234b7b760e91b606082015260800190565b6020808252601f908201527f546865206c6f636b656420616d6f756e74206973206e6f7420656e6f75676800604082015260600190565b60208082526023908201527f546865204e465420636f706965732073686f756c64206c61726765722074686160408201526206e20360ec1b606082015260800190565b6020808252601690820152754f6e6c792073656c6c65722063616e2072656d6f766560501b604082015260600190565b6020808252601b908201527f5468652061756374696f6e20616c726561647920657870697265640000000000604082015260600190565b60208082526023908201527f5468652062696464696e6720706572696f6420686176656e277420636f6d706c60408201526265746560e81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526011908201527042696420707269636520746f6f206c6f7760781b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b602080825260139082015272496e76616c696420666978656420707269636560681b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526019908201527f4f6e6c79206269646465722063616e20636c61696d204e465400000000000000604082015260600190565b8681526020810186905260c08101612b1460408301876122d7565b8460608301528360808301528260a0830152979650505050505050565b60008219821115612b4457612b44612be6565b500190565b600082612b6457634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612b8357612b83612be6565b500290565b600082821015612b9a57612b9a612be6565b500390565b60005b83811015612bba578181015183820152602001612ba2565b838111156115a65750506000910152565b6000600019821415612bdf57612bdf612be6565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146109d057600080fdfea26469706673582212207233f7f733935f04e5f8f6f22b8c54296d3edfa64ead46abcdaab7c73943371064736f6c63430008010033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000079003a1052658f3b664cc080a001875d501be4b1000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000e9e65e22edcdfbba43e71ff3ba9f382429a34d8e
-----Decoded View---------------
Arg [0] : _owner (address): 0x79003a1052658f3B664Cc080A001875d501Be4B1
Arg [1] : _tokenAddr (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [2] : _mrConfig (address): 0xE9e65E22eDcDFbBA43E71Ff3BA9f382429A34D8E
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000079003a1052658f3b664cc080a001875d501be4b1
Arg [1] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [2] : 000000000000000000000000e9e65e22edcdfbba43e71ff3ba9f382429a34d8e
Deployed Bytecode Sourcemap
88548:3459:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74301:50;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;74071;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;:::i;86669:209::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;74569:47::-;;;:::i;:::-;;;;;;;:::i;74911:45::-;;;;;;:::i;:::-;;:::i;83124:122::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;82778:223::-;;;;;;:::i;:::-;;:::i;74811:25::-;;;:::i;:::-;;;;;;;:::i;74531:29::-;;;:::i;84557:730::-;;;;;;:::i;:::-;;:::i;:::-;;82437:122;;;;;;:::i;:::-;;:::i;74623:45::-;;;:::i;74874:28::-;;;:::i;21092:103::-;;;:::i;87459:165::-;;;;;;:::i;:::-;;:::i;20441:87::-;;;:::i;74675:22::-;;;:::i;74965:32::-;;;:::i;74181:51::-;;;;;;:::i;:::-;;:::i;89376:453::-;;;;;;:::i;:::-;;:::i;88989:120::-;;;;;;:::i;:::-;;:::i;74411:51::-;;;;;;:::i;:::-;;:::i;88588:18::-;;;:::i;90021:147::-;;;;;;:::i;:::-;;:::i;90316:529::-;;;;;;:::i;:::-;;:::i;86974:217::-;;;;;;:::i;:::-;;:::i;21350:201::-;;;;;;:::i;:::-;;:::i;74301:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74301:50:0;;;;;;;:::o;74071:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74071:50:0;;;;;;;;;;;;;;;;;;;;;:::o;86669:209::-;-1:-1:-1;;;86669:209:0;;;;;;;:::o;74569:47::-;74612:4;74569:47;:::o;74911:45::-;;;;;;;;;;;;;:::o;83124:122::-;-1:-1:-1;;;;;83218:20:0;;;;;;:14;:20;;;;;;;;;83211:27;;;;;;;;;;;;;;;;;83182:16;;83211:27;;;83218:20;83211:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83124:122;;;:::o;82778:223::-;82836:7;82878:26;;;:15;:26;;;;;82923:9;;;;82915:51;;;;-1:-1:-1;;;82915:51:0;;;;;;;:::i;:::-;;;;;;;;;82984:9;;;;82778:223;-1:-1:-1;;82778:223:0:o;74811:25::-;;;-1:-1:-1;;;;;74811:25:0;;:::o;74531:29::-;;;;:::o;84557:730::-;70146:1;70744:7;;:19;;70736:63;;;;-1:-1:-1;;;70736:63:0;;;;;;;:::i;:::-;70146:1;70877:7;:18;;;84632:19:::1;84654:26:::0;;;::::1;::::0;;;;;;;;84825:12:::1;::::0;::::1;::::0;::::1;;::::0;:35;::::1;;;;-1:-1:-1::0;;;84825:35:0::1;;;;;;;;;;84821:154;;84916:15;84901:3;:12;;;84885:3;:13;;;:28;;;;:::i;:::-;:46;84877:86;;;;-1:-1:-1::0;;;84877:86:0::1;;;;;;;:::i;:::-;84993:10:::0;;-1:-1:-1;;;;;84993:10:0::1;85007;84993:24;84985:59;;;;-1:-1:-1::0;;;84985:59:0::1;;;;;;;:::i;:::-;85063:13;::::0;::::1;::::0;:18;85055:69:::1;;;;-1:-1:-1::0;;;85055:69:0::1;;;;;;;:::i;:::-;85199:16;::::0;::::1;::::0;85217:11:::1;::::0;::::1;::::0;85174:55:::1;::::0;85187:10:::1;::::0;-1:-1:-1;;;;;85199:16:0;;::::1;::::0;85174:12:::1;:55::i;:::-;85268:10:::0;;85242:37:::1;::::0;85257:9;;-1:-1:-1;;;;;85268:10:0::1;85242:14;:37::i;:::-;-1:-1:-1::0;;70102:1:0;71056:22;;84557:730::o;82437:122::-;-1:-1:-1;;;;;82531:20:0;;;;;;:14;:20;;;;;;;;;82524:27;;;;;;;;;;;;;;;;;82495:16;;82524:27;;;82531:20;82524:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82437:122;;;:::o;74623:45::-;74663:5;74623:45;:::o;74874:28::-;;;;:::o;21092:103::-;20672:12;:10;:12::i;:::-;-1:-1:-1;;;;;20661:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;20661:23:0;;20653:68;;;;-1:-1:-1;;;20653:68:0;;;;;;;:::i;:::-;21157:30:::1;21184:1;21157:18;:30::i;:::-;21092:103::o:0;87459:165::-;20672:12;:10;:12::i;:::-;-1:-1:-1;;;;;20661:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;20661:23:0;;20653:68;;;;-1:-1:-1;;;20653:68:0;;;;;;;:::i;:::-;74612:4:::1;87538:8;:28;;87530:57;;;;-1:-1:-1::0;;;87530:57:0::1;;;;;;;:::i;:::-;87598:7;:18:::0;87459:165::o;20441:87::-;20487:7;20514:6;-1:-1:-1;;;;;20514:6:0;20441:87;:::o;74675:22::-;;;;:::o;74965:32::-;;;;:::o;74181:51::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;89376:453::-;70146:1;70744:7;;:19;;70736:63;;;;-1:-1:-1;;;70736:63:0;;;;;;;:::i;:::-;70146:1;70877:7;:18;89632:189:::1;89658:13:::0;89686:8;89709:7;89731:9;89755:6;89776:10;89801:9;89632:11:::1;:189::i;:::-;-1:-1:-1::0;;70102:1:0;71056:22;;-1:-1:-1;;;;;89376:453:0:o;88989:120::-;70146:1;70744:7;;:19;;70736:63;;;;-1:-1:-1;;;70736:63:0;;;;;;;:::i;:::-;70146:1;70877:7;:18;89074:27:::1;89084:9:::0;89095:5;89074:9:::1;:27::i;74411:51::-:0;;;;;;;;;;;;;;;;;;;;88588:18;;;-1:-1:-1;;;;;88588:18:0;;:::o;90021:147::-;70146:1;70744:7;;:19;;70736:63;;;;-1:-1:-1;;;70736:63:0;;;;;;;:::i;:::-;70146:1;70877:7;:18;90089:13:::1;90105:19;90114:9:::0;90105:8:::1;:19::i;:::-;90089:35;;90135:25;90143:9;90154:5;90135:7;:25::i;:::-;-1:-1:-1::0;;70102:1:0;71056:22;;-1:-1:-1;90021:147:0:o;90316:529::-;70146:1;70744:7;;:19;;70736:63;;;;-1:-1:-1;;;70736:63:0;;;;;;;:::i;:::-;70146:1;70877:7;:18;90386:19:::1;90408:26:::0;;;:15:::1;:26;::::0;;;;90453:10;;-1:-1:-1;;;;;90453:10:0::1;90467;90453:24;90445:62;;;;-1:-1:-1::0;;;90445:62:0::1;;;;;;;:::i;:::-;90558:13;::::0;::::1;::::0;90520:19:::1;90542:30:::0;;;:15:::1;:30;::::0;;;;90605:12:::1;::::0;::::1;::::0;90620:15:::1;-1:-1:-1::0;90583:115:0::1;;;;-1:-1:-1::0;;;90583:115:0::1;;;;;;;:::i;:::-;90807:30;90817:9;90828:3;90833;90807:9;:30::i;86974:217::-:0;-1:-1:-1;;;86974:217:0;;;;;;;;:::o;21350:201::-;20672:12;:10;:12::i;:::-;-1:-1:-1;;;;;20661:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;20661:23:0;;20653:68;;;;-1:-1:-1;;;20653:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;21439:22:0;::::1;21431:73;;;;-1:-1:-1::0;;;21431:73:0::1;;;;;;;:::i;:::-;21515:28;21534:8;21515:18;:28::i;:::-;21350:201:::0;:::o;85992:583::-;86125:67;;-1:-1:-1;;;86125:67:0;;-1:-1:-1;;;;;86125:40:0;;;;;:67;;-1:-1:-1;;;86166:25:0;86125:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86121:447;;;86266:57;;-1:-1:-1;;;86266:57:0;;86237:13;;-1:-1:-1;;;;;86266:28:0;;;;;:57;;86303:4;;86310:2;;86314:8;;86266:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86121:447;;;;86345:68;;-1:-1:-1;;;86345:68:0;;-1:-1:-1;;;;;86345:40:0;;;;;:68;;-1:-1:-1;;;86386:26:0;86345:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86341:227;;;86489:67;;-1:-1:-1;;;86489:67:0;;86460:13;;-1:-1:-1;;;;;86489:28:0;;;;;:67;;86526:4;;86533:2;;86537:8;;86547:1;;86489:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86341:227;;85992:583;;;:::o;83753:275::-;-1:-1:-1;;;;;83864:22:0;;;;;;:14;:22;;;;;83832:55;;83853:9;;83832:20;:55::i;:::-;83943:26;;;;:15;:26;;;;;;;;83936:33;;-1:-1:-1;;;;;;83936:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;83936:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;83987;-1:-1:-1;;;;;83987:33:0;;;83959:9;;83987:33;;83943:26;83987:33;83753:275;;:::o;19159:98::-;19239:10;19159:98;:::o;21711:191::-;21785:16;21804:6;;-1:-1:-1;;;;;21821:17:0;;;-1:-1:-1;;;;;;21821:17:0;;;;;;21854:40;;21804:6;;;;;;;21854:40;;21785:16;21854:40;21711:191;;:::o;75923:2050::-;76250:19;76237:9;:32;;;;;;-1:-1:-1;;;76237:32:0;;;;;;;;;;76233:319;;76308:15;76294:10;:29;;76286:81;;;;-1:-1:-1;;;76286:81:0;;;;;;;:::i;:::-;76421:8;;;;;;;;;-1:-1:-1;;;;;76421:8:0;-1:-1:-1;;;;;76421:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76408:9;:38;;:80;;;;;76463:8;;;;;;;;;-1:-1:-1;;;;;76463:8:0;-1:-1:-1;;;;;76463:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76450:9;:38;;76408:80;76382:158;;;;-1:-1:-1;;;76382:158:0;;;;;;;:::i;:::-;76580:1;76570:7;:11;76562:59;;;;-1:-1:-1;;;76562:59:0;;;;;;;:::i;:::-;76651:19;76638:9;:32;;;;;;-1:-1:-1;;;76638:32:0;;;;;;;;;;76634:225;;;76704:1;76695:6;:10;76687:42;;;;-1:-1:-1;;;76687:42:0;;;;;;;:::i;:::-;76634:225;;;76764:16;76751:9;:29;;;;;;-1:-1:-1;;;76751:29:0;;;;;;;;;;76747:112;;;76814:1;76805:6;:10;76797:50;;;;-1:-1:-1;;;76797:50:0;;;;;;;:::i;:::-;76872:57;76884:10;76896:13;76911:8;76921:7;76872:11;:57::i;:::-;76947:13;76942:1024;76974:7;76966:5;:15;76942:1024;;;77007:17;77072:14;;77088:13;77103:8;77055:57;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;77027:100;;;;;;77007:120;;77180:10;77144:15;:26;77160:9;77144:26;;;;;;;;;;;:33;;;:46;;;;;-1:-1:-1;;;;;77144:46:0;;;;;-1:-1:-1;;;;;77144:46:0;;;;;;77247:13;77205:15;:26;77221:9;77205:26;;;;;;;;;;;:39;;;:55;;;;;-1:-1:-1;;;;;77205:55:0;;;;;-1:-1:-1;;;;;77205:55:0;;;;;;77312:8;77275:15;:26;77291:9;77275:26;;;;;;;;;;;:34;;:45;;;;77373:9;77335:15;:26;77351:9;77335:26;;;;;;;;;;;:35;;;:47;;;;;;;;;;;;;;;;;-1:-1:-1;;;77335:47:0;;;;;;;;;;;;;-1:-1:-1;77397:26:0;;;;:15;:26;;;;;:32;;;:41;;;77453:36;;;:49;;;77517:35;;;;:47;;;77579:16;;;;;;:::i;:::-;;;;-1:-1:-1;;77627:10:0;77612:26;;;;:14;:26;;;;;;;;:42;;;;;;;;;;;;;;;;;;77676:278;-1:-1:-1;;;;;77676:278:0;;;77627:10;77644:9;;77676:278;;;;77797:8;;77824:5;;77848:9;;77876:6;;77901:10;;77930:9;;77676:278;:::i;:::-;;;;;;;;-1:-1:-1;76983:7:0;;;:::i;:::-;;;76942:1024;;77981:1622;78054:19;78076:26;;;:15;:26;;;;;78137:16;78121:12;;;;;;;:32;;;;;-1:-1:-1;;;78121:32:0;;;;;;;;;;78113:80;;;;-1:-1:-1;;;78113:80:0;;;;;;;:::i;:::-;78231:3;:13;;;78212:15;:32;;78204:75;;;;-1:-1:-1;;;78204:75:0;;;;;;;:::i;:::-;78330:15;78314:3;:12;;;78298:3;:13;;;:28;;;;:::i;:::-;:47;;78290:87;;;;-1:-1:-1;;;78290:87:0;;;;;;;:::i;:::-;78410:10;;-1:-1:-1;;;;;78410:10:0;78396;:24;;78388:60;;;;-1:-1:-1;;;78388:60:0;;;;;;;:::i;:::-;78480:9;;;;78506:13;;;;:18;78502:98;;-1:-1:-1;78568:13:0;;;;78552:30;;;;:15;:30;;;;;:36;;;78502:98;78628:8;78620:5;:16;78612:46;;;;-1:-1:-1;;;78612:46:0;;;;;;;:::i;:::-;78760:13;;;;:18;78756:260;;78833:13;;;;78795:19;78817:30;;;:15;:30;;;;;:37;;78910:36;;;;;-1:-1:-1;;;;;78817:37:0;;;;78869:78;;78817:37;;;;78869:14;:78::i;:::-;78962:42;78977:3;:13;;;78992:11;78962:14;:42::i;:::-;78756:260;;79028:20;79042:5;79028:13;:20::i;:::-;79122:14;;79138:16;;;;79156:11;;;;79105:63;;79061:17;;79105:63;;79122:14;;-1:-1:-1;;;;;79138:16:0;;;;79105:63;;;:::i;:::-;;;;-1:-1:-1;;79105:63:0;;;;;;;;;79081:98;;79105:63;79081:98;;;;79192:26;;;;:15;:26;;;;;;:46;;-1:-1:-1;;;;;;79192:46:0;79228:10;79192:46;;;;79249:36;;:48;;;79308:32;;;:40;;;79398:15;79359:36;;;;:54;79426:14;:16;;79081:98;;-1:-1:-1;79426:16:0;;;;;:::i;:::-;;;;-1:-1:-1;;79455:13:0;;;:25;;;79508:10;79493:26;;;;:14;:26;;;;;;;;:42;;;;;;;;;;;;;;;;;;79553;79471:9;;79553:42;;;;79578:9;;79589:5;;79553:42;:::i;:::-;;;;;;;;77981:1622;;;;;:::o;80869:897::-;80938:20;80993:26;;;:15;:26;;;;;81054:16;81038:12;;;;;;;:32;;;;;-1:-1:-1;;;81038:32:0;;;;;;;;;;;81030:72;;;;-1:-1:-1;;;81030:72:0;;;;;;;:::i;:::-;81135:10;;-1:-1:-1;;;;;81135:10:0;81121;:24;;81113:59;;;;-1:-1:-1;;;81113:59:0;;;;;;;:::i;:::-;81200:16;;;;-1:-1:-1;;;;;81200:16:0;;-1:-1:-1;81229:18:0;81241:5;81229:11;:18::i;:::-;81317:20;81331:5;81317:13;:20::i;:::-;81409:16;;;;81373:5;;81393:33;;-1:-1:-1;;;;;81409:16:0;81393:15;:33::i;:::-;81389:135;;;81475:16;;;;81493:11;;;;81458:54;;-1:-1:-1;;;;;81475:16:0;;81506:5;81458:16;:54::i;:::-;81443:69;;81389:135;81563:10;;81536:52;;81551:10;;-1:-1:-1;;;;;81563:10:0;81575:12;81536:14;:52::i;:::-;81624:16;;;;81642:11;;;;81599:55;;81612:10;;-1:-1:-1;;;;;81624:16:0;;;;81599:12;:55::i;:::-;81690:10;-1:-1:-1;;;;;81672:36:0;81679:9;81672:36;81702:5;81672:36;;;;;;:::i;:::-;;;;;;;;81747:10;;81721:37;;81736:9;;-1:-1:-1;;;;;81747:10:0;81721:14;:37::i;:::-;80869:897;;;;;;:::o;81774:655::-;81908:22;81920:3;:9;;;81908:11;:22::i;:::-;81966:16;;;;81984:11;;;;81941:55;;81954:10;;-1:-1:-1;;;;;81966:16:0;;;;81941:12;:55::i;:::-;82032:9;;;;82072:16;;;;82056:33;;-1:-1:-1;;;;;82072:16:0;82056:15;:33::i;:::-;82052:139;;;82138:16;;;;82156:11;;;;;82169:9;;;;82121:58;;-1:-1:-1;;;;;82138:16:0;;82156:11;82121:16;:58::i;:::-;82106:73;;82052:139;82230:10;;82203:52;;82218:10;;-1:-1:-1;;;;;82230:10:0;82242:12;82203:14;:52::i;:::-;82282:13;;;;82273:46;;82308:10;;82297:9;;82273:46;;;;;82347:13;;;;82362:10;;82332:41;;82347:13;-1:-1:-1;;;;;82362:10:0;82332:14;:41::i;:::-;82410:10;;82384:37;;82399:9;;-1:-1:-1;;;;;82410:10:0;82384:14;:37::i;:::-;81774:655;;;;:::o;83254:491::-;83370:17;;83353:14;83398:277;83430:6;83422:5;:14;83398:277;;;83553:9;83532:10;83543:5;83532:17;;;;;;-1:-1:-1;;;83532:17:0;;;;;;;;;;;;;;;;;:30;:53;;;;-1:-1:-1;83575:10:0;83584:1;83575:6;:10;:::i;:::-;83566:5;:19;;83532:53;83528:136;;;83626:10;83637;83646:1;83637:6;:10;:::i;:::-;83626:22;;;;;;-1:-1:-1;;;83626:22:0;;;;;;;;;;;;;;;;;83606:10;83617:5;83606:17;;;;;;-1:-1:-1;;;83606:17:0;;;;;;;;;;;;;;;;;;:42;83528:136;83438:7;;;:::i;:::-;;;83398:277;;;;83721:10;:16;;;;;-1:-1:-1;;;83721:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;83254:491;;;:::o;85295:689::-;85455:67;;-1:-1:-1;;;85455:67:0;;-1:-1:-1;;;;;85455:40:0;;;;;:67;;-1:-1:-1;;;85496:25:0;85455:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85451:526;;;85547:7;85558:1;85547:12;85539:54;;;;-1:-1:-1;;;85539:54:0;;;;;;;:::i;:::-;85665:59;;-1:-1:-1;;;85665:59:0;;85636:13;;-1:-1:-1;;;;;85665:28:0;;;;;:59;;85694:4;;85708;;85715:8;;85665:59;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85451:526;;;;85746:68;;-1:-1:-1;;;85746:68:0;;-1:-1:-1;;;;;85746:40:0;;;;;:68;;-1:-1:-1;;;85787:26:0;85746:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85742:235;;;85890:75;;-1:-1:-1;;;85890:75:0;;85861:13;;-1:-1:-1;;;;;85890:28:0;;;;;:75;;85919:4;;85933;;85940:8;;85950:7;;85890:75;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85742:235;85295:689;;;;:::o;91664:338::-;-1:-1:-1;;;;;91802:16:0;;;;;;:10;:16;;;;;;:27;-1:-1:-1;91802:27:0;91794:71;;;;-1:-1:-1;;;91794:71:0;;;;;;;:::i;:::-;91899:4;;91876:41;;-1:-1:-1;;;;;91899:4:0;91905:2;91909:7;91876:22;:41::i;:::-;-1:-1:-1;;;;;91928:16:0;;;;;;:10;:16;;;;;:27;;91948:7;;91928:16;:27;;91948:7;;91928:27;:::i;:::-;;;;;;;;91987:7;91966:17;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;91664:338:0:o;84036:275::-;-1:-1:-1;;;;;84147:22:0;;;;;;:14;:22;;;;;84115:55;;84136:9;;84115:20;:55::i;:::-;84226:26;;;;:15;:26;;;;;;84219:33;;-1:-1:-1;;;;;;84219:33:0;;;;;;;;;;;;;;;;;;;;84270;-1:-1:-1;;;;;84270:33:0;;;84242:9;;84270:33;;84226:26;84270:33;84036:275;;:::o;91222:394::-;91484:4;;91457:68;;-1:-1:-1;;;;;91484:4:0;91490:10;91510:4;91517:7;91457:26;:68::i;:::-;91547:10;91536:22;;;;:10;:22;;;;;:33;;91562:7;;91536:22;:33;;91562:7;;91536:33;:::i;:::-;;;;;;;;91601:7;91580:17;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;;91222:394:0:o;90893:281::-;90958:11;74663:5;90981:7;;90973:5;:15;;;;:::i;:::-;90972:33;;;;:::i;:::-;91075:4;;91093:8;;:28;;;-1:-1:-1;;;91093:28:0;;;;90958:47;;-1:-1:-1;90958:47:0;;91048:83;;-1:-1:-1;;;;;91075:4:0;;;;91081:10;;91093:8;;;:26;;:28;;;;;;;;;;;;;;;:8;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91123:7;91048:26;:83::i;:::-;91159:7;91142:13;;:24;;;;;;;:::i;75453:190::-;75552:58;;-1:-1:-1;;;75552:58:0;;75520:4;;;;-1:-1:-1;;;;;75552:35:0;;;;;:58;;-1:-1:-1;;;75588:21:0;75552:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75537:73;75453:190;-1:-1:-1;;;75453:190:0:o;79611:1250::-;79749:21;79842:25;79869:23;79905:9;-1:-1:-1;;;;;79896:31:0;;79942:7;79964:14;79896:93;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79841:148;;-1:-1:-1;79841:148:0;-1:-1:-1;80045:20:0;80068:32;79841:148;80068:14;:32;:::i;:::-;80045:55;-1:-1:-1;80173:19:0;;80169:653;;80209:18;74663:5;80249:8;;;;;;;;;-1:-1:-1;;;;;80249:8:0;-1:-1:-1;;;;;80249:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80231:47;;:15;:47;:::i;:::-;80230:65;;;;:::i;:::-;80209:86;-1:-1:-1;80314:14:0;;80310:243;;80349:68;80364:10;80376:8;;;;;;;;;-1:-1:-1;;;;;80376:8:0;-1:-1:-1;;;;;80376:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80406:10;80349:14;:68::i;:::-;80453:10;80436:13;;:27;;;;;;;:::i;:::-;;;;;;;;80517:7;80506:9;-1:-1:-1;;;;;80489:48:0;;80526:10;80489:48;;;;;;:::i;:::-;;;;;;;;80310:243;80569:21;80593:28;80611:10;80593:15;:28;:::i;:::-;80569:52;;80636:60;80651:10;80663:17;80682:13;80636:14;:60::i;:::-;80787:7;80776:9;-1:-1:-1;;;;;80762:48:0;;80796:13;80762:48;;;;;;:::i;:::-;;;;;;;;80169:653;;;80841:12;79611:1250;-1:-1:-1;;;;;;79611:1250:0:o;12127:211::-;12244:86;12264:5;12294:23;;;12319:2;12323:5;12271:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;12271:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;12271:58:0;-1:-1:-1;;;;;;12271:58:0;;;;;;;;;;12244:19;:86::i;12346:248::-;12490:96;12510:5;12540:27;;;12569:4;12575:2;12579:5;12517:68;;;;;;;;;;:::i;14700:716::-;15124:23;15150:69;15178:4;15150:69;;;;;;;;;;;;;;;;;15158:5;-1:-1:-1;;;;;15150:27:0;;;:69;;;;;:::i;:::-;15234:17;;15124:95;;-1:-1:-1;15234:21:0;15230:179;;15331:10;15320:30;;;;;;;;;;;;:::i;:::-;15312:85;;;;-1:-1:-1;;;15312:85:0;;;;;;;:::i;6899:229::-;7036:12;7068:52;7090:6;7098:4;7104:1;7107:12;7068:21;:52::i;:::-;7061:59;6899:229;-1:-1:-1;;;;6899:229:0:o;8019:510::-;8189:12;8247:5;8222:21;:30;;8214:81;;;;-1:-1:-1;;;8214:81:0;;;;;;;:::i;:::-;8314:18;8325:6;8314:10;:18::i;:::-;8306:60;;;;-1:-1:-1;;;8306:60:0;;;;;;;:::i;:::-;8380:12;8394:23;8421:6;-1:-1:-1;;;;;8421:11:0;8440:5;8447:4;8421:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8379:73;;;;8470:51;8487:7;8496:10;8508:12;8470:16;:51::i;:::-;8463:58;8019:510;-1:-1:-1;;;;;;;8019:510:0:o;4154:326::-;-1:-1:-1;;;;;4449:19:0;;:23;;;4154:326::o;10705:712::-;10855:12;10884:7;10880:530;;;-1:-1:-1;10915:10:0;10908:17;;10880:530;11029:17;;:21;11025:374;;11227:10;11221:17;11288:15;11275:10;11271:2;11267:19;11260:44;11175:148;11370:12;11363:20;;-1:-1:-1;;;11363:20:0;;;;;;;;:::i;14:377:1:-;;;131:3;124:4;116:6;112:17;108:27;98:2;;156:8;146;139:26;98:2;-1:-1:-1;186:20:1;;229:18;218:30;;215:2;;;268:8;258;251:26;215:2;312:4;304:6;300:17;288:29;;364:3;357:4;348:6;340;336:19;332:30;329:39;326:2;;;381:1;378;371:12;326:2;88:303;;;;;:::o;396:259::-;;508:2;496:9;487:7;483:23;479:32;476:2;;;529:6;521;514:22;476:2;573:9;560:23;592:33;619:5;592:33;:::i;660:263::-;;783:2;771:9;762:7;758:23;754:32;751:2;;;804:6;796;789:22;751:2;841:9;835:16;860:33;887:5;860:33;:::i;928:780::-;;;;;;1110:3;1098:9;1089:7;1085:23;1081:33;1078:2;;;1132:6;1124;1117:22;1078:2;1176:9;1163:23;1195:33;1222:5;1195:33;:::i;:::-;1247:5;-1:-1:-1;1304:2:1;1289:18;;1276:32;1317:35;1276:32;1317:35;:::i;:::-;1371:7;-1:-1:-1;1425:2:1;1410:18;;1397:32;;-1:-1:-1;1480:2:1;1465:18;;1452:32;1507:18;1496:30;;1493:2;;;1544:6;1536;1529:22;1493:2;1588:60;1640:7;1631:6;1620:9;1616:22;1588:60;:::i;:::-;1068:640;;;;-1:-1:-1;1068:640:1;;-1:-1:-1;1667:8:1;;1562:86;1068:640;-1:-1:-1;;;1068:640:1:o;1713:849::-;;;;;;;1912:3;1900:9;1891:7;1887:23;1883:33;1880:2;;;1934:6;1926;1919:22;1880:2;1978:9;1965:23;1997:33;2024:5;1997:33;:::i;:::-;2049:5;-1:-1:-1;2106:2:1;2091:18;;2078:32;2119:35;2078:32;2119:35;:::i;:::-;2173:7;-1:-1:-1;2227:2:1;2212:18;;2199:32;;-1:-1:-1;2278:2:1;2263:18;;2250:32;;-1:-1:-1;2333:3:1;2318:19;;2305:33;2361:18;2350:30;;2347:2;;;2398:6;2390;2383:22;2347:2;2442:60;2494:7;2485:6;2474:9;2470:22;2442:60;:::i;:::-;1870:692;;;;-1:-1:-1;1870:692:1;;-1:-1:-1;1870:692:1;;2521:8;;1870:692;-1:-1:-1;;;1870:692:1:o;2567:327::-;;;2696:2;2684:9;2675:7;2671:23;2667:32;2664:2;;;2717:6;2709;2702:22;2664:2;2761:9;2748:23;2780:33;2807:5;2780:33;:::i;:::-;2832:5;2884:2;2869:18;;;;2856:32;;-1:-1:-1;;;2654:240:1:o;2899:324::-;;;3039:2;3027:9;3018:7;3014:23;3010:32;3007:2;;;3060:6;3052;3045:22;3007:2;3097:9;3091:16;3116:33;3143:5;3116:33;:::i;:::-;3213:2;3198:18;;;;3192:25;3168:5;;3192:25;;-1:-1:-1;;;2997:226:1:o;3228:776::-;;;;;;;;3455:3;3443:9;3434:7;3430:23;3426:33;3423:2;;;3477:6;3469;3462:22;3423:2;3521:9;3508:23;3540:33;3567:5;3540:33;:::i;:::-;3592:5;-1:-1:-1;3644:2:1;3629:18;;3616:32;;-1:-1:-1;3695:2:1;3680:18;;3667:32;;-1:-1:-1;3751:2:1;3736:18;;3723:32;3786:1;3774:14;;3764:2;;3807:6;3799;3792:22;3764:2;3413:591;;;;-1:-1:-1;3413:591:1;;3889:3;3874:19;;3861:33;;3941:3;3926:19;;3913:33;;-1:-1:-1;3993:3:1;3978:19;;;3965:33;;-1:-1:-1;3413:591:1;-1:-1:-1;;3413:591:1:o;4009:297::-;;4129:2;4117:9;4108:7;4104:23;4100:32;4097:2;;;4150:6;4142;4135:22;4097:2;4187:9;4181:16;4240:5;4233:13;4226:21;4219:5;4216:32;4206:2;;4267:6;4259;4252:22;4311:190;;4423:2;4411:9;4402:7;4398:23;4394:32;4391:2;;;4444:6;4436;4429:22;4391:2;-1:-1:-1;4472:23:1;;4381:120;-1:-1:-1;4381:120:1:o;4506:258::-;;;4635:2;4623:9;4614:7;4610:23;4606:32;4603:2;;;4656:6;4648;4641:22;4603:2;-1:-1:-1;;4684:23:1;;;4754:2;4739:18;;;4726:32;;-1:-1:-1;4593:171:1:o;4964:194::-;;5087:2;5075:9;5066:7;5062:23;5058:32;5055:2;;;5108:6;5100;5093:22;5055:2;-1:-1:-1;5136:16:1;;5045:113;-1:-1:-1;5045:113:1:o;5163:239::-;5246:1;5239:5;5236:12;5226:2;;5291:10;5286:3;5282:20;5279:1;5272:31;5326:4;5323:1;5316:15;5354:4;5351:1;5344:15;5226:2;5378:18;;5216:186::o;5407:153::-;5486:1;5474:14;;-1:-1:-1;;;5513:4:1;5504:14;;5497:29;5551:2;5542:12;;5464:96::o;5565:274::-;;5732:6;5726:13;5748:53;5794:6;5789:3;5782:4;5774:6;5770:17;5748:53;:::i;:::-;5817:16;;;;;5702:137;-1:-1:-1;;5702:137:1:o;5844:359::-;6029:19;;;6086:2;6082:15;;;;-1:-1:-1;;6078:53:1;6073:2;6064:12;;6057:75;6157:2;6148:12;;6141:28;6194:2;6185:12;;6019:184::o;6208:203::-;-1:-1:-1;;;;;6372:32:1;;;;6354:51;;6342:2;6327:18;;6309:102::o;6416:375::-;-1:-1:-1;;;;;6674:15:1;;;6656:34;;6726:15;;;;6721:2;6706:18;;6699:43;6773:2;6758:18;;6751:34;;;;6606:2;6591:18;;6573:218::o;6796:767::-;-1:-1:-1;;;;;7206:15:1;;;7188:34;;7258:15;;7253:2;7238:18;;7231:43;7305:2;7290:18;;7283:34;;;7137:3;7122:19;;7326:55;7377:2;7362:18;;7354:6;7326:55;:::i;:::-;7418:6;7412:3;7401:9;7397:19;7390:35;7462:6;7456:3;7445:9;7441:19;7434:35;7506:6;7500:3;7489:9;7485:19;7478:35;7550:6;7544:3;7533:9;7529:19;7522:35;7104:459;;;;;;;;;;;:::o;7568:629::-;-1:-1:-1;;;;;7927:15:1;;;7909:34;;7979:15;;7974:2;7959:18;;7952:43;8026:2;8011:18;;8004:34;;;8069:2;8054:18;;8047:34;;;7889:3;8112;8097:19;;8090:32;;;7568:629;;8139:52;;8171:19;;8139:52;:::i;8828:417::-;-1:-1:-1;;;;;9077:32:1;;;;9059:51;;9141:2;9126:18;;9119:34;;;;9184:2;9169:18;;9162:34;9227:2;9212:18;;9205:34;9046:3;9031:19;;9013:232::o;9250:274::-;-1:-1:-1;;;;;9442:32:1;;;;9424:51;;9506:2;9491:18;;9484:34;9412:2;9397:18;;9379:145::o;9529:635::-;9700:2;9752:21;;;9822:13;;9725:18;;;9844:22;;;9529:635;;9700:2;9923:15;;;;9897:2;9882:18;;;9529:635;9969:169;9983:6;9980:1;9977:13;9969:169;;;10044:13;;10032:26;;10113:15;;;;10078:12;;;;10005:1;9998:9;9969:169;;;-1:-1:-1;10155:3:1;;9680:484;-1:-1:-1;;;;;;9680:484:1:o;10169:177::-;10315:25;;;10303:2;10288:18;;10270:76::o;10351:248::-;10525:25;;;10581:2;10566:18;;10559:34;10513:2;10498:18;;10480:119::o;10604:202::-;-1:-1:-1;;;;;;10766:33:1;;;;10748:52;;10736:2;10721:18;;10703:103::o;11258:383::-;;11407:2;11396:9;11389:21;11439:6;11433:13;11482:6;11477:2;11466:9;11462:18;11455:34;11498:66;11557:6;11552:2;11541:9;11537:18;11532:2;11524:6;11520:15;11498:66;:::i;:::-;11625:2;11604:15;-1:-1:-1;;11600:29:1;11585:45;;;;11632:2;11581:54;;11379:262;-1:-1:-1;;11379:262:1:o;11646:403::-;11848:2;11830:21;;;11887:2;11867:18;;;11860:30;11926:34;11921:2;11906:18;;11899:62;-1:-1:-1;;;11992:2:1;11977:18;;11970:37;12039:3;12024:19;;11820:229::o;12054:346::-;12256:2;12238:21;;;12295:2;12275:18;;;12268:30;-1:-1:-1;;;12329:2:1;12314:18;;12307:52;12391:2;12376:18;;12228:172::o;12405:347::-;12607:2;12589:21;;;12646:2;12626:18;;;12619:30;12685:25;12680:2;12665:18;;12658:53;12743:2;12728:18;;12579:173::o;12757:402::-;12959:2;12941:21;;;12998:2;12978:18;;;12971:30;13037:34;13032:2;13017:18;;13010:62;-1:-1:-1;;;13103:2:1;13088:18;;13081:36;13149:3;13134:19;;12931:228::o;13164:340::-;13366:2;13348:21;;;13405:2;13385:18;;;13378:30;-1:-1:-1;;;13439:2:1;13424:18;;13417:46;13495:2;13480:18;;13338:166::o;13509:351::-;13711:2;13693:21;;;13750:2;13730:18;;;13723:30;13789:29;13784:2;13769:18;;13762:57;13851:2;13836:18;;13683:177::o;13865:353::-;14067:2;14049:21;;;14106:2;14086:18;;;14079:30;14145:31;14140:2;14125:18;;14118:59;14209:2;14194:18;;14039:179::o;14223:402::-;14425:2;14407:21;;;14464:2;14444:18;;;14437:30;14503:34;14498:2;14483:18;;14476:62;-1:-1:-1;;;14569:2:1;14554:18;;14547:36;14615:3;14600:19;;14397:228::o;14630:349::-;14832:2;14814:21;;;14871:2;14851:18;;;14844:30;14910:27;14905:2;14890:18;;14883:55;14970:2;14955:18;;14804:175::o;14984:351::-;15186:2;15168:21;;;15225:2;15205:18;;;15198:30;15264:29;15259:2;15244:18;;15237:57;15326:2;15311:18;;15158:177::o;15340:402::-;15542:2;15524:21;;;15581:2;15561:18;;;15554:30;15620:34;15615:2;15600:18;;15593:62;-1:-1:-1;;;15686:2:1;15671:18;;15664:36;15732:3;15717:19;;15514:228::o;15747:351::-;15949:2;15931:21;;;15988:2;15968:18;;;15961:30;16027:29;16022:2;16007:18;;16000:57;16089:2;16074:18;;15921:177::o;16103:354::-;16305:2;16287:21;;;16344:2;16324:18;;;16317:30;16383:32;16378:2;16363:18;;16356:60;16448:2;16433:18;;16277:180::o;16462:356::-;16664:2;16646:21;;;16683:18;;;16676:30;16742:34;16737:2;16722:18;;16715:62;16809:2;16794:18;;16636:182::o;16823:340::-;17025:2;17007:21;;;17064:2;17044:18;;;17037:30;-1:-1:-1;;;17098:2:1;17083:18;;17076:46;17154:2;17139:18;;16997:166::o;17168:399::-;17370:2;17352:21;;;17409:2;17389:18;;;17382:30;17448:34;17443:2;17428:18;;17421:62;-1:-1:-1;;;17514:2:1;17499:18;;17492:33;17557:3;17542:19;;17342:225::o;17572:355::-;17774:2;17756:21;;;17813:2;17793:18;;;17786:30;17852:33;17847:2;17832:18;;17825:61;17918:2;17903:18;;17746:181::o;17932:399::-;18134:2;18116:21;;;18173:2;18153:18;;;18146:30;18212:34;18207:2;18192:18;;18185:62;-1:-1:-1;;;18278:2:1;18263:18;;18256:33;18321:3;18306:19;;18106:225::o;18336:346::-;18538:2;18520:21;;;18577:2;18557:18;;;18550:30;-1:-1:-1;;;18611:2:1;18596:18;;18589:52;18673:2;18658:18;;18510:172::o;18687:351::-;18889:2;18871:21;;;18928:2;18908:18;;;18901:30;18967:29;18962:2;18947:18;;18940:57;19029:2;19014:18;;18861:177::o;19043:399::-;19245:2;19227:21;;;19284:2;19264:18;;;19257:30;19323:34;19318:2;19303:18;;19296:62;-1:-1:-1;;;19389:2:1;19374:18;;19367:33;19432:3;19417:19;;19217:225::o;19447:353::-;19649:2;19631:21;;;19688:2;19668:18;;;19661:30;19727:31;19722:2;19707:18;;19700:59;19791:2;19776:18;;19621:179::o;19805:341::-;20007:2;19989:21;;;20046:2;20026:18;;;20019:30;-1:-1:-1;;;20080:2:1;20065:18;;20058:47;20137:2;20122:18;;19979:167::o;20151:406::-;20353:2;20335:21;;;20392:2;20372:18;;;20365:30;20431:34;20426:2;20411:18;;20404:62;-1:-1:-1;;;20497:2:1;20482:18;;20475:40;20547:3;20532:19;;20325:232::o;20562:343::-;20764:2;20746:21;;;20803:2;20783:18;;;20776:30;-1:-1:-1;;;20837:2:1;20822:18;;20815:49;20896:2;20881:18;;20736:169::o;20910:355::-;21112:2;21094:21;;;21151:2;21131:18;;;21124:30;21190:33;21185:2;21170:18;;21163:61;21256:2;21241:18;;21084:181::o;21270:349::-;21472:2;21454:21;;;21511:2;21491:18;;;21484:30;21550:27;21545:2;21530:18;;21523:55;21610:2;21595:18;;21444:175::o;22059:567::-;22357:25;;;22413:2;22398:18;;22391:34;;;22344:3;22329:19;;22434:55;22485:2;22470:18;;22462:6;22434:55;:::i;:::-;22525:6;22520:2;22509:9;22505:18;22498:34;22569:6;22563:3;22552:9;22548:19;22541:35;22613:6;22607:3;22596:9;22592:19;22585:35;22311:315;;;;;;;;;:::o;22631:128::-;;22702:1;22698:6;22695:1;22692:13;22689:2;;;22708:18;;:::i;:::-;-1:-1:-1;22744:9:1;;22679:80::o;22764:217::-;;22830:1;22820:2;;-1:-1:-1;;;22855:31:1;;22909:4;22906:1;22899:15;22937:4;22862:1;22927:15;22820:2;-1:-1:-1;22966:9:1;;22810:171::o;22986:168::-;;23092:1;23088;23084:6;23080:14;23077:1;23074:21;23069:1;23062:9;23055:17;23051:45;23048:2;;;23099:18;;:::i;:::-;-1:-1:-1;23139:9:1;;23038:116::o;23159:125::-;;23227:1;23224;23221:8;23218:2;;;23232:18;;:::i;:::-;-1:-1:-1;23269:9:1;;23208:76::o;23289:258::-;23361:1;23371:113;23385:6;23382:1;23379:13;23371:113;;;23461:11;;;23455:18;23442:11;;;23435:39;23407:2;23400:10;23371:113;;;23502:6;23499:1;23496:13;23493:2;;;-1:-1:-1;;23537:1:1;23519:16;;23512:27;23342:205::o;23552:135::-;;-1:-1:-1;;23612:17:1;;23609:2;;;23632:18;;:::i;:::-;-1:-1:-1;23679:1:1;23668:13;;23599:88::o;23692:127::-;23753:10;23748:3;23744:20;23741:1;23734:31;23784:4;23781:1;23774:15;23808:4;23805:1;23798:15;23824:133;-1:-1:-1;;;;;23901:31:1;;23891:42;;23881:2;;23947:1;23944;23937:12
Swarm Source
ipfs://7233f7f733935f04e5f8f6f22b8c54296d3edfa64ead46abcdaab7c739433710
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
[ Download: CSV Export ]
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.