Source Code
Overview
GLMR Balance
GLMR Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 19 from a total of 19 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 13963933 | 21 days ago | IN | 0 GLMR | 0.00083315 | ||||
| Set Approval For... | 13963933 | 21 days ago | IN | 0 GLMR | 0.00533175 | ||||
| Safe Transfer Fr... | 13845708 | 30 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Safe Transfer Fr... | 13825210 | 32 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Safe Transfer Fr... | 13825205 | 32 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Safe Transfer Fr... | 13825201 | 32 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Set Approval For... | 13802312 | 34 days ago | IN | 0 GLMR | 0.00533175 | ||||
| Set Approval For... | 13800646 | 34 days ago | IN | 0 GLMR | 0.00533175 | ||||
| Set Approval For... | 13800645 | 34 days ago | IN | 0 GLMR | 0.00533175 | ||||
| Safe Transfer Fr... | 13800090 | 34 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Safe Transfer Fr... | 13800081 | 34 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Set Approval For... | 13726976 | 40 days ago | IN | 0 GLMR | 0.00533175 | ||||
| Safe Transfer Fr... | 13570023 | 53 days ago | IN | 0 GLMR | 0.00917575 | ||||
| Safe Transfer Fr... | 13569764 | 53 days ago | IN | 0 GLMR | 0.00917575 | ||||
| Safe Transfer Fr... | 13569644 | 53 days ago | IN | 0 GLMR | 0.00917575 | ||||
| Safe Transfer Fr... | 13569608 | 53 days ago | IN | 0 GLMR | 0.00917575 | ||||
| Safe Transfer Fr... | 13569593 | 53 days ago | IN | 0 GLMR | 0.00917575 | ||||
| Safe Transfer Fr... | 13461064 | 62 days ago | IN | 0 GLMR | 0.00541175 | ||||
| Set Approval For... | 13339774 | 72 days ago | IN | 0 GLMR | 0.00533175 |
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 12711175 | 124 days ago | Contract Creation | 0 GLMR |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Booster
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
import "./ERC1155BaseToken.sol";
contract Booster is ERC1155BaseToken {
constructor(
string memory tokenName,
string memory tokenBaseURI,
string memory tokenContractURI,
address owner
) {
_initialize(owner, tokenName, tokenBaseURI, tokenContractURI);
}
/**
* Função para mintar novos tokens.
* @param to Endereço que receberá os tokens.
* @param tokenId ID do token a ser criado.
* @param amount Quantidade de tokens a ser criada.
* @param data Dados adicionais (opcional).
*/
function mint(
address to,
uint256 tokenId,
uint256 amount,
bytes memory data
) external onlyRole(DEFAULT_ADMIN_ROLE) {
_mint(to, tokenId, amount, data);
}
function batchMint(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(ids.length == amounts.length, "IDs and amounts length mismatch");
for (uint256 i = 0; i < ids.length; i++) {
_mint(to, ids[i], amounts[i], data);
}
}
function batchBurn(address owner, uint256[] memory tokenIds, uint256[] memory amounts) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(tokenIds.length == amounts.length, "Mismatched array lengths");
for (uint256 i = 0; i < tokenIds.length; i++) {
_burn(owner, tokenIds[i], amounts[i]);
}
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
import {IERC2981Controlled} from "@0xsequence/contracts-library/tokens/common/IERC2981Controlled.sol";
import {ERC2981} from "@openzeppelin/contracts/token/common/ERC2981.sol";
import {AccessControlEnumerable} from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
/**
* An implementation of ERC-2981 that allows updates by roles.
*/
abstract contract ERC2981Controlled is ERC2981, AccessControlEnumerable, IERC2981Controlled {
bytes32 internal constant ROYALTY_ADMIN_ROLE = keccak256("ROYALTY_ADMIN_ROLE");
//
// Royalty
//
/**
* Sets the royalty information that all ids in this contract will default to.
* @param receiver Address of who should be sent the royalty payment
* @param feeNumerator The royalty fee numerator in basis points (e.g. 15% would be 1500)
*/
function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyRole(ROYALTY_ADMIN_ROLE) {
_setDefaultRoyalty(receiver, feeNumerator);
}
/**
* Sets the royalty information that a given token id in this contract will use.
* @param tokenId The token id to set the royalty information for
* @param receiver Address of who should be sent the royalty payment
* @param feeNumerator The royalty fee numerator in basis points (e.g. 15% would be 1500)
* @notice This overrides the default royalty information for this token id
*/
function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator)
external
onlyRole(ROYALTY_ADMIN_ROLE)
{
_setTokenRoyalty(tokenId, receiver, feeNumerator);
}
//
// Views
//
/**
* Check interface support.
* @param interfaceId Interface id
* @return True if supported
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override (ERC2981, AccessControlEnumerable)
returns (bool)
{
return ERC2981.supportsInterface(interfaceId) || AccessControlEnumerable.supportsInterface(interfaceId)
|| type(IERC2981Controlled).interfaceId == interfaceId || super.supportsInterface(interfaceId);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
interface IERC2981ControlledFunctions {
/**
* Sets the royalty information that all ids in this contract will default to.
* @param receiver Address of who should be sent the royalty payment
* @param feeNumerator The royalty fee numerator in basis points (e.g. 15% would be 1500)
*/
function setDefaultRoyalty(address receiver, uint96 feeNumerator) external;
/**
* Sets the royalty information that a given token id in this contract will use.
* @param tokenId The token id to set the royalty information for
* @param receiver Address of who should be sent the royalty payment
* @param feeNumerator The royalty fee numerator in basis points (e.g. 15% would be 1500)
* @notice This overrides the default royalty information for this token id
*/
function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external;
}
interface IERC2981Controlled is IERC2981ControlledFunctions {}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
import {ERC1155} from "@0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155.sol";
import {
IERC1155Supply,
IERC1155SupplyFunctions
} from "@0xsequence/contracts-library/tokens/ERC1155/extensions/supply/IERC1155Supply.sol";
/**
* An ERC-1155 extension that tracks token supply.
*/
abstract contract ERC1155Supply is ERC1155, IERC1155Supply {
// Current supply
uint256 public totalSupply;
mapping(uint256 => uint256) public tokenSupply;
/**
* Mint _amount of tokens of a given id
* @param _to The address to mint tokens to
* @param _id Token id to mint
* @param _amount The amount to be minted
* @param _data Data to pass if receiver is contract
*/
function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data) internal virtual {
totalSupply += _amount;
tokenSupply[_id] += _amount;
balances[_to][_id] += _amount;
emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);
_callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
}
/**
* Mint tokens for each ids in _ids
* @param _to The address to mint tokens to
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
* @param _data Data to pass if receiver is contract
*/
function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
internal
virtual
{
uint256 nMint = _ids.length;
if (nMint != _amounts.length) {
revert InvalidArrayLength();
}
// Executing all minting
uint256 totalAmount = 0;
for (uint256 i = 0; i < nMint; i++) {
// Update storage balance
balances[_to][_ids[i]] += _amounts[i];
tokenSupply[_ids[i]] += _amounts[i];
totalAmount += _amounts[i];
}
totalSupply += totalAmount;
emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);
// Calling onReceive method if recipient is contract
_callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
}
/**
* Burn _amount of tokens of a given token id
* @param _from The address to burn tokens from
* @param _id Token id to burn
* @param _amount The amount to be burned
*/
function _burn(address _from, uint256 _id, uint256 _amount) internal virtual {
// Supply
totalSupply -= _amount;
tokenSupply[_id] -= _amount;
// Balances
balances[_from][_id] -= _amount;
// Emit event
emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
}
/**
* Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
* @param _from The address to burn tokens from
* @param _ids Array of token ids to burn
* @param _amounts Array of the amount to be burned
*/
function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts) internal virtual {
uint256 nBurn = _ids.length;
if (nBurn != _amounts.length) {
revert InvalidArrayLength();
}
uint256 totalAmount = 0;
for (uint256 i = 0; i < nBurn; i++) {
// Update balances
balances[_from][_ids[i]] -= _amounts[i];
tokenSupply[_ids[i]] -= _amounts[i];
totalAmount += _amounts[i];
}
totalSupply -= totalAmount;
// Emit batch mint event
emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
}
//
// Views
//
/**
* Check interface support.
* @param interfaceId Interface id
* @return True if supported
*/
function supportsInterface(bytes4 interfaceId) public view virtual override (ERC1155) returns (bool) {
return type(IERC1155SupplyFunctions).interfaceId == interfaceId || super.supportsInterface(interfaceId);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
interface IERC1155SupplyFunctions {
/**
* Returns the total supply of ERC1155 tokens.
*/
function totalSupply() external returns (uint256);
/**
* Returns the total supply of a given ERC1155 token.
* @param tokenId The ERC1155 token id.
*/
function tokenSupply(uint256 tokenId) external returns (uint256);
}
interface IERC1155SupplySignals {
/**
* Invalid array input length.
*/
error InvalidArrayLength();
}
interface IERC1155Supply is IERC1155SupplySignals {}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import './IERC165.sol';
interface IERC1155 is IERC165 {
/****************************************|
| Events |
|_______________________________________*/
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);
/**
* @dev MUST emit when an approval is updated
*/
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
/****************************************|
| Functions |
|_______________________________________*/
/**
* @notice Transfers amount of an _id from the _from address to the _to address specified
* @dev MUST emit TransferSingle event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev MUST emit TransferBatch event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if length of `_ids` is not the same as length of `_amounts`
* MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id) external view returns (uint256);
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @dev MUST emit the ApprovalForAll event on success
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved) external;
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return isOperator True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
interface IERC1155Metadata {
event URI(string _uri, uint256 indexed _id);
/****************************************|
| Functions |
|_______________________________________*/
/**
* @notice A distinct Uniform Resource Identifier (URI) for a given token.
* @dev URIs are defined in RFC 3986.
* URIs are assumed to be deterministically generated based on token ID
* Token IDs are assumed to be represented in their hex format in URIs
* @return URI string
*/
function uri(uint256 _id) external view returns (string memory);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
/**
* @dev ERC-1155 interface for accepting safe transfers.
*/
interface IERC1155TokenReceiver {
/**
* @notice Handle the receipt of a single ERC1155 token type
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value MUST result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeTransferFrom` function
* @param _from The address which previously owned the token
* @param _id The id of the token being transferred
* @param _amount The amount of tokens being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
*/
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);
/**
* @notice Handle the receipt of multiple ERC1155 token types
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value WILL result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeBatchTransferFrom` function
* @param _from The address which previously owned the token
* @param _ids An array containing ids of each token being transferred
* @param _amounts An array containing amounts of each token being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
*/
function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
/**
* @title ERC165
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
*/
interface IERC165 {
/**
* @notice Query if a contract implements an interface
* @dev Interface identification is specified in ERC-165. This function
* uses less than 30,000 gas
* @param _interfaceId The interface identifier, as specified in ERC-165
*/
function supportsInterface(bytes4 _interfaceId)
external
view
returns (bool);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";
/**
* @dev Implementation of Multi-Token Standard contract
*/
contract ERC1155 is IERC1155, ERC165 {
using Address for address;
/***********************************|
| Variables and Events |
|__________________________________*/
// onReceive function signatures
bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;
// Objects balances
mapping (address => mapping(uint256 => uint256)) internal balances;
// Operator Functions
mapping (address => mapping(address => bool)) internal operators;
/***********************************|
| Public Transfer Functions |
|__________________________________*/
/**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
public virtual override
{
require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR");
require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT");
_safeTransferFrom(_from, _to, _id, _amount);
_callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
public virtual override
{
// Requirements
require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR");
require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT");
_safeBatchTransferFrom(_from, _to, _ids, _amounts);
_callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
}
/***********************************|
| Internal Transfer Functions |
|__________________________________*/
/**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
*/
function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
internal virtual
{
// Update balances
balances[_from][_id] -= _amount;
balances[_to][_id] += _amount;
// Emit event
emit TransferSingle(msg.sender, _from, _to, _id, _amount);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
*/
function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
internal virtual
{
// Check if recipient is contract
if (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas: _gasLimit}(msg.sender, _from, _id, _amount, _data);
require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
}
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
*/
function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
internal virtual
{
require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");
// Number of transfer to execute
uint256 nTransfer = _ids.length;
// Executing all transfers
for (uint256 i = 0; i < nTransfer; i++) {
// Update storage balance of previous bin
balances[_from][_ids[i]] -= _amounts[i];
balances[_to][_ids[i]] += _amounts[i];
}
// Emit event
emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
*/
function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
internal virtual
{
// Pass data if recipient is contract
if (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
}
}
/***********************************|
| Operator Functions |
|__________________________________*/
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved)
external virtual override
{
// Update operator status
operators[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return isOperator True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator)
public view virtual override returns (bool isOperator)
{
return operators[_owner][_operator];
}
/***********************************|
| Balance Functions |
|__________________________________*/
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id)
public view virtual override returns (uint256)
{
return balances[_owner][_id];
}
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
public view virtual override returns (uint256[] memory)
{
require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH");
// Variables
uint256[] memory batchBalances = new uint256[](_owners.length);
// Iterate over each owner and token ID
for (uint256 i = 0; i < _owners.length; i++) {
batchBalances[i] = balances[_owners[i]][_ids[i]];
}
return batchBalances;
}
/***********************************|
| ERC165 Functions |
|__________________________________*/
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/
function supportsInterface(bytes4 _interfaceID) public view virtual override(ERC165, IERC165) returns (bool) {
if (_interfaceID == type(IERC1155).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import '../../interfaces/IERC1155Metadata.sol';
import '../../utils/ERC165.sol';
/**
* @notice Contract that handles metadata related methods.
* @dev Methods assume a deterministic generation of URI based on token IDs.
* Methods also assume that URI uses hex representation of token IDs.
*/
contract ERC1155Metadata is IERC1155Metadata, ERC165 {
// URI's default URI prefix
string public baseURI;
string public name;
// set the initial name and base URI
constructor(string memory _name, string memory _baseURI) {
name = _name;
baseURI = _baseURI;
}
/***********************************|
| Metadata Public Functions |
|__________________________________*/
/**
* @notice A distinct Uniform Resource Identifier (URI) for a given token.
* @dev URIs are defined in RFC 3986.
* URIs are assumed to be deterministically generated based on token ID
* @return URI string
*/
function uri(uint256 _id) public view virtual override returns (string memory) {
return string(abi.encodePacked(baseURI, _uint2str(_id), ".json"));
}
/***********************************|
| Metadata Internal Functions |
|__________________________________*/
/**
* @notice Will emit default URI log event for corresponding token _id
* @param _tokenIDs Array of IDs of tokens to log default URI
*/
function _logURIs(uint256[] memory _tokenIDs) internal virtual {
string memory baseURL = baseURI;
string memory tokenURI;
for (uint256 i = 0; i < _tokenIDs.length; i++) {
tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json"));
emit URI(tokenURI, _tokenIDs[i]);
}
}
/**
* @notice Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/
function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal {
baseURI = _newBaseMetadataURI;
}
/**
* @notice Will update the name of the contract
* @param _newName New contract name
*/
function _setContractName(string memory _newName) internal {
name = _newName;
}
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/
function supportsInterface(bytes4 _interfaceID) public view virtual override returns (bool) {
if (_interfaceID == type(IERC1155Metadata).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
/***********************************|
| Utility Internal Functions |
|__________________________________*/
function _uint2str(uint _i) internal pure returns (string memory _uintAsString) {
if (_i == 0) {
return '0';
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
}pragma solidity ^0.8.0;
/**
* Utility library of inline functions on addresses
*/
library Address {
// Default hash for EOA accounts returned by extcodehash
bytes32 constant internal ACCOUNT_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract.
* @param _address address of the account to check
* @return Whether the target address is a contract
*/
function isContract(address _address) internal view returns (bool) {
bytes32 codehash;
// Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address or if it has a non-zero code hash or account hash
assembly { codehash := extcodehash(_address) }
return (codehash != 0x0 && codehash != ACCOUNT_HASH);
}
}pragma solidity ^0.8.0;
import "../interfaces/IERC165.sol";
abstract contract ERC165 is IERC165 {
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID`
*/
function supportsInterface(bytes4 _interfaceID) public view virtual override returns (bool) {
return _interfaceID == this.supportsInterface.selector;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* 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:
*
* ```solidity
* 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}:
*
* ```solidity
* 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. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `_msgSender()` is missing `role`.
* Overriding this function changes the behavior of the {onlyRole} modifier.
*
* Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @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 virtual override 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.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_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.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_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 revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address account) public virtual override {
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.
*
* May emit a {RoleGranted} event.
*
* [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}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
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 {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControlEnumerable.sol";
import "./AccessControl.sol";
import "../utils/structs/EnumerableSet.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @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 virtual override returns (address) {
return _roleMembers[role].at(index);
}
/**
* @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 virtual override returns (uint256) {
return _roleMembers[role].length();
}
/**
* @dev Overload {_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override {
super._grantRole(role, account);
_roleMembers[role].add(account);
}
/**
* @dev Overload {_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override {
super._revokeRole(role, account);
_roleMembers[role].remove(account);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @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 {AccessControl-_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) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @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) external;
/**
* @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) external;
/**
* @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) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
*/
interface IAccessControlEnumerable is IAccessControl {
/**
* @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) external view returns (address);
/**
* @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) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165.sol";
/**
* @dev Interface for the NFT Royalty Standard.
*
* A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
* support for royalty payments across all NFT marketplaces and ecosystem participants.
*
* _Available since v4.5._
*/
interface IERC2981 is IERC165 {
/**
* @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
* exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
*/
function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) external view returns (address receiver, uint256 royaltyAmount);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)
pragma solidity ^0.8.0;
import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
*
* Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
* specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
*
* Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
* fee is specified in basis points by default.
*
* IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
* https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
* voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
*
* _Available since v4.5._
*/
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @inheritdoc IERC2981
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
/**
* @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
* fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
* override.
*/
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
/**
* @dev Sets the royalty information that all ids in this contract will default to.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: invalid receiver");
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Removes default royalty information.
*/
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
/**
* @dev Sets the royalty information for a specific token id, overriding the global default.
*
* Requirements:
*
* - `receiver` cannot be the zero address.
* - `feeNumerator` cannot be greater than the fee denominator.
*/
function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: Invalid parameters");
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
/**
* @dev Resets royalty information for the token id back to the global default.
*/
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^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.
*
* ```solidity
* 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.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
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;
if (lastIndex != toDeleteIndex) {
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] = valueIndex; // Replace lastValue's index to valueIndex
}
// 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) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// 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);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// 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))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// 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 in 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));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.19;
import {
ERC1155Supply, ERC1155
} from "@0xsequence/contracts-library/tokens/ERC1155/extensions/supply/ERC1155Supply.sol";
import {ERC1155Metadata} from "@0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155Metadata.sol";
import {ERC2981Controlled} from "@0xsequence/contracts-library/tokens/common/ERC2981Controlled.sol";
error InvalidInitialization();
/**
* A standard base implementation of ERC-1155 for use in Sequence library contracts.
*/
abstract contract ERC1155BaseToken is ERC1155Supply, ERC1155Metadata, ERC2981Controlled {
bytes32 internal constant METADATA_ADMIN_ROLE = keccak256("METADATA_ADMIN_ROLE");
string private _contractURI;
/**
* Deploy contract.
*/
constructor() ERC1155Metadata("", "") {}
/**
* Initialize the contract.
* @param owner Owner address.
* @param tokenName Token name.
* @param tokenBaseURI Base URI for token metadata.
* @param tokenContractURI Contract URI for token metadata.
* @dev This should be called immediately after deployment.
*/
function _initialize(
address owner,
string memory tokenName,
string memory tokenBaseURI,
string memory tokenContractURI
)
internal
{
name = tokenName;
baseURI = tokenBaseURI;
_contractURI = tokenContractURI;
_grantRole(DEFAULT_ADMIN_ROLE, owner);
_grantRole(ROYALTY_ADMIN_ROLE, owner);
_grantRole(METADATA_ADMIN_ROLE, owner);
}
//
// Metadata
//
/**
* Update the base URI of token's URI.
* @param tokenBaseURI New base URI of token's URI
*/
function setBaseMetadataURI(string memory tokenBaseURI) external onlyRole(METADATA_ADMIN_ROLE) {
_setBaseMetadataURI(tokenBaseURI);
}
/**
* Update the name of the contract.
* @param tokenName New contract name
*/
function setContractName(string memory tokenName) external onlyRole(METADATA_ADMIN_ROLE) {
_setContractName(tokenName);
}
/**
* Update the contract URI of token's URI.
* @param tokenContractURI New contract URI of token's URI
* @notice Refer to https://docs.opensea.io/docs/contract-level-metadata
*/
function setContractURI(string memory tokenContractURI) external onlyRole(METADATA_ADMIN_ROLE) {
_contractURI = tokenContractURI;
}
//
// Burn
//
/**
* Allows the owner of the token to burn their tokens.
* @param tokenId Id of token to burn
* @param amount Amount of tokens to burn
*/
function burn(uint256 tokenId, uint256 amount) public virtual {
_burn(msg.sender, tokenId, amount);
}
/**
* Burn tokens of given token id for each (tokenIds[i], amounts[i]) pair.
* @param tokenIds Array of token ids to burn
* @param amounts Array of the amount to be burned
*/
function batchBurn(uint256[] memory tokenIds, uint256[] memory amounts) public virtual {
_batchBurn(msg.sender, tokenIds, amounts);
}
function burnFrom(address from, uint256 tokenId, uint256 amount) public virtual onlyRole(DEFAULT_ADMIN_ROLE){
_burn(from, tokenId, amount);
}
//
// Views
//
/**
* Get the contract URI of token's URI.
* @return Contract URI of token's URI
* @notice Refer to https://docs.opensea.io/docs/contract-level-metadata
*/
function contractURI() public view returns (string memory) {
return _contractURI;
}
/**
* Check interface support.
* @param interfaceId Interface id
* @return True if supported
*/
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override (ERC1155Supply, ERC1155Metadata, ERC2981Controlled)
returns (bool)
{
return ERC1155Supply.supportsInterface(interfaceId) || ERC1155Metadata.supportsInterface(interfaceId)
|| ERC2981Controlled.supportsInterface(interfaceId) || super.supportsInterface(interfaceId);
}
}{
"evmVersion": "paris",
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenBaseURI","type":"string"},{"internalType":"string","name":"tokenContractURI","type":"string"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidArrayLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","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":"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":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":"_amounts","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":"_amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_uri","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"batchBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"batchBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"string","name":"tokenBaseURI","type":"string"}],"name":"setBaseMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenName","type":"string"}],"name":"setContractName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenContractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","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":"uint256","name":"","type":"uint256"}],"name":"tokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506040516158f63803806158f683398181016040528101906100329190610574565b604051806020016040528060008152506040518060200160405280600081525081600590816100619190610850565b5080600490816100719190610850565b5050506100868185858561008f60201b60201c565b50505050610922565b826005908161009e9190610850565b5081600490816100ae9190610850565b5080600a90816100be9190610850565b506100d26000801b8561013860201b60201c565b6101027f6db4061a20ca83a3be756ee172bd37a029093ac5afe4ce968c6d5435b43cb0118561013860201b60201c565b6101327fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a58561013860201b60201c565b50505050565b610148828261017260201b60201c565b61016d816009600085815260200190815260200160002061025f60201b90919060201c565b505050565b610182828261029560201b60201c565b61025b5760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061020061030060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600061028d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61030860201b60201c565b905092915050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600061031a838361037e60201b60201c565b610373578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050610378565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610408826103bf565b810181811067ffffffffffffffff82111715610427576104266103d0565b5b80604052505050565b600061043a6103a1565b905061044682826103ff565b919050565b600067ffffffffffffffff821115610466576104656103d0565b5b61046f826103bf565b9050602081019050919050565b60005b8381101561049a57808201518184015260208101905061047f565b60008484015250505050565b60006104b96104b48461044b565b610430565b9050828152602081018484840111156104d5576104d46103ba565b5b6104e084828561047c565b509392505050565b600082601f8301126104fd576104fc6103b5565b5b815161050d8482602086016104a6565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061054182610516565b9050919050565b61055181610536565b811461055c57600080fd5b50565b60008151905061056e81610548565b92915050565b6000806000806080858703121561058e5761058d6103ab565b5b600085015167ffffffffffffffff8111156105ac576105ab6103b0565b5b6105b8878288016104e8565b945050602085015167ffffffffffffffff8111156105d9576105d86103b0565b5b6105e5878288016104e8565b935050604085015167ffffffffffffffff811115610606576106056103b0565b5b610612878288016104e8565b92505060606106238782880161055f565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061068157607f821691505b6020821081036106945761069361063a565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026106fc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826106bf565b61070686836106bf565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061074d6107486107438461071e565b610728565b61071e565b9050919050565b6000819050919050565b61076783610732565b61077b61077382610754565b8484546106cc565b825550505050565b600090565b610790610783565b61079b81848461075e565b505050565b5b818110156107bf576107b4600082610788565b6001810190506107a1565b5050565b601f821115610804576107d58161069a565b6107de846106af565b810160208510156107ed578190505b6108016107f9856106af565b8301826107a0565b50505b505050565b600082821c905092915050565b600061082760001984600802610809565b1980831691505092915050565b60006108408383610816565b9150826002028217905092915050565b6108598261062f565b67ffffffffffffffff811115610872576108716103d0565b5b61087c8254610669565b6108878282856107c3565b600060209050601f8311600181146108ba57600084156108a8578287015190505b6108b28582610834565b86555061091a565b601f1984166108c88661069a565b60005b828110156108f0578489015182556001820191506020850194506020810190506108cb565b8683101561090d5784890151610909601f891682610816565b8355505b6001600288020188555050505b505050505050565b614fc5806109316000396000f3fe608060405234801561001057600080fd5b50600436106101fa5760003560e01c80635944c7531161011a578063a22cb465116100ad578063d547741f1161007c578063d547741f146105e0578063e8a3d485146105fc578063e985e9c51461061a578063f242432a1461064a578063f6eb127a14610666576101fa565b8063a22cb4651461055c578063b390c0ab14610578578063b48ab8b614610594578063ca15c873146105b0576101fa565b80639010d07c116100e95780639010d07c146104c257806391d14854146104f2578063938e3d7b14610522578063a217fddf1461053e576101fa565b80635944c753146104505780636c0360eb1461046c578063731133e91461048a5780637e518ec8146104a6576101fa565b806320ec271b116101925780632eb2c2d6116101615780632eb2c2d6146103cc5780632f2ff15d146103e857806336568abe146104045780634e1273f414610420576101fa565b806320ec271b1461031f578063248a9ca31461033b5780632693ebf21461036b5780632a55205a1461039b576101fa565b80630b5ee006116101ce5780630b5ee006146102995780630e89341c146102b5578063124d91e5146102e557806318160ddd14610301576101fa565b8062fdd58e146101ff57806301ffc9a71461022f57806304634d8d1461025f57806306fdde031461027b575b600080fd5b610219600480360381019061021491906130af565b610682565b60405161022691906130fe565b60405180910390f35b61024960048036038101906102449190613171565b6106dc565b60405161025691906131b9565b60405180910390f35b61027960048036038101906102749190613218565b61071e565b005b610283610757565b60405161029091906132e8565b60405180910390f35b6102b360048036038101906102ae919061343f565b6107e5565b005b6102cf60048036038101906102ca9190613488565b61081c565b6040516102dc91906132e8565b60405180910390f35b6102ff60048036038101906102fa91906134b5565b610850565b005b61030961086e565b60405161031691906130fe565b60405180910390f35b610339600480360381019061033491906135d0565b610874565b005b6103556004803603810190610350919061367e565b610883565b60405161036291906136ba565b60405180910390f35b61038560048036038101906103809190613488565b6108a3565b60405161039291906130fe565b60405180910390f35b6103b560048036038101906103b091906136d5565b6108bb565b6040516103c3929190613724565b60405180910390f35b6103e660048036038101906103e191906137ee565b610aa5565b005b61040260048036038101906103fd91906138bd565b610bb4565b005b61041e600480360381019061041991906138bd565b610bd5565b005b61043a600480360381019061043591906139c0565b610c58565b6040516104479190613af6565b60405180910390f35b61046a60048036038101906104659190613b18565b610db3565b005b610474610dee565b60405161048191906132e8565b60405180910390f35b6104a4600480360381019061049f9190613b6b565b610e7c565b005b6104c060048036038101906104bb919061343f565b610e9c565b005b6104dc60048036038101906104d79190613bee565b610ed3565b6040516104e99190613c2e565b60405180910390f35b61050c600480360381019061050791906138bd565b610f02565b60405161051991906131b9565b60405180910390f35b61053c6004803603810190610537919061343f565b610f6d565b005b610546610fab565b60405161055391906136ba565b60405180910390f35b61057660048036038101906105719190613c75565b610fb2565b005b610592600480360381019061058d91906136d5565b6110af565b005b6105ae60048036038101906105a99190613cb5565b6110be565b005b6105ca60048036038101906105c5919061367e565b611170565b6040516105d791906130fe565b60405180910390f35b6105fa60048036038101906105f591906138bd565b611194565b005b6106046111b5565b60405161061191906132e8565b60405180910390f35b610634600480360381019061062f9190613d70565b611247565b60405161064191906131b9565b60405180910390f35b610664600480360381019061065f9190613db0565b6112db565b005b610680600480360381019061067b9190613e47565b6113ea565b005b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60006106e78261149a565b806106f757506106f682611514565b5b80610707575061070682611595565b5b80610717575061071682611595565b5b9050919050565b7f6db4061a20ca83a3be756ee172bd37a029093ac5afe4ce968c6d5435b43cb01161074881611610565b6107528383611624565b505050565b6005805461076490613f01565b80601f016020809104026020016040519081016040528092919081815260200182805461079090613f01565b80156107dd5780601f106107b2576101008083540402835291602001916107dd565b820191906000526020600020905b8154815290600101906020018083116107c057829003601f168201915b505050505081565b7fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a561080f81611610565b610818826117b9565b5050565b60606004610829836117cc565b60405160200161083a929190614052565b6040516020818303038152906040529050919050565b6000801b61085d81611610565b610868848484611954565b50505050565b60025481565b61087f338383611a81565b5050565b600060086000838152602001908152602001600020600101549050919050565b60036020528060005260406000206000915090505481565b6000806000600760008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610a505760066040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610a5a611c9a565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610a8691906140b0565b610a909190614121565b90508160000151819350935050509250929050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610ae55750610ae48533611247565b5b610b24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1b906141c4565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8a90614256565b60405180910390fd5b610b9f85858585611ca4565b610bad858585855a86611ec0565b5050505050565b610bbd82610883565b610bc681611610565b610bd08383611fff565b505050565b610bdd612033565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c41906142e8565b60405180910390fd5b610c54828261203b565b5050565b60608151835114610c9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c959061437a565b60405180910390fd5b6000835167ffffffffffffffff811115610cbb57610cba613314565b5b604051908082528060200260200182016040528015610ce95781602001602082028036833780820191505090505b50905060005b8451811015610da857600080868381518110610d0e57610d0d61439a565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858381518110610d6557610d6461439a565b5b6020026020010151815260200190815260200160002054828281518110610d8f57610d8e61439a565b5b6020026020010181815250508080600101915050610cef565b508091505092915050565b7f6db4061a20ca83a3be756ee172bd37a029093ac5afe4ce968c6d5435b43cb011610ddd81611610565b610de884848461206f565b50505050565b60048054610dfb90613f01565b80601f0160208091040260200160405190810160405280929190818152602001828054610e2790613f01565b8015610e745780601f10610e4957610100808354040283529160200191610e74565b820191906000526020600020905b815481529060010190602001808311610e5757829003601f168201915b505050505081565b6000801b610e8981611610565b610e9585858585612216565b5050505050565b7fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a5610ec681611610565b610ecf82612353565b5050565b6000610efa826009600086815260200190815260200160002061236690919063ffffffff16565b905092915050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a5610f9781611610565b81600a9081610fa69190614560565b505050565b6000801b81565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110a391906131b9565b60405180910390a35050565b6110ba338383611954565b5050565b6000801b6110cb81611610565b825184511461110f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111069061467e565b60405180910390fd5b60005b84518110156111685761115b868683815181106111325761113161439a565b5b602002602001015186848151811061114d5761114c61439a565b5b602002602001015186612216565b8080600101915050611112565b505050505050565b600061118d60096000848152602001908152602001600020612380565b9050919050565b61119d82610883565b6111a681611610565b6111b0838361203b565b505050565b6060600a80546111c490613f01565b80601f01602080910402602001604051908101604052809291908181526020018280546111f090613f01565b801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061131b575061131a8533611247565b5b61135a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135190614710565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036113c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c0906147a2565b60405180910390fd5b6113d585858585612395565b6113e3858585855a866124e5565b5050505050565b6000801b6113f781611610565b815183511461143b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114329061480e565b60405180910390fd5b60005b8351811015611493576114868585838151811061145e5761145d61439a565b5b60200260200101518584815181106114795761147861439a565b5b6020026020010151611954565b808060010191505061143e565b5050505050565b6000817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f3e85e62f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061150d575061150c82612624565b5b9050919050565b60007f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036115845760019050611590565b61158d8261149a565b90505b919050565b60006115a0826126a5565b806115b057506115af8261271f565b5b806115f95750817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061160957506116088261271f565b5b9050919050565b6116218161161c612033565b612799565b50565b61162c611c9a565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111561168a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611681906148a0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f09061490c565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b80600590816117c89190614560565b5050565b606060008203611813576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061194f565b600082905060005b6000821461184557808061182e9061492c565b915050600a8261183e9190614121565b915061181b565b60008167ffffffffffffffff81111561186157611860613314565b5b6040519080825280601f01601f1916602001820160405280156118935781602001600182028036833780820191505090505b50905060008290505b60008614611947576001816118b19190614974565b90506000600a80886118c39190614121565b6118cd91906140b0565b876118d89190614974565b60306118e491906149b5565b905060008160f81b9050808484815181106119025761190161439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8861193e9190614121565b9750505061189c565b819450505050505b919050565b80600260008282546119669190614974565b92505081905550806003600084815260200190815260200160002060008282546119909190614974565b92505081905550806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008282546119f69190614974565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051611a749291906149ea565b60405180910390a4505050565b60008251905081518114611ac1576040517f9d89020a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b82811015611bfa57838181518110611ae057611adf61439a565b5b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878481518110611b3b57611b3a61439a565b5b602002602001015181526020019081526020016000206000828254611b609190614974565b92505081905550838181518110611b7a57611b7961439a565b5b602002602001015160036000878481518110611b9957611b9861439a565b5b602002602001015181526020019081526020016000206000828254611bbe9190614974565b92505081905550838181518110611bd857611bd761439a565b5b602002602001015182611beb9190614a13565b91508080600101915050611ac5565b508060026000828254611c0d9190614974565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611c8b929190614a47565b60405180910390a45050505050565b6000612710905090565b8051825114611ce8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdf90614af0565b60405180910390fd5b60008251905060005b81811015611e3a57828181518110611d0c57611d0b61439a565b5b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000868481518110611d6757611d6661439a565b5b602002602001015181526020019081526020016000206000828254611d8c9190614974565b92505081905550828181518110611da657611da561439a565b5b60200260200101516000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000868481518110611e0157611e0061439a565b5b602002602001015181526020019081526020016000206000828254611e269190614a13565b925050819055508080600101915050611cf1565b508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611eb1929190614a47565b60405180910390a45050505050565b611edf8573ffffffffffffffffffffffffffffffffffffffff1661281e565b15611ff75760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401611f28959493929190614b65565b60206040518083038160008887f1158015611f47573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611f6c9190614be2565b905063bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611ff5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fec90614c81565b60405180910390fd5b505b505050505050565b6120098282612863565b61202e816009600085815260200190815260200160002061294490919063ffffffff16565b505050565b600033905090565b6120458282612974565b61206a8160096000858152602001908152602001600020612a5690919063ffffffff16565b505050565b612077611c9a565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156120d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120cc906148a0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b90614ced565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff168152506007600085815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b81600260008282546122289190614a13565b92505081905550816003600085815260200190815260200160002060008282546122529190614a13565b92505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002060008282546122b89190614a13565b925050819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6286866040516123369291906149ea565b60405180910390a461234d60008585855a866124e5565b50505050565b80600490816123629190614560565b5050565b60006123758360000183612a86565b60001c905092915050565b600061238e82600001612ab1565b9050919050565b806000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008282546123f49190614974565b92505081905550806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020600082825461245a9190614a13565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6285856040516124d79291906149ea565b60405180910390a450505050565b6125048573ffffffffffffffffffffffffffffffffffffffff1661281e565b1561261c5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b815260040161254d959493929190614d0d565b60206040518083038160008887f115801561256c573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906125919190614be2565b905063f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461261a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261190614dd9565b60405180910390fd5b505b505050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361269457600190506126a0565b61269d82612ac2565b90505b919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612718575061271782612b13565b5b9050919050565b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612792575061279182612b7d565b5b9050919050565b6127a38282610f02565b61281a576127b081612bf7565b6127be8360001c6020612c24565b6040516020016127cf929190614e91565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161281191906132e8565b60405180910390fd5b5050565b600080823f90506000801b811415801561285b57507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b8114155b915050919050565b61286d8282610f02565b6129405760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506128e5612033565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600061296c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612e60565b905092915050565b61297e8282610f02565b15612a525760006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506129f7612033565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000612a7e836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612ed0565b905092915050565b6000826000018281548110612a9e57612a9d61439a565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b60006301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612bf05750612bef826126a5565b5b9050919050565b6060612c1d8273ffffffffffffffffffffffffffffffffffffffff16601460ff16612c24565b9050919050565b606060006002836002612c3791906140b0565b612c419190614a13565b67ffffffffffffffff811115612c5a57612c59613314565b5b6040519080825280601f01601f191660200182016040528015612c8c5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612cc457612cc361439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612d2857612d2761439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612d6891906140b0565b612d729190614a13565b90505b6001811115612e12577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612db457612db361439a565b5b1a60f81b828281518110612dcb57612dca61439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612e0b90614ecb565b9050612d75565b5060008414612e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e4d90614f40565b60405180910390fd5b8091505092915050565b6000612e6c8383612fe4565b612ec5578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612eca565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114612fd8576000600182612f029190614974565b9050600060018660000180549050612f1a9190614974565b9050818114612f89576000866000018281548110612f3b57612f3a61439a565b5b9060005260206000200154905080876000018481548110612f5f57612f5e61439a565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612f9d57612f9c614f60565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612fde565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130468261301b565b9050919050565b6130568161303b565b811461306157600080fd5b50565b6000813590506130738161304d565b92915050565b6000819050919050565b61308c81613079565b811461309757600080fd5b50565b6000813590506130a981613083565b92915050565b600080604083850312156130c6576130c5613011565b5b60006130d485828601613064565b92505060206130e58582860161309a565b9150509250929050565b6130f881613079565b82525050565b600060208201905061311360008301846130ef565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61314e81613119565b811461315957600080fd5b50565b60008135905061316b81613145565b92915050565b60006020828403121561318757613186613011565b5b60006131958482850161315c565b91505092915050565b60008115159050919050565b6131b38161319e565b82525050565b60006020820190506131ce60008301846131aa565b92915050565b60006bffffffffffffffffffffffff82169050919050565b6131f5816131d4565b811461320057600080fd5b50565b600081359050613212816131ec565b92915050565b6000806040838503121561322f5761322e613011565b5b600061323d85828601613064565b925050602061324e85828601613203565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613292578082015181840152602081019050613277565b60008484015250505050565b6000601f19601f8301169050919050565b60006132ba82613258565b6132c48185613263565b93506132d4818560208601613274565b6132dd8161329e565b840191505092915050565b6000602082019050818103600083015261330281846132af565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61334c8261329e565b810181811067ffffffffffffffff8211171561336b5761336a613314565b5b80604052505050565b600061337e613007565b905061338a8282613343565b919050565b600067ffffffffffffffff8211156133aa576133a9613314565b5b6133b38261329e565b9050602081019050919050565b82818337600083830152505050565b60006133e26133dd8461338f565b613374565b9050828152602081018484840111156133fe576133fd61330f565b5b6134098482856133c0565b509392505050565b600082601f8301126134265761342561330a565b5b81356134368482602086016133cf565b91505092915050565b60006020828403121561345557613454613011565b5b600082013567ffffffffffffffff81111561347357613472613016565b5b61347f84828501613411565b91505092915050565b60006020828403121561349e5761349d613011565b5b60006134ac8482850161309a565b91505092915050565b6000806000606084860312156134ce576134cd613011565b5b60006134dc86828701613064565b93505060206134ed8682870161309a565b92505060406134fe8682870161309a565b9150509250925092565b600067ffffffffffffffff82111561352357613522613314565b5b602082029050602081019050919050565b600080fd5b600061354c61354784613508565b613374565b9050808382526020820190506020840283018581111561356f5761356e613534565b5b835b818110156135985780613584888261309a565b845260208401935050602081019050613571565b5050509392505050565b600082601f8301126135b7576135b661330a565b5b81356135c7848260208601613539565b91505092915050565b600080604083850312156135e7576135e6613011565b5b600083013567ffffffffffffffff81111561360557613604613016565b5b613611858286016135a2565b925050602083013567ffffffffffffffff81111561363257613631613016565b5b61363e858286016135a2565b9150509250929050565b6000819050919050565b61365b81613648565b811461366657600080fd5b50565b60008135905061367881613652565b92915050565b60006020828403121561369457613693613011565b5b60006136a284828501613669565b91505092915050565b6136b481613648565b82525050565b60006020820190506136cf60008301846136ab565b92915050565b600080604083850312156136ec576136eb613011565b5b60006136fa8582860161309a565b925050602061370b8582860161309a565b9150509250929050565b61371e8161303b565b82525050565b60006040820190506137396000830185613715565b61374660208301846130ef565b9392505050565b600067ffffffffffffffff82111561376857613767613314565b5b6137718261329e565b9050602081019050919050565b600061379161378c8461374d565b613374565b9050828152602081018484840111156137ad576137ac61330f565b5b6137b88482856133c0565b509392505050565b600082601f8301126137d5576137d461330a565b5b81356137e584826020860161377e565b91505092915050565b600080600080600060a0868803121561380a57613809613011565b5b600061381888828901613064565b955050602061382988828901613064565b945050604086013567ffffffffffffffff81111561384a57613849613016565b5b613856888289016135a2565b935050606086013567ffffffffffffffff81111561387757613876613016565b5b613883888289016135a2565b925050608086013567ffffffffffffffff8111156138a4576138a3613016565b5b6138b0888289016137c0565b9150509295509295909350565b600080604083850312156138d4576138d3613011565b5b60006138e285828601613669565b92505060206138f385828601613064565b9150509250929050565b600067ffffffffffffffff82111561391857613917613314565b5b602082029050602081019050919050565b600061393c613937846138fd565b613374565b9050808382526020820190506020840283018581111561395f5761395e613534565b5b835b8181101561398857806139748882613064565b845260208401935050602081019050613961565b5050509392505050565b600082601f8301126139a7576139a661330a565b5b81356139b7848260208601613929565b91505092915050565b600080604083850312156139d7576139d6613011565b5b600083013567ffffffffffffffff8111156139f5576139f4613016565b5b613a0185828601613992565b925050602083013567ffffffffffffffff811115613a2257613a21613016565b5b613a2e858286016135a2565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613a6d81613079565b82525050565b6000613a7f8383613a64565b60208301905092915050565b6000602082019050919050565b6000613aa382613a38565b613aad8185613a43565b9350613ab883613a54565b8060005b83811015613ae9578151613ad08882613a73565b9750613adb83613a8b565b925050600181019050613abc565b5085935050505092915050565b60006020820190508181036000830152613b108184613a98565b905092915050565b600080600060608486031215613b3157613b30613011565b5b6000613b3f8682870161309a565b9350506020613b5086828701613064565b9250506040613b6186828701613203565b9150509250925092565b60008060008060808587031215613b8557613b84613011565b5b6000613b9387828801613064565b9450506020613ba48782880161309a565b9350506040613bb58782880161309a565b925050606085013567ffffffffffffffff811115613bd657613bd5613016565b5b613be2878288016137c0565b91505092959194509250565b60008060408385031215613c0557613c04613011565b5b6000613c1385828601613669565b9250506020613c248582860161309a565b9150509250929050565b6000602082019050613c436000830184613715565b92915050565b613c528161319e565b8114613c5d57600080fd5b50565b600081359050613c6f81613c49565b92915050565b60008060408385031215613c8c57613c8b613011565b5b6000613c9a85828601613064565b9250506020613cab85828601613c60565b9150509250929050565b60008060008060808587031215613ccf57613cce613011565b5b6000613cdd87828801613064565b945050602085013567ffffffffffffffff811115613cfe57613cfd613016565b5b613d0a878288016135a2565b935050604085013567ffffffffffffffff811115613d2b57613d2a613016565b5b613d37878288016135a2565b925050606085013567ffffffffffffffff811115613d5857613d57613016565b5b613d64878288016137c0565b91505092959194509250565b60008060408385031215613d8757613d86613011565b5b6000613d9585828601613064565b9250506020613da685828601613064565b9150509250929050565b600080600080600060a08688031215613dcc57613dcb613011565b5b6000613dda88828901613064565b9550506020613deb88828901613064565b9450506040613dfc8882890161309a565b9350506060613e0d8882890161309a565b925050608086013567ffffffffffffffff811115613e2e57613e2d613016565b5b613e3a888289016137c0565b9150509295509295909350565b600080600060608486031215613e6057613e5f613011565b5b6000613e6e86828701613064565b935050602084013567ffffffffffffffff811115613e8f57613e8e613016565b5b613e9b868287016135a2565b925050604084013567ffffffffffffffff811115613ebc57613ebb613016565b5b613ec8868287016135a2565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f1957607f821691505b602082108103613f2c57613f2b613ed2565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b60008154613f5f81613f01565b613f698186613f32565b94506001821660008114613f845760018114613f9957613fcc565b60ff1983168652811515820286019350613fcc565b613fa285613f3d565b60005b83811015613fc457815481890152600182019150602081019050613fa5565b838801955050505b50505092915050565b6000613fe082613258565b613fea8185613f32565b9350613ffa818560208601613274565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061403c600583613f32565b915061404782614006565b600582019050919050565b600061405e8285613f52565b915061406a8284613fd5565b91506140758261402f565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006140bb82613079565b91506140c683613079565b92508282026140d481613079565b915082820484148315176140eb576140ea614081565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061412c82613079565b915061413783613079565b925082614147576141466140f2565b5b828204905092915050565b7f45524331313535237361666542617463685472616e7366657246726f6d3a204960008201527f4e56414c49445f4f50455241544f520000000000000000000000000000000000602082015250565b60006141ae602f83613263565b91506141b982614152565b604082019050919050565b600060208201905081810360008301526141dd816141a1565b9050919050565b7f45524331313535237361666542617463685472616e7366657246726f6d3a204960008201527f4e56414c49445f524543495049454e5400000000000000000000000000000000602082015250565b6000614240603083613263565b915061424b826141e4565b604082019050919050565b6000602082019050818103600083015261426f81614233565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006142d2602f83613263565b91506142dd82614276565b604082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b7f455243313135352362616c616e63654f6642617463683a20494e56414c49445f60008201527f41525241595f4c454e4754480000000000000000000000000000000000000000602082015250565b6000614364602c83613263565b915061436f82614308565b604082019050919050565b6000602082019050818103600083015261439381614357565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020601f8301049050919050565b600082821b905092915050565b6000600883026144167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826143d9565b61442086836143d9565b95508019841693508086168417925050509392505050565b6000819050919050565b600061445d61445861445384613079565b614438565b613079565b9050919050565b6000819050919050565b61447783614442565b61448b61448382614464565b8484546143e6565b825550505050565b600090565b6144a0614493565b6144ab81848461446e565b505050565b5b818110156144cf576144c4600082614498565b6001810190506144b1565b5050565b601f821115614514576144e581613f3d565b6144ee846143c9565b810160208510156144fd578190505b614511614509856143c9565b8301826144b0565b50505b505050565b600082821c905092915050565b600061453760001984600802614519565b1980831691505092915050565b60006145508383614526565b9150826002028217905092915050565b61456982613258565b67ffffffffffffffff81111561458257614581613314565b5b61458c8254613f01565b6145978282856144d3565b600060209050601f8311600181146145ca57600084156145b8578287015190505b6145c28582614544565b86555061462a565b601f1984166145d886613f3d565b60005b82811015614600578489015182556001820191506020850194506020810190506145db565b8683101561461d5784890151614619601f891682614526565b8355505b6001600288020188555050505b505050505050565b7f49447320616e6420616d6f756e7473206c656e677468206d69736d6174636800600082015250565b6000614668601f83613263565b915061467382614632565b602082019050919050565b600060208201905081810360008301526146978161465b565b9050919050565b7f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008201527f445f4f50455241544f5200000000000000000000000000000000000000000000602082015250565b60006146fa602a83613263565b91506147058261469e565b604082019050919050565b60006020820190508181036000830152614729816146ed565b9050919050565b7f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008201527f445f524543495049454e54000000000000000000000000000000000000000000602082015250565b600061478c602b83613263565b915061479782614730565b604082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f4d69736d617463686564206172726179206c656e677468730000000000000000600082015250565b60006147f8601883613263565b9150614803826147c2565b602082019050919050565b60006020820190508181036000830152614827816147eb565b9050919050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b600061488a602a83613263565b91506148958261482e565b604082019050919050565b600060208201905081810360008301526148b98161487d565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b60006148f6601983613263565b9150614901826148c0565b602082019050919050565b60006020820190508181036000830152614925816148e9565b9050919050565b600061493782613079565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361496957614968614081565b5b600182019050919050565b600061497f82613079565b915061498a83613079565b92508282039050818111156149a2576149a1614081565b5b92915050565b600060ff82169050919050565b60006149c0826149a8565b91506149cb836149a8565b9250828201905060ff8111156149e4576149e3614081565b5b92915050565b60006040820190506149ff60008301856130ef565b614a0c60208301846130ef565b9392505050565b6000614a1e82613079565b9150614a2983613079565b9250828201905080821115614a4157614a40614081565b5b92915050565b60006040820190508181036000830152614a618185613a98565b90508181036020830152614a758184613a98565b90509392505050565b7f45524331313535235f7361666542617463685472616e7366657246726f6d3a2060008201527f494e56414c49445f4152524159535f4c454e4754480000000000000000000000602082015250565b6000614ada603583613263565b9150614ae582614a7e565b604082019050919050565b60006020820190508181036000830152614b0981614acd565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614b3782614b10565b614b418185614b1b565b9350614b51818560208601613274565b614b5a8161329e565b840191505092915050565b600060a082019050614b7a6000830188613715565b614b876020830187613715565b8181036040830152614b998186613a98565b90508181036060830152614bad8185613a98565b90508181036080830152614bc18184614b2c565b90509695505050505050565b600081519050614bdc81613145565b92915050565b600060208284031215614bf857614bf7613011565b5b6000614c0684828501614bcd565b91505092915050565b7f45524331313535235f63616c6c6f6e455243313135354261746368526563656960008201527f7665643a20494e56414c49445f4f4e5f524543454956455f4d45535341474500602082015250565b6000614c6b603f83613263565b9150614c7682614c0f565b604082019050919050565b60006020820190508181036000830152614c9a81614c5e565b9050919050565b7f455243323938313a20496e76616c696420706172616d65746572730000000000600082015250565b6000614cd7601b83613263565b9150614ce282614ca1565b602082019050919050565b60006020820190508181036000830152614d0681614cca565b9050919050565b600060a082019050614d226000830188613715565b614d2f6020830187613715565b614d3c60408301866130ef565b614d4960608301856130ef565b8181036080830152614d5b8184614b2c565b90509695505050505050565b7f45524331313535235f63616c6c6f6e4552433131353552656365697665643a2060008201527f494e56414c49445f4f4e5f524543454956455f4d455353414745000000000000602082015250565b6000614dc3603a83613263565b9150614dce82614d67565b604082019050919050565b60006020820190508181036000830152614df281614db6565b9050919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000614e2f601783613f32565b9150614e3a82614df9565b601782019050919050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614e7b601183613f32565b9150614e8682614e45565b601182019050919050565b6000614e9c82614e22565b9150614ea88285613fd5565b9150614eb382614e6e565b9150614ebf8284613fd5565b91508190509392505050565b6000614ed682613079565b915060008203614ee957614ee8614081565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614f2a602083613263565b9150614f3582614ef4565b602082019050919050565b60006020820190508181036000830152614f5981614f1d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220a3fac6cff69fece6bd1585cbadd23837cb211d7ffa73742e5cfe16a1651a440564736f6c634300081c0033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000c67fea70aac3d0be93ae032659dc710048fdab5b000000000000000000000000000000000000000000000000000000000000000c424f4f53544552205041434b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101fa5760003560e01c80635944c7531161011a578063a22cb465116100ad578063d547741f1161007c578063d547741f146105e0578063e8a3d485146105fc578063e985e9c51461061a578063f242432a1461064a578063f6eb127a14610666576101fa565b8063a22cb4651461055c578063b390c0ab14610578578063b48ab8b614610594578063ca15c873146105b0576101fa565b80639010d07c116100e95780639010d07c146104c257806391d14854146104f2578063938e3d7b14610522578063a217fddf1461053e576101fa565b80635944c753146104505780636c0360eb1461046c578063731133e91461048a5780637e518ec8146104a6576101fa565b806320ec271b116101925780632eb2c2d6116101615780632eb2c2d6146103cc5780632f2ff15d146103e857806336568abe146104045780634e1273f414610420576101fa565b806320ec271b1461031f578063248a9ca31461033b5780632693ebf21461036b5780632a55205a1461039b576101fa565b80630b5ee006116101ce5780630b5ee006146102995780630e89341c146102b5578063124d91e5146102e557806318160ddd14610301576101fa565b8062fdd58e146101ff57806301ffc9a71461022f57806304634d8d1461025f57806306fdde031461027b575b600080fd5b610219600480360381019061021491906130af565b610682565b60405161022691906130fe565b60405180910390f35b61024960048036038101906102449190613171565b6106dc565b60405161025691906131b9565b60405180910390f35b61027960048036038101906102749190613218565b61071e565b005b610283610757565b60405161029091906132e8565b60405180910390f35b6102b360048036038101906102ae919061343f565b6107e5565b005b6102cf60048036038101906102ca9190613488565b61081c565b6040516102dc91906132e8565b60405180910390f35b6102ff60048036038101906102fa91906134b5565b610850565b005b61030961086e565b60405161031691906130fe565b60405180910390f35b610339600480360381019061033491906135d0565b610874565b005b6103556004803603810190610350919061367e565b610883565b60405161036291906136ba565b60405180910390f35b61038560048036038101906103809190613488565b6108a3565b60405161039291906130fe565b60405180910390f35b6103b560048036038101906103b091906136d5565b6108bb565b6040516103c3929190613724565b60405180910390f35b6103e660048036038101906103e191906137ee565b610aa5565b005b61040260048036038101906103fd91906138bd565b610bb4565b005b61041e600480360381019061041991906138bd565b610bd5565b005b61043a600480360381019061043591906139c0565b610c58565b6040516104479190613af6565b60405180910390f35b61046a60048036038101906104659190613b18565b610db3565b005b610474610dee565b60405161048191906132e8565b60405180910390f35b6104a4600480360381019061049f9190613b6b565b610e7c565b005b6104c060048036038101906104bb919061343f565b610e9c565b005b6104dc60048036038101906104d79190613bee565b610ed3565b6040516104e99190613c2e565b60405180910390f35b61050c600480360381019061050791906138bd565b610f02565b60405161051991906131b9565b60405180910390f35b61053c6004803603810190610537919061343f565b610f6d565b005b610546610fab565b60405161055391906136ba565b60405180910390f35b61057660048036038101906105719190613c75565b610fb2565b005b610592600480360381019061058d91906136d5565b6110af565b005b6105ae60048036038101906105a99190613cb5565b6110be565b005b6105ca60048036038101906105c5919061367e565b611170565b6040516105d791906130fe565b60405180910390f35b6105fa60048036038101906105f591906138bd565b611194565b005b6106046111b5565b60405161061191906132e8565b60405180910390f35b610634600480360381019061062f9190613d70565b611247565b60405161064191906131b9565b60405180910390f35b610664600480360381019061065f9190613db0565b6112db565b005b610680600480360381019061067b9190613e47565b6113ea565b005b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60006106e78261149a565b806106f757506106f682611514565b5b80610707575061070682611595565b5b80610717575061071682611595565b5b9050919050565b7f6db4061a20ca83a3be756ee172bd37a029093ac5afe4ce968c6d5435b43cb01161074881611610565b6107528383611624565b505050565b6005805461076490613f01565b80601f016020809104026020016040519081016040528092919081815260200182805461079090613f01565b80156107dd5780601f106107b2576101008083540402835291602001916107dd565b820191906000526020600020905b8154815290600101906020018083116107c057829003601f168201915b505050505081565b7fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a561080f81611610565b610818826117b9565b5050565b60606004610829836117cc565b60405160200161083a929190614052565b6040516020818303038152906040529050919050565b6000801b61085d81611610565b610868848484611954565b50505050565b60025481565b61087f338383611a81565b5050565b600060086000838152602001908152602001600020600101549050919050565b60036020528060005260406000206000915090505481565b6000806000600760008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610a505760066040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000610a5a611c9a565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff1686610a8691906140b0565b610a909190614121565b90508160000151819350935050509250929050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610ae55750610ae48533611247565b5b610b24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1b906141c4565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610b93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b8a90614256565b60405180910390fd5b610b9f85858585611ca4565b610bad858585855a86611ec0565b5050505050565b610bbd82610883565b610bc681611610565b610bd08383611fff565b505050565b610bdd612033565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c41906142e8565b60405180910390fd5b610c54828261203b565b5050565b60608151835114610c9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c959061437a565b60405180910390fd5b6000835167ffffffffffffffff811115610cbb57610cba613314565b5b604051908082528060200260200182016040528015610ce95781602001602082028036833780820191505090505b50905060005b8451811015610da857600080868381518110610d0e57610d0d61439a565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858381518110610d6557610d6461439a565b5b6020026020010151815260200190815260200160002054828281518110610d8f57610d8e61439a565b5b6020026020010181815250508080600101915050610cef565b508091505092915050565b7f6db4061a20ca83a3be756ee172bd37a029093ac5afe4ce968c6d5435b43cb011610ddd81611610565b610de884848461206f565b50505050565b60048054610dfb90613f01565b80601f0160208091040260200160405190810160405280929190818152602001828054610e2790613f01565b8015610e745780601f10610e4957610100808354040283529160200191610e74565b820191906000526020600020905b815481529060010190602001808311610e5757829003601f168201915b505050505081565b6000801b610e8981611610565b610e9585858585612216565b5050505050565b7fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a5610ec681611610565b610ecf82612353565b5050565b6000610efa826009600086815260200190815260200160002061236690919063ffffffff16565b905092915050565b60006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b7fe02a0315b383857ac496e9d2b2546a699afaeb4e5e83a1fdef64376d0b74e5a5610f9781611610565b81600a9081610fa69190614560565b505050565b6000801b81565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110a391906131b9565b60405180910390a35050565b6110ba338383611954565b5050565b6000801b6110cb81611610565b825184511461110f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111069061467e565b60405180910390fd5b60005b84518110156111685761115b868683815181106111325761113161439a565b5b602002602001015186848151811061114d5761114c61439a565b5b602002602001015186612216565b8080600101915050611112565b505050505050565b600061118d60096000848152602001908152602001600020612380565b9050919050565b61119d82610883565b6111a681611610565b6111b0838361203b565b505050565b6060600a80546111c490613f01565b80601f01602080910402602001604051908101604052809291908181526020018280546111f090613f01565b801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061131b575061131a8533611247565b5b61135a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135190614710565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036113c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c0906147a2565b60405180910390fd5b6113d585858585612395565b6113e3858585855a866124e5565b5050505050565b6000801b6113f781611610565b815183511461143b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114329061480e565b60405180910390fd5b60005b8351811015611493576114868585838151811061145e5761145d61439a565b5b60200260200101518584815181106114795761147861439a565b5b6020026020010151611954565b808060010191505061143e565b5050505050565b6000817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f3e85e62f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061150d575061150c82612624565b5b9050919050565b60007f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036115845760019050611590565b61158d8261149a565b90505b919050565b60006115a0826126a5565b806115b057506115af8261271f565b5b806115f95750817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061160957506116088261271f565b5b9050919050565b6116218161161c612033565b612799565b50565b61162c611c9a565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111561168a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611681906148a0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036116f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f09061490c565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815250600660008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055509050505050565b80600590816117c89190614560565b5050565b606060008203611813576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061194f565b600082905060005b6000821461184557808061182e9061492c565b915050600a8261183e9190614121565b915061181b565b60008167ffffffffffffffff81111561186157611860613314565b5b6040519080825280601f01601f1916602001820160405280156118935781602001600182028036833780820191505090505b50905060008290505b60008614611947576001816118b19190614974565b90506000600a80886118c39190614121565b6118cd91906140b0565b876118d89190614974565b60306118e491906149b5565b905060008160f81b9050808484815181106119025761190161439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8861193e9190614121565b9750505061189c565b819450505050505b919050565b80600260008282546119669190614974565b92505081905550806003600084815260200190815260200160002060008282546119909190614974565b92505081905550806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008282546119f69190614974565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051611a749291906149ea565b60405180910390a4505050565b60008251905081518114611ac1576040517f9d89020a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b82811015611bfa57838181518110611ae057611adf61439a565b5b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878481518110611b3b57611b3a61439a565b5b602002602001015181526020019081526020016000206000828254611b609190614974565b92505081905550838181518110611b7a57611b7961439a565b5b602002602001015160036000878481518110611b9957611b9861439a565b5b602002602001015181526020019081526020016000206000828254611bbe9190614974565b92505081905550838181518110611bd857611bd761439a565b5b602002602001015182611beb9190614a13565b91508080600101915050611ac5565b508060026000828254611c0d9190614974565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611c8b929190614a47565b60405180910390a45050505050565b6000612710905090565b8051825114611ce8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdf90614af0565b60405180910390fd5b60008251905060005b81811015611e3a57828181518110611d0c57611d0b61439a565b5b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000868481518110611d6757611d6661439a565b5b602002602001015181526020019081526020016000206000828254611d8c9190614974565b92505081905550828181518110611da657611da561439a565b5b60200260200101516000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000868481518110611e0157611e0061439a565b5b602002602001015181526020019081526020016000206000828254611e269190614a13565b925050819055508080600101915050611cf1565b508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611eb1929190614a47565b60405180910390a45050505050565b611edf8573ffffffffffffffffffffffffffffffffffffffff1661281e565b15611ff75760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401611f28959493929190614b65565b60206040518083038160008887f1158015611f47573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611f6c9190614be2565b905063bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611ff5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fec90614c81565b60405180910390fd5b505b505050505050565b6120098282612863565b61202e816009600085815260200190815260200160002061294490919063ffffffff16565b505050565b600033905090565b6120458282612974565b61206a8160096000858152602001908152602001600020612a5690919063ffffffff16565b505050565b612077611c9a565b6bffffffffffffffffffffffff16816bffffffffffffffffffffffff1611156120d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120cc906148a0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213b90614ced565b60405180910390fd5b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff168152506007600085815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b81600260008282546122289190614a13565b92505081905550816003600085815260200190815260200160002060008282546122529190614a13565b92505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002060008282546122b89190614a13565b925050819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6286866040516123369291906149ea565b60405180910390a461234d60008585855a866124e5565b50505050565b80600490816123629190614560565b5050565b60006123758360000183612a86565b60001c905092915050565b600061238e82600001612ab1565b9050919050565b806000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008282546123f49190614974565b92505081905550806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020600082825461245a9190614a13565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6285856040516124d79291906149ea565b60405180910390a450505050565b6125048573ffffffffffffffffffffffffffffffffffffffff1661281e565b1561261c5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b815260040161254d959493929190614d0d565b60206040518083038160008887f115801561256c573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906125919190614be2565b905063f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461261a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261190614dd9565b60405180910390fd5b505b505050505050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361269457600190506126a0565b61269d82612ac2565b90505b919050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612718575061271782612b13565b5b9050919050565b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612792575061279182612b7d565b5b9050919050565b6127a38282610f02565b61281a576127b081612bf7565b6127be8360001c6020612c24565b6040516020016127cf929190614e91565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161281191906132e8565b60405180910390fd5b5050565b600080823f90506000801b811415801561285b57507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b8114155b915050919050565b61286d8282610f02565b6129405760016008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506128e5612033565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600061296c836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612e60565b905092915050565b61297e8282610f02565b15612a525760006008600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506129f7612033565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000612a7e836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612ed0565b905092915050565b6000826000018281548110612a9e57612a9d61439a565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b60006301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612bf05750612bef826126a5565b5b9050919050565b6060612c1d8273ffffffffffffffffffffffffffffffffffffffff16601460ff16612c24565b9050919050565b606060006002836002612c3791906140b0565b612c419190614a13565b67ffffffffffffffff811115612c5a57612c59613314565b5b6040519080825280601f01601f191660200182016040528015612c8c5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612cc457612cc361439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612d2857612d2761439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612d6891906140b0565b612d729190614a13565b90505b6001811115612e12577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612db457612db361439a565b5b1a60f81b828281518110612dcb57612dca61439a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612e0b90614ecb565b9050612d75565b5060008414612e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e4d90614f40565b60405180910390fd5b8091505092915050565b6000612e6c8383612fe4565b612ec5578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612eca565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114612fd8576000600182612f029190614974565b9050600060018660000180549050612f1a9190614974565b9050818114612f89576000866000018281548110612f3b57612f3a61439a565b5b9060005260206000200154905080876000018481548110612f5f57612f5e61439a565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612f9d57612f9c614f60565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612fde565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006130468261301b565b9050919050565b6130568161303b565b811461306157600080fd5b50565b6000813590506130738161304d565b92915050565b6000819050919050565b61308c81613079565b811461309757600080fd5b50565b6000813590506130a981613083565b92915050565b600080604083850312156130c6576130c5613011565b5b60006130d485828601613064565b92505060206130e58582860161309a565b9150509250929050565b6130f881613079565b82525050565b600060208201905061311360008301846130ef565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61314e81613119565b811461315957600080fd5b50565b60008135905061316b81613145565b92915050565b60006020828403121561318757613186613011565b5b60006131958482850161315c565b91505092915050565b60008115159050919050565b6131b38161319e565b82525050565b60006020820190506131ce60008301846131aa565b92915050565b60006bffffffffffffffffffffffff82169050919050565b6131f5816131d4565b811461320057600080fd5b50565b600081359050613212816131ec565b92915050565b6000806040838503121561322f5761322e613011565b5b600061323d85828601613064565b925050602061324e85828601613203565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613292578082015181840152602081019050613277565b60008484015250505050565b6000601f19601f8301169050919050565b60006132ba82613258565b6132c48185613263565b93506132d4818560208601613274565b6132dd8161329e565b840191505092915050565b6000602082019050818103600083015261330281846132af565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61334c8261329e565b810181811067ffffffffffffffff8211171561336b5761336a613314565b5b80604052505050565b600061337e613007565b905061338a8282613343565b919050565b600067ffffffffffffffff8211156133aa576133a9613314565b5b6133b38261329e565b9050602081019050919050565b82818337600083830152505050565b60006133e26133dd8461338f565b613374565b9050828152602081018484840111156133fe576133fd61330f565b5b6134098482856133c0565b509392505050565b600082601f8301126134265761342561330a565b5b81356134368482602086016133cf565b91505092915050565b60006020828403121561345557613454613011565b5b600082013567ffffffffffffffff81111561347357613472613016565b5b61347f84828501613411565b91505092915050565b60006020828403121561349e5761349d613011565b5b60006134ac8482850161309a565b91505092915050565b6000806000606084860312156134ce576134cd613011565b5b60006134dc86828701613064565b93505060206134ed8682870161309a565b92505060406134fe8682870161309a565b9150509250925092565b600067ffffffffffffffff82111561352357613522613314565b5b602082029050602081019050919050565b600080fd5b600061354c61354784613508565b613374565b9050808382526020820190506020840283018581111561356f5761356e613534565b5b835b818110156135985780613584888261309a565b845260208401935050602081019050613571565b5050509392505050565b600082601f8301126135b7576135b661330a565b5b81356135c7848260208601613539565b91505092915050565b600080604083850312156135e7576135e6613011565b5b600083013567ffffffffffffffff81111561360557613604613016565b5b613611858286016135a2565b925050602083013567ffffffffffffffff81111561363257613631613016565b5b61363e858286016135a2565b9150509250929050565b6000819050919050565b61365b81613648565b811461366657600080fd5b50565b60008135905061367881613652565b92915050565b60006020828403121561369457613693613011565b5b60006136a284828501613669565b91505092915050565b6136b481613648565b82525050565b60006020820190506136cf60008301846136ab565b92915050565b600080604083850312156136ec576136eb613011565b5b60006136fa8582860161309a565b925050602061370b8582860161309a565b9150509250929050565b61371e8161303b565b82525050565b60006040820190506137396000830185613715565b61374660208301846130ef565b9392505050565b600067ffffffffffffffff82111561376857613767613314565b5b6137718261329e565b9050602081019050919050565b600061379161378c8461374d565b613374565b9050828152602081018484840111156137ad576137ac61330f565b5b6137b88482856133c0565b509392505050565b600082601f8301126137d5576137d461330a565b5b81356137e584826020860161377e565b91505092915050565b600080600080600060a0868803121561380a57613809613011565b5b600061381888828901613064565b955050602061382988828901613064565b945050604086013567ffffffffffffffff81111561384a57613849613016565b5b613856888289016135a2565b935050606086013567ffffffffffffffff81111561387757613876613016565b5b613883888289016135a2565b925050608086013567ffffffffffffffff8111156138a4576138a3613016565b5b6138b0888289016137c0565b9150509295509295909350565b600080604083850312156138d4576138d3613011565b5b60006138e285828601613669565b92505060206138f385828601613064565b9150509250929050565b600067ffffffffffffffff82111561391857613917613314565b5b602082029050602081019050919050565b600061393c613937846138fd565b613374565b9050808382526020820190506020840283018581111561395f5761395e613534565b5b835b8181101561398857806139748882613064565b845260208401935050602081019050613961565b5050509392505050565b600082601f8301126139a7576139a661330a565b5b81356139b7848260208601613929565b91505092915050565b600080604083850312156139d7576139d6613011565b5b600083013567ffffffffffffffff8111156139f5576139f4613016565b5b613a0185828601613992565b925050602083013567ffffffffffffffff811115613a2257613a21613016565b5b613a2e858286016135a2565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613a6d81613079565b82525050565b6000613a7f8383613a64565b60208301905092915050565b6000602082019050919050565b6000613aa382613a38565b613aad8185613a43565b9350613ab883613a54565b8060005b83811015613ae9578151613ad08882613a73565b9750613adb83613a8b565b925050600181019050613abc565b5085935050505092915050565b60006020820190508181036000830152613b108184613a98565b905092915050565b600080600060608486031215613b3157613b30613011565b5b6000613b3f8682870161309a565b9350506020613b5086828701613064565b9250506040613b6186828701613203565b9150509250925092565b60008060008060808587031215613b8557613b84613011565b5b6000613b9387828801613064565b9450506020613ba48782880161309a565b9350506040613bb58782880161309a565b925050606085013567ffffffffffffffff811115613bd657613bd5613016565b5b613be2878288016137c0565b91505092959194509250565b60008060408385031215613c0557613c04613011565b5b6000613c1385828601613669565b9250506020613c248582860161309a565b9150509250929050565b6000602082019050613c436000830184613715565b92915050565b613c528161319e565b8114613c5d57600080fd5b50565b600081359050613c6f81613c49565b92915050565b60008060408385031215613c8c57613c8b613011565b5b6000613c9a85828601613064565b9250506020613cab85828601613c60565b9150509250929050565b60008060008060808587031215613ccf57613cce613011565b5b6000613cdd87828801613064565b945050602085013567ffffffffffffffff811115613cfe57613cfd613016565b5b613d0a878288016135a2565b935050604085013567ffffffffffffffff811115613d2b57613d2a613016565b5b613d37878288016135a2565b925050606085013567ffffffffffffffff811115613d5857613d57613016565b5b613d64878288016137c0565b91505092959194509250565b60008060408385031215613d8757613d86613011565b5b6000613d9585828601613064565b9250506020613da685828601613064565b9150509250929050565b600080600080600060a08688031215613dcc57613dcb613011565b5b6000613dda88828901613064565b9550506020613deb88828901613064565b9450506040613dfc8882890161309a565b9350506060613e0d8882890161309a565b925050608086013567ffffffffffffffff811115613e2e57613e2d613016565b5b613e3a888289016137c0565b9150509295509295909350565b600080600060608486031215613e6057613e5f613011565b5b6000613e6e86828701613064565b935050602084013567ffffffffffffffff811115613e8f57613e8e613016565b5b613e9b868287016135a2565b925050604084013567ffffffffffffffff811115613ebc57613ebb613016565b5b613ec8868287016135a2565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f1957607f821691505b602082108103613f2c57613f2b613ed2565b5b50919050565b600081905092915050565b60008190508160005260206000209050919050565b60008154613f5f81613f01565b613f698186613f32565b94506001821660008114613f845760018114613f9957613fcc565b60ff1983168652811515820286019350613fcc565b613fa285613f3d565b60005b83811015613fc457815481890152600182019150602081019050613fa5565b838801955050505b50505092915050565b6000613fe082613258565b613fea8185613f32565b9350613ffa818560208601613274565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b600061403c600583613f32565b915061404782614006565b600582019050919050565b600061405e8285613f52565b915061406a8284613fd5565b91506140758261402f565b91508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006140bb82613079565b91506140c683613079565b92508282026140d481613079565b915082820484148315176140eb576140ea614081565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061412c82613079565b915061413783613079565b925082614147576141466140f2565b5b828204905092915050565b7f45524331313535237361666542617463685472616e7366657246726f6d3a204960008201527f4e56414c49445f4f50455241544f520000000000000000000000000000000000602082015250565b60006141ae602f83613263565b91506141b982614152565b604082019050919050565b600060208201905081810360008301526141dd816141a1565b9050919050565b7f45524331313535237361666542617463685472616e7366657246726f6d3a204960008201527f4e56414c49445f524543495049454e5400000000000000000000000000000000602082015250565b6000614240603083613263565b915061424b826141e4565b604082019050919050565b6000602082019050818103600083015261426f81614233565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006142d2602f83613263565b91506142dd82614276565b604082019050919050565b60006020820190508181036000830152614301816142c5565b9050919050565b7f455243313135352362616c616e63654f6642617463683a20494e56414c49445f60008201527f41525241595f4c454e4754480000000000000000000000000000000000000000602082015250565b6000614364602c83613263565b915061436f82614308565b604082019050919050565b6000602082019050818103600083015261439381614357565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020601f8301049050919050565b600082821b905092915050565b6000600883026144167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826143d9565b61442086836143d9565b95508019841693508086168417925050509392505050565b6000819050919050565b600061445d61445861445384613079565b614438565b613079565b9050919050565b6000819050919050565b61447783614442565b61448b61448382614464565b8484546143e6565b825550505050565b600090565b6144a0614493565b6144ab81848461446e565b505050565b5b818110156144cf576144c4600082614498565b6001810190506144b1565b5050565b601f821115614514576144e581613f3d565b6144ee846143c9565b810160208510156144fd578190505b614511614509856143c9565b8301826144b0565b50505b505050565b600082821c905092915050565b600061453760001984600802614519565b1980831691505092915050565b60006145508383614526565b9150826002028217905092915050565b61456982613258565b67ffffffffffffffff81111561458257614581613314565b5b61458c8254613f01565b6145978282856144d3565b600060209050601f8311600181146145ca57600084156145b8578287015190505b6145c28582614544565b86555061462a565b601f1984166145d886613f3d565b60005b82811015614600578489015182556001820191506020850194506020810190506145db565b8683101561461d5784890151614619601f891682614526565b8355505b6001600288020188555050505b505050505050565b7f49447320616e6420616d6f756e7473206c656e677468206d69736d6174636800600082015250565b6000614668601f83613263565b915061467382614632565b602082019050919050565b600060208201905081810360008301526146978161465b565b9050919050565b7f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008201527f445f4f50455241544f5200000000000000000000000000000000000000000000602082015250565b60006146fa602a83613263565b91506147058261469e565b604082019050919050565b60006020820190508181036000830152614729816146ed565b9050919050565b7f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008201527f445f524543495049454e54000000000000000000000000000000000000000000602082015250565b600061478c602b83613263565b915061479782614730565b604082019050919050565b600060208201905081810360008301526147bb8161477f565b9050919050565b7f4d69736d617463686564206172726179206c656e677468730000000000000000600082015250565b60006147f8601883613263565b9150614803826147c2565b602082019050919050565b60006020820190508181036000830152614827816147eb565b9050919050565b7f455243323938313a20726f79616c7479206665652077696c6c2065786365656460008201527f2073616c65507269636500000000000000000000000000000000000000000000602082015250565b600061488a602a83613263565b91506148958261482e565b604082019050919050565b600060208201905081810360008301526148b98161487d565b9050919050565b7f455243323938313a20696e76616c696420726563656976657200000000000000600082015250565b60006148f6601983613263565b9150614901826148c0565b602082019050919050565b60006020820190508181036000830152614925816148e9565b9050919050565b600061493782613079565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361496957614968614081565b5b600182019050919050565b600061497f82613079565b915061498a83613079565b92508282039050818111156149a2576149a1614081565b5b92915050565b600060ff82169050919050565b60006149c0826149a8565b91506149cb836149a8565b9250828201905060ff8111156149e4576149e3614081565b5b92915050565b60006040820190506149ff60008301856130ef565b614a0c60208301846130ef565b9392505050565b6000614a1e82613079565b9150614a2983613079565b9250828201905080821115614a4157614a40614081565b5b92915050565b60006040820190508181036000830152614a618185613a98565b90508181036020830152614a758184613a98565b90509392505050565b7f45524331313535235f7361666542617463685472616e7366657246726f6d3a2060008201527f494e56414c49445f4152524159535f4c454e4754480000000000000000000000602082015250565b6000614ada603583613263565b9150614ae582614a7e565b604082019050919050565b60006020820190508181036000830152614b0981614acd565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614b3782614b10565b614b418185614b1b565b9350614b51818560208601613274565b614b5a8161329e565b840191505092915050565b600060a082019050614b7a6000830188613715565b614b876020830187613715565b8181036040830152614b998186613a98565b90508181036060830152614bad8185613a98565b90508181036080830152614bc18184614b2c565b90509695505050505050565b600081519050614bdc81613145565b92915050565b600060208284031215614bf857614bf7613011565b5b6000614c0684828501614bcd565b91505092915050565b7f45524331313535235f63616c6c6f6e455243313135354261746368526563656960008201527f7665643a20494e56414c49445f4f4e5f524543454956455f4d45535341474500602082015250565b6000614c6b603f83613263565b9150614c7682614c0f565b604082019050919050565b60006020820190508181036000830152614c9a81614c5e565b9050919050565b7f455243323938313a20496e76616c696420706172616d65746572730000000000600082015250565b6000614cd7601b83613263565b9150614ce282614ca1565b602082019050919050565b60006020820190508181036000830152614d0681614cca565b9050919050565b600060a082019050614d226000830188613715565b614d2f6020830187613715565b614d3c60408301866130ef565b614d4960608301856130ef565b8181036080830152614d5b8184614b2c565b90509695505050505050565b7f45524331313535235f63616c6c6f6e4552433131353552656365697665643a2060008201527f494e56414c49445f4f4e5f524543454956455f4d455353414745000000000000602082015250565b6000614dc3603a83613263565b9150614dce82614d67565b604082019050919050565b60006020820190508181036000830152614df281614db6565b9050919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000614e2f601783613f32565b9150614e3a82614df9565b601782019050919050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000614e7b601183613f32565b9150614e8682614e45565b601182019050919050565b6000614e9c82614e22565b9150614ea88285613fd5565b9150614eb382614e6e565b9150614ebf8284613fd5565b91508190509392505050565b6000614ed682613079565b915060008203614ee957614ee8614081565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000614f2a602083613263565b9150614f3582614ef4565b602082019050919050565b60006020820190508181036000830152614f5981614f1d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220a3fac6cff69fece6bd1585cbadd23837cb211d7ffa73742e5cfe16a1651a440564736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000c67fea70aac3d0be93ae032659dc710048fdab5b000000000000000000000000000000000000000000000000000000000000000c424f4f53544552205041434b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : tokenName (string): BOOSTER PACK
Arg [1] : tokenBaseURI (string):
Arg [2] : tokenContractURI (string):
Arg [3] : owner (address): 0xC67FEA70aac3D0BE93Ae032659Dc710048fDAb5B
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 000000000000000000000000c67fea70aac3d0be93ae032659dc710048fdab5b
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [5] : 424f4f53544552205041434b0000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.