Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 193 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Safe Transfer Fr... | 41188248 | 2 days ago | IN | 0 ETH | 0.00000044 | ||||
| Set Approval For... | 41074604 | 5 days ago | IN | 0 ETH | 0.00000084 | ||||
| Set Approval For... | 40877544 | 9 days ago | IN | 0 ETH | 0.0000003 | ||||
| Set Approval For... | 40654387 | 15 days ago | IN | 0 ETH | 0.00000004 | ||||
| Set Approval For... | 40255385 | 24 days ago | IN | 0 ETH | 0.00000012 | ||||
| Safe Transfer Fr... | 40117119 | 27 days ago | IN | 0 ETH | 0.00000043 | ||||
| Safe Transfer Fr... | 40111395 | 27 days ago | IN | 0 ETH | 0.00000038 | ||||
| Set Approval For... | 39961693 | 31 days ago | IN | 0 ETH | 0.00000006 | ||||
| Set Approval For... | 39567715 | 40 days ago | IN | 0 ETH | 0.00000002 | ||||
| Safe Transfer Fr... | 39358314 | 45 days ago | IN | 0 ETH | 0.00000039 | ||||
| Set Approval For... | 39161878 | 49 days ago | IN | 0 ETH | 0.00000012 | ||||
| Safe Transfer Fr... | 39161692 | 49 days ago | IN | 0 ETH | 0.00000014 | ||||
| Set Approval For... | 37989604 | 76 days ago | IN | 0 ETH | 0.00000012 | ||||
| Set Approval For... | 37955044 | 77 days ago | IN | 0 ETH | 0.00000037 | ||||
| Set Approval For... | 37949855 | 77 days ago | IN | 0 ETH | 0.00000064 | ||||
| Set Approval For... | 37829084 | 80 days ago | IN | 0 ETH | 0.00000137 | ||||
| Set Approval For... | 37767713 | 81 days ago | IN | 0 ETH | 0.00000034 | ||||
| Safe Transfer Fr... | 37574547 | 86 days ago | IN | 0 ETH | 0.00000065 | ||||
| Set Approval For... | 37516874 | 87 days ago | IN | 0 ETH | 0.00000051 | ||||
| Set Approval For... | 37463519 | 88 days ago | IN | 0 ETH | 0.00000027 | ||||
| Safe Transfer Fr... | 37351638 | 91 days ago | IN | 0 ETH | 0.00000494 | ||||
| Safe Transfer Fr... | 37105951 | 97 days ago | IN | 0 ETH | 0.00000106 | ||||
| Set Approval For... | 37067583 | 98 days ago | IN | 0 ETH | 0.00000012 | ||||
| Set Approval For... | 37005878 | 99 days ago | IN | 0 ETH | 0.0000003 | ||||
| Set Approval For... | 36874571 | 102 days ago | IN | 0 ETH | 0.00000332 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
CDHInventory
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.6;
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/utils/Pausable.sol";
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC1155/ERC1155.sol";
import "./CDHAccessControl.sol";
import "./pool/CardPool.sol";
/// @title CDHInventory is ERC1155 token; manages and holds them where tokens of all the users are handled.
/// @dev Inventory contract is ERC1155 standard token, is pausable and can be maintained by address with correct permissions.
contract CDHInventory is Ownable, Pausable, ERC1155, CDHAccessControl{
event SetNewPool(bytes1 poolId, address poolAddress);
mapping(uint256 => uint256) private counter; //card Id => no of tokens of card Id minted
mapping(bytes1 => address) private availablePools; // pool identifier => pool contract address
mapping(uint256 => address) private tokenPools; // token id => pool address
mapping(uint256 => string) private uris; // token id => metadata uri
mapping(address => uint256[]) private allTokens; // user address => list of available token ids. Unordered Array.
mapping(uint256 => uint256) private blockNumber; // nft address => minted block number
mapping(uint256 => bool) public airdropBatchStatus; // airdrop batch id => status
constructor(string memory _uri)
Pausable()
ERC1155(_uri)
CDHAccessControl() {
}
/// @notice Return Card Id for the Token Id
/// @param tokenId Token Id value to get cardId of
/// @return Returns uint256 value that represents the cardId
function card(uint256 tokenId) public pure returns (uint256) {
return (tokenId >> 80) << 80;
}
/// @notice Get detailed information of the tokenId, including its name, type, rarity, rank, level and uri to token.
/// @dev Card information is returned from the pool based on where token is created.
/// @param id Token Id for which card details is to be retrieved.
/// @return name (Card Name), cardType(Card Type), rarity, Rank, Level, _uri(card urls) and blockNum.
function info(uint256 id) external view returns (string memory name, bytes16 cardType, bytes1 rarity, uint256 rank, uint256 level, string memory _uri, uint256 blockNum) {
uint256 cardId = card(id);
CardPool _pool = CardPool(tokenPools[id]);
(name, cardType, rarity, rank, level, _uri) = _pool.getCard(cardId);
blockNum = blockNumber[id];
}
/// @notice Get total count of tokens for `user`
/// @param user Address of user to get count of
/// @return Returns number value for the count of tokens that user has
function count(address user) external view returns (uint256) {
return allTokens[user].length;
}
/// @notice Get all the tokens of address
/// @param user Address of user
/// @return Returns list of tokens for the user
function getAllTokens(address user) external view returns (uint256[] memory){
return allTokens[user];
}
/// @notice Get uri of the tokens that is mapped in their specific data pools
/// @dev URIs in inventory contract is mapped to tokenId from data pool
/// @param tokenId Token Id for which url is mapped
/// @return Returns String value for the tokenId
function uri(uint256 tokenId) external view virtual override returns (string memory) {
return uris[tokenId];
}
/// @notice Set pool for specific Pool Id, pool id is mapped to pool address.
/// @dev Set new available pools for Pool Id on `availablePools`
/// @param poolId Bytes1 that represents a pool
/// @param poolAddress Contract address for pools
function setPool(bytes1 poolId, address poolAddress) external onlyAdmin(DEFAULT_ADMIN_ROLE) {
require(availablePools[poolId] == address(0), "Duplicate Pool ID");
emit SetNewPool(poolId, poolAddress);
availablePools[poolId] = poolAddress;
}
/// @notice Get contract address of the pool
/// @dev Get address of the available pool
/// @param poolId Pool Identifier for the pool
/// @return Returns address value of pool identifier
function pool(bytes1 poolId) external view returns (address) {
return availablePools[poolId];
}
/// @notice Return the pool address value for specific Token Id
/// @dev Get address pool from `tokenPools` mapping for token Id
/// @param token Token Id of the minted cards
/// @return Return address value of pool of the minted token
function pool(uint256 token) external view returns (address) {
return tokenPools[token];
}
/// @notice Set base URI for the inventory, this can be external api for CDH
/// @param newuri New URI to set as base uri for CDH
function setURI(string memory newuri) external onlyAdmin(DEFAULT_ADMIN_ROLE) {
_setURI(newuri);
}
/// @notice Generated `tokenId` based on the `cardId`, url for the Token Id is also set based on the URI of the cardId from pool
/// @dev counter of the cardId is also stored, along with mapping for the tokenId with pool address, uri and block numbers.
/// @param _cardId Card Id that is retrieved from data pool by random generated seed
/// @return Returns Token Id number based on Card ID
function _generateTokenId(uint256 _cardId) internal returns (uint256) {
(,, bytes1 poolId,,, uint256 _count) = parse(_cardId);
require(_count == 0, "Card ID Invalid");
address _pool = availablePools[poolId];
CardPool cardPool = CardPool(_pool);
require(cardPool.exists(_cardId), "Card does not exist");
counter[_cardId]++;
bytes32 tokenId = bytes32(_cardId);
tokenId |= (bytes32(counter[_cardId]) << 16);
tokenId |= bytes32(uint256(1));
require(blockNumber[uint256(tokenId)] == 0, "Token already minted");
tokenPools[uint256(tokenId)] = _pool;
(,,,,, string memory _uri) = cardPool.getCard(_cardId);
uris[uint256(tokenId)] = _uri;
blockNumber[uint256(tokenId)] = block.number;
return uint256(tokenId);
}
/// @notice Minting tokens based on card Id in Inventory that is called from Chest Operator
/// @param account Address executes call to open chest/s
/// @param cardId Card Id number to generate Token Id
/// @param amount Amount of tokens to mint
/// @param data Data of minting token
function mint(address account, uint256 cardId, uint256 amount, bytes memory data) external onlyMinter {
uint256 tokenId = _generateTokenId(cardId);
_mint(account, tokenId, amount, data);
}
function setTokenInfo(uint256 tokenId) internal {
require(blockNumber[tokenId] == 0, "Token already minted");
blockNumber[uint256(tokenId)] = block.number;
}
function airdrop(
uint256 batchId,
address[] memory _accounts,
uint256[] memory _tokenIds,
bytes memory data
) external onlyMinter {
require(!airdropBatchStatus[batchId], "Airdrop batch already processed");
airdropBatchStatus[batchId] = true;
for (uint256 i = 0; i < _accounts.length; i++ ) {
uint256 tokenId = _tokenIds[i];
require(blockNumber[tokenId] == 0, "Token already minted");
bytes1 poolId = bytes1(bytes32((tokenId >> 216) << 248));
address _pool = availablePools[poolId];
require(_pool != address(0), "Pool not found");
CardPool cardPool = CardPool(_pool);
uint256 cardId = card(tokenId);
require(cardPool.exists(cardId), "Card not found");
counter[cardId]++;
uris[tokenId] = cardPool.getUri(cardId);
blockNumber[tokenId] = block.number;
_mint(_accounts[i], _tokenIds[i], 1, data);
}
}
/// @notice Minting tokens based on batch of card Ids in Inventory that is called from Chest Operator
/// @param to Address executes call to open chest/s
/// @param cardIds List of Card Ids number to generate Token Id
/// @param amounts List of amount of tokens to mint in batch
/// @param data Data of minting token
function mintBatch(address to, uint256[] memory cardIds, uint256[] memory amounts, bytes memory data)
external onlyMinter {
uint256[] memory tokenIds = new uint256[](cardIds.length);
for (uint256 i; i < cardIds.length; i++) {
tokenIds[i] = _generateTokenId(cardIds[i]);
}
_mintBatch(to, tokenIds, amounts, data);
}
/// @notice Handle the token transfers from user that minted to tokens to other users.
/// @dev This changes the list of tokens for users in `allTokens`
/// @param operator Address of the Operator
/// @param from Address that calls transfer function to transfer token from
/// @param to Address to transfer token to
/// @param ids List of Token Ids to transfer
/// @param amounts Amount of tokens
/// @param data Data to store on transferring token from one to another address
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
)
internal
override
whenNotPaused {
uint256[] storage senderTokenList = allTokens[from];
for (uint256 i; i < ids.length; i++) {
// add transferred token to 'to' user token list
allTokens[to].push(ids[i]);
// find and remove the transferred token from the 'from' user token list
// the code below finds the token id, moves the last token to found index
// and decreases the array length. So, the allTokens is an unordered array of tokens.
for (uint256 j; j < senderTokenList.length; j++) {
if (senderTokenList[j] == ids[i]) {
senderTokenList[j] = senderTokenList[senderTokenList.length - 1];
senderTokenList.pop();
}
}
}
}
/// @notice Parse any tokenId to their specific data sections, CDH Id, pool, card type, rarity
/// @dev Shifting of the tokenId is done to decode other information
/// @param id Token Id that are minted
function parse(uint256 id) public pure returns (bytes1 token, bytes4 cdhId, bytes1 poolId, bytes32 cardType, bytes1 rarity, uint256 counter_){
uint256 temp = id;
cdhId = bytes4(bytes32((temp >> 224) << 224));
temp = id;
poolId = bytes1(bytes32((temp >> 216) << 248));
temp = id;
cardType = bytes32((temp >> 88) << 128);
temp = id;
rarity = bytes1(bytes32((temp >> 80) << 248));
temp = id;
counter_ = ((temp >> 16) << 192) >> 192;
temp = id;
token = bytes1(bytes32(temp << 248));
}
/// @notice Get the counter of specific cardId from `counter` mapping
/// @param _cardId Card Id number available in pool
/// @return Returns Card Id number
function countByCardId(uint256 _cardId) external view returns (uint256) {
return counter[_cardId];
}
function pause() external onlyAdmin(DEFAULT_ADMIN_ROLE) {
_pause();
}
function unpause() external onlyAdmin(DEFAULT_ADMIN_ROLE) {
_unpause();
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view returns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), 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 {
emit OwnershipTransferred(_owner, address(0));
_owner = 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");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
// Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC1155.sol";
import "./IERC1155MetadataURI.sol";
import "./IERC1155Receiver.sol";
import "../../utils/Context.sol";
import "../../introspection/ERC165.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
*
* @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 SafeMath for uint256;
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;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
/**
* @dev See {_setURI}.
*/
constructor (string memory uri_) public {
_setURI(uri_);
// register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
}
/**
* @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) external 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 {
require(_msgSender() != operator, "ERC1155: setting approval status for self");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_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(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
_balances[id][to] = _balances[id][to].add(amount);
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, 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(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
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];
_balances[id][from] = _balances[id][from].sub(
amount,
"ERC1155: insufficient balance for transfer"
);
_balances[id][to] = _balances[id][to].add(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 `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
require(account != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount);
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, 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 (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
}
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 `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/
function _burn(address account, uint256 id, uint256 amount) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
_balances[id][account] = _balances[id][account].sub(
amount,
"ERC1155: burn amount exceeds balance"
);
emit TransferSingle(operator, account, 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 account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub(
amounts[i],
"ERC1155: burn amount exceeds balance"
);
}
emit TransferBatch(operator, account, address(0), ids, amounts);
}
/**
* @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(to).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(to).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;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "../../introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
import "./IERC1155.sol";
/**
* @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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../introspection/IERC165.sol";
/**
* _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.
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. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
)
external
returns(bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @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
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 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");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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");
// solhint-disable-next-line avoid-low-level-calls
(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");
// solhint-disable-next-line avoid-low-level-calls
(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");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// 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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <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 GSN 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 payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor () internal {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.6;
import "@openzeppelin/contracts/access/AccessControl.sol";
// import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/access/AccessControl.sol";
contract CDHAccessControl is AccessControl {
bytes32 public constant MINTER_ROLE = 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6; // keccak256(abi.encodePacked("MINTER_ROLE"));
bytes32 public constant MINTER_ROLE_ADMIN = 0x11c2020b6b4f4e00c2410234e0c72636b4739cf7cda4d8e24ef6b881350e6704; //keccak256(abi.encodePacked("MINTER_ROLE_ADMIN"));
modifier onlyAdmin(bytes32 role) {
require(hasRole(role, _msgSender()));
_;
}
modifier onlyMinter {
require(hasRole(MINTER_ROLE, _msgSender()));
_;
}
constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setRoleAdmin(MINTER_ROLE, MINTER_ROLE_ADMIN);
_setupRole(MINTER_ROLE_ADMIN, _msgSender());
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.6;
library Constants {
bytes1 public constant RARITY_UNKNOWN = 0x00;
bytes1 public constant RARITY_COMMON = 0x01;
bytes1 public constant RARITY_RARE = 0x02;
bytes1 public constant RARITY_EPIC = 0x03;
bytes1 public constant RARITY_LEGENDARY = 0x04;
bytes1 public constant UNKNOWN_POOL_IDENTIFIER = 0x00;
bytes1 public constant EQUIPMENT_POOL_IDENTIFIER = 0x01;
bytes1 public constant HERO_POOL_IDENTIFIER = 0x02;
bytes1 public constant SPELL_POOL_IDENTIFIER = 0x03;
bytes1 public constant TOWER_POOL_IDENTIFIER = 0x04;
bytes4 public constant CRAZY_DEFENCE_HEROES = 0x2ebc3cb3; // bytes4(keccak256(abi.encodePacked("CRAZY DEFENCE HEROES")));
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.6;
import "../Constants.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
//import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/access/Ownable.sol";
//import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/utils/Pausable.sol";
abstract contract CardPool is Ownable, Pausable {
bytes1 private constant IDENTIFIER = 0x00;
string private constant NAME = "CRAZY DEFENCE HEROES CARD POOL";
struct Card {
bytes16 cardType;
bytes1 rarity;
uint256 rank;
uint256 level;
}
/// @notice URI location where the JSON for items are stored/pinned.
/// @dev uri is set individually for each pools, this might be ipfs pinned
/// location or http endpoint
string public uri;
mapping(uint256 => Card) private cards;
/// @dev Map of list of card types by rarity of card
/// eg. Rarity 0x01 -> [cardId1, cardId2, cardId3, ... ]
mapping(bytes1 => uint256[]) private rarityCardType; // rarity => cardId[]
/// @dev Map of card hash (card type) to name of card
mapping(bytes16 => string) private cardTypeName;
/// @dev Map of name of card to card hash, used to check if specific card type already exists
/// and avoid multiple hashing and having multiple records map for Card Name and Card Type
mapping(string => bytes16) private reverseCardType;
/// @notice Total number of cards for specific card pool
uint256 public totalCards;
/// @dev Emitted when URI to json files are set in the pool.
event URIUpdated(string oldURI, string newURI);
/// @notice Get identifier of the pool
/// @dev Returns identifier of the pool and used while generating Card Id for each new card
/// @dev NOTE: This method is overridden in all Pools for determine identifier of pool
/// @return constant defined bytes1 value representing identifier of pool
function identifier() public virtual pure returns (bytes1) {
return IDENTIFIER;
}
/// @notice Get name of the contract
/// @dev NOTE: This method is overridden in all Pools for determine name of pool
/// @return string value of the name of contract
function name() external virtual pure returns (string memory) {
return NAME;
}
/// @notice Returns the cardId for specific record of data set in pool
/// @dev Single uint256 number is generated by shifting specific portion of information
/// in the cardId, so if cardId is provided, it could be decoded to which card type,
/// rarity or what category of card (pool) it is generated for.
/// CDH bytes = First 4 bytes (32 bits )
/// identifier = 1 byte (8 bits )
/// card type = 16 byte (128 bits )
/// rarity = 1 byte (8 bits )
/// remaining bits are left as it is, and not required
/// @param _cardType Card Type hash to use while generating cardId
/// @param _rarity Rarity of Card
/// @param _rank Rank of card, default is 1
/// @param _level Level of card, default is 1
/// @return uint256 for the bytes32 cardId
function generateCardId(bytes32 _cardType, bytes1 _rarity, uint256 _rank, uint256 _level) public pure returns (uint256) {
bytes32 cardId = Constants.CRAZY_DEFENCE_HEROES;
cardId |= (bytes32(identifier()) >> 32);
cardId |= (_cardType >> 40);
cardId |= (bytes32(_rarity) >> 168);
cardId |= (bytes32(_rank) >> 200);
cardId |= (bytes32(_level) >> 232);
return uint256(cardId);
}
/// @notice Check if the cardId exists and is created
/// @dev check cards mapping for cardId to check card type
/// @param cardId Card Type hash to check if it exists in card pool
/// @return Returns a boolean value if cardId exists in pool mapping.
function exists(uint256 cardId) external view returns (bool) {
return (cards[cardId].cardType != bytes16(0));
}
/// @notice Number of card types by rarity.
/// @dev Count of card type hashes for specific rarity from created cards list
/// @param rarity bytes1 value of card rarity from enum
/// @return Returns a number representing number of card types for user provided rarity
function numberOfCardsByRarity(bytes1 rarity) external view returns (uint256) {
return rarityCardType[rarity].length;
}
/// @notice Retrieve card id from rarity mapping at given index
/// @dev Retrieve Card Id from rarityCardType for the rarity at given index
/// @param rarity Rarity of the card
/// @param index Number value representing index in the list
/// @return Returns uint256 Card Id
function getCardIdByRarity(bytes1 rarity, uint256 index) external view returns (uint256) {
return rarityCardType[rarity][index];
}
/// @notice Get URI for json file for the card Id
/// @param id Card Id for which json value to set
/// @return String value of full url to json
function getUri(uint256 id) public view returns (string memory) {
return string(abi.encodePacked(uri, uint2str(id), ".json"));
}
/// @notice Name of card by card type hash in mapping
/// @param _cardType Card type hash for the card name when new card is created
/// @return Returns string value Card Name for the card type
function getCardNameByType(bytes16 _cardType) public view returns (string memory) {
return cardTypeName[_cardType];
}
/// @dev Similar getCardNameByType but get card name by cardId
function getCardName(uint256 _cardId) public view returns (string memory) {
return getCardNameByType(cards[_cardId].cardType);
}
/// @notice Get all the information of cards including Card Name, Card Type, Rarity, Rank, Level and URI of cardId
/// @param _id Card Id generated and stored in mappings
/// @return Returns multiple values : Card Name, Card Type, Rarity, Rank, Level, URI
function getCard(uint256 _id) external view returns (string memory, bytes16, bytes1, uint256, uint256, string memory) {
Card memory _card = cards[_id];
return (getCardName(_id), _card.cardType, _card.rarity, _card.rank, _card.level, getUri(_id));
}
/// @notice Get Card Name by card type of the card
/// @return Returns bytes16 value of card type
function getCardTypeByName(string memory _name) external view returns (bytes16) {
return reverseCardType[_name];
}
/*
Generate new card for corresponding pools.
Call this only in constructor with proper arguments, Card Name, Rarity , Rank and Level
*/
function _newCard(string memory _cardTypeName, bytes1 _rarity, uint256 _rank, uint256 _level) internal whenNotPaused {
if (reverseCardType[_cardTypeName] == bytes16(0)) {
bytes16 hash = bytes16(keccak256(abi.encodePacked(_cardTypeName)));
cardTypeName[hash] = _cardTypeName;
reverseCardType[_cardTypeName] = hash;
}
bytes16 cardType = reverseCardType[_cardTypeName];
uint256 id = generateCardId(cardType, _rarity, _rank, _level);
cards[id] = Card(cardType, _rarity, _rank, _level);
rarityCardType[_rarity].push(id);
totalCards++;
}
/// @notice Set URI for the specific pool
/// Emits a event `URIUpdated` when update succeeds.
/// @param _uri set URI from the owner of the contract when its not paused
function setURI(string memory _uri) external onlyOwner whenNotPaused {
emit URIUpdated(uri, _uri);
uri = _uri;
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function uint2str(uint256 num) internal pure returns (string memory _uintAsString) {
if (num == 0) {
return "0";
}
uint256 j = num;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (num != 0) {
k--;
bstr[k] = bytes1(uint8(48 + (num % 10)));
num /= 10;
}
return string(bstr);
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes1","name":"poolId","type":"bytes1"},{"indexed":false,"internalType":"address","name":"poolAddress","type":"address"}],"name":"SetNewPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"batchId","type":"uint256"},{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"airdropBatchStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"card","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"countByCardId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAllTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"info","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes16","name":"cardType","type":"bytes16"},{"internalType":"bytes1","name":"rarity","type":"bytes1"},{"internalType":"uint256","name":"rank","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"},{"internalType":"uint256","name":"blockNum","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"cardId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"cardIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"parse","outputs":[{"internalType":"bytes1","name":"token","type":"bytes1"},{"internalType":"bytes4","name":"cdhId","type":"bytes4"},{"internalType":"bytes1","name":"poolId","type":"bytes1"},{"internalType":"bytes32","name":"cardType","type":"bytes32"},{"internalType":"bytes1","name":"rarity","type":"bytes1"},{"internalType":"uint256","name":"counter_","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes1","name":"poolId","type":"bytes1"}],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"token","type":"uint256"}],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes1","name":"poolId","type":"bytes1"},{"internalType":"address","name":"poolAddress","type":"address"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b50604051620041af380380620041af833981810160405260208110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052505050806000620001006200023160201b60201c565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506000805460ff60a01b19169055620001696301ffc9a760e01b62000235565b6200017481620002bd565b62000186636cdb3d1360e11b62000235565b620001986303a24d0760e21b62000235565b50620001af6000620001a962000231565b620002d6565b620001fb7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a67f11c2020b6b4f4e00c2410234e0c72636b4739cf7cda4d8e24ef6b881350e6704620002e2565b6200022a7f11c2020b6b4f4e00c2410234e0c72636b4739cf7cda4d8e24ef6b881350e6704620001a962000231565b50620004e2565b3390565b6001600160e01b0319808216141562000295576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152600160208190526040909120805460ff19169091179055565b8051620002d290600490602084019062000436565b5050565b620002d2828262000334565b600082815260056020526040808220600201549051839285917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a460009182526005602052604090912060020155565b60008281526005602090815260409091206200035b91839062002691620003af821b17901c565b15620002d2576200036b62000231565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620003c6836001600160a01b038416620003cf565b90505b92915050565b6000620003dd83836200041e565b6200041557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620003c9565b506000620003c9565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200046e5760008555620004b9565b82601f106200048957805160ff1916838001178555620004b9565b82800160010185558215620004b9579182015b82811115620004b95782518255916020019190600101906200049c565b50620004c7929150620004cb565b5090565b5b80821115620004c75760008155600101620004cc565b613cbd80620004f26000396000f3fe608060405234801561001057600080fd5b50600436106102315760003560e01c806371bc5e1f11610130578063a22cb465116100b8578063d547741f1161007c578063d547741f14610f53578063e985e9c514610f7f578063f242432a14610fad578063f2fde38b14611076578063fe3131121461109c57610231565b8063a22cb46514610d34578063a4aeff5514610d62578063bfcfd9b914610f11578063ca15c87314610f2e578063d539139314610f4b57610231565b80638e2ce69a116100ff5780638e2ce69a14610c555780639010d07c14610cc057806391d1485414610ce35780639be8060d14610d0f578063a217fddf14610d2c57610231565b806371bc5e1f14610b68578063731133e914610b855780638456cb5914610c455780638da5cb5b14610c4d57610231565b8063263a8527116101be5780633f4ba83a116101825780633f4ba83a146109f75780634e1273f4146109ff5780635630710914610b225780635c975abb14610b58578063715018a614610b6057610231565b8063263a8527146106605780632e340599146106a35780632eb2c2d6146107de5780632f2ff15d1461099f57806336568abe146109cb57610231565b80630e89341c116102055780630e89341c1461037b57806311d15e7a1461040d578063178b6de6146104155780631f7fdffa1461048b578063248a9ca31461064357610231565b8062fdd58e1461023657806301ffc9a71461027457806302fe5305146102af57806305d85eda14610355575b600080fd5b6102626004803603604081101561024c57600080fd5b506001600160a01b0381351690602001356110b9565b60408051918252519081900360200190f35b61029b6004803603602081101561028a57600080fd5b50356001600160e01b03191661112b565b604080519115158252519081900360200190f35b610353600480360360208110156102c557600080fd5b810190602081018135600160201b8111156102df57600080fd5b8201836020820111156102f157600080fd5b803590602001918460018302840111600160201b8311171561031257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061114a945050505050565b005b6102626004803603602081101561036b57600080fd5b50356001600160a01b0316611173565b6103986004803603602081101561039157600080fd5b503561118e565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103d25781810151838201526020016103ba565b50505050905090810190601f1680156103ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61026261122f565b61043b6004803603602081101561042b57600080fd5b50356001600160a01b0316611253565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561047757818101518382015260200161045f565b505050509050019250505060405180910390f35b610353600480360360808110156104a157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104cb57600080fd5b8201836020820111156104dd57600080fd5b803590602001918460208302840111600160201b831117156104fe57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561054d57600080fd5b82018360208201111561055f57600080fd5b803590602001918460208302840111600160201b8311171561058057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156105cf57600080fd5b8201836020820111156105e157600080fd5b803590602001918460018302840111600160201b8311171561060257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506112be945050505050565b6102626004803603602081101561065957600080fd5b5035611383565b6106876004803603602081101561067657600080fd5b50356001600160f81b031916611398565b604080516001600160a01b039092168252519081900360200190f35b6106c0600480360360208110156106b957600080fd5b50356113bd565b6040518080602001886fffffffffffffffffffffffffffffffff19168152602001876001600160f81b03191681526020018681526020018581526020018060200184815260200183810383528a818151815260200191508051906020019080838360005b8381101561073c578181015183820152602001610724565b50505050905090810190601f1680156107695780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101561079c578181015183820152602001610784565b50505050905090810190601f1680156107c95780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b610353600480360360a08110156107f457600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561082757600080fd5b82018360208201111561083957600080fd5b803590602001918460208302840111600160201b8311171561085a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156108a957600080fd5b8201836020820111156108bb57600080fd5b803590602001918460208302840111600160201b831117156108dc57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561092b57600080fd5b82018360208201111561093d57600080fd5b803590602001918460018302840111600160201b8311171561095e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611610945050505050565b610353600480360360408110156109b557600080fd5b50803590602001356001600160a01b0316611913565b610353600480360360408110156109e157600080fd5b50803590602001356001600160a01b0316611976565b6103536119d7565b61043b60048036036040811015610a1557600080fd5b810190602081018135600160201b811115610a2f57600080fd5b820183602082011115610a4157600080fd5b803590602001918460208302840111600160201b83111715610a6257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ab157600080fd5b820183602082011115610ac357600080fd5b803590602001918460208302840111600160201b83111715610ae457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506119f9945050505050565b61035360048036036040811015610b3857600080fd5b5080356001600160f81b03191690602001356001600160a01b0316611ae5565b61029b611bed565b610353611bfe565b61026260048036036020811015610b7e57600080fd5b5035611cbc565b61035360048036036080811015610b9b57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b811115610bd157600080fd5b820183602082011115610be357600080fd5b803590602001918460018302840111600160201b83111715610c0457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611cce945050505050565b610353611d0a565b610687611d29565b610c7260048036036020811015610c6b57600080fd5b5035611d38565b604080516001600160f81b031997881681526001600160e01b03199096166020870152938616858501526060850192909252909316608083015260a082019290925290519081900360c00190f35b61068760048036036040811015610cd657600080fd5b5080359060200135611d8e565b61029b60048036036040811015610cf957600080fd5b50803590602001356001600160a01b0316611dad565b61029b60048036036020811015610d2557600080fd5b5035611dc5565b610262611dda565b61035360048036036040811015610d4a57600080fd5b506001600160a01b0381351690602001351515611ddf565b61035360048036036080811015610d7857600080fd5b81359190810190604081016020820135600160201b811115610d9957600080fd5b820183602082011115610dab57600080fd5b803590602001918460208302840111600160201b83111715610dcc57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610e1b57600080fd5b820183602082011115610e2d57600080fd5b803590602001918460208302840111600160201b83111715610e4e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610e9d57600080fd5b820183602082011115610eaf57600080fd5b803590602001918460018302840111600160201b83111715610ed057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ece945050505050565b61026260048036036020811015610f2757600080fd5b50356122d7565b61026260048036036020811015610f4457600080fd5b50356122e7565b6102626122fe565b61035360048036036040811015610f6957600080fd5b50803590602001356001600160a01b0316612310565b61029b60048036036040811015610f9557600080fd5b506001600160a01b0381358116916020013516612369565b610353600480360360a0811015610fc357600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561100257600080fd5b82018360208201111561101457600080fd5b803590602001918460018302840111600160201b8311171561103557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612397945050505050565b6103536004803603602081101561108c57600080fd5b50356001600160a01b0316612562565b610687600480360360208110156110b257600080fd5b5035612676565b60006001600160a01b0383166111005760405162461bcd60e51b815260040180806020018281038252602b815260200180613a73602b913960400191505060405180910390fd5b5060008181526002602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526001602052604090205460ff1690565b600061115d816111586126a6565b611dad565b61116657600080fd5b61116f826126aa565b5050565b6001600160a01b03166000908152600a602052604090205490565b60008181526009602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156112235780601f106111f857610100808354040283529160200191611223565b820191906000526020600020905b81548152906001019060200180831161120657829003601f168201915b50505050509050919050565b7f11c2020b6b4f4e00c2410234e0c72636b4739cf7cda4d8e24ef6b881350e670481565b6001600160a01b0381166000908152600a602090815260409182902080548351818402810184019094528084526060939283018282801561122357602002820191906000526020600020905b81548152602001906001019080831161129f5750505050509050919050565b6112d8600080516020613b9e8339815191526111586126a6565b6112e157600080fd5b6000835167ffffffffffffffff811180156112fb57600080fd5b50604051908082528060200260200182016040528015611325578160200160208202803683370190505b50905060005b845181101561136f5761135085828151811061134357fe5b60200260200101516126bd565b82828151811061135c57fe5b602090810291909101015260010161132b565b5061137c85828585612acb565b5050505050565b60009081526005602052604090206002015490565b6001600160f81b0319166000908152600760205260409020546001600160a01b031690565b606060008060008060606000806113d3896122d7565b60008a8152600860205260408082205481516348c4698960e11b81526004810185905291519394506001600160a01b0316928392639188d3129260248082019391829003018186803b15801561142857600080fd5b505afa15801561143c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c081101561146557600080fd5b8101908080516040519392919084600160201b82111561148457600080fd5b90830190602082018581111561149957600080fd5b8251600160201b8111828201881017156114b257600080fd5b82525081516020918201929091019080838360005b838110156114df5781810151838201526020016114c7565b50505050905090810190601f16801561150c5780820380516001836020036101000a031916815260200191505b5060408181526020830151908301516060840151608085015160a09095018051939792969195949384600160201b82111561154657600080fd5b90830190602082018581111561155b57600080fd5b8251600160201b81118282018810171561157457600080fd5b82525081516020918201929091019080838360005b838110156115a1578181015183820152602001611589565b50505050905090810190601f1680156115ce5780820380516001836020036101000a031916815260200191505b50604052505050809950819a50829b50839c50849d50859e50505050505050600b60008b81526020019081526020016000205492505050919395979092949650565b81518351146116505760405162461bcd60e51b8152600401808060200182810382526028815260200180613c106028913960400191505060405180910390fd5b6001600160a01b0384166116955760405162461bcd60e51b8152600401808060200182810382526025815260200180613b1d6025913960400191505060405180910390fd5b61169d6126a6565b6001600160a01b0316856001600160a01b031614806116c857506116c8856116c36126a6565b612369565b6117035760405162461bcd60e51b8152600401808060200182810382526032815260200180613b426032913960400191505060405180910390fd5b600061170d6126a6565b905061171d818787878787612d19565b60005b845181101561182357600085828151811061173757fe5b60200260200101519050600085838151811061174f57fe5b602002602001015190506117bc816040518060600160405280602a8152602001613b74602a91396002600086815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002054612e7d9092919063ffffffff16565b60008381526002602090815260408083206001600160a01b038e811685529252808320939093558a16815220546117f39082612f14565b60009283526002602090815260408085206001600160a01b038c1686529091529092209190915550600101611720565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156118a9578181015183820152602001611891565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156118e85781810151838201526020016118d0565b5050505090500194505050505060405180910390a461190b818787878787612f6e565b505050505050565b600082815260056020526040902060020154611931906111586126a6565b61196c5760405162461bcd60e51b815260040180806020018281038252602f815260200180613a44602f913960400191505060405180910390fd5b61116f82826131ed565b61197e6126a6565b6001600160a01b0316816001600160a01b0316146119cd5760405162461bcd60e51b815260040180806020018281038252602f815260200180613c59602f913960400191505060405180910390fd5b61116f8282613256565b60006119e5816111586126a6565b6119ee57600080fd5b6119f66132bf565b50565b60608151835114611a3b5760405162461bcd60e51b8152600401808060200182810382526029815260200180613be76029913960400191505060405180910390fd5b6000835167ffffffffffffffff81118015611a5557600080fd5b50604051908082528060200260200182016040528015611a7f578160200160208202803683370190505b50905060005b8451811015611add57611abe858281518110611a9d57fe5b6020026020010151858381518110611ab157fe5b60200260200101516110b9565b828281518110611aca57fe5b6020908102919091010152600101611a85565b509392505050565b6000611af3816111586126a6565b611afc57600080fd5b6001600160f81b031983166000908152600760205260409020546001600160a01b031615611b65576040805162461bcd60e51b8152602060048201526011602482015270111d5c1b1a58d85d1948141bdbdb081251607a1b604482015290519081900360640190fd5b604080516001600160f81b0319851681526001600160a01b038416602082015281517febeda574509491f8af1764dd814d8dc1edc8e4b917707c15584de69e4beba476929181900390910190a1506001600160f81b031991909116600090815260076020526040902080546001600160a01b0319166001600160a01b03909216919091179055565b600054600160a01b900460ff165b90565b611c066126a6565b6001600160a01b0316611c17611d29565b6001600160a01b031614611c72576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60009081526006602052604090205490565b611ce8600080516020613b9e8339815191526111586126a6565b611cf157600080fd5b6000611cfc846126bd565b905061137c85828585613362565b6000611d18816111586126a6565b611d2157600080fd5b6119f6613463565b6000546001600160a01b031690565b60f881901b916001600160e01b0319821691602081901b6001600160f81b031990811692602883901b6fffffffffffffffffffffffffffffffff19169260a881901b9092169160101c67ffffffffffffffff1690565b6000828152600560205260408120611da690836134ec565b9392505050565b6000828152600560205260408120611da690836134f8565b600c6020526000908152604090205460ff1681565b600081565b816001600160a01b0316611df16126a6565b6001600160a01b03161415611e375760405162461bcd60e51b8152600401808060200182810382526029815260200180613bbe6029913960400191505060405180910390fd5b8060036000611e446126a6565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611e886126a6565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b611ee8600080516020613b9e8339815191526111586126a6565b611ef157600080fd5b6000848152600c602052604090205460ff1615611f55576040805162461bcd60e51b815260206004820152601f60248201527f41697264726f7020626174636820616c72656164792070726f63657373656400604482015290519081900360640190fd5b6000848152600c60205260408120805460ff191660011790555b835181101561137c576000838281518110611f8657fe5b60200260200101519050600b600082815260200190815260200160002054600014611fef576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b5a5b9d195960621b604482015290519081900360640190fd5b602081811b6001600160f81b031916600081815260079092526040909120546001600160a01b03168061205a576040805162461bcd60e51b815260206004820152600e60248201526d141bdbdb081b9bdd08199bdd5b9960921b604482015290519081900360640190fd5b806000612066856122d7565b9050816001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156120ac57600080fd5b505afa1580156120c0573d6000803e3d6000fd5b505050506040513d60208110156120d657600080fd5b505161211a576040805162461bcd60e51b815260206004820152600e60248201526d10d85c99081b9bdd08199bdd5b9960921b604482015290519081900360640190fd5b600081815260066020526040808220805460010190558051636d02a25560e11b81526004810184905290516001600160a01b0385169263da0544aa9260248082019391829003018186803b15801561217157600080fd5b505afa158015612185573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156121ae57600080fd5b8101908080516040519392919084600160201b8211156121cd57600080fd5b9083019060208201858111156121e257600080fd5b8251600160201b8111828201881017156121fb57600080fd5b82525081516020918201929091019080838360005b83811015612228578181015183820152602001612210565b50505050905090810190601f1680156122555780820380516001836020036101000a031916815260200191505b50604090815260008a815260096020908152919020855161227e96919550910192509050613879565b506000858152600b6020526040902043905588516122c6908a90889081106122a257fe5b60200260200101518988815181106122b657fe5b602002602001015160018a613362565b505060019093019250611f6f915050565b69ffffffffffffffffffff191690565b60008181526005602052604081206111259061350d565b600080516020613b9e83398151915281565b60008281526005602052604090206002015461232e906111586126a6565b6119cd5760405162461bcd60e51b8152600401808060200182810382526030815260200180613aed6030913960400191505060405180910390fd5b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166123dc5760405162461bcd60e51b8152600401808060200182810382526025815260200180613b1d6025913960400191505060405180910390fd5b6123e46126a6565b6001600160a01b0316856001600160a01b0316148061240a575061240a856116c36126a6565b6124455760405162461bcd60e51b8152600401808060200182810382526029815260200180613ac46029913960400191505060405180910390fd5b600061244f6126a6565b905061246f81878761246088613518565b61246988613518565b87612d19565b6124b6836040518060600160405280602a8152602001613b74602a913960008781526002602090815260408083206001600160a01b038d1684529091529020549190612e7d565b60008581526002602090815260408083206001600160a01b038b811685529252808320939093558716815220546124ed9084612f14565b60008581526002602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461190b81878787878761355d565b61256a6126a6565b6001600160a01b031661257b611d29565b6001600160a01b0316146125d6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b03811661261b5760405162461bcd60e51b8152600401808060200182810382526026815260200180613a9e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000908152600860205260409020546001600160a01b031690565b6000611da6836001600160a01b0384166136ce565b3390565b805161116f906004906020840190613879565b60008060006126cb84611d38565b95505050935050508060001461271a576040805162461bcd60e51b815260206004820152600f60248201526e10d85c9908125108125b9d985b1a59608a1b604482015290519081900360640190fd5b6001600160f81b03198216600090815260076020908152604091829020548251634f558e7960e01b81526004810188905292516001600160a01b039091169283928392634f558e79926024808201939291829003018186803b15801561277f57600080fd5b505afa158015612793573d6000803e3d6000fd5b505050506040513d60208110156127a957600080fd5b50516127f2576040805162461bcd60e51b815260206004820152601360248201527210d85c9908191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b6000868152600660209081526040808320805460019081019182905560109190911b8a1717808452600b909252909120541561286c576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b5a5b9d195960621b604482015290519081900360640190fd5b60008181526008602052604080822080546001600160a01b0319166001600160a01b038781169190911790915581516348c4698960e11b8152600481018b9052915190851691639188d3129160248083019286929190829003018186803b1580156128d657600080fd5b505afa1580156128ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c081101561291357600080fd5b8101908080516040519392919084600160201b82111561293257600080fd5b90830190602082018581111561294757600080fd5b8251600160201b81118282018810171561296057600080fd5b82525081516020918201929091019080838360005b8381101561298d578181015183820152602001612975565b50505050905090810190601f1680156129ba5780820380516001836020036101000a031916815260200191505b5060408181526020830151908301516060840151608085015160a09095018051939792969195949384600160201b8211156129f457600080fd5b908301906020820185811115612a0957600080fd5b8251600160201b811182820188101715612a2257600080fd5b82525081516020918201929091019080838360005b83811015612a4f578181015183820152602001612a37565b50505050905090810190601f168015612a7c5780820380516001836020036101000a031916815260200191505b50604090815260008c8152600960209081529190208551959b50612aae9a5098508a0196509294506138799350505050565b50506000818152600b602052604090204390559695505050505050565b6001600160a01b038416612b105760405162461bcd60e51b8152600401808060200182810382526021815260200180613c386021913960400191505060405180910390fd5b8151835114612b505760405162461bcd60e51b8152600401808060200182810382526028815260200180613c106028913960400191505060405180910390fd5b6000612b5a6126a6565b9050612b6b81600087878787612d19565b60005b8451811015612c2f57612be660026000878481518110612b8a57fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002054858381518110612bd057fe5b6020026020010151612f1490919063ffffffff16565b60026000878481518110612bf657fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101612b6e565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612cb6578181015183820152602001612c9e565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612cf5578181015183820152602001612cdd565b5050505090500194505050505060405180910390a461137c81600087878787612f6e565b612d21611bed565b15612d66576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0385166000908152600a60205260408120905b8451811015612e73576001600160a01b0386166000908152600a602052604090208551869083908110612daf57fe5b60209081029190910181015182546001810184556000938452918320909101555b8254811015612e6a57858281518110612de557fe5b6020026020010151838281548110612df957fe5b90600052602060002001541415612e6257825483906000198101908110612e1c57fe5b9060005260206000200154838281548110612e3357fe5b906000526020600020018190555082805480612e4b57fe5b600190038181906000526020600020016000905590555b600101612dd0565b50600101612d80565b5050505050505050565b60008184841115612f0c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612ed1578181015183820152602001612eb9565b50505050905090810190601f168015612efe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015611da6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612f80846001600160a01b0316613718565b1561190b57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b8381101561300e578181015183820152602001612ff6565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561304d578181015183820152602001613035565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015613089578181015183820152602001613071565b50505050905090810190601f1680156130b65780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1580156130db57600080fd5b505af192505050801561310057506040513d60208110156130fb57600080fd5b505160015b6131955761310c613920565b80613117575061315e565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315612ed1578181015183820152602001612eb9565b60405162461bcd60e51b81526004018080602001828103825260348152602001806139c66034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b146131e45760405162461bcd60e51b8152600401808060200182810382526028815260200180613a1c6028913960400191505060405180910390fd5b50505050505050565b60008281526005602052604090206132059082612691565b1561116f576132126126a6565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260056020526040902061326e908261371e565b1561116f5761327b6126a6565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6132c7611bed565b61330f576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6133456126a6565b604080516001600160a01b039092168252519081900360200190a1565b6001600160a01b0384166133a75760405162461bcd60e51b8152600401808060200182810382526021815260200180613c386021913960400191505060405180910390fd5b60006133b16126a6565b90506133c38160008761246088613518565b60008481526002602090815260408083206001600160a01b03891684529091529020546133f09084612f14565b60008581526002602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461137c8160008787878761355d565b61346b611bed565b156134b0576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586133456126a6565b6000611da68383613733565b6000611da6836001600160a01b038416613797565b6000611125826137af565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061354c57fe5b602090810291909101015292915050565b61356f846001600160a01b0316613718565b1561190b57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156135fe5781810151838201526020016135e6565b50505050905090810190601f16801561362b5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561364e57600080fd5b505af192505050801561367357506040513d602081101561366e57600080fd5b505160015b61367f5761310c613920565b6001600160e01b0319811663f23a6e6160e01b146131e45760405162461bcd60e51b8152600401808060200182810382526028815260200180613a1c6028913960400191505060405180910390fd5b60006136da8383613797565b61371057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611125565b506000611125565b3b151590565b6000611da6836001600160a01b0384166137b3565b815460009082106137755760405162461bcd60e51b81526004018080602001828103825260228152602001806139fa6022913960400191505060405180910390fd5b82600001828154811061378457fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000818152600183016020526040812054801561386f57835460001980830191908101906000908790839081106137e657fe5b906000526020600020015490508087600001848154811061380357fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061383357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611125565b6000915050611125565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826138af57600085556138f5565b82601f106138c857805160ff19168380011785556138f5565b828001600101855582156138f5579182015b828111156138f55782518255916020019190600101906138da565b50613901929150613905565b5090565b5b808211156139015760008155600101613906565b60e01c90565b600060443d101561393057611bfb565b600481823e6308c379a0613944825161391a565b1461394e57611bfb565b6040513d600319016004823e80513d67ffffffffffffffff816024840111818411171561397e5750505050611bfb565b828401925082519150808211156139985750505050611bfb565b503d830160208284010111156139b057505050611bfb565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74455243313135353a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e736665729f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d61746368455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220a103df9e57b30eb4ec0cfe44841824cb9d62b9d1fed40a9e4d0b7725c2241b9564736f6c634300070600330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005168747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d58514d436f7338525853765577467a6f6235503432423958636751395478455672397175434645424447416a2f000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102315760003560e01c806371bc5e1f11610130578063a22cb465116100b8578063d547741f1161007c578063d547741f14610f53578063e985e9c514610f7f578063f242432a14610fad578063f2fde38b14611076578063fe3131121461109c57610231565b8063a22cb46514610d34578063a4aeff5514610d62578063bfcfd9b914610f11578063ca15c87314610f2e578063d539139314610f4b57610231565b80638e2ce69a116100ff5780638e2ce69a14610c555780639010d07c14610cc057806391d1485414610ce35780639be8060d14610d0f578063a217fddf14610d2c57610231565b806371bc5e1f14610b68578063731133e914610b855780638456cb5914610c455780638da5cb5b14610c4d57610231565b8063263a8527116101be5780633f4ba83a116101825780633f4ba83a146109f75780634e1273f4146109ff5780635630710914610b225780635c975abb14610b58578063715018a614610b6057610231565b8063263a8527146106605780632e340599146106a35780632eb2c2d6146107de5780632f2ff15d1461099f57806336568abe146109cb57610231565b80630e89341c116102055780630e89341c1461037b57806311d15e7a1461040d578063178b6de6146104155780631f7fdffa1461048b578063248a9ca31461064357610231565b8062fdd58e1461023657806301ffc9a71461027457806302fe5305146102af57806305d85eda14610355575b600080fd5b6102626004803603604081101561024c57600080fd5b506001600160a01b0381351690602001356110b9565b60408051918252519081900360200190f35b61029b6004803603602081101561028a57600080fd5b50356001600160e01b03191661112b565b604080519115158252519081900360200190f35b610353600480360360208110156102c557600080fd5b810190602081018135600160201b8111156102df57600080fd5b8201836020820111156102f157600080fd5b803590602001918460018302840111600160201b8311171561031257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061114a945050505050565b005b6102626004803603602081101561036b57600080fd5b50356001600160a01b0316611173565b6103986004803603602081101561039157600080fd5b503561118e565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103d25781810151838201526020016103ba565b50505050905090810190601f1680156103ff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61026261122f565b61043b6004803603602081101561042b57600080fd5b50356001600160a01b0316611253565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561047757818101518382015260200161045f565b505050509050019250505060405180910390f35b610353600480360360808110156104a157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104cb57600080fd5b8201836020820111156104dd57600080fd5b803590602001918460208302840111600160201b831117156104fe57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561054d57600080fd5b82018360208201111561055f57600080fd5b803590602001918460208302840111600160201b8311171561058057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156105cf57600080fd5b8201836020820111156105e157600080fd5b803590602001918460018302840111600160201b8311171561060257600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506112be945050505050565b6102626004803603602081101561065957600080fd5b5035611383565b6106876004803603602081101561067657600080fd5b50356001600160f81b031916611398565b604080516001600160a01b039092168252519081900360200190f35b6106c0600480360360208110156106b957600080fd5b50356113bd565b6040518080602001886fffffffffffffffffffffffffffffffff19168152602001876001600160f81b03191681526020018681526020018581526020018060200184815260200183810383528a818151815260200191508051906020019080838360005b8381101561073c578181015183820152602001610724565b50505050905090810190601f1680156107695780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101561079c578181015183820152602001610784565b50505050905090810190601f1680156107c95780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b610353600480360360a08110156107f457600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561082757600080fd5b82018360208201111561083957600080fd5b803590602001918460208302840111600160201b8311171561085a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156108a957600080fd5b8201836020820111156108bb57600080fd5b803590602001918460208302840111600160201b831117156108dc57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561092b57600080fd5b82018360208201111561093d57600080fd5b803590602001918460018302840111600160201b8311171561095e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611610945050505050565b610353600480360360408110156109b557600080fd5b50803590602001356001600160a01b0316611913565b610353600480360360408110156109e157600080fd5b50803590602001356001600160a01b0316611976565b6103536119d7565b61043b60048036036040811015610a1557600080fd5b810190602081018135600160201b811115610a2f57600080fd5b820183602082011115610a4157600080fd5b803590602001918460208302840111600160201b83111715610a6257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ab157600080fd5b820183602082011115610ac357600080fd5b803590602001918460208302840111600160201b83111715610ae457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506119f9945050505050565b61035360048036036040811015610b3857600080fd5b5080356001600160f81b03191690602001356001600160a01b0316611ae5565b61029b611bed565b610353611bfe565b61026260048036036020811015610b7e57600080fd5b5035611cbc565b61035360048036036080811015610b9b57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b811115610bd157600080fd5b820183602082011115610be357600080fd5b803590602001918460018302840111600160201b83111715610c0457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611cce945050505050565b610353611d0a565b610687611d29565b610c7260048036036020811015610c6b57600080fd5b5035611d38565b604080516001600160f81b031997881681526001600160e01b03199096166020870152938616858501526060850192909252909316608083015260a082019290925290519081900360c00190f35b61068760048036036040811015610cd657600080fd5b5080359060200135611d8e565b61029b60048036036040811015610cf957600080fd5b50803590602001356001600160a01b0316611dad565b61029b60048036036020811015610d2557600080fd5b5035611dc5565b610262611dda565b61035360048036036040811015610d4a57600080fd5b506001600160a01b0381351690602001351515611ddf565b61035360048036036080811015610d7857600080fd5b81359190810190604081016020820135600160201b811115610d9957600080fd5b820183602082011115610dab57600080fd5b803590602001918460208302840111600160201b83111715610dcc57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610e1b57600080fd5b820183602082011115610e2d57600080fd5b803590602001918460208302840111600160201b83111715610e4e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610e9d57600080fd5b820183602082011115610eaf57600080fd5b803590602001918460018302840111600160201b83111715610ed057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ece945050505050565b61026260048036036020811015610f2757600080fd5b50356122d7565b61026260048036036020811015610f4457600080fd5b50356122e7565b6102626122fe565b61035360048036036040811015610f6957600080fd5b50803590602001356001600160a01b0316612310565b61029b60048036036040811015610f9557600080fd5b506001600160a01b0381358116916020013516612369565b610353600480360360a0811015610fc357600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561100257600080fd5b82018360208201111561101457600080fd5b803590602001918460018302840111600160201b8311171561103557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612397945050505050565b6103536004803603602081101561108c57600080fd5b50356001600160a01b0316612562565b610687600480360360208110156110b257600080fd5b5035612676565b60006001600160a01b0383166111005760405162461bcd60e51b815260040180806020018281038252602b815260200180613a73602b913960400191505060405180910390fd5b5060008181526002602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526001602052604090205460ff1690565b600061115d816111586126a6565b611dad565b61116657600080fd5b61116f826126aa565b5050565b6001600160a01b03166000908152600a602052604090205490565b60008181526009602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156112235780601f106111f857610100808354040283529160200191611223565b820191906000526020600020905b81548152906001019060200180831161120657829003601f168201915b50505050509050919050565b7f11c2020b6b4f4e00c2410234e0c72636b4739cf7cda4d8e24ef6b881350e670481565b6001600160a01b0381166000908152600a602090815260409182902080548351818402810184019094528084526060939283018282801561122357602002820191906000526020600020905b81548152602001906001019080831161129f5750505050509050919050565b6112d8600080516020613b9e8339815191526111586126a6565b6112e157600080fd5b6000835167ffffffffffffffff811180156112fb57600080fd5b50604051908082528060200260200182016040528015611325578160200160208202803683370190505b50905060005b845181101561136f5761135085828151811061134357fe5b60200260200101516126bd565b82828151811061135c57fe5b602090810291909101015260010161132b565b5061137c85828585612acb565b5050505050565b60009081526005602052604090206002015490565b6001600160f81b0319166000908152600760205260409020546001600160a01b031690565b606060008060008060606000806113d3896122d7565b60008a8152600860205260408082205481516348c4698960e11b81526004810185905291519394506001600160a01b0316928392639188d3129260248082019391829003018186803b15801561142857600080fd5b505afa15801561143c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c081101561146557600080fd5b8101908080516040519392919084600160201b82111561148457600080fd5b90830190602082018581111561149957600080fd5b8251600160201b8111828201881017156114b257600080fd5b82525081516020918201929091019080838360005b838110156114df5781810151838201526020016114c7565b50505050905090810190601f16801561150c5780820380516001836020036101000a031916815260200191505b5060408181526020830151908301516060840151608085015160a09095018051939792969195949384600160201b82111561154657600080fd5b90830190602082018581111561155b57600080fd5b8251600160201b81118282018810171561157457600080fd5b82525081516020918201929091019080838360005b838110156115a1578181015183820152602001611589565b50505050905090810190601f1680156115ce5780820380516001836020036101000a031916815260200191505b50604052505050809950819a50829b50839c50849d50859e50505050505050600b60008b81526020019081526020016000205492505050919395979092949650565b81518351146116505760405162461bcd60e51b8152600401808060200182810382526028815260200180613c106028913960400191505060405180910390fd5b6001600160a01b0384166116955760405162461bcd60e51b8152600401808060200182810382526025815260200180613b1d6025913960400191505060405180910390fd5b61169d6126a6565b6001600160a01b0316856001600160a01b031614806116c857506116c8856116c36126a6565b612369565b6117035760405162461bcd60e51b8152600401808060200182810382526032815260200180613b426032913960400191505060405180910390fd5b600061170d6126a6565b905061171d818787878787612d19565b60005b845181101561182357600085828151811061173757fe5b60200260200101519050600085838151811061174f57fe5b602002602001015190506117bc816040518060600160405280602a8152602001613b74602a91396002600086815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002054612e7d9092919063ffffffff16565b60008381526002602090815260408083206001600160a01b038e811685529252808320939093558a16815220546117f39082612f14565b60009283526002602090815260408085206001600160a01b038c1686529091529092209190915550600101611720565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156118a9578181015183820152602001611891565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156118e85781810151838201526020016118d0565b5050505090500194505050505060405180910390a461190b818787878787612f6e565b505050505050565b600082815260056020526040902060020154611931906111586126a6565b61196c5760405162461bcd60e51b815260040180806020018281038252602f815260200180613a44602f913960400191505060405180910390fd5b61116f82826131ed565b61197e6126a6565b6001600160a01b0316816001600160a01b0316146119cd5760405162461bcd60e51b815260040180806020018281038252602f815260200180613c59602f913960400191505060405180910390fd5b61116f8282613256565b60006119e5816111586126a6565b6119ee57600080fd5b6119f66132bf565b50565b60608151835114611a3b5760405162461bcd60e51b8152600401808060200182810382526029815260200180613be76029913960400191505060405180910390fd5b6000835167ffffffffffffffff81118015611a5557600080fd5b50604051908082528060200260200182016040528015611a7f578160200160208202803683370190505b50905060005b8451811015611add57611abe858281518110611a9d57fe5b6020026020010151858381518110611ab157fe5b60200260200101516110b9565b828281518110611aca57fe5b6020908102919091010152600101611a85565b509392505050565b6000611af3816111586126a6565b611afc57600080fd5b6001600160f81b031983166000908152600760205260409020546001600160a01b031615611b65576040805162461bcd60e51b8152602060048201526011602482015270111d5c1b1a58d85d1948141bdbdb081251607a1b604482015290519081900360640190fd5b604080516001600160f81b0319851681526001600160a01b038416602082015281517febeda574509491f8af1764dd814d8dc1edc8e4b917707c15584de69e4beba476929181900390910190a1506001600160f81b031991909116600090815260076020526040902080546001600160a01b0319166001600160a01b03909216919091179055565b600054600160a01b900460ff165b90565b611c066126a6565b6001600160a01b0316611c17611d29565b6001600160a01b031614611c72576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60009081526006602052604090205490565b611ce8600080516020613b9e8339815191526111586126a6565b611cf157600080fd5b6000611cfc846126bd565b905061137c85828585613362565b6000611d18816111586126a6565b611d2157600080fd5b6119f6613463565b6000546001600160a01b031690565b60f881901b916001600160e01b0319821691602081901b6001600160f81b031990811692602883901b6fffffffffffffffffffffffffffffffff19169260a881901b9092169160101c67ffffffffffffffff1690565b6000828152600560205260408120611da690836134ec565b9392505050565b6000828152600560205260408120611da690836134f8565b600c6020526000908152604090205460ff1681565b600081565b816001600160a01b0316611df16126a6565b6001600160a01b03161415611e375760405162461bcd60e51b8152600401808060200182810382526029815260200180613bbe6029913960400191505060405180910390fd5b8060036000611e446126a6565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611e886126a6565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b611ee8600080516020613b9e8339815191526111586126a6565b611ef157600080fd5b6000848152600c602052604090205460ff1615611f55576040805162461bcd60e51b815260206004820152601f60248201527f41697264726f7020626174636820616c72656164792070726f63657373656400604482015290519081900360640190fd5b6000848152600c60205260408120805460ff191660011790555b835181101561137c576000838281518110611f8657fe5b60200260200101519050600b600082815260200190815260200160002054600014611fef576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b5a5b9d195960621b604482015290519081900360640190fd5b602081811b6001600160f81b031916600081815260079092526040909120546001600160a01b03168061205a576040805162461bcd60e51b815260206004820152600e60248201526d141bdbdb081b9bdd08199bdd5b9960921b604482015290519081900360640190fd5b806000612066856122d7565b9050816001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156120ac57600080fd5b505afa1580156120c0573d6000803e3d6000fd5b505050506040513d60208110156120d657600080fd5b505161211a576040805162461bcd60e51b815260206004820152600e60248201526d10d85c99081b9bdd08199bdd5b9960921b604482015290519081900360640190fd5b600081815260066020526040808220805460010190558051636d02a25560e11b81526004810184905290516001600160a01b0385169263da0544aa9260248082019391829003018186803b15801561217157600080fd5b505afa158015612185573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156121ae57600080fd5b8101908080516040519392919084600160201b8211156121cd57600080fd5b9083019060208201858111156121e257600080fd5b8251600160201b8111828201881017156121fb57600080fd5b82525081516020918201929091019080838360005b83811015612228578181015183820152602001612210565b50505050905090810190601f1680156122555780820380516001836020036101000a031916815260200191505b50604090815260008a815260096020908152919020855161227e96919550910192509050613879565b506000858152600b6020526040902043905588516122c6908a90889081106122a257fe5b60200260200101518988815181106122b657fe5b602002602001015160018a613362565b505060019093019250611f6f915050565b69ffffffffffffffffffff191690565b60008181526005602052604081206111259061350d565b600080516020613b9e83398151915281565b60008281526005602052604090206002015461232e906111586126a6565b6119cd5760405162461bcd60e51b8152600401808060200182810382526030815260200180613aed6030913960400191505060405180910390fd5b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205460ff1690565b6001600160a01b0384166123dc5760405162461bcd60e51b8152600401808060200182810382526025815260200180613b1d6025913960400191505060405180910390fd5b6123e46126a6565b6001600160a01b0316856001600160a01b0316148061240a575061240a856116c36126a6565b6124455760405162461bcd60e51b8152600401808060200182810382526029815260200180613ac46029913960400191505060405180910390fd5b600061244f6126a6565b905061246f81878761246088613518565b61246988613518565b87612d19565b6124b6836040518060600160405280602a8152602001613b74602a913960008781526002602090815260408083206001600160a01b038d1684529091529020549190612e7d565b60008581526002602090815260408083206001600160a01b038b811685529252808320939093558716815220546124ed9084612f14565b60008581526002602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461190b81878787878761355d565b61256a6126a6565b6001600160a01b031661257b611d29565b6001600160a01b0316146125d6576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b03811661261b5760405162461bcd60e51b8152600401808060200182810382526026815260200180613a9e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000908152600860205260409020546001600160a01b031690565b6000611da6836001600160a01b0384166136ce565b3390565b805161116f906004906020840190613879565b60008060006126cb84611d38565b95505050935050508060001461271a576040805162461bcd60e51b815260206004820152600f60248201526e10d85c9908125108125b9d985b1a59608a1b604482015290519081900360640190fd5b6001600160f81b03198216600090815260076020908152604091829020548251634f558e7960e01b81526004810188905292516001600160a01b039091169283928392634f558e79926024808201939291829003018186803b15801561277f57600080fd5b505afa158015612793573d6000803e3d6000fd5b505050506040513d60208110156127a957600080fd5b50516127f2576040805162461bcd60e51b815260206004820152601360248201527210d85c9908191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b6000868152600660209081526040808320805460019081019182905560109190911b8a1717808452600b909252909120541561286c576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b5a5b9d195960621b604482015290519081900360640190fd5b60008181526008602052604080822080546001600160a01b0319166001600160a01b038781169190911790915581516348c4698960e11b8152600481018b9052915190851691639188d3129160248083019286929190829003018186803b1580156128d657600080fd5b505afa1580156128ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260c081101561291357600080fd5b8101908080516040519392919084600160201b82111561293257600080fd5b90830190602082018581111561294757600080fd5b8251600160201b81118282018810171561296057600080fd5b82525081516020918201929091019080838360005b8381101561298d578181015183820152602001612975565b50505050905090810190601f1680156129ba5780820380516001836020036101000a031916815260200191505b5060408181526020830151908301516060840151608085015160a09095018051939792969195949384600160201b8211156129f457600080fd5b908301906020820185811115612a0957600080fd5b8251600160201b811182820188101715612a2257600080fd5b82525081516020918201929091019080838360005b83811015612a4f578181015183820152602001612a37565b50505050905090810190601f168015612a7c5780820380516001836020036101000a031916815260200191505b50604090815260008c8152600960209081529190208551959b50612aae9a5098508a0196509294506138799350505050565b50506000818152600b602052604090204390559695505050505050565b6001600160a01b038416612b105760405162461bcd60e51b8152600401808060200182810382526021815260200180613c386021913960400191505060405180910390fd5b8151835114612b505760405162461bcd60e51b8152600401808060200182810382526028815260200180613c106028913960400191505060405180910390fd5b6000612b5a6126a6565b9050612b6b81600087878787612d19565b60005b8451811015612c2f57612be660026000878481518110612b8a57fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002054858381518110612bd057fe5b6020026020010151612f1490919063ffffffff16565b60026000878481518110612bf657fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101612b6e565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612cb6578181015183820152602001612c9e565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612cf5578181015183820152602001612cdd565b5050505090500194505050505060405180910390a461137c81600087878787612f6e565b612d21611bed565b15612d66576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0385166000908152600a60205260408120905b8451811015612e73576001600160a01b0386166000908152600a602052604090208551869083908110612daf57fe5b60209081029190910181015182546001810184556000938452918320909101555b8254811015612e6a57858281518110612de557fe5b6020026020010151838281548110612df957fe5b90600052602060002001541415612e6257825483906000198101908110612e1c57fe5b9060005260206000200154838281548110612e3357fe5b906000526020600020018190555082805480612e4b57fe5b600190038181906000526020600020016000905590555b600101612dd0565b50600101612d80565b5050505050505050565b60008184841115612f0c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612ed1578181015183820152602001612eb9565b50505050905090810190601f168015612efe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015611da6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612f80846001600160a01b0316613718565b1561190b57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b8381101561300e578181015183820152602001612ff6565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561304d578181015183820152602001613035565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015613089578181015183820152602001613071565b50505050905090810190601f1680156130b65780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1580156130db57600080fd5b505af192505050801561310057506040513d60208110156130fb57600080fd5b505160015b6131955761310c613920565b80613117575061315e565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315612ed1578181015183820152602001612eb9565b60405162461bcd60e51b81526004018080602001828103825260348152602001806139c66034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b146131e45760405162461bcd60e51b8152600401808060200182810382526028815260200180613a1c6028913960400191505060405180910390fd5b50505050505050565b60008281526005602052604090206132059082612691565b1561116f576132126126a6565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260056020526040902061326e908261371e565b1561116f5761327b6126a6565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6132c7611bed565b61330f576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6133456126a6565b604080516001600160a01b039092168252519081900360200190a1565b6001600160a01b0384166133a75760405162461bcd60e51b8152600401808060200182810382526021815260200180613c386021913960400191505060405180910390fd5b60006133b16126a6565b90506133c38160008761246088613518565b60008481526002602090815260408083206001600160a01b03891684529091529020546133f09084612f14565b60008581526002602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461137c8160008787878761355d565b61346b611bed565b156134b0576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586133456126a6565b6000611da68383613733565b6000611da6836001600160a01b038416613797565b6000611125826137af565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061354c57fe5b602090810291909101015292915050565b61356f846001600160a01b0316613718565b1561190b57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156135fe5781810151838201526020016135e6565b50505050905090810190601f16801561362b5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561364e57600080fd5b505af192505050801561367357506040513d602081101561366e57600080fd5b505160015b61367f5761310c613920565b6001600160e01b0319811663f23a6e6160e01b146131e45760405162461bcd60e51b8152600401808060200182810382526028815260200180613a1c6028913960400191505060405180910390fd5b60006136da8383613797565b61371057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611125565b506000611125565b3b151590565b6000611da6836001600160a01b0384166137b3565b815460009082106137755760405162461bcd60e51b81526004018080602001828103825260228152602001806139fa6022913960400191505060405180910390fd5b82600001828154811061378457fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000818152600183016020526040812054801561386f57835460001980830191908101906000908790839081106137e657fe5b906000526020600020015490508087600001848154811061380357fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061383357fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611125565b6000915050611125565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826138af57600085556138f5565b82601f106138c857805160ff19168380011785556138f5565b828001600101855582156138f5579182015b828111156138f55782518255916020019190600101906138da565b50613901929150613905565b5090565b5b808211156139015760008155600101613906565b60e01c90565b600060443d101561393057611bfb565b600481823e6308c379a0613944825161391a565b1461394e57611bfb565b6040513d600319016004823e80513d67ffffffffffffffff816024840111818411171561397e5750505050611bfb565b828401925082519150808211156139985750505050611bfb565b503d830160208284010111156139b057505050611bfb565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e74455243313135353a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e736665729f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d61746368455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66a2646970667358221220a103df9e57b30eb4ec0cfe44841824cb9d62b9d1fed40a9e4d0b7725c2241b9564736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005168747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d58514d436f7338525853765577467a6f6235503432423958636751395478455672397175434645424447416a2f000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _uri (string): https://gateway.pinata.cloud/ipfs/QmXQMCos8RXSvUwFzob5P42B9XcgQ9TxEVr9quCFEBDGAj/
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000051
Arg [2] : 68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066
Arg [3] : 732f516d58514d436f7338525853765577467a6f623550343242395863675139
Arg [4] : 5478455672397175434645424447416a2f000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 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.