Source Code
Overview
ETH Balance
0.587455325454241497 ETH
Eth Value
$1,133.48 (@ $1,929.47/ETH)Latest 25 from a total of 346 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Nft Staking ... | 14305639 | 1461 days ago | IN | 0 ETH | 0.0018182 | ||||
| Mint With Points | 14264590 | 1467 days ago | IN | 0.0016 ETH | 0.01592732 | ||||
| Mint With Points | 14240248 | 1471 days ago | IN | 0.0032 ETH | 0.01638704 | ||||
| Mint With Points | 14211125 | 1476 days ago | IN | 0.0016 ETH | 0.00670951 | ||||
| Mint With Points | 14184814 | 1480 days ago | IN | 0.0016 ETH | 0.00515915 | ||||
| Mint With Points | 14177944 | 1481 days ago | IN | 0.0016 ETH | 0.01069771 | ||||
| Mint With Points | 14143780 | 1486 days ago | IN | 0.0016 ETH | 0.01517937 | ||||
| Mint With Points | 14141747 | 1486 days ago | IN | 0.0032 ETH | 0.02932529 | ||||
| Mint With Points | 14140231 | 1486 days ago | IN | 0.02 ETH | 0.02221209 | ||||
| Merge | 14138006 | 1487 days ago | IN | 0.05 ETH | 0.00932876 | ||||
| Merge | 14114016 | 1491 days ago | IN | 0.05 ETH | 0.01085647 | ||||
| Merge | 14097280 | 1493 days ago | IN | 0.05 ETH | 0.01505113 | ||||
| Merge | 14084591 | 1495 days ago | IN | 0.05 ETH | 0.01477558 | ||||
| Merge | 14079727 | 1496 days ago | IN | 0.05 ETH | 0.01101209 | ||||
| Merge | 14069270 | 1497 days ago | IN | 0.05 ETH | 0.04106468 | ||||
| Merge | 14040568 | 1502 days ago | IN | 0.05 ETH | 0.01354917 | ||||
| Merge | 14035408 | 1503 days ago | IN | 0.05 ETH | 0.01196634 | ||||
| Merge | 14023748 | 1504 days ago | IN | 0.05 ETH | 0.01446203 | ||||
| Merge | 14022882 | 1505 days ago | IN | 0.05 ETH | 0.00987803 | ||||
| Mint With Points | 14012238 | 1506 days ago | IN | 0.0016 ETH | 0.023865 | ||||
| Mint With Points | 13913651 | 1521 days ago | IN | 0.0016 ETH | 0.0134281 | ||||
| Merge | 13893023 | 1525 days ago | IN | 0.05 ETH | 0.00798621 | ||||
| Withdraw Eth | 13878172 | 1527 days ago | IN | 0 ETH | 0.00216372 | ||||
| Merge | 13875436 | 1527 days ago | IN | 0.05 ETH | 0.01048238 | ||||
| Mint With Points | 13869224 | 1528 days ago | IN | 0.0128 ETH | 0.01447917 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 14140231 | 1486 days ago | 0.00014467 ETH | ||||
| - | 13878172 | 1527 days ago | 4.5408 ETH | ||||
| - | 13855212 | 1531 days ago | 0.008 ETH | ||||
| - | 13855205 | 1531 days ago | 0.008 ETH | ||||
| - | 13855204 | 1531 days ago | 0.008 ETH | ||||
| - | 13855202 | 1531 days ago | 0.008 ETH | ||||
| - | 13855200 | 1531 days ago | 0.008 ETH | ||||
| - | 13848741 | 1532 days ago | 5.8825221 ETH | ||||
| - | 13744254 | 1548 days ago | 0.016 ETH | ||||
| - | 13744254 | 1548 days ago | 0.032 ETH | ||||
| - | 13639411 | 1565 days ago | 0.032 ETH | ||||
| - | 13639299 | 1565 days ago | 0.024 ETH | ||||
| - | 13639272 | 1565 days ago | 0.1027 ETH | ||||
| - | 13639272 | 1565 days ago | 0.024 ETH | ||||
| - | 13639272 | 1565 days ago | 0.00098069 ETH | ||||
| - | 13639266 | 1565 days ago | 0.008 ETH | ||||
| - | 13639266 | 1565 days ago | 0.024 ETH | ||||
| - | 13639266 | 1565 days ago | 0.024 ETH | ||||
| - | 13639264 | 1565 days ago | 0.016 ETH | ||||
| - | 13639254 | 1565 days ago | 0.008 ETH | ||||
| - | 13639254 | 1565 days ago | 0.016 ETH | ||||
| - | 13639254 | 1565 days ago | 0.008 ETH | ||||
| - | 13639252 | 1565 days ago | 0.016 ETH | ||||
| - | 13639249 | 1565 days ago | 0.008 ETH | ||||
| - | 13639245 | 1565 days ago | 0.008 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RainiNft1155Functions
Compiler Version
v0.8.3+commit.8d00100c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// "SPDX-License-Identifier: MIT"
pragma solidity ^0.8.3;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
interface IStakingPool {
function balanceOf(address _owner) external view returns (uint256 balance);
function burn(address _owner, uint256 _amount) external;
}
interface INftStakingPool {
function getTokenStamina(uint256 _tokenId, address _nftContractAddress) external view returns (uint256 stamina);
function mergeTokens(uint256 _newTokenId, uint256[] memory _tokenIds, address _nftContractAddress) external;
}
interface IRainiCustomNFT {
function onTransfered(address from, address to, uint256 id, uint256 amount, bytes memory data) external;
function onMerged(uint256 _newTokenId, uint256[] memory _tokenId, address _nftContractAddress, uint256[] memory data) external;
function onMinted(address _to, uint256 _tokenId, uint256 _cardId, uint256 _cardLevel, uint256 _amount, bytes1 _mintedContractChar, uint256 _number, uint256[] memory _data) external;
function uri(uint256 id) external view returns (string memory);
}
interface IRainiNft1155 is IERC1155 {
struct CardLevel {
uint64 conversionRate; // number of base tokens required to create
uint32 numberMinted;
uint128 tokenId; // ID of token if grouped, 0 if not
uint32 maxStamina; // The initial and maxiumum stamina for a token
}
struct Card {
uint64 costInUnicorns;
uint64 costInRainbows;
uint16 maxMintsPerAddress;
uint32 maxSupply; // number of base tokens mintable
uint32 allocation; // number of base tokens mintable with points on this contract
uint32 mintTimeStart; // the timestamp from which the card can be minted
bool locked;
address subContract;
}
struct TokenVars {
uint128 cardId;
uint32 level;
uint32 number; // to assign a numbering to NFTs
bytes1 mintedContractChar;
}
function maxTokenId() external view returns (uint256);
function contractChar() external view returns (bytes1);
function numberMintedByAddress(address _address, uint256 _cardID) external view returns (uint256);
function burn(address _owner, uint256 _tokenId, uint256 _amount, bool _isBridged) external;
function getPathUri(uint256 _cardId) view external returns (string memory);
function cards(uint256 _cardId) external view returns (Card memory);
function cardLevels(uint256 _cardId, uint256 _level) external view returns (CardLevel memory);
function tokenVars(uint256 _tokenId) external view returns (TokenVars memory);
function mint(address _to, uint256 _cardId, uint256 _cardLevel, uint256 _amount, bytes1 _mintedContractChar, uint256 _number, uint256[] memory _data) external;
function addToNumberMintedByAddress(address _address, uint256 _cardId, uint256 amount) external;
}
contract RainiNft1155Functions is AccessControl, ReentrancyGuard {
address public nftStakingPoolAddress;
uint256 public constant POINT_COST_DECIMALS = 1000000000000000000;
uint256 public rainbowToEth;
uint256 public unicornToEth;
uint256 public minPointsPercentToMint;
mapping(address => bool) public rainbowPools;
mapping(address => bool) public unicornPools;
mapping(uint256 => uint256) public mergeFees;
mapping(uint256 => uint256) public startTimeOverrides;
uint256 public mintingFeeBasisPoints;
IRainiNft1155 nftContract;
constructor(address _nftContractAddress, address _contractOwner) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(DEFAULT_ADMIN_ROLE, _contractOwner);
nftContract = IRainiNft1155(_nftContractAddress);
}
modifier onlyOwner() {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()));
_;
}
function addRainbowPool(address _rainbowPool)
external onlyOwner {
rainbowPools[_rainbowPool] = true;
}
function removeRainbowPool(address _rainbowPool)
external onlyOwner {
rainbowPools[_rainbowPool] = false;
}
function addUnicornPool(address _unicornPool)
external onlyOwner {
unicornPools[_unicornPool] = true;
}
function removeUnicornPool(address _unicornPool)
external onlyOwner {
unicornPools[_unicornPool] = false;
}
function setEtherValues(uint256 _unicornToEth, uint256 _rainbowToEth, uint256 _minPointsPercentToMint)
external onlyOwner {
unicornToEth = _unicornToEth;
rainbowToEth = _rainbowToEth;
minPointsPercentToMint = _minPointsPercentToMint;
}
function setFees(uint256 _mintingFeeBasisPoints, uint256[] memory _mergeFees)
external onlyOwner {
mintingFeeBasisPoints =_mintingFeeBasisPoints;
for (uint256 i = 1; i < _mergeFees.length; i++) {
mergeFees[i] = _mergeFees[i];
}
}
function setNftStakingPoolAddress(address _nftStakingPoolAddress)
external onlyOwner {
nftStakingPoolAddress = (_nftStakingPoolAddress);
}
function setTimeStartOverrides(uint256[] memory _cardId, uint256[] memory _newStartTime)
external onlyOwner {
for (uint256 i = 0; i < _cardId.length; i++) {
startTimeOverrides[_cardId[i]] = _newStartTime[i];
}
}
struct MergeData {
uint256 cost;
uint256 totalPointsBurned;
uint256 currentTokenToMint;
bool willCallPool;
bool willCallSubContract;
}
function merge(uint256 _cardId, uint256 _level, uint256 _mintAmount, uint256[] memory _tokenIds, uint256[] memory _burnAmounts, uint256[] memory _data)
external payable nonReentrant {
IRainiNft1155.CardLevel memory _cardLevel = nftContract.cardLevels(_cardId, _level);
require(_level > 0 && _cardLevel.conversionRate > 0, "merge not allowed");
MergeData memory _locals = MergeData({
cost: 0,
totalPointsBurned: 0,
currentTokenToMint: 0,
willCallPool: false,
willCallSubContract: false
});
_locals.cost = _cardLevel.conversionRate * _mintAmount;
uint256[] memory mergedTokensIds;
INftStakingPool nftStakingPool;
IRainiCustomNFT subContract;
_locals.willCallPool = nftStakingPoolAddress != address(0) && _level > 0 && nftContract.cardLevels(_cardId, _level-1).tokenId == 0;
_locals.willCallSubContract = _cardLevel.tokenId == 0 && nftContract.cards(_cardId).subContract != address(0);
if (_locals.willCallPool || _locals.willCallSubContract) {
mergedTokensIds = new uint256[](_tokenIds.length);
if (_locals.willCallPool) {
nftStakingPool = INftStakingPool(nftStakingPoolAddress);
}
if (_locals.willCallSubContract) {
subContract = IRainiCustomNFT(nftContract.cards(_cardId).subContract);
}
}
for (uint256 i = 0; i < _tokenIds.length; i++) {
require(_burnAmounts[i] <= nftContract.balanceOf(_msgSender(), _tokenIds[i]), 'not enough balance');
IRainiNft1155.TokenVars memory _tempTokenVars = nftContract.tokenVars(_tokenIds[i]);
require(_tempTokenVars.cardId == _cardId, "card mismatch");
require(_tempTokenVars.level < _level, "can only merge into higher levels");
IRainiNft1155.CardLevel memory _tempCardLevel = nftContract.cardLevels(_tempTokenVars.cardId, _tempTokenVars.level);
if (_tempTokenVars.level == 0) {
_locals.totalPointsBurned += _burnAmounts[i];
} else {
_locals.totalPointsBurned += _burnAmounts[i] * _tempCardLevel.conversionRate;
}
nftContract.burn(_msgSender(), _tokenIds[i], _burnAmounts[i], false);
if (_locals.willCallPool || _locals.willCallSubContract) {
mergedTokensIds[i] = _tokenIds[i];
if (_locals.totalPointsBurned > (_locals.currentTokenToMint + 1) * _cardLevel.conversionRate || i == _tokenIds.length - 1) {
_locals.currentTokenToMint++;
if (_locals.willCallPool) {
nftStakingPool.mergeTokens(_locals.currentTokenToMint + nftContract.maxTokenId(), mergedTokensIds, address(nftContract));
}
if (_locals.willCallSubContract) {
subContract.onMerged(_locals.currentTokenToMint + nftContract.maxTokenId(), mergedTokensIds, address(nftContract), _data);
}
if (_locals.currentTokenToMint < _mintAmount) {
mergedTokensIds = new uint256[](_cardLevel.conversionRate);
}
}
}
}
require(_locals.totalPointsBurned == _locals.cost, "wrong no tkns burned");
require(mergeFees[_level] * _mintAmount <= msg.value, "Not enough ETH");
(bool success, ) = _msgSender().call{ value: msg.value - mergeFees[_level] * _mintAmount}(""); // refund excess Eth
require(success, "transfer failed");
nftContract.mint(_msgSender(), _cardId, _level, _mintAmount, nftContract.contractChar(), 0, _data);
}
struct MintWithPointsData {
uint256 totalPriceRainbows;
uint256 totalPriceUnicorns;
uint256 fee;
uint256 amountEthToWithdraw;
bool success;
}
function mintWithPoints(uint256[] memory _cardId, uint256[] memory _amount, bool[] memory _useUnicorns, uint256[][] memory _data, address[] memory _rainbowPools, address[] memory _unicornPools)
external payable nonReentrant {
MintWithPointsData memory _locals = MintWithPointsData({
totalPriceRainbows: 0,
totalPriceUnicorns: 0,
fee: 0,
amountEthToWithdraw: 0,
success: false
});
for (uint256 i = 0; i < _cardId.length; i++) {
IRainiNft1155.Card memory card = nftContract.cards(_cardId[i]);
IRainiNft1155.CardLevel memory cardLevel = nftContract.cardLevels(_cardId[i], 0);
uint256 startTime = card.mintTimeStart;
if (startTimeOverrides[_cardId[i]] > 0) {
startTime = startTimeOverrides[_cardId[i]];
}
require(block.timestamp >= startTime || hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), 'too early');
require(nftContract.numberMintedByAddress(_msgSender(), _cardId[i]) + _amount[i] <= card.maxMintsPerAddress, "Max mints reached for address");
if (cardLevel.numberMinted + _amount[i] > card.allocation) {
_amount[i] = card.allocation - cardLevel.numberMinted;
}
if (_useUnicorns[i]) {
require(card.costInUnicorns > 0, "unicorns not allowed");
_locals.totalPriceUnicorns += card.costInUnicorns * _amount[i] * POINT_COST_DECIMALS;
} else {
require(card.costInRainbows > 0, "rainbows not allowed");
_locals.totalPriceRainbows += card.costInRainbows * _amount[i] * POINT_COST_DECIMALS;
}
if (card.costInRainbows > 0) {
_locals.fee += (card.costInRainbows * _amount[i] * POINT_COST_DECIMALS * mintingFeeBasisPoints) / (rainbowToEth * 10000);
} else {
_locals.fee += (card.costInUnicorns * _amount[i] * POINT_COST_DECIMALS * mintingFeeBasisPoints) / (unicornToEth * 10000);
}
}
_locals.amountEthToWithdraw = 0;
for (uint256 n = 0; n < 2; n++) {
bool loopTypeUnicorns = n > 0;
uint256 totalBalance = 0;
uint256 totalPrice = loopTypeUnicorns ? _locals.totalPriceUnicorns : _locals.totalPriceRainbows;
uint256 remainingPrice = totalPrice;
if (totalPrice > 0) {
uint256 loopLength = loopTypeUnicorns ? _unicornPools.length : _rainbowPools.length;
require(loopLength > 0, "invalid pools");
for (uint256 i = 0; i < loopLength; i++) {
IStakingPool pool;
if (loopTypeUnicorns) {
require((unicornPools[_unicornPools[i]]), "invalid unicorn pool");
pool = IStakingPool(_unicornPools[i]);
} else {
require((rainbowPools[_rainbowPools[i]]), "invalid rainbow pool");
pool = IStakingPool(_rainbowPools[i]);
}
uint256 _balance = pool.balanceOf(_msgSender());
totalBalance += _balance;
if (totalBalance >= totalPrice) {
pool.burn(_msgSender(), remainingPrice);
remainingPrice = 0;
break;
} else {
pool.burn(_msgSender(), _balance);
remainingPrice -= _balance;
}
}
if (remainingPrice > 0) {
uint256 minPoints = (totalPrice * minPointsPercentToMint) / 100;
require(totalPrice - remainingPrice >= minPoints, "not enough balance");
uint256 pointsToEth = loopTypeUnicorns ? unicornToEth : rainbowToEth;
require(msg.value * pointsToEth > remainingPrice, "not enough balance");
_locals.amountEthToWithdraw += remainingPrice / pointsToEth;
}
}
}
// Add minting fees
_locals.amountEthToWithdraw += _locals.fee;
require(_locals.amountEthToWithdraw <= msg.value);
(_locals.success, ) = _msgSender().call{ value: msg.value - _locals.amountEthToWithdraw }(""); // refund excess Eth
require(_locals.success, "transfer failed");
bool _tokenMinted = false;
for (uint256 i = 0; i < _cardId.length; i++) {
if (_amount[i] > 0) {
nftContract.addToNumberMintedByAddress(_msgSender(), _cardId[i], _amount[i]);
nftContract.mint(_msgSender(), _cardId[i], 0, _amount[i], nftContract.contractChar(), 0, _data[i]);
_tokenMinted = true;
}
}
require(_tokenMinted, 'Allocation exhausted');
}
// Allow the owner to withdraw Ether payed into the contract
function withdrawEth(uint256 _amount)
external onlyOwner {
require(_amount <= address(this).balance, "not enough balance");
(bool success, ) = _msgSender().call{ value: _amount }("");
require(success, "transfer failed");
}
}// SPDX-License-Identifier: MIT
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
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
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
@dev Handles the receipt of a single ERC1155 token type. This function is
called at the end of a `safeTransferFrom` after the balance has been updated.
To accept the transfer, this must return
`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
(i.e. 0xf23a6e61, or its own function selector).
@param operator The address which initiated the transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param id The ID of the token being transferred
@param value The amount of tokens being transferred
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
@dev Handles the receipt of a multiple ERC1155 token types. This function
is called at the end of a `safeBatchTransferFrom` after the balances have
been updated. To accept the transfer(s), this must return
`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
(i.e. 0xbc197c81, or its own function selector).
@param operator The address which initiated the batch transfer (i.e. msg.sender)
@param from The address which previously owned the token
@param ids An array containing ids of each token being transferred (order and length must match values array)
@param values An array containing amounts of each token being transferred (order and length must match ids array)
@param data Additional data with no specified format
@return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri_) {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: balance query for the zero address");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
require(_msgSender() != operator, "ERC1155: setting approval status for self");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not owner nor approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: transfer caller is not owner nor approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address account,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(account != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] += amount;
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address account,
uint256 id,
uint256 amount
) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
uint256 accountBalance = _balances[id][account];
require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][account] = accountBalance - amount;
}
emit TransferSingle(operator, account, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address account,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(account != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 accountBalance = _balances[id][account];
require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][account] = accountBalance - amount;
}
}
emit TransferBatch(operator, account, address(0), ids, amounts);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
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
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:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/
abstract contract AccessControl is Context, 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, _msgSender());
_;
}
/**
* @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 override returns (bool) {
return _roles[role].members[account];
}
/**
* @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 {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" 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 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.
*/
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.
*/
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 granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
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.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) private {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}{
"remappings": [],
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "istanbul",
"libraries": {},
"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":"address","name":"_nftContractAddress","type":"address"},{"internalType":"address","name":"_contractOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POINT_COST_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rainbowPool","type":"address"}],"name":"addRainbowPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_unicornPool","type":"address"}],"name":"addUnicornPool","outputs":[],"stateMutability":"nonpayable","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":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"},{"internalType":"uint256","name":"_level","type":"uint256"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_burnAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_data","type":"uint256[]"}],"name":"merge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mergeFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minPointsPercentToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_cardId","type":"uint256[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"},{"internalType":"bool[]","name":"_useUnicorns","type":"bool[]"},{"internalType":"uint256[][]","name":"_data","type":"uint256[][]"},{"internalType":"address[]","name":"_rainbowPools","type":"address[]"},{"internalType":"address[]","name":"_unicornPools","type":"address[]"}],"name":"mintWithPoints","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintingFeeBasisPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftStakingPoolAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rainbowPools","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rainbowToEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rainbowPool","type":"address"}],"name":"removeRainbowPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_unicornPool","type":"address"}],"name":"removeUnicornPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unicornToEth","type":"uint256"},{"internalType":"uint256","name":"_rainbowToEth","type":"uint256"},{"internalType":"uint256","name":"_minPointsPercentToMint","type":"uint256"}],"name":"setEtherValues","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintingFeeBasisPoints","type":"uint256"},{"internalType":"uint256[]","name":"_mergeFees","type":"uint256[]"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftStakingPoolAddress","type":"address"}],"name":"setNftStakingPoolAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_cardId","type":"uint256[]"},{"internalType":"uint256[]","name":"_newStartTime","type":"uint256[]"}],"name":"setTimeStartOverrides","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"startTimeOverrides","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"unicornPools","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unicornToEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200363f3803806200363f833981016040819052620000349162000146565b600180556200004560003362000079565b6200005260008262000079565b50600b80546001600160a01b0319166001600160a01b03929092169190911790556200017d565b62000085828262000089565b5050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000085576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620000e53390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b80516001600160a01b03811681146200014157600080fd5b919050565b6000806040838503121562000159578182fd5b620001648362000129565b9150620001746020840162000129565b90509250929050565b6134b2806200018d6000396000f3fe6080604052600436106101b75760003560e01c80638350fbab116100ec578063bda3ed071161008a578063deebe61011610064578063deebe610146104fc578063e0e5120d1461051c578063f7e177de1461053c578063f9f98af614610552576101b7565b8063bda3ed071461048f578063c311d049146104bc578063d547741f146104dc576101b7565b8063928cb148116100c6578063928cb1481461042b578063a217fddf1461044b578063ae3068c114610460578063b29dc70a1461047c576101b7565b80638350fbab146103cb57806388d1ae6c146103f857806391d148541461040b576101b7565b8063248a9ca31161015957806336568abe1161013357806336568abe1461035557806354a7d0a914610375578063582f706f146103955780635a3b336c146103ab576101b7565b8063248a9ca3146102e5578063257ea0ab146103155780632f2ff15d14610335576101b7565b806313f431601161019557806313f431601461025957806315d21e11146102895780631c513339146102ad5780631d9083f3146102c3576101b7565b806301ffc9a7146101bc57806308a55a6e146101f15780630c02477614610221575b600080fd5b3480156101c857600080fd5b506101dc6101d7366004612e49565b610572565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b506101dc61020c366004612c7f565b60066020526000908152604090205460ff1681565b34801561022d57600080fd5b50600254610241906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b34801561026557600080fd5b506101dc610274366004612c7f565b60076020526000908152604090205460ff1681565b34801561029557600080fd5b5061029f60045481565b6040519081526020016101e8565b3480156102b957600080fd5b5061029f60035481565b3480156102cf57600080fd5b506102e36102de366004612c7f565b6105ab565b005b3480156102f157600080fd5b5061029f610300366004612e02565b60009081526020819052604090206001015490565b34801561032157600080fd5b506102e3610330366004612c7f565b6105e1565b34801561034157600080fd5b506102e3610350366004612e1a565b610616565b34801561036157600080fd5b506102e3610370366004612e1a565b610642565b34801561038157600080fd5b506102e3610390366004613026565b6106c5565b3480156103a157600080fd5b5061029f600a5481565b3480156103b757600080fd5b506102e36103c6366004612c7f565b6106e7565b3480156103d757600080fd5b5061029f6103e6366004612e02565b60096020526000908152604090205481565b6102e3610406366004613051565b61071f565b34801561041757600080fd5b506101dc610426366004612e1a565b611546565b34801561043757600080fd5b506102e3610446366004612c7f565b61156f565b34801561045757600080fd5b5061029f600081565b34801561046c57600080fd5b5061029f670de0b6b3a764000081565b6102e361048a366004612cfb565b6115a7565b34801561049b57600080fd5b5061029f6104aa366004612e02565b60086020526000908152604090205481565b3480156104c857600080fd5b506102e36104d7366004612e02565b612547565b3480156104e857600080fd5b506102e36104f7366004612e1a565b6125e3565b34801561050857600080fd5b506102e3610517366004612c9b565b612609565b34801561052857600080fd5b506102e3610537366004612c7f565b6126a2565b34801561054857600080fd5b5061029f60055481565b34801561055e57600080fd5b506102e361056d366004612fec565b6126d7565b60006001600160e01b03198216637965db0b60e01b14806105a357506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b6105b6600033610426565b6105bf57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6105ec600033610426565b6105f557600080fd5b6001600160a01b03166000908152600660205260409020805460ff19169055565b60008281526020819052604090206001015461063381335b61274a565b61063d83836127ae565b505050565b6001600160a01b03811633146106b75760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6106c18282612832565b5050565b6106d0600033610426565b6106d957600080fd5b600492909255600355600555565b6106f2600033610426565b6106fb57600080fd5b6001600160a01b03166000908152600660205260409020805460ff19166001179055565b600260015414156107725760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106ae565b6002600155600b54604051631c39f49d60e21b815260048101889052602481018790526000916001600160a01b0316906370e7d2749060440160806040518083038186803b1580156107c357600080fd5b505afa1580156107d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fb9190612e71565b9050600086118015610816575080516001600160401b031615155b6108565760405162461bcd60e51b81526020600482015260116024820152701b595c99d9481b9bdd08185b1b1bddd959607a1b60448201526064016106ae565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915281516108979087906001600160401b031661336d565b815260025460609060009081906001600160a01b0316158015906108bb575060008a115b80156109625750600b546001600160a01b03166370e7d2748c6108df60018e61338c565b6040516001600160e01b031960e085901b1681526004810192909252602482015260440160806040518083038186803b15801561091b57600080fd5b505afa15801561092f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109539190612e71565b604001516001600160801b0316155b1515606085015260408501516001600160801b0316158015610a0d5750600b546040516311b820ed60e31b8152600481018d90526000916001600160a01b031690638dc10768906024016101006040518083038186803b1580156109c557600080fd5b505afa1580156109d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fd9190612ed1565b60e001516001600160a01b031614155b15156080850152606084015180610a25575083608001515b15610b245787516001600160401b03811115610a5157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a7a578160200160208202803683370190505b509250836060015115610a96576002546001600160a01b031691505b836080015115610b2457600b546040516311b820ed60e31b8152600481018d90526001600160a01b0390911690638dc10768906024016101006040518083038186803b158015610ae557600080fd5b505afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d9190612ed1565b60e0015190505b60005b885181101561131357600b546001600160a01b031662fdd58e338b8481518110610b6157634e487b7160e01b600052603260045260246000fd5b60200260200101516040518363ffffffff1660e01b8152600401610b9a9291906001600160a01b03929092168252602082015260400190565b60206040518083038186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bea9190612fd4565b888281518110610c0a57634e487b7160e01b600052603260045260246000fd5b60200260200101511115610c305760405162461bcd60e51b81526004016106ae90613217565b600b5489516000916001600160a01b0316906301870f02908c9085908110610c6857634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401610c8e91815260200190565b60806040518083038186803b158015610ca657600080fd5b505afa158015610cba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cde9190612f80565b80519091506001600160801b03168d14610d2a5760405162461bcd60e51b815260206004820152600d60248201526c0c6c2e4c840dad2e6dac2e8c6d609b1b60448201526064016106ae565b8b816020015163ffffffff1610610d8d5760405162461bcd60e51b815260206004820152602160248201527f63616e206f6e6c79206d6572676520696e746f20686967686572206c6576656c6044820152607360f81b60648201526084016106ae565b600b5481516020830151604051631c39f49d60e21b81526001600160801b03909216600483015263ffffffff1660248201526000916001600160a01b0316906370e7d2749060440160806040518083038186803b158015610ded57600080fd5b505afa158015610e01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e259190612e71565b9050816020015163ffffffff1660001415610e7b57898381518110610e5a57634e487b7160e01b600052603260045260246000fd5b602002602001015187602001818151610e739190613335565b905250610ed0565b80600001516001600160401b03168a8481518110610ea957634e487b7160e01b600052603260045260246000fd5b6020026020010151610ebb919061336d565b87602001818151610ecc9190613335565b9052505b600b546001600160a01b03166331126dd1338d8681518110610f0257634e487b7160e01b600052603260045260246000fd5b60200260200101518d8781518110610f2a57634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260006064820152608401600060405180830381600087803b158015610f8a57600080fd5b505af1158015610f9e573d6000803e3d6000fd5b50505050866060015180610fb3575086608001515b156112fe578a8381518110610fd857634e487b7160e01b600052603260045260246000fd5b602002602001015186848151811061100057634e487b7160e01b600052603260045260246000fd5b60200260200101818152505087600001516001600160401b03168760400151600161102b9190613335565b611035919061336d565b87602001511180611052575060018b5161104f919061338c565b83145b156112fe57604087018051906110678261340f565b90525060608701511561117d57846001600160a01b031663feb0ae7f600b60009054906101000a90046001600160a01b03166001600160a01b03166391ba317a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110d157600080fd5b505afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111099190612fd4565b89604001516111189190613335565b600b546040516001600160e01b031960e085901b16815261114a92918b916001600160a01b039091169060040161326c565b600060405180830381600087803b15801561116457600080fd5b505af1158015611178573d6000803e3d6000fd5b505050505b86608001511561129257836001600160a01b031663e4a3fba9600b60009054906101000a90046001600160a01b03166001600160a01b03166391ba317a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111e457600080fd5b505afa1580156111f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121c9190612fd4565b896040015161122b9190613335565b600b546040516001600160e01b031960e085901b16815261125f92918b916001600160a01b03909116908f9060040161329d565b600060405180830381600087803b15801561127957600080fd5b505af115801561128d573d6000803e3d6000fd5b505050505b8b876040015110156112fe5787600001516001600160401b03166001600160401b038111156112d157634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156112fa578160200160208202803683370190505b5095505b5050808061130b9061340f565b915050610b27565b50835160208501511461135f5760405162461bcd60e51b81526020600482015260146024820152731ddc9bdb99c81b9bc81d1adb9cc8189d5c9b995960621b60448201526064016106ae565b60008a815260086020526040902054349061137b908b9061336d565b11156113ba5760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced0408aa8960931b60448201526064016106ae565b60008a81526008602052604081205433906113d6908c9061336d565b6113e0903461338c565b604051600081818185875af1925050503d806000811461141c576040519150601f19603f3d011682016040523d82523d6000602084013e611421565b606091505b50509050806114425760405162461bcd60e51b81526004016106ae90613243565b600b546001600160a01b031663a39501df338e8e8e600b60009054906101000a90046001600160a01b03166001600160a01b0316636bb2e32d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114a557600080fd5b505afa1580156114b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114dd9190612de8565b60008e6040518863ffffffff1660e01b81526004016115029796959493929190613192565b600060405180830381600087803b15801561151c57600080fd5b505af1158015611530573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61157a600033610426565b61158357600080fd5b6001600160a01b03166000908152600760205260409020805460ff19166001179055565b600260015414156115fa5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106ae565b60026001556040805160a0810182526000808252602082018190529181018290526060810182905260808101829052905b8751811015611d4557600b5488516000916001600160a01b031690638dc10768908b908590811061166c57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161169291815260200190565b6101006040518083038186803b1580156116ab57600080fd5b505afa1580156116bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e39190612ed1565b600b548a519192506000916001600160a01b03909116906370e7d274908c908690811061172057634e487b7160e01b600052603260045260246000fd5b602002602001015160006040518363ffffffff1660e01b8152600401611750929190918252602082015260400190565b60806040518083038186803b15801561176857600080fd5b505afa15801561177c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a09190612e71565b905060008260a0015163ffffffff1690506000600960008d87815181106117d757634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002054111561183257600960008c868151811061181857634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000205490505b80421015806118475750611847600033610426565b61187f5760405162461bcd60e51b8152602060048201526009602482015268746f6f206561726c7960b81b60448201526064016106ae565b826040015161ffff168a85815181106118a857634e487b7160e01b600052603260045260246000fd5b6020908102919091010151600b546001600160a01b0316630a3de451338f89815181106118e557634e487b7160e01b600052603260045260246000fd5b60200260200101516040518363ffffffff1660e01b815260040161191e9291906001600160a01b03929092168252602082015260400190565b60206040518083038186803b15801561193657600080fd5b505afa15801561194a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196e9190612fd4565b6119789190613335565b11156119c65760405162461bcd60e51b815260206004820152601d60248201527f4d6178206d696e7473207265616368656420666f72206164647265737300000060448201526064016106ae565b826080015163ffffffff168a85815181106119f157634e487b7160e01b600052603260045260246000fd5b6020026020010151836020015163ffffffff16611a0e9190613335565b1115611a5b5781602001518360800151611a2891906133a3565b63ffffffff168a8581518110611a4e57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b888481518110611a7b57634e487b7160e01b600052603260045260246000fd5b602002602001015115611b425782516001600160401b0316611ad65760405162461bcd60e51b81526020600482015260146024820152731d5b9a58dbdc9b9cc81b9bdd08185b1b1bddd95960621b60448201526064016106ae565b670de0b6b3a76400008a8581518110611aff57634e487b7160e01b600052603260045260246000fd5b602002602001015184600001516001600160401b0316611b1f919061336d565b611b29919061336d565b85602001818151611b3a9190613335565b905250611bfc565b600083602001516001600160401b031611611b965760405162461bcd60e51b81526020600482015260146024820152731c985a5b989bdddcc81b9bdd08185b1b1bddd95960621b60448201526064016106ae565b670de0b6b3a76400008a8581518110611bbf57634e487b7160e01b600052603260045260246000fd5b602002602001015184602001516001600160401b0316611bdf919061336d565b611be9919061336d565b85518690611bf8908390613335565b9052505b60208301516001600160401b031615611ca157600354611c1e9061271061336d565b600a54670de0b6b3a76400008c8781518110611c4a57634e487b7160e01b600052603260045260246000fd5b602002602001015186602001516001600160401b0316611c6a919061336d565b611c74919061336d565b611c7e919061336d565b611c88919061334d565b85604001818151611c999190613335565b905250611d2f565b600454611cb09061271061336d565b600a54670de0b6b3a76400008c8781518110611cdc57634e487b7160e01b600052603260045260246000fd5b602002602001015186600001516001600160401b0316611cfc919061336d565b611d06919061336d565b611d10919061336d565b611d1a919061334d565b85604001818151611d2b9190613335565b9052505b5050508080611d3d9061340f565b91505061162b565b506000606082018190525b60028110156121c75780151560008082611d6b578451611d71565b84602001515b90508080156121b057600084611d88578851611d8b565b87515b905060008111611dcd5760405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420706f6f6c7360981b60448201526064016106ae565b60005b818110156121025760008615611e9d57600760008b8481518110611e0457634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611e6e5760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081d5b9a58dbdc9b881c1bdbdb60621b60448201526064016106ae565b898281518110611e8e57634e487b7160e01b600052603260045260246000fd5b60200260200101519050611f56565b600660008c8481518110611ec157634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611f2b5760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081c985a5b989bddc81c1bdbdb60621b60448201526064016106ae565b8a8281518110611f4b57634e487b7160e01b600052603260045260246000fd5b602002602001015190505b60006001600160a01b0382166370a08231336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b158015611fa757600080fd5b505afa158015611fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fdf9190612fd4565b9050611feb8188613335565b965085871061206f576001600160a01b038216639dc29fac336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101889052604401600060405180830381600087803b15801561204c57600080fd5b505af1158015612060573d6000803e3d6000fd5b50505050600094505050612102565b6001600160a01b038216639dc29fac336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101849052604401600060405180830381600087803b1580156120c757600080fd5b505af11580156120db573d6000803e3d6000fd5b5050505080856120eb919061338c565b9450505080806120fa9061340f565b915050611dd0565b5081156121ae57600060646005548561211b919061336d565b612125919061334d565b905080612132848661338c565b10156121505760405162461bcd60e51b81526004016106ae90613217565b60008661215f57600354612163565b6004545b905083612170823461336d565b1161218d5760405162461bcd60e51b81526004016106ae90613217565b612197818561334d565b896060018181516121a89190613335565b90525050505b505b5050505080806121bf9061340f565b915050611d50565b508060400151816060018181516121de9190613335565b90525060608101513410156121f257600080fd5b60608101513390612203903461338c565b604051600081818185875af1925050503d806000811461223f576040519150601f19603f3d011682016040523d82523d6000602084013e612244565b606091505b505015156080820181905261226b5760405162461bcd60e51b81526004016106ae90613243565b6000805b88518110156124f457600088828151811061229a57634e487b7160e01b600052603260045260246000fd5b602002602001015111156124e257600b546001600160a01b031663c2fa4019338b84815181106122da57634e487b7160e01b600052603260045260246000fd5b60200260200101518b858151811061230257634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801561235b57600080fd5b505af115801561236f573d6000803e3d6000fd5b5050600b546001600160a01b0316915063a39501df9050338b84815181106123a757634e487b7160e01b600052603260045260246000fd5b602002602001015160008c86815181106123d157634e487b7160e01b600052603260045260246000fd5b6020026020010151600b60009054906101000a90046001600160a01b03166001600160a01b0316636bb2e32d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561242757600080fd5b505afa15801561243b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245f9190612de8565b60008d898151811061248157634e487b7160e01b600052603260045260246000fd5b60200260200101516040518863ffffffff1660e01b81526004016124ab9796959493929190613192565b600060405180830381600087803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50505050600191505b806124ec8161340f565b91505061226f565b50806125395760405162461bcd60e51b8152602060048201526014602482015273105b1b1bd8d85d1a5bdb88195e1a185d5cdd195960621b60448201526064016106ae565b505060018055505050505050565b612552600033610426565b61255b57600080fd5b4781111561257b5760405162461bcd60e51b81526004016106ae90613217565b604051600090339083908381818185875af1925050503d80600081146125bd576040519150601f19603f3d011682016040523d82523d6000602084013e6125c2565b606091505b50509050806106c15760405162461bcd60e51b81526004016106ae90613243565b6000828152602081905260409020600101546125ff813361062e565b61063d8383612832565b612614600033610426565b61261d57600080fd5b60005b825181101561063d5781818151811061264957634e487b7160e01b600052603260045260246000fd5b60200260200101516009600085848151811061267557634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002081905550808061269a9061340f565b915050612620565b6126ad600033610426565b6126b657600080fd5b6001600160a01b03166000908152600760205260409020805460ff19169055565b6126e2600033610426565b6126eb57600080fd5b600a82905560015b815181101561063d5781818151811061271c57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008381526008909252604090912055806127428161340f565b9150506126f3565b6127548282611546565b6106c15761276c816001600160a01b03166014612897565b612777836020612897565b60405160200161278892919061311d565b60408051601f198184030181529082905262461bcd60e51b82526106ae916004016131e4565b6127b88282611546565b6106c1576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556127ee3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61283c8282611546565b156106c1576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b606060006128a683600261336d565b6128b1906002613335565b6001600160401b038111156128d657634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612900576020820181803683370190505b509050600360fc1b8160008151811061292957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061296657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600061298a84600261336d565b612995906001613335565b90505b6001811115612a29576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106129d757634e487b7160e01b600052603260045260246000fd5b1a60f81b8282815181106129fb57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93612a22816133f8565b9050612998565b508315612a785760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106ae565b9392505050565b80516105a681613456565b600082601f830112612a9a578081fd5b81356020612aaf612aaa83613312565b6132e2565b80838252828201915082860187848660051b8901011115612ace578586fd5b855b85811015612af5578135612ae381613456565b84529284019290840190600101612ad0565b5090979650505050505050565b600082601f830112612b12578081fd5b81356020612b22612aaa83613312565b82815281810190858301855b85811015612af557612b45898684358b0101612bbd565b84529284019290840190600101612b2e565b600082601f830112612b67578081fd5b81356020612b77612aaa83613312565b80838252828201915082860187848660051b8901011115612b96578586fd5b855b85811015612af5578135612bab8161346e565b84529284019290840190600101612b98565b600082601f830112612bcd578081fd5b81356020612bdd612aaa83613312565b80838252828201915082860187848660051b8901011115612bfc578586fd5b855b85811015612af557813584529284019290840190600101612bfe565b80516105a68161346e565b80516001600160f81b0319811681146105a657600080fd5b80516001600160801b03811681146105a657600080fd5b805163ffffffff811681146105a657600080fd5b80516001600160401b03811681146105a657600080fd5b600060208284031215612c90578081fd5b8135612a7881613456565b60008060408385031215612cad578081fd5b82356001600160401b0380821115612cc3578283fd5b612ccf86838701612bbd565b93506020850135915080821115612ce4578283fd5b50612cf185828601612bbd565b9150509250929050565b60008060008060008060c08789031215612d13578182fd5b86356001600160401b0380821115612d29578384fd5b612d358a838b01612bbd565b97506020890135915080821115612d4a578384fd5b612d568a838b01612bbd565b96506040890135915080821115612d6b578384fd5b612d778a838b01612b57565b95506060890135915080821115612d8c578384fd5b612d988a838b01612b02565b94506080890135915080821115612dad578384fd5b612db98a838b01612a8a565b935060a0890135915080821115612dce578283fd5b50612ddb89828a01612a8a565b9150509295509295509295565b600060208284031215612df9578081fd5b612a7882612c25565b600060208284031215612e13578081fd5b5035919050565b60008060408385031215612e2c578182fd5b823591506020830135612e3e81613456565b809150509250929050565b600060208284031215612e5a578081fd5b81356001600160e01b031981168114612a78578182fd5b600060808284031215612e82578081fd5b612e8c60806132e2565b612e9583612c68565b8152612ea360208401612c54565b6020820152612eb460408401612c3d565b6040820152612ec560608401612c54565b60608201529392505050565b6000610100808385031215612ee4578182fd5b612eed816132e2565b9050612ef883612c68565b8152612f0660208401612c68565b6020820152604083015161ffff81168114612f1f578283fd5b6040820152612f3060608401612c54565b6060820152612f4160808401612c54565b6080820152612f5260a08401612c54565b60a0820152612f6360c08401612c1a565b60c0820152612f7460e08401612a7f565b60e08201529392505050565b600060808284031215612f91578081fd5b612f9b60806132e2565b612fa483612c3d565b8152612fb260208401612c54565b6020820152612fc360408401612c54565b6040820152612ec560608401612c25565b600060208284031215612fe5578081fd5b5051919050565b60008060408385031215612ffe578182fd5b8235915060208301356001600160401b0381111561301a578182fd5b612cf185828601612bbd565b60008060006060848603121561303a578081fd5b505081359360208301359350604090920135919050565b60008060008060008060c08789031215613069578384fd5b86359550602087013594506040870135935060608701356001600160401b0380821115613094578384fd5b6130a08a838b01612bbd565b945060808901359150808211156130b5578384fd5b6130c18a838b01612bbd565b935060a08901359150808211156130d6578283fd5b50612ddb89828a01612bbd565b6000815180845260208085019450808401835b83811015613112578151875295820195908201906001016130f6565b509495945050505050565b60007f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000825283516131558160178501602088016133c8565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516131868160288401602088016133c8565b01602801949350505050565b600060018060a01b038916825287602083015286604083015285606083015260ff60f81b851660808301528360a083015260e060c08301526131d760e08301846130e3565b9998505050505050505050565b60006020825282518060208401526132038160408501602087016133c8565b601f01601f19169190910160400192915050565b6020808252601290820152716e6f7420656e6f7567682062616c616e636560701b604082015260600190565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b60008482526060602083015261328560608301856130e3565b905060018060a01b0383166040830152949350505050565b6000858252608060208301526132b660808301866130e3565b6001600160a01b038516604084015282810360608401526132d781856130e3565b979650505050505050565b604051601f8201601f191681016001600160401b038111828210171561330a5761330a613440565b604052919050565b60006001600160401b0382111561332b5761332b613440565b5060051b60200190565b600082198211156133485761334861342a565b500190565b60008261336857634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156133875761338761342a565b500290565b60008282101561339e5761339e61342a565b500390565b600063ffffffff838116908316818110156133c0576133c061342a565b039392505050565b60005b838110156133e35781810151838201526020016133cb565b838111156133f2576000848401525b50505050565b6000816134075761340761342a565b506000190190565b60006000198214156134235761342361342a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461346b57600080fd5b50565b801515811461346b57600080fdfea2646970667358221220fe577a55f06b2b53fb3afbdcb537833751cbb438ae26e789b4e07c80c8eb581d64736f6c63430008030033000000000000000000000000fb2e0ef40f552d460098d6d8ac70e6e3ee96f49600000000000000000000000082f9d5fe6c46990f3c2536e83b2b4e1c0a91f27f
Deployed Bytecode
0x6080604052600436106101b75760003560e01c80638350fbab116100ec578063bda3ed071161008a578063deebe61011610064578063deebe610146104fc578063e0e5120d1461051c578063f7e177de1461053c578063f9f98af614610552576101b7565b8063bda3ed071461048f578063c311d049146104bc578063d547741f146104dc576101b7565b8063928cb148116100c6578063928cb1481461042b578063a217fddf1461044b578063ae3068c114610460578063b29dc70a1461047c576101b7565b80638350fbab146103cb57806388d1ae6c146103f857806391d148541461040b576101b7565b8063248a9ca31161015957806336568abe1161013357806336568abe1461035557806354a7d0a914610375578063582f706f146103955780635a3b336c146103ab576101b7565b8063248a9ca3146102e5578063257ea0ab146103155780632f2ff15d14610335576101b7565b806313f431601161019557806313f431601461025957806315d21e11146102895780631c513339146102ad5780631d9083f3146102c3576101b7565b806301ffc9a7146101bc57806308a55a6e146101f15780630c02477614610221575b600080fd5b3480156101c857600080fd5b506101dc6101d7366004612e49565b610572565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b506101dc61020c366004612c7f565b60066020526000908152604090205460ff1681565b34801561022d57600080fd5b50600254610241906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b34801561026557600080fd5b506101dc610274366004612c7f565b60076020526000908152604090205460ff1681565b34801561029557600080fd5b5061029f60045481565b6040519081526020016101e8565b3480156102b957600080fd5b5061029f60035481565b3480156102cf57600080fd5b506102e36102de366004612c7f565b6105ab565b005b3480156102f157600080fd5b5061029f610300366004612e02565b60009081526020819052604090206001015490565b34801561032157600080fd5b506102e3610330366004612c7f565b6105e1565b34801561034157600080fd5b506102e3610350366004612e1a565b610616565b34801561036157600080fd5b506102e3610370366004612e1a565b610642565b34801561038157600080fd5b506102e3610390366004613026565b6106c5565b3480156103a157600080fd5b5061029f600a5481565b3480156103b757600080fd5b506102e36103c6366004612c7f565b6106e7565b3480156103d757600080fd5b5061029f6103e6366004612e02565b60096020526000908152604090205481565b6102e3610406366004613051565b61071f565b34801561041757600080fd5b506101dc610426366004612e1a565b611546565b34801561043757600080fd5b506102e3610446366004612c7f565b61156f565b34801561045757600080fd5b5061029f600081565b34801561046c57600080fd5b5061029f670de0b6b3a764000081565b6102e361048a366004612cfb565b6115a7565b34801561049b57600080fd5b5061029f6104aa366004612e02565b60086020526000908152604090205481565b3480156104c857600080fd5b506102e36104d7366004612e02565b612547565b3480156104e857600080fd5b506102e36104f7366004612e1a565b6125e3565b34801561050857600080fd5b506102e3610517366004612c9b565b612609565b34801561052857600080fd5b506102e3610537366004612c7f565b6126a2565b34801561054857600080fd5b5061029f60055481565b34801561055e57600080fd5b506102e361056d366004612fec565b6126d7565b60006001600160e01b03198216637965db0b60e01b14806105a357506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b6105b6600033610426565b6105bf57600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6105ec600033610426565b6105f557600080fd5b6001600160a01b03166000908152600660205260409020805460ff19169055565b60008281526020819052604090206001015461063381335b61274a565b61063d83836127ae565b505050565b6001600160a01b03811633146106b75760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6106c18282612832565b5050565b6106d0600033610426565b6106d957600080fd5b600492909255600355600555565b6106f2600033610426565b6106fb57600080fd5b6001600160a01b03166000908152600660205260409020805460ff19166001179055565b600260015414156107725760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106ae565b6002600155600b54604051631c39f49d60e21b815260048101889052602481018790526000916001600160a01b0316906370e7d2749060440160806040518083038186803b1580156107c357600080fd5b505afa1580156107d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fb9190612e71565b9050600086118015610816575080516001600160401b031615155b6108565760405162461bcd60e51b81526020600482015260116024820152701b595c99d9481b9bdd08185b1b1bddd959607a1b60448201526064016106ae565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915281516108979087906001600160401b031661336d565b815260025460609060009081906001600160a01b0316158015906108bb575060008a115b80156109625750600b546001600160a01b03166370e7d2748c6108df60018e61338c565b6040516001600160e01b031960e085901b1681526004810192909252602482015260440160806040518083038186803b15801561091b57600080fd5b505afa15801561092f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109539190612e71565b604001516001600160801b0316155b1515606085015260408501516001600160801b0316158015610a0d5750600b546040516311b820ed60e31b8152600481018d90526000916001600160a01b031690638dc10768906024016101006040518083038186803b1580156109c557600080fd5b505afa1580156109d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fd9190612ed1565b60e001516001600160a01b031614155b15156080850152606084015180610a25575083608001515b15610b245787516001600160401b03811115610a5157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a7a578160200160208202803683370190505b509250836060015115610a96576002546001600160a01b031691505b836080015115610b2457600b546040516311b820ed60e31b8152600481018d90526001600160a01b0390911690638dc10768906024016101006040518083038186803b158015610ae557600080fd5b505afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d9190612ed1565b60e0015190505b60005b885181101561131357600b546001600160a01b031662fdd58e338b8481518110610b6157634e487b7160e01b600052603260045260246000fd5b60200260200101516040518363ffffffff1660e01b8152600401610b9a9291906001600160a01b03929092168252602082015260400190565b60206040518083038186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bea9190612fd4565b888281518110610c0a57634e487b7160e01b600052603260045260246000fd5b60200260200101511115610c305760405162461bcd60e51b81526004016106ae90613217565b600b5489516000916001600160a01b0316906301870f02908c9085908110610c6857634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401610c8e91815260200190565b60806040518083038186803b158015610ca657600080fd5b505afa158015610cba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cde9190612f80565b80519091506001600160801b03168d14610d2a5760405162461bcd60e51b815260206004820152600d60248201526c0c6c2e4c840dad2e6dac2e8c6d609b1b60448201526064016106ae565b8b816020015163ffffffff1610610d8d5760405162461bcd60e51b815260206004820152602160248201527f63616e206f6e6c79206d6572676520696e746f20686967686572206c6576656c6044820152607360f81b60648201526084016106ae565b600b5481516020830151604051631c39f49d60e21b81526001600160801b03909216600483015263ffffffff1660248201526000916001600160a01b0316906370e7d2749060440160806040518083038186803b158015610ded57600080fd5b505afa158015610e01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e259190612e71565b9050816020015163ffffffff1660001415610e7b57898381518110610e5a57634e487b7160e01b600052603260045260246000fd5b602002602001015187602001818151610e739190613335565b905250610ed0565b80600001516001600160401b03168a8481518110610ea957634e487b7160e01b600052603260045260246000fd5b6020026020010151610ebb919061336d565b87602001818151610ecc9190613335565b9052505b600b546001600160a01b03166331126dd1338d8681518110610f0257634e487b7160e01b600052603260045260246000fd5b60200260200101518d8781518110610f2a57634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260006064820152608401600060405180830381600087803b158015610f8a57600080fd5b505af1158015610f9e573d6000803e3d6000fd5b50505050866060015180610fb3575086608001515b156112fe578a8381518110610fd857634e487b7160e01b600052603260045260246000fd5b602002602001015186848151811061100057634e487b7160e01b600052603260045260246000fd5b60200260200101818152505087600001516001600160401b03168760400151600161102b9190613335565b611035919061336d565b87602001511180611052575060018b5161104f919061338c565b83145b156112fe57604087018051906110678261340f565b90525060608701511561117d57846001600160a01b031663feb0ae7f600b60009054906101000a90046001600160a01b03166001600160a01b03166391ba317a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110d157600080fd5b505afa1580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111099190612fd4565b89604001516111189190613335565b600b546040516001600160e01b031960e085901b16815261114a92918b916001600160a01b039091169060040161326c565b600060405180830381600087803b15801561116457600080fd5b505af1158015611178573d6000803e3d6000fd5b505050505b86608001511561129257836001600160a01b031663e4a3fba9600b60009054906101000a90046001600160a01b03166001600160a01b03166391ba317a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111e457600080fd5b505afa1580156111f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121c9190612fd4565b896040015161122b9190613335565b600b546040516001600160e01b031960e085901b16815261125f92918b916001600160a01b03909116908f9060040161329d565b600060405180830381600087803b15801561127957600080fd5b505af115801561128d573d6000803e3d6000fd5b505050505b8b876040015110156112fe5787600001516001600160401b03166001600160401b038111156112d157634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156112fa578160200160208202803683370190505b5095505b5050808061130b9061340f565b915050610b27565b50835160208501511461135f5760405162461bcd60e51b81526020600482015260146024820152731ddc9bdb99c81b9bc81d1adb9cc8189d5c9b995960621b60448201526064016106ae565b60008a815260086020526040902054349061137b908b9061336d565b11156113ba5760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced0408aa8960931b60448201526064016106ae565b60008a81526008602052604081205433906113d6908c9061336d565b6113e0903461338c565b604051600081818185875af1925050503d806000811461141c576040519150601f19603f3d011682016040523d82523d6000602084013e611421565b606091505b50509050806114425760405162461bcd60e51b81526004016106ae90613243565b600b546001600160a01b031663a39501df338e8e8e600b60009054906101000a90046001600160a01b03166001600160a01b0316636bb2e32d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114a557600080fd5b505afa1580156114b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114dd9190612de8565b60008e6040518863ffffffff1660e01b81526004016115029796959493929190613192565b600060405180830381600087803b15801561151c57600080fd5b505af1158015611530573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61157a600033610426565b61158357600080fd5b6001600160a01b03166000908152600760205260409020805460ff19166001179055565b600260015414156115fa5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106ae565b60026001556040805160a0810182526000808252602082018190529181018290526060810182905260808101829052905b8751811015611d4557600b5488516000916001600160a01b031690638dc10768908b908590811061166c57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161169291815260200190565b6101006040518083038186803b1580156116ab57600080fd5b505afa1580156116bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e39190612ed1565b600b548a519192506000916001600160a01b03909116906370e7d274908c908690811061172057634e487b7160e01b600052603260045260246000fd5b602002602001015160006040518363ffffffff1660e01b8152600401611750929190918252602082015260400190565b60806040518083038186803b15801561176857600080fd5b505afa15801561177c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a09190612e71565b905060008260a0015163ffffffff1690506000600960008d87815181106117d757634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002054111561183257600960008c868151811061181857634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000205490505b80421015806118475750611847600033610426565b61187f5760405162461bcd60e51b8152602060048201526009602482015268746f6f206561726c7960b81b60448201526064016106ae565b826040015161ffff168a85815181106118a857634e487b7160e01b600052603260045260246000fd5b6020908102919091010151600b546001600160a01b0316630a3de451338f89815181106118e557634e487b7160e01b600052603260045260246000fd5b60200260200101516040518363ffffffff1660e01b815260040161191e9291906001600160a01b03929092168252602082015260400190565b60206040518083038186803b15801561193657600080fd5b505afa15801561194a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196e9190612fd4565b6119789190613335565b11156119c65760405162461bcd60e51b815260206004820152601d60248201527f4d6178206d696e7473207265616368656420666f72206164647265737300000060448201526064016106ae565b826080015163ffffffff168a85815181106119f157634e487b7160e01b600052603260045260246000fd5b6020026020010151836020015163ffffffff16611a0e9190613335565b1115611a5b5781602001518360800151611a2891906133a3565b63ffffffff168a8581518110611a4e57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b888481518110611a7b57634e487b7160e01b600052603260045260246000fd5b602002602001015115611b425782516001600160401b0316611ad65760405162461bcd60e51b81526020600482015260146024820152731d5b9a58dbdc9b9cc81b9bdd08185b1b1bddd95960621b60448201526064016106ae565b670de0b6b3a76400008a8581518110611aff57634e487b7160e01b600052603260045260246000fd5b602002602001015184600001516001600160401b0316611b1f919061336d565b611b29919061336d565b85602001818151611b3a9190613335565b905250611bfc565b600083602001516001600160401b031611611b965760405162461bcd60e51b81526020600482015260146024820152731c985a5b989bdddcc81b9bdd08185b1b1bddd95960621b60448201526064016106ae565b670de0b6b3a76400008a8581518110611bbf57634e487b7160e01b600052603260045260246000fd5b602002602001015184602001516001600160401b0316611bdf919061336d565b611be9919061336d565b85518690611bf8908390613335565b9052505b60208301516001600160401b031615611ca157600354611c1e9061271061336d565b600a54670de0b6b3a76400008c8781518110611c4a57634e487b7160e01b600052603260045260246000fd5b602002602001015186602001516001600160401b0316611c6a919061336d565b611c74919061336d565b611c7e919061336d565b611c88919061334d565b85604001818151611c999190613335565b905250611d2f565b600454611cb09061271061336d565b600a54670de0b6b3a76400008c8781518110611cdc57634e487b7160e01b600052603260045260246000fd5b602002602001015186600001516001600160401b0316611cfc919061336d565b611d06919061336d565b611d10919061336d565b611d1a919061334d565b85604001818151611d2b9190613335565b9052505b5050508080611d3d9061340f565b91505061162b565b506000606082018190525b60028110156121c75780151560008082611d6b578451611d71565b84602001515b90508080156121b057600084611d88578851611d8b565b87515b905060008111611dcd5760405162461bcd60e51b815260206004820152600d60248201526c696e76616c696420706f6f6c7360981b60448201526064016106ae565b60005b818110156121025760008615611e9d57600760008b8481518110611e0457634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611e6e5760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081d5b9a58dbdc9b881c1bdbdb60621b60448201526064016106ae565b898281518110611e8e57634e487b7160e01b600052603260045260246000fd5b60200260200101519050611f56565b600660008c8481518110611ec157634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611f2b5760405162461bcd60e51b81526020600482015260146024820152731a5b9d985b1a59081c985a5b989bddc81c1bdbdb60621b60448201526064016106ae565b8a8281518110611f4b57634e487b7160e01b600052603260045260246000fd5b602002602001015190505b60006001600160a01b0382166370a08231336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260240160206040518083038186803b158015611fa757600080fd5b505afa158015611fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fdf9190612fd4565b9050611feb8188613335565b965085871061206f576001600160a01b038216639dc29fac336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101889052604401600060405180830381600087803b15801561204c57600080fd5b505af1158015612060573d6000803e3d6000fd5b50505050600094505050612102565b6001600160a01b038216639dc29fac336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101849052604401600060405180830381600087803b1580156120c757600080fd5b505af11580156120db573d6000803e3d6000fd5b5050505080856120eb919061338c565b9450505080806120fa9061340f565b915050611dd0565b5081156121ae57600060646005548561211b919061336d565b612125919061334d565b905080612132848661338c565b10156121505760405162461bcd60e51b81526004016106ae90613217565b60008661215f57600354612163565b6004545b905083612170823461336d565b1161218d5760405162461bcd60e51b81526004016106ae90613217565b612197818561334d565b896060018181516121a89190613335565b90525050505b505b5050505080806121bf9061340f565b915050611d50565b508060400151816060018181516121de9190613335565b90525060608101513410156121f257600080fd5b60608101513390612203903461338c565b604051600081818185875af1925050503d806000811461223f576040519150601f19603f3d011682016040523d82523d6000602084013e612244565b606091505b505015156080820181905261226b5760405162461bcd60e51b81526004016106ae90613243565b6000805b88518110156124f457600088828151811061229a57634e487b7160e01b600052603260045260246000fd5b602002602001015111156124e257600b546001600160a01b031663c2fa4019338b84815181106122da57634e487b7160e01b600052603260045260246000fd5b60200260200101518b858151811061230257634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801561235b57600080fd5b505af115801561236f573d6000803e3d6000fd5b5050600b546001600160a01b0316915063a39501df9050338b84815181106123a757634e487b7160e01b600052603260045260246000fd5b602002602001015160008c86815181106123d157634e487b7160e01b600052603260045260246000fd5b6020026020010151600b60009054906101000a90046001600160a01b03166001600160a01b0316636bb2e32d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561242757600080fd5b505afa15801561243b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245f9190612de8565b60008d898151811061248157634e487b7160e01b600052603260045260246000fd5b60200260200101516040518863ffffffff1660e01b81526004016124ab9796959493929190613192565b600060405180830381600087803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b50505050600191505b806124ec8161340f565b91505061226f565b50806125395760405162461bcd60e51b8152602060048201526014602482015273105b1b1bd8d85d1a5bdb88195e1a185d5cdd195960621b60448201526064016106ae565b505060018055505050505050565b612552600033610426565b61255b57600080fd5b4781111561257b5760405162461bcd60e51b81526004016106ae90613217565b604051600090339083908381818185875af1925050503d80600081146125bd576040519150601f19603f3d011682016040523d82523d6000602084013e6125c2565b606091505b50509050806106c15760405162461bcd60e51b81526004016106ae90613243565b6000828152602081905260409020600101546125ff813361062e565b61063d8383612832565b612614600033610426565b61261d57600080fd5b60005b825181101561063d5781818151811061264957634e487b7160e01b600052603260045260246000fd5b60200260200101516009600085848151811061267557634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002081905550808061269a9061340f565b915050612620565b6126ad600033610426565b6126b657600080fd5b6001600160a01b03166000908152600760205260409020805460ff19169055565b6126e2600033610426565b6126eb57600080fd5b600a82905560015b815181101561063d5781818151811061271c57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008381526008909252604090912055806127428161340f565b9150506126f3565b6127548282611546565b6106c15761276c816001600160a01b03166014612897565b612777836020612897565b60405160200161278892919061311d565b60408051601f198184030181529082905262461bcd60e51b82526106ae916004016131e4565b6127b88282611546565b6106c1576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556127ee3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61283c8282611546565b156106c1576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b606060006128a683600261336d565b6128b1906002613335565b6001600160401b038111156128d657634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612900576020820181803683370190505b509050600360fc1b8160008151811061292957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061296657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600061298a84600261336d565b612995906001613335565b90505b6001811115612a29576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106129d757634e487b7160e01b600052603260045260246000fd5b1a60f81b8282815181106129fb57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93612a22816133f8565b9050612998565b508315612a785760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106ae565b9392505050565b80516105a681613456565b600082601f830112612a9a578081fd5b81356020612aaf612aaa83613312565b6132e2565b80838252828201915082860187848660051b8901011115612ace578586fd5b855b85811015612af5578135612ae381613456565b84529284019290840190600101612ad0565b5090979650505050505050565b600082601f830112612b12578081fd5b81356020612b22612aaa83613312565b82815281810190858301855b85811015612af557612b45898684358b0101612bbd565b84529284019290840190600101612b2e565b600082601f830112612b67578081fd5b81356020612b77612aaa83613312565b80838252828201915082860187848660051b8901011115612b96578586fd5b855b85811015612af5578135612bab8161346e565b84529284019290840190600101612b98565b600082601f830112612bcd578081fd5b81356020612bdd612aaa83613312565b80838252828201915082860187848660051b8901011115612bfc578586fd5b855b85811015612af557813584529284019290840190600101612bfe565b80516105a68161346e565b80516001600160f81b0319811681146105a657600080fd5b80516001600160801b03811681146105a657600080fd5b805163ffffffff811681146105a657600080fd5b80516001600160401b03811681146105a657600080fd5b600060208284031215612c90578081fd5b8135612a7881613456565b60008060408385031215612cad578081fd5b82356001600160401b0380821115612cc3578283fd5b612ccf86838701612bbd565b93506020850135915080821115612ce4578283fd5b50612cf185828601612bbd565b9150509250929050565b60008060008060008060c08789031215612d13578182fd5b86356001600160401b0380821115612d29578384fd5b612d358a838b01612bbd565b97506020890135915080821115612d4a578384fd5b612d568a838b01612bbd565b96506040890135915080821115612d6b578384fd5b612d778a838b01612b57565b95506060890135915080821115612d8c578384fd5b612d988a838b01612b02565b94506080890135915080821115612dad578384fd5b612db98a838b01612a8a565b935060a0890135915080821115612dce578283fd5b50612ddb89828a01612a8a565b9150509295509295509295565b600060208284031215612df9578081fd5b612a7882612c25565b600060208284031215612e13578081fd5b5035919050565b60008060408385031215612e2c578182fd5b823591506020830135612e3e81613456565b809150509250929050565b600060208284031215612e5a578081fd5b81356001600160e01b031981168114612a78578182fd5b600060808284031215612e82578081fd5b612e8c60806132e2565b612e9583612c68565b8152612ea360208401612c54565b6020820152612eb460408401612c3d565b6040820152612ec560608401612c54565b60608201529392505050565b6000610100808385031215612ee4578182fd5b612eed816132e2565b9050612ef883612c68565b8152612f0660208401612c68565b6020820152604083015161ffff81168114612f1f578283fd5b6040820152612f3060608401612c54565b6060820152612f4160808401612c54565b6080820152612f5260a08401612c54565b60a0820152612f6360c08401612c1a565b60c0820152612f7460e08401612a7f565b60e08201529392505050565b600060808284031215612f91578081fd5b612f9b60806132e2565b612fa483612c3d565b8152612fb260208401612c54565b6020820152612fc360408401612c54565b6040820152612ec560608401612c25565b600060208284031215612fe5578081fd5b5051919050565b60008060408385031215612ffe578182fd5b8235915060208301356001600160401b0381111561301a578182fd5b612cf185828601612bbd565b60008060006060848603121561303a578081fd5b505081359360208301359350604090920135919050565b60008060008060008060c08789031215613069578384fd5b86359550602087013594506040870135935060608701356001600160401b0380821115613094578384fd5b6130a08a838b01612bbd565b945060808901359150808211156130b5578384fd5b6130c18a838b01612bbd565b935060a08901359150808211156130d6578283fd5b50612ddb89828a01612bbd565b6000815180845260208085019450808401835b83811015613112578151875295820195908201906001016130f6565b509495945050505050565b60007f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000825283516131558160178501602088016133c8565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516131868160288401602088016133c8565b01602801949350505050565b600060018060a01b038916825287602083015286604083015285606083015260ff60f81b851660808301528360a083015260e060c08301526131d760e08301846130e3565b9998505050505050505050565b60006020825282518060208401526132038160408501602087016133c8565b601f01601f19169190910160400192915050565b6020808252601290820152716e6f7420656e6f7567682062616c616e636560701b604082015260600190565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b60008482526060602083015261328560608301856130e3565b905060018060a01b0383166040830152949350505050565b6000858252608060208301526132b660808301866130e3565b6001600160a01b038516604084015282810360608401526132d781856130e3565b979650505050505050565b604051601f8201601f191681016001600160401b038111828210171561330a5761330a613440565b604052919050565b60006001600160401b0382111561332b5761332b613440565b5060051b60200190565b600082198211156133485761334861342a565b500190565b60008261336857634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156133875761338761342a565b500290565b60008282101561339e5761339e61342a565b500390565b600063ffffffff838116908316818110156133c0576133c061342a565b039392505050565b60005b838110156133e35781810151838201526020016133cb565b838111156133f2576000848401525b50505050565b6000816134075761340761342a565b506000190190565b60006000198214156134235761342361342a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461346b57600080fd5b50565b801515811461346b57600080fdfea2646970667358221220fe577a55f06b2b53fb3afbdcb537833751cbb438ae26e789b4e07c80c8eb581d64736f6c63430008030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fb2e0ef40f552d460098d6d8ac70e6e3ee96f49600000000000000000000000082f9d5fe6c46990f3c2536e83b2b4e1c0a91f27f
-----Decoded View---------------
Arg [0] : _nftContractAddress (address): 0xfB2e0Ef40f552D460098d6D8aC70e6e3eE96f496
Arg [1] : _contractOwner (address): 0x82F9d5FE6C46990f3C2536e83b2B4e1c0a91F27f
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000fb2e0ef40f552d460098d6d8ac70e6e3ee96f496
Arg [1] : 00000000000000000000000082f9d5fe6c46990f3c2536e83b2b4e1c0a91f27f
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1,138.44
Net Worth in ETH
0.59003
Token Allocations
ETH
99.56%
BNB
0.44%
Multichain Portfolio | 33 Chains
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.