Source Code
Latest 25 from a total of 2,203 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Start Reveal | 11783942 | 428 days ago | IN | 0 ETH | 0.00000052 | ||||
| Start Reveal | 11712260 | 430 days ago | IN | 0 ETH | 0.0000003 | ||||
| Start Reveal | 11712249 | 430 days ago | IN | 0 ETH | 0.00000031 | ||||
| Start Reveal | 11712230 | 430 days ago | IN | 0 ETH | 0.0000003 | ||||
| Start Reveal | 11712222 | 430 days ago | IN | 0 ETH | 0.0000003 | ||||
| Start Reveal | 11712210 | 430 days ago | IN | 0 ETH | 0.0000003 | ||||
| Start Reveal | 11712200 | 430 days ago | IN | 0 ETH | 0.0000003 | ||||
| Start Reveal | 11712188 | 430 days ago | IN | 0 ETH | 0.00000031 | ||||
| Start Reveal | 11666497 | 431 days ago | IN | 0 ETH | 0.00000044 | ||||
| Start Reveal | 11498863 | 435 days ago | IN | 0 ETH | 0.00000079 | ||||
| Start Reveal | 11498860 | 435 days ago | IN | 0 ETH | 0.00000104 | ||||
| Start Reveal | 11469909 | 435 days ago | IN | 0 ETH | 0.00000051 | ||||
| Start Reveal | 11407767 | 437 days ago | IN | 0 ETH | 0.00000118 | ||||
| Start Reveal | 11385241 | 437 days ago | IN | 0 ETH | 0.00000066 | ||||
| Start Reveal | 11367178 | 438 days ago | IN | 0 ETH | 0.00000025 | ||||
| Start Reveal | 11356794 | 438 days ago | IN | 0 ETH | 0.00000043 | ||||
| Start Reveal | 11356168 | 438 days ago | IN | 0 ETH | 0.00000047 | ||||
| Start Reveal | 11350916 | 438 days ago | IN | 0 ETH | 0.00000105 | ||||
| Start Reveal | 11316073 | 439 days ago | IN | 0 ETH | 0.00000055 | ||||
| Start Reveal | 11316062 | 439 days ago | IN | 0 ETH | 0.00000057 | ||||
| Start Reveal | 11316049 | 439 days ago | IN | 0 ETH | 0.00000058 | ||||
| Start Reveal | 11316037 | 439 days ago | IN | 0 ETH | 0.00000057 | ||||
| Start Reveal | 11316025 | 439 days ago | IN | 0 ETH | 0.00000058 | ||||
| Start Reveal | 11279050 | 440 days ago | IN | 0 ETH | 0.00000104 | ||||
| Start Reveal | 11279040 | 440 days ago | IN | 0 ETH | 0.00000096 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
NFTOverlord
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 2000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
import "../interfaces/INFTOverlord.sol";
import "../interfaces/IRNGProxy.sol";
import "../managers/BaseBlastManager.sol";
import "../interfaces/INFTAttributesManager.sol";
import "../interfaces/IAccountManager.sol";
import "../interfaces/IMunchNFT.sol";
contract NFTOverlord is BaseBlastManager, INFTOverlord {
uint16 MAX_REVEAL_QUEUE;
mapping(address => uint16) unrevealedNFTs;
mapping(address => uint16) revealQueue;
mapping(address => uint96) rngNonce;
uint8[] realmLookup;
mapping(uint8 => MintProbability) mintProbabilities;
mapping(uint256 => LevelUpRequest) levelUpRequests;
uint256[] levelThresholds;
address munchNFT;
IRNGProxy rngProxy;
INFTAttributesManager nftAttributesManager;
IAccountManager accountManager;
constructor(address _configStorage) {
__BaseConfigStorage_setConfigStorage(_configStorage);
_reconfigure();
}
function _reconfigure() internal {
munchNFT = configStorage.getAddress(StorageKey.MunchNFT);
rngProxy = IRNGProxy(
configStorage.getAddress(StorageKey.RNGProxyContract)
);
nftAttributesManager = INFTAttributesManager(
configStorage.getAddress(StorageKey.NFTAttributesManager)
);
accountManager = IAccountManager(
configStorage.getAddress(StorageKey.AccountManager)
);
_populateDefaultProbabilities();
_populateDefaultRealmLookup();
levelThresholds = configStorage.getUintArray(
StorageKey.LevelThresholds
);
MAX_REVEAL_QUEUE = uint16(
configStorage.getSmallInt(StorageKey.MaxRevealQueue)
); // 1
super.__BaseBlastManager_reconfigure();
}
function configUpdated() external override onlyConfigStorage {
_reconfigure();
}
/// @inheritdoc INFTOverlord
function addReveal(
address _player,
uint16 _quantity
) external override onlyConfiguredContract(StorageKey.LockManager) {
// LockManager has already verified this is a registered account
unrevealedNFTs[_player] += _quantity;
}
/// @inheritdoc INFTOverlord
function startReveal() external notPaused {
// a sub-account can start a reveal for the main account
(address _mainAccount, ) = _getMainAccountRequireRegistered(msg.sender);
if (unrevealedNFTs[_mainAccount] == 0)
revert NoUnrevealedMunchablesError();
if (revealQueue[_mainAccount] >= MAX_REVEAL_QUEUE)
revert RevealQueueFullError();
uint256 revealIndex = uint256(uint160(_mainAccount)) |
(uint256(rngNonce[_mainAccount]) << 160);
unrevealedNFTs[_mainAccount]--;
revealQueue[_mainAccount]++;
rngNonce[_mainAccount]++;
rngProxy.requestRandom(
address(this),
bytes4(keccak256("reveal(uint256,bytes)")),
revealIndex
);
emit MunchableRevealRequested(_mainAccount);
}
/// @inheritdoc INFTOverlord
// Called by the rng proxy
function reveal(
uint256 _player,
bytes memory _signature
)
external
onlyConfiguredContract(StorageKey.RNGProxyContract)
returns (uint256 _tokenId)
{
// decode _player
address player = address(uint160(_player));
if (revealQueue[player] == 0) revert RevealQueueEmptyError();
uint256 tokenId = IMunchNFT(munchNFT).nextTokenId();
_createWithEntropy(
tokenId,
_signature,
MunchablesCommonLib.Rarity.Mythic
);
// Message validated, mint the token
IMunchNFT(munchNFT).mint(player);
MunchablesCommonLib.NFTImmutableAttributes
memory _immutableAttributes = nftAttributesManager
.getImmutableAttributes(tokenId);
--revealQueue[player];
_tokenId = tokenId;
emit Revealed(player, tokenId, _immutableAttributes);
}
function mintFromPrimordial(
address _account
) external onlyConfiguredContract(StorageKey.PrimordialManager) {
(address _player, ) = accountManager.getPlayer(_account);
// start reveal process
if (revealQueue[_player] >= MAX_REVEAL_QUEUE)
revert RevealQueueFullError();
uint256 revealIndex = uint256(uint160(_player)) |
(uint256(rngNonce[_player]) << 160);
revealQueue[_player]++;
rngNonce[_player]++;
rngProxy.requestRandom(
address(this),
bytes4(keccak256("revealFromPrimordial(uint256,bytes)")),
revealIndex
);
}
/// @inheritdoc INFTOverlord
// Called by the rng proxy
function revealFromPrimordial(
uint256 _player,
bytes memory _signature
)
external
onlyConfiguredContract(StorageKey.RNGProxyContract)
returns (uint256 _tokenId)
{
// decode _player
address player = address(uint160(_player));
if (revealQueue[player] == 0) revert RevealQueueEmptyError();
// Message validated, mint the token
uint256 tokenId = IMunchNFT(munchNFT).nextTokenId();
_createWithEntropy(
tokenId,
_signature,
MunchablesCommonLib.Rarity.Rare
);
IMunchNFT(munchNFT).mint(player);
MunchablesCommonLib.NFTImmutableAttributes
memory _immutableAttributes = nftAttributesManager
.getImmutableAttributes(tokenId);
--revealQueue[player];
_tokenId = tokenId;
emit PrimordialHatched(player, _immutableAttributes);
}
/// @inheritdoc INFTOverlord
function mintForMigration(
address _player,
MunchablesCommonLib.NFTAttributes memory _attributes,
MunchablesCommonLib.NFTImmutableAttributes memory _immutableAttributes,
MunchablesCommonLib.NFTGameAttribute[] memory _gameAttributes
)
external
override
onlyConfiguredContract(StorageKey.MigrationManager)
returns (uint256 _tokenId)
{
uint256 tokenId = IMunchNFT(munchNFT).nextTokenId();
nftAttributesManager.createWithImmutable(tokenId, _immutableAttributes);
nftAttributesManager.setAttributes(tokenId, _attributes);
nftAttributesManager.setGameAttributes(tokenId, _gameAttributes);
IMunchNFT(munchNFT).mint(_player);
_tokenId = tokenId;
emit MintedForMigration(
_player,
tokenId,
_immutableAttributes,
_attributes,
_gameAttributes
);
}
/// @inheritdoc INFTOverlord
function levelUp(
uint256 _requestId,
bytes memory _rng
) external onlyConfiguredContract(StorageKey.RNGProxyContract) {
LevelUpRequest memory levelUpRequest = levelUpRequests[_requestId];
if (levelUpRequest.owner == address(0)) revert InvalidLevelUpRequest();
uint16 toLevel = levelUpRequest.toLevel;
// verify levelUp
MunchablesCommonLib.NFTAttributes
memory attributes = nftAttributesManager.getAttributes(
levelUpRequest.tokenId
);
if (attributes.level != levelUpRequest.fromLevel)
revert InvalidLevelUpRequest();
if (levelUpRequest.toLevel <= levelUpRequest.fromLevel)
revert InvalidLevelUpRequest();
MunchablesCommonLib.NFTGameAttribute[]
memory gameAttributes = nftAttributesManager.getGameAttributes(
levelUpRequest.tokenId,
new MunchablesCommonLib.GameAttributeIndex[](0)
);
if (_rng.length < gameAttributes.length)
revert MunchablesCommonLib.NotEnoughRandomError();
uint16 thisToLevel = levelUpRequest.toLevel;
uint16 nextFromLevel;
if (levelUpRequest.toLevel - levelUpRequest.fromLevel > 1) {
thisToLevel = levelUpRequest.fromLevel + 1;
nextFromLevel = thisToLevel;
}
int16 zeroed;
for (uint8 i; i < gameAttributes.length; i++) {
if (
nftAttributesManager.getGameAttributeDataType(i) ==
MunchablesCommonLib.GameAttributeType.SmallInt
) {
if (
gameAttributes[i].dataType ==
MunchablesCommonLib.GameAttributeType.NotSet
) {
gameAttributes[i].dataType = MunchablesCommonLib
.GameAttributeType
.SmallInt;
gameAttributes[i].value = abi.encode(zeroed);
}
int16 currentValue;
if (gameAttributes[i].value.length == 32) {
currentValue = abi.decode(gameAttributes[i].value, (int16));
}
if (uint8(_rng[i]) % 3 > 0) {
currentValue += int16(int8(uint8(_rng[i]) % 3));
gameAttributes[i].value = abi.encode(currentValue);
}
}
}
attributes.level = thisToLevel;
nftAttributesManager.setAttributes(levelUpRequest.tokenId, attributes);
nftAttributesManager.setGameAttributes(
levelUpRequest.tokenId,
gameAttributes
);
if (toLevel != thisToLevel) {
// send another request
_requestLevelUpRng(
levelUpRequest.owner,
levelUpRequest.tokenId,
nextFromLevel,
levelUpRequest.toLevel
);
}
delete levelUpRequests[_requestId];
emit LevelledUp(
levelUpRequest.owner,
levelUpRequest.tokenId,
levelUpRequest.fromLevel,
thisToLevel,
gameAttributes
);
}
/// @inheritdoc INFTOverlord
function munchableFed(
uint256 _tokenId,
address _owner
) external onlyConfiguredContract(StorageKey.SnuggeryManager) {
MunchablesCommonLib.NFTAttributes
memory currentAttributes = nftAttributesManager.getAttributes(
_tokenId
);
// Calculate levelup, just send event for the off-chain process to handle
(uint16 _currentLevel, ) = MunchablesCommonLib.getLevelThresholds(
levelThresholds,
currentAttributes.chonks
);
if (_currentLevel > currentAttributes.level) {
// level up, request RNG
_requestLevelUpRng(
_owner,
_tokenId,
currentAttributes.level,
_currentLevel
);
emit MunchableLevelUpRequest(
_owner,
_tokenId,
currentAttributes.level,
_currentLevel
);
}
}
function retriggerLevelRNG(
uint256[] memory _tokenIds
) external onlyRole(Role.Minter) {
for (uint i; i < _tokenIds.length; i++) {
uint256 _tokenId = _tokenIds[i];
address owner = IERC721(munchNFT).ownerOf(_tokenId);
MunchablesCommonLib.NFTAttributes
memory attrs = nftAttributesManager.getAttributes(_tokenId);
uint16 toLevel = attrs.level;
attrs.level = 1;
nftAttributesManager.setAttributes(_tokenId, attrs);
MunchablesCommonLib.NFTGameAttribute[]
memory gameAttributes = nftAttributesManager.getGameAttributes(
_tokenId,
new MunchablesCommonLib.GameAttributeIndex[](0)
);
for (uint8 j; j < gameAttributes.length; j++) {
if (
nftAttributesManager.getGameAttributeDataType(j) ==
MunchablesCommonLib.GameAttributeType.SmallInt
) {
gameAttributes[j].value = abi.encode(int16(0));
} else if (
nftAttributesManager.getGameAttributeDataType(j) ==
MunchablesCommonLib.GameAttributeType.Bool
) {
gameAttributes[j].value = abi.encode(uint256(1));
}
}
nftAttributesManager.setGameAttributes(_tokenId, gameAttributes);
_requestLevelUpRng(owner, _tokenId, 1, toLevel);
}
emit RetriggeredLevelRNG(_tokenIds);
}
function setUnrevealedNFTs(
address _player,
uint16 _unrevealed
) external onlyRole(Role.Minter) {
unrevealedNFTs[_player] = _unrevealed;
}
/// @inheritdoc INFTOverlord
function getUnrevealedNFTs(
address _player
) external view returns (uint16 _unrevealed) {
(address _mainAccount, ) = accountManager.getPlayer(_player);
_unrevealed = unrevealedNFTs[_mainAccount];
}
/// @inheritdoc INFTOverlord
function getLevelUpData(
uint256 _chonks
)
external
view
returns (uint16 _currentLevel, uint256 _currentLevelThreshold)
{
(_currentLevel, _currentLevelThreshold) = MunchablesCommonLib
.getLevelThresholds(levelThresholds, _chonks);
}
// used during reveal
function _createWithEntropy(
uint256 _tokenId,
bytes memory _entropy,
MunchablesCommonLib.Rarity _maxRarity
) internal {
// Use algorithm for choosing NFT rarity and then species
(
MunchablesCommonLib.Rarity rarity,
uint16 speciesId
) = _calculateRaritySpecies(_entropy, _maxRarity);
if (speciesId >= realmLookup.length)
revert NoRealmFoundError(speciesId);
MunchablesCommonLib.NFTImmutableAttributes
memory immutableAttributes = MunchablesCommonLib
.NFTImmutableAttributes({
rarity: rarity,
species: speciesId,
realm: MunchablesCommonLib.Realm(realmLookup[speciesId]),
generation: 2,
hatchedDate: uint32(block.timestamp)
});
nftAttributesManager.createWithImmutable(_tokenId, immutableAttributes);
// set level to 1 for new nfts
MunchablesCommonLib.NFTAttributes memory attrs;
attrs.level = 1;
nftAttributesManager.setAttributes(_tokenId, attrs);
}
function _calculateRaritySpecies(
bytes memory randomBytes,
MunchablesCommonLib.Rarity maxRarity
) internal view returns (MunchablesCommonLib.Rarity, uint16) {
(uint32 rarityPercentage, uint32 speciesPercent) = MunchablesCommonLib
.calculateRaritySpeciesPercentage(randomBytes);
MunchablesCommonLib.Rarity selectedRarity = MunchablesCommonLib
.Rarity
.Invalid;
uint16 selectedSpeciesId;
// Loop through the rarities starting at Common and ending at Mythic
// check if cumulative percentage has been passed
uint256 cumulativePercent;
uint256 randomIndex;
for (
uint8 i = uint8(MunchablesCommonLib.Rarity.Common);
i <= uint8(MunchablesCommonLib.Rarity.Mythic);
i++
) {
// Compare mintProbabilities[i].percentage to rarityPercentage
cumulativePercent += mintProbabilities[i].percentage;
if (cumulativePercent >= rarityPercentage) {
// if they exceeded max then give max rarity instead
if (i > uint8(maxRarity)) {
selectedRarity = maxRarity;
} else {
selectedRarity = MunchablesCommonLib.Rarity(i);
}
// Randomly select a species from the mintProbabilities entry
uint256 speciesCount = mintProbabilities[uint8(selectedRarity)]
.species
.length;
if (speciesCount == 0)
revert NoSpeciesFoundError(selectedRarity);
randomIndex = uint256(speciesPercent) % speciesCount;
if (
randomIndex ==
mintProbabilities[uint8(selectedRarity)].species.length
) {
randomIndex =
mintProbabilities[uint8(selectedRarity)]
.species
.length -
1;
}
selectedSpeciesId = mintProbabilities[uint8(selectedRarity)]
.species[randomIndex];
break;
}
}
return (selectedRarity, selectedSpeciesId);
}
function _populateDefaultProbabilities() internal {
MunchablesCommonLib.Rarity[5] memory rarities = [
MunchablesCommonLib.Rarity.Common,
MunchablesCommonLib.Rarity.Rare,
MunchablesCommonLib.Rarity.Epic,
MunchablesCommonLib.Rarity.Legendary,
MunchablesCommonLib.Rarity.Mythic
];
StorageKey[5] memory percentageKeys = [
StorageKey.CommonPercentage,
StorageKey.RarePercentage,
StorageKey.EpicPercentage,
StorageKey.LegendaryPercentage,
StorageKey.MythicPercentage
];
StorageKey[5] memory speciesKeys = [
StorageKey.CommonSpecies,
StorageKey.RareSpecies,
StorageKey.EpicSpecies,
StorageKey.LegendarySpecies,
StorageKey.MythicSpecies
];
for (uint8 i = 0; i < rarities.length; i++) {
mintProbabilities[uint8(rarities[i])] = MintProbability({
percentage: uint32(configStorage.getUint(percentageKeys[i])),
species: configStorage.getSmallUintArray(speciesKeys[i])
});
}
}
function _populateDefaultRealmLookup() internal {
uint8[] memory realms = configStorage.getSmallUintArray(
StorageKey.RealmLookups
);
for (uint16 i = 0; i < realms.length; i++) {
realmLookup.push(realms[i]);
}
}
function _getMainAccountRequireRegistered(
address _account
)
internal
view
returns (
address _mainAccount,
MunchablesCommonLib.Player memory _player
)
{
(_mainAccount, _player) = accountManager.getPlayer(_account);
if (_player.registrationDate == 0) revert PlayerNotRegisteredError();
}
function _toUint256(bytes32 input) private pure returns (uint256 result) {
assembly {
result := input
}
}
function _requestLevelUpRng(
address _owner,
uint256 _tokenId,
uint16 _fromLevel,
uint16 _toLevel
) private {
bytes32 dataHash = keccak256(
abi.encode(_owner, _tokenId, _fromLevel, _toLevel)
);
uint256 levelUpIndex = _toUint256(dataHash);
levelUpRequests[levelUpIndex] = LevelUpRequest({
owner: _owner,
tokenId: _tokenId,
fromLevel: _fromLevel,
toLevel: _toLevel
});
rngProxy.requestRandom(
address(this),
bytes4(keccak256("levelUp(uint256,bytes)")),
levelUpIndex
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for the NFT Overlord
/// @notice This interface manages NFT minting and level up functions which rely on the RNGProxy. The implementation
/// contract will also handle notification from the LockManager contract when a player has earned
interface INFTOverlord {
/// @notice Stored between level up requests for a specific token id
struct LevelUpRequest {
address owner;
uint256 tokenId;
uint16 fromLevel;
uint16 toLevel;
}
/// @notice Struct to define mint probabilities based on percentage and species array
struct MintProbability {
uint32 percentage; // Probability percentage
uint8[] species; // Array of species IDs that can be minted under this probability
}
/// @notice Deduct one from Player.unrevealedNFTs and add one to AccountManager.revealQueue
/// @custom:frontend Use to reveal an NFT, listen for the events to see when it was minted
function startReveal() external;
/// @notice Add to Player.unrevealedNFTs, function only callable by lock manager
/// @param _player Address of the player
/// @param _quantity Quantity of reveals to add
function addReveal(address _player, uint16 _quantity) external;
/// @notice Reveals an NFT based on provided player ID and signature, decrementing the reveal queue
/// @param _player The player ID for whom the NFT will be revealed
/// @param _signature The signature to validate the reveal process
/// @return _tokenId The ID of the minted NFT
/// @dev This function should be called after RNG process
function reveal(
uint256 _player,
bytes memory _signature
) external returns (uint256 _tokenId);
/// @notice Called by PrimordialManager when a primordial has reached level 0 and can be hatched into a Munchable
/// @param _player The player address
function mintFromPrimordial(address _player) external; // only PrimordialManager
/// @notice Reveals an NFT based on provided player ID and signature, this is from a primordial hatching
/// @param _player The player ID whom the NFT will be revealed
/// @param _signature The signature to validate the reveal process
/// @return _tokenId The ID of the minted NFT
/// @dev This function should be called after RNG process
function revealFromPrimordial(
uint256 _player,
bytes memory _signature
) external returns (uint256 _tokenId);
/// @notice Mints an NFT for migration from V1 to V2, preserving attributes
/// @param _player The address of the player receiving the NFT
/// @param _attributes The dynamic attributes of the NFT
/// @param _immutableAttributes The immutable attributes of the NFT
/// @param _gameAttributes The game attributes of the NFT
/// @return _tokenId The token ID of the newly minted NFT
/// @dev Only callable by the migration manager
function mintForMigration(
address _player,
MunchablesCommonLib.NFTAttributes memory _attributes,
MunchablesCommonLib.NFTImmutableAttributes memory _immutableAttributes,
MunchablesCommonLib.NFTGameAttribute[] memory _gameAttributes
) external returns (uint256 _tokenId);
/// @notice Called post-level-up to randomly adjust game attributes based on transaction hash and signature
/// @param _requestId The ID of the RNG request
/// @param _rng Random bytes from the RNGProxy
/// @dev Only can be called by the RNGProxy
function levelUp(uint256 _requestId, bytes memory _rng) external;
/// @notice Called by SnuggeryManager when a player feeds a Munchable, it will check if level up is needed and
/// request randomness to update game attributes
/// @param _tokenId The token ID which was fed
/// @param _owner The eventual owner of the NFT at the time of the level up
function munchableFed(uint256 _tokenId, address _owner) external; // onlySnuggeryManager
/// @notice Get a player's unrevealed NFTs
/// @param _player The player to query, if a sub account is provided the main account unrevealedNFTs will be returned
function getUnrevealedNFTs(
address _player
) external view returns (uint16 _unrevealed);
/// @notice Get the current level and the next level threshold for a NFT given its schnibbles count
/// @param _chonks Quantity of schnibbles
/// @return _currentLevel Current level of the NFT
/// @return _nextLevelThreshold Schnibbles threshold for the next level
function getLevelUpData(
uint256 _chonks
) external view returns (uint16 _currentLevel, uint256 _nextLevelThreshold);
/// @notice Emitted when a player requests to reveal a munchable
/// @param _player The address of the player who initiated the reveal
event MunchableRevealRequested(address indexed _player);
/// @notice Emitted when a munchable levels up and requires an update to its attributes by an off-chain process
/// @param _player The address of the player whose munchable is leveling up
/// @param _tokenId The token ID of the munchable leveling up
/// @param _levelFrom The current level of the munchable
/// @param _levelTo The new level that the munchable should be updated to
event MunchableLevelUpRequest(
address indexed _player,
uint256 _tokenId,
uint16 _levelFrom,
uint16 _levelTo
);
/// @notice Event emitted when an NFT is revealed
event Revealed(
address indexed _owner,
uint256 _tokenId,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes
);
/// @notice Event emitted when an NFT is leveled up
event LevelledUp(
address _owner,
uint256 _tokenId,
uint16 _fromLevel,
uint16 _toLevel,
MunchablesCommonLib.NFTGameAttribute[] _gameAttributes
);
/// @notice Emitted when a primordial is hatched into a munchable
event PrimordialHatched(
address indexed _player,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes
);
/// @notice Event emitted when an NFT is minted for migration
event MintedForMigration(
address _player,
uint256 indexed _tokenId,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes,
MunchablesCommonLib.NFTAttributes _attributes,
MunchablesCommonLib.NFTGameAttribute[] _gameAttributes
);
/// @notice Error thrown when there are no unrevealed munchables available for a player
error NoUnrevealedMunchablesError();
/// @notice Error thrown when a player's reveal queue is full and cannot handle more reveals
error RevealQueueFullError();
/// @notice Error thrown when a player's reveal queue is empty and there is nothing to reveal
error RevealQueueEmptyError();
/// @notice Error when a level up request either doesn't exist or the fromLevel is invalid
error InvalidLevelUpRequest();
/// @notice Error when no species is found for a given rarity during NFT creation
/// @param _rarity The rarity level that failed to produce a species
error NoSpeciesFoundError(MunchablesCommonLib.Rarity _rarity);
/// @notice Error if reveal cannot find species in realmLookup
/// @param _speciesId The species that failed
error NoRealmFoundError(uint16 _speciesId);
/// @notice Error thrown when a player attempts to claim a primordial while not being eligible
error PrimordialNotEligibleError();
/// @notice Error thrown when an action is attempted that requires the player to be registered, but they are not
error PlayerNotRegisteredError();
/// @notice Retrigger level rng
event RetriggeredLevelRNG(uint256[] tokenIds);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
interface IRNGProxy {
/// @notice Request a random number to be provided back to the contract specified
/// @param _contract The contract that will receive the data
/// @param _selector The function on the contract to call
/// @param _index A unique identifier which the contract can use to identify the target for the data
function requestRandom(
address _contract,
bytes4 _selector,
uint256 _index
) external;
event RandomRequested(
address indexed _target,
bytes4 _selector,
uint256 indexed _index
);
event RandomRequestComplete(
uint256 indexed _index,
bool _success,
bytes _data
);
error NoRequestError();
error CallbackFailedError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IConfigStorage.sol";
import "../interfaces/IConfigNotifiable.sol";
import "../config/BaseConfigStorage.sol";
import "../interfaces/IBaseBlastManager.sol";
import "../interfaces/IHoldsGovernorship.sol";
import "../interfaces/IERC20YieldClaimable.sol";
import "../interfaces/IBlast.sol";
abstract contract BaseBlastManager is
IBaseBlastManager,
IERC20YieldClaimable,
BaseConfigStorage
{
IBlast public blastContract;
IBlastPoints public blastPointsContract;
address private _governorConfigured;
address private _pointsOperatorConfigured;
bool private _blastClaimableConfigured;
IERC20 public USDB;
IERC20 public WETH;
error InvalidGovernorError();
function __BaseBlastManager_reconfigure() internal {
// load config from the config storage contract and configure myself
address blastAddress = configStorage.getAddress(
StorageKey.BlastContract
);
if (blastAddress != address(blastContract)) {
blastContract = IBlast(blastAddress);
if (blastContract.isAuthorized(address(this))) {
blastContract.configureClaimableGas();
// fails on cloned networks
(bool success, ) = blastAddress.call(
abi.encodeWithSelector(
bytes4(keccak256("configureClaimableYield()"))
)
);
if (success) {
// not on a cloned network and no compiler error!
}
}
}
address pointsContractAddress = configStorage.getAddress(
StorageKey.BlastPointsContract
);
if (pointsContractAddress != address(blastPointsContract)) {
blastPointsContract = IBlastPoints(pointsContractAddress);
address pointsOperator = configStorage.getAddress(
StorageKey.BlastPointsOperator
);
if (_pointsOperatorConfigured == address(0)) {
// Reassignment must be called from the point operator itself
blastPointsContract.configurePointsOperator(pointsOperator);
_pointsOperatorConfigured = pointsOperator;
}
}
address usdbAddress = configStorage.getAddress(StorageKey.USDBContract);
address wethAddress = configStorage.getAddress(StorageKey.WETHContract);
if (usdbAddress != address(USDB)) {
USDB = IERC20(usdbAddress);
IERC20Rebasing _USDB = IERC20Rebasing(usdbAddress);
_USDB.configure(YieldMode.CLAIMABLE);
}
if (wethAddress != address(WETH)) {
WETH = IERC20(wethAddress);
IERC20Rebasing _WETH = IERC20Rebasing(wethAddress);
_WETH.configure(YieldMode.CLAIMABLE);
}
address rewardsManagerAddress = configStorage.getAddress(
StorageKey.RewardsManager
);
if (rewardsManagerAddress != address(0)) {
setBlastGovernor(rewardsManagerAddress);
}
super.__BaseConfigStorage_reconfigure();
}
function setBlastGovernor(address _governor) internal {
if (_governor == address(0)) revert InvalidGovernorError();
if (address(blastContract) == address(0)) return;
if (_governorConfigured == address(0)) {
// if this contract is the governor then it should claim its own yield/gas
if (_governor != address(this)) {
// Once this is called the governor will be the only account allowed to configure
blastContract.configureGovernor(_governor);
}
} else {
IHoldsGovernorship(_governorConfigured).reassignBlastGovernor(
_governor
);
}
_governorConfigured = _governor;
}
function claimERC20Yield(
address _tokenContract,
uint256 _amount
) external onlyConfiguredContract(StorageKey.RewardsManager) {
IERC20Rebasing(_tokenContract).claim(
configStorage.getAddress(StorageKey.RewardsManager),
_amount
);
}
function getConfiguredGovernor() external view returns (address _governor) {
_governor = _governorConfigured;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for NFT Attributes Manager V1
/// @notice This interface manages the attributes and metadata of NFTs within the Munch ecosystem.
interface INFTAttributesManager {
/// @notice Called from MunchableManager to initialise a new record
function createWithImmutable(
uint256 _tokenId,
MunchablesCommonLib.NFTImmutableAttributes memory _immutableAttributes
) external;
/// @notice Sets dynamic attributes for a specific NFT, typically called after feeding or interaction events
/// @param _tokenId The ID of the NFT
/// @param _attributes Struct of new attributes
function setAttributes(
uint256 _tokenId,
MunchablesCommonLib.NFTAttributes calldata _attributes
) external;
/// @notice Sets game attributes for a specific NFT, typically called after level up
/// @param _tokenId The ID of the NFT
/// @param _attributes Array of new game attributes
function setGameAttributes(
uint256 _tokenId,
MunchablesCommonLib.NFTGameAttribute[] calldata _attributes
) external;
/// @notice Retrieves all data associated with an NFT in a single call
/// @param _tokenId The ID of the NFT
/// @return _nftData A struct containing all attributes (dynamic, immutable, and game-specific)
// function getFullNFTData(
// uint256 _tokenId
// ) external view returns (NFTFull memory _nftData);
/// @notice Retrieves dynamic attributes for a specific token
/// @param _tokenId The ID of the NFT
/// @return _attributes Struct of the NFT's dynamic attributes
function getAttributes(
uint256 _tokenId
)
external
view
returns (MunchablesCommonLib.NFTAttributes memory _attributes);
/// @notice Retrieves immutable attributes for a specific token
/// @param _tokenId The ID of the NFT
/// @return _immutableAttributes Struct of the NFT's immutable attributes
function getImmutableAttributes(
uint256 _tokenId
)
external
view
returns (
MunchablesCommonLib.NFTImmutableAttributes
memory _immutableAttributes
);
/// @notice Retrieves game-specific attributes for a specific token
/// @param _tokenId The ID of the NFT
/// @param _requestedIndexes Array of GameAttributeIndex to define subset of attributes to include in the result
/// @return _gameAttributes Struct of the NFT's game attributes
function getGameAttributes(
uint256 _tokenId,
MunchablesCommonLib.GameAttributeIndex[] calldata _requestedIndexes
)
external
view
returns (MunchablesCommonLib.NFTGameAttribute[] memory _gameAttributes);
function getGameAttributeDataType(
uint8 _index
) external pure returns (MunchablesCommonLib.GameAttributeType _dataType);
event CreatedWithImmutable(
uint256 _tokenId,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes
);
/// @notice Event emitted when NFT attributes are updated
event AttributesUpdated(uint256 indexed _tokenId);
/// @notice Event emitted when NFT game attributes are updated
event GameAttributesUpdated(uint256 indexed _tokenId);
/// @notice Error when the owner of the NFT does not match the expected address
error IncorrectOwnerError();
/// @notice Error when the 'from' level specified is invalid
error InvalidLevelFromError();
/// @notice Error when the oracle recovering the signature is invalid
/// @param _recoveredSigner The address of the invalid signer
error InvalidOracleError(address _recoveredSigner);
/// @notice Error when a call is made by a non-authorized migration manager
error NotAuthorizedMigrationManagerError();
/// @notice When user tries to set attributes when the record hasnt been created
error NotCreatedError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for the Account Manager
/// @notice This interface manages player accounts including their snuggery, schibbles, chonks, and sub-accounts
interface IAccountManager {
/// @notice Struct representing a "Squirt", which is a distribution of schnibbles to a player
struct Squirt {
address player; // The address of the player receiving schnibbles
uint256 schnibbles; // The amount of schnibbles being distributed to that player
}
/// @notice Struct representing a proposal to spray schnibbles across multiple accounts
struct SprayProposal {
uint32 proposedDate; // The date the proposal was made
Squirt[] squirts; // Array of "Squirt" structs detailing the distribution
}
/// @notice Register a new account, create a new Player record, and set snuggery and referrer
/// @dev This should be the first function called when onboarding a new user
/// @param _snuggeryRealm The realm of the new snuggery, which cannot be changed later
/// @param _referrer The account referring this user, use the null address if there is no referrer
/// @custom:frontend Register a new account
function register(
MunchablesCommonLib.Realm _snuggeryRealm,
address _referrer
) external;
/// @notice Calculate schnibbles to distribute and credit to unfedSchnibbles, set lastHarvestDate
/// @custom:frontend Harvest schnibbles
function harvest() external returns (uint256 _harvested);
/// @notice Used when a user adds to their lock to force claim at the previous locked value
/// @param _player Address of the player whose harvest to force
function forceHarvest(address _player) external;
/// @notice Propose a spray of schnibbles to multiple accounts
/// @param _players Array of player addresses
/// @param _schnibbles Array of schnibbles amounts corresponding to each player
function spraySchnibblesPropose(
address[] calldata _players,
uint256[] calldata _schnibbles
) external;
/// @notice Approve a proposed spray of schnibbles
/// @param _proposer Address of the proposer of the spray
function execSprayProposal(address _proposer) external;
/// @notice Remove a proposed spray of schnibbles
/// @param _proposer Address of the proposer of the spray to remove
function removeSprayProposal(address _proposer) external;
/// @notice Add a sub-account for a player
/// @param _subAccount The sub-account to add
/// @custom:frontend Use to add a new sub-account
function addSubAccount(address _subAccount) external;
/// @notice Remove a previously added sub-account
/// @param _subAccount The sub-account to remove
/// @custom:frontend Use to remove an existing sub-account
function removeSubAccount(address _subAccount) external;
/// @notice Restricted to the Munchable Manager only
function updatePlayer(
address _account,
MunchablesCommonLib.Player memory _player
) external;
/// @notice Look up the main account associated with a potentially sub-account
/// @param _maybeSubAccount Account to check
/// @return _mainAccount Main account associated, or the input if not a sub-account
function getMainAccount(
address _maybeSubAccount
) external view returns (address _mainAccount);
/// @notice Get a list of sub-accounts associated with a main account
/// @param _player Main account to check
/// @param _start Index to start pagination
/// @return _subAccounts List of sub-accounts
/// @return _more Whether there are more sub-accounts beyond the returned list
/// @custom:frontend Use this to populate a UI for managing sub accounts
function getSubAccounts(
address _player,
uint256 _start
) external view returns (address[20] memory _subAccounts, bool _more);
/// @notice Retrieve player data for a given account
/// @param _account Account to retrieve data for
/// @return _mainAccount Main account associated, or the input if not a sub-account
/// @return _player Player data structure
/// @custom:frontend Call this straight after log in to get the data about this player. The account
/// logging in may be a sub account and in this case the _mainAccount parameter
/// will be different from the logged in user. In this case the UI should show only
/// functions available to a sub-account
function getPlayer(
address _account
)
external
view
returns (
address _mainAccount,
MunchablesCommonLib.Player memory _player
);
/// @notice Retrieve detailed player and snuggery data
/// @param _account Address of the player
/// @return _mainAccount Main account associated
/// @return _player Player data
/// @return _snuggery List of snuggery NFTs
/// @custom:frontend Use this to fetch player and snuggery data
function getFullPlayerData(
address _account
)
external
view
returns (
address _mainAccount,
MunchablesCommonLib.Player memory _player,
MunchablesCommonLib.SnuggeryNFT[] memory _snuggery
);
/// @notice Get daily schnibbles that an account is accrueing
/// @param _player The address of the player
function getDailySchnibbles(
address _player
) external view returns (uint256 _dailySchnibbles, uint256 _bonus);
/// @notice Emitted when a player registers for a new account
/// @param _player The address of the player who registered
/// @param _snuggeryRealm The realm associated with the new snuggery chosen by the player
/// @param _referrer The address of the referrer, if any; otherwise, the zero address
/// @custom:frontend You should only receive this event once and only if you are onboarding a new user
/// safe to ignore if you are in the onboarding process
event PlayerRegistered(
address indexed _player,
MunchablesCommonLib.Realm _snuggeryRealm,
address _referrer
);
/// @notice Emitted when a player's schnibbles are harvested
/// @param _player The address of the player who harvested schnibbles
/// @param _harvestedSchnibbles The total amount of schnibbles that were harvested
/// @custom:frontend Listen for events where _player is your mainAccount and update unfedSchnibbles total
event Harvested(address indexed _player, uint256 _harvestedSchnibbles);
/// @notice Emitted when a sub-account is added to a player's account
/// @param _player The address of the main account to which a sub-account was added
/// @param _subAccount The address of the sub-account that was added
/// @custom:frontend If you are managing sub accounts (ie the logged in user is not a subAccount), then use this
/// event to reload your cache of sub accounts
event SubAccountAdded(address indexed _player, address _subAccount);
/// @notice Emitted when a sub-account is removed from a player's account
/// @param _player The address of the main account from which a sub-account was removed
/// @param _subAccount The address of the sub-account that was removed
/// @custom:frontend If you are managing sub accounts (ie the logged in user is not a subAccount), then use this
/// event to reload your cache of sub accounts
event SubAccountRemoved(address indexed _player, address _subAccount);
/// @notice Emitted when a proposal to spray schnibbles is made
/// @param _proposer The address of the player who proposed the spray
/// @param _squirts An array of "Squirt" details defining the proposed schnibble distribution
/// @custom:admin
event ProposedScnibblesSpray(address indexed _proposer, Squirt[] _squirts);
/// @notice Emitted when a schnibble spray is executed for each player
/// @param _player The player receiving schnibbles
/// @param _schnibbles The amount of schnibbles received
event SchnibblesSprayed(address indexed _player, uint256 _schnibbles);
/// @notice Emitted when a spray proposal is executed
/// @param _proposer The account which proposed the spray
event SprayProposalExecuted(address indexed _proposer);
/// @notice Emitted when a spray proposal is removed
/// @param _proposer Account that proposed the proposal
event SprayProposalRemoved(address indexed _proposer);
// Errors
/// @notice Error thrown when a player is already registered and attempts to register again
error PlayerAlreadyRegisteredError();
/// @notice Error thrown when an action is attempted that requires the player to be registered, but they are not
error PlayerNotRegisteredError();
/// @notice Error thrown when the main account of a player is not registered
error MainAccountNotRegisteredError(address _mainAccount);
/// @notice Error thrown when there are no pending reveals for a player
error NoPendingRevealError();
/// @notice Error thrown when a sub-account is already registered and an attempt is made to register it again
error SubAccountAlreadyRegisteredError();
/// @notice Error thrown when a sub-account attempts to register as a main account
error SubAccountCannotRegisterError();
/// @notice Error thrown when a spray proposal already exists and another one is attempted
error ExistingProposalError();
/// @notice Error thrown when the parameters provided to a function do not match in quantity or type
error UnMatchedParametersError();
/// @notice Error thrown when too many entries are attempted to be processed at once
error TooManyEntriesError();
/// @notice Error thrown when an expected parameter is empty
error EmptyParameterError();
/// @notice Error thrown when a realm is invalid
error InvalidRealmError();
/// @notice Error thrown when a sub-account is not registered and is tried to be removed
error SubAccountNotRegisteredError();
/// @notice Error thrown when a proposal is attempted to be executed, but none exists
error EmptyProposalError();
/// @notice Error thrown when a player attempts to refer themselves
error SelfReferralError();
/// @notice Error thrown when the same sprayer gets added twice in a proposal
error DuplicateSprayerError();
/// @notice When a user tries to create too many sub accounts (currently 5 max)
error TooManySubAccountsError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
interface IMunchNFT {
/// @notice Get the next token ID
/// @return The next token ID
function nextTokenId() external view returns (uint256);
/// @notice Mint a new, empty token. Restrict access to only the NFTOverlord
/// @param _owner The owner of the newly minted NFT
function mint(address _owner) external returns (uint256 _tokenId);
/// @notice Update the token URL, restricted to off-chain role
/// @param _tokenId The token ID to update
/// @param _tokenURI The new URI, will be an IPFS hash
function setTokenURI(uint256 _tokenId, string memory _tokenURI) external;
/// @notice Blacklist an account from transferring tokens
/// @param _account The account to blacklist
function blAccount(address _account) external;
/// @notice Blacklist an token from being transferred
/// @param _tokenId The token ID to blacklist
function blToken(uint256 _tokenId) external;
/// @notice Remove blacklist for an account
/// @param _account The account to remove from the blacklist
function removeBlAccount(address _account) external;
/// @notice Remove blacklist on a token
/// @param _tokenId The token ID to remove from the blacklist
function removeBlToken(uint256 _tokenId) external;
/// @notice Error when a blacklisted account/token tries to transfer
error ForbiddenTransferError();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @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: UNLICENSED
pragma solidity 0.8.25;
library MunchablesCommonLib {
enum Rarity {
Primordial,
Common,
Rare,
Epic,
Legendary,
Mythic,
Invalid
}
enum Realm {
Everfrost,
Drench,
Moltania,
Arridia,
Verdentis,
Invalid
}
struct NFTImmutableAttributes {
Rarity rarity;
uint16 species;
Realm realm;
uint8 generation;
uint32 hatchedDate;
}
struct NFTAttributes {
uint256 chonks;
uint16 level;
uint16 evolution;
uint256 lastPettedTime;
}
struct NFTGameAttribute {
GameAttributeType dataType;
bytes value;
}
struct Munchadex {
mapping(Realm => uint256) numInRealm;
mapping(Rarity => uint256) numInRarity;
mapping(bytes32 => uint256) unique;
uint256 numUnique;
}
enum GameAttributeIndex {
Strength,
Agility,
Stamina,
Defence,
Voracity,
Cuteness,
Charisma,
Trustworthiness,
Leadership,
Empathy,
Intelligence,
Cunning,
Creativity,
Adaptability,
Wisdom,
IsOriginal,
IndexCount // Do not use and keep at the end to detect number of indexes
}
enum GameAttributeType {
NotSet,
Bool,
String,
SmallInt,
BigUInt,
Bytes
}
struct PrimordialData {
uint256 chonks;
uint32 createdDate;
int8 level;
bool hatched;
}
struct SnuggeryNFT {
uint256 tokenId;
uint32 importedDate;
}
struct NFTFull {
uint256 tokenId;
NFTImmutableAttributes immutableAttributes;
NFTAttributes attributes;
NFTGameAttribute[] gameAttributes;
}
struct Player {
uint32 registrationDate;
uint32 lastPetMunchable;
uint32 lastHarvestDate;
Realm snuggeryRealm;
uint16 maxSnuggerySize;
uint256 unfedSchnibbles;
address referrer;
}
// Pure Functions
/// @notice Error when insufficient random data is provided for operations
error NotEnoughRandomError();
function calculateRaritySpeciesPercentage(
bytes memory randomBytes
) internal pure returns (uint32, uint32) {
if (randomBytes.length < 5) revert NotEnoughRandomError();
uint32 rarityBytes;
uint8 speciesByte;
uint32 rarityPercentage;
uint32 speciesPercent;
rarityBytes =
(uint32(uint8(randomBytes[0])) << 24) |
(uint32(uint8(randomBytes[1])) << 16) |
(uint32(uint8(randomBytes[2])) << 8) |
uint32(uint8(randomBytes[3]));
speciesByte = uint8(randomBytes[4]);
uint256 rarityPercentageTmp = (uint256(rarityBytes) * 1e6) /
uint256(4294967295);
uint256 speciesPercentTmp = (uint256(speciesByte) * 1e6) / uint256(255);
rarityPercentage = uint32(rarityPercentageTmp);
speciesPercent = uint32(speciesPercentTmp);
return (rarityPercentage, speciesPercent);
}
function getLevelThresholds(
uint256[] memory levelThresholds,
uint256 _chonk
)
internal
pure
returns (uint16 _currentLevel, uint256 _currentLevelThreshold)
{
if (_chonk >= levelThresholds[99]) {
return (101, levelThresholds[99]);
}
if (_chonk < levelThresholds[0]) {
return (1, 0);
}
uint256 low = 0;
uint256 high = levelThresholds.length;
uint256 mid = 0;
uint16 answer = 0;
while (low < high) {
mid = (low + high) / 2;
if (levelThresholds[mid] <= _chonk) {
low = mid + 1;
} else {
answer = uint16(mid);
high = mid;
}
}
_currentLevel = answer + 1;
_currentLevelThreshold = levelThresholds[uint256(answer - 1)];
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
enum StorageKey {
Many,
Paused,
LockManager,
AccountManager,
ClaimManager,
MigrationManager,
NFTOverlord,
SnuggeryManager,
PrimordialManager,
MunchadexManager,
MunchNFT,
MunchToken,
RewardsManager,
YieldDistributor,
GasFeeDistributor,
BlastContract,
BlastPointsContract,
BlastPointsOperator,
USDBContract,
WETHContract,
RNGProxyContract,
NFTAttributesManager,
Treasury,
OldMunchNFT,
MaxLockDuration,
DefaultSnuggerySize,
MaxSnuggerySize,
MaxRevealQueue,
MaxSchnibbleSpray,
PetTotalSchnibbles,
NewSlotCost,
PrimordialsEnabled,
BonusManager,
ReferralBonus,
RealmBonuses,
RarityBonuses,
LevelThresholds,
PrimordialLevelThresholds,
TotalMunchables,
MunchablesPerRealm,
MunchablesPerRarity,
RaritySetBonuses,
PointsPerPeriod,
PointsPerToken,
SwapEnabled,
PointsPerMigratedNFT,
PointsPerUnrevealedNFT,
MinETHPetBonus,
MaxETHPetBonus,
PetBonusMultiplier,
RealmLookups,
// Species & Probabilities
CommonSpecies,
RareSpecies,
EpicSpecies,
LegendarySpecies,
MythicSpecies,
CommonPercentage,
RarePercentage,
EpicPercentage,
LegendaryPercentage,
MythicPercentage,
MigrationBonus,
MigrationBonusEndTime,
MigrationDiscountFactor
}
enum Role {
Admin,
Social_1,
Social_2,
Social_3,
Social_4,
Social_5,
SocialApproval_1,
SocialApproval_2,
SocialApproval_3,
SocialApproval_4,
SocialApproval_5,
PriceFeed_1,
PriceFeed_2,
PriceFeed_3,
PriceFeed_4,
PriceFeed_5,
Snapshot,
NewPeriod,
ClaimYield,
Minter,
NFTOracle
}
enum StorageType {
Uint,
SmallUintArray,
UintArray,
SmallInt,
SmallIntArray,
Bool,
Address,
AddressArray,
Bytes32
}
interface IConfigStorage {
// Manual notify
function manualNotify(uint8 _index, uint8 _length) external;
// Manual notify for a specific contract
function manualNotifyAddress(address _contract) external;
// Setters
function setRole(Role _role, address _contract, address _addr) external;
function setUniversalRole(Role _role, address _addr) external;
function setUint(StorageKey _key, uint256 _value, bool _notify) external;
function setUintArray(
StorageKey _key,
uint256[] memory _value,
bool _notify
) external;
function setSmallUintArray(
StorageKey _key,
uint8[] calldata _smallUintArray,
bool _notify
) external;
function setSmallInt(StorageKey _key, int16 _value, bool _notify) external;
function setSmallIntArray(
StorageKey _key,
int16[] memory _value,
bool _notify
) external;
function setBool(StorageKey _key, bool _value, bool _notify) external;
function setAddress(StorageKey _key, address _value, bool _notify) external;
function setAddresses(
StorageKey[] memory _keys,
address[] memory _values,
bool _notify
) external;
function setAddressArray(
StorageKey _key,
address[] memory _value,
bool _notify
) external;
function setBytes32(StorageKey _key, bytes32 _value, bool _notify) external;
// Getters
function getRole(Role _role) external view returns (address);
function getContractRole(
Role _role,
address _contract
) external view returns (address);
function getUniversalRole(Role _role) external view returns (address);
function getUint(StorageKey _key) external view returns (uint256);
function getUintArray(
StorageKey _key
) external view returns (uint256[] memory);
function getSmallUintArray(
StorageKey _key
) external view returns (uint8[] memory _smallUintArray);
function getSmallInt(StorageKey _key) external view returns (int16);
function getSmallIntArray(
StorageKey _key
) external view returns (int16[] memory);
function getBool(StorageKey _key) external view returns (bool);
function getAddress(StorageKey _key) external view returns (address);
function getAddressArray(
StorageKey _key
) external view returns (address[] memory);
function getBytes32(StorageKey _key) external view returns (bytes32);
// Notification Address Management
function addNotifiableAddress(address _addr) external;
function addNotifiableAddresses(address[] memory _addresses) external;
function removeNotifiableAddress(address _addr) external;
function getNotifiableAddresses()
external
view
returns (address[] memory _addresses);
error ArrayTooLongError();
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import "./IConfigStorage.sol";
interface IConfigNotifiable {
function configUpdated() external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../interfaces/IConfigStorage.sol";
abstract contract BaseConfigStorage {
IConfigStorage public configStorage;
bool _paused;
modifier onlyConfigStorage() {
if (msg.sender != address(configStorage)) revert OnlyStorageError();
_;
}
modifier onlyConfiguredContract(StorageKey _key) {
address configuredContract = configStorage.getAddress(_key);
if (configuredContract == address(0)) revert UnconfiguredError(_key);
if (configuredContract != msg.sender) revert UnauthorisedError();
_;
}
modifier onlyConfiguredContract2(StorageKey _key, StorageKey _key2) {
address configuredContract = configStorage.getAddress(_key);
address configuredContract2 = configStorage.getAddress(_key2);
if (
configuredContract != msg.sender &&
configuredContract2 != msg.sender
) {
if (configuredContract == address(0))
revert UnconfiguredError(_key);
if (configuredContract2 == address(0))
revert UnconfiguredError(_key2);
revert UnauthorisedError();
}
_;
}
modifier onlyOneOfRoles(Role[5] memory roles) {
for (uint256 i = 0; i < roles.length; i++) {
if (msg.sender == configStorage.getRole(roles[i])) {
_;
return;
}
}
revert InvalidRoleError();
}
modifier onlyRole(Role role) {
if (msg.sender != configStorage.getRole(role))
revert InvalidRoleError();
_;
}
modifier onlyUniversalRole(Role role) {
if (msg.sender != configStorage.getUniversalRole(role))
revert InvalidRoleError();
_;
}
modifier onlyAdmin() {
if (msg.sender != configStorage.getUniversalRole(Role.Admin))
revert InvalidRoleError();
_;
}
modifier notPaused() {
if (_paused) revert ContractsPausedError();
_;
}
error UnconfiguredError(StorageKey _key);
error UnauthorisedError();
error OnlyStorageError();
error InvalidRoleError();
error ContractsPausedError();
function configUpdated() external virtual;
function __BaseConfigStorage_setConfigStorage(
address _configStorage
) internal {
configStorage = IConfigStorage(_configStorage);
}
function __BaseConfigStorage_reconfigure() internal {
_paused = configStorage.getBool(StorageKey.Paused);
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
interface IBaseBlastManager {
function getConfiguredGovernor() external view returns (address _governor);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
/// @notice Contracts which implement this interface will be the governor for other contracts and
/// give it up on request from the contract
interface IHoldsGovernorship {
function reassignBlastGovernor(address _newAddress) external;
function isGovernorOfContract(
address _contract
) external view returns (bool);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
/// @notice Contracts which implement this interface can be instructed by Rewards Manager to claim their yield for
/// ERC20 tokens and send the yield back to the rewards manager
interface IERC20YieldClaimable {
function claimERC20Yield(address _tokenContract, uint256 _amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
enum YieldMode {
AUTOMATIC,
VOID,
CLAIMABLE
}
enum GasMode {
VOID,
CLAIMABLE
}
interface IBlastPoints {
function configurePointsOperator(address operator) external;
}
interface IERC20Rebasing {
function configure(YieldMode) external returns (uint256);
function claim(
address recipient,
uint256 amount
) external returns (uint256);
function getClaimableAmount(
address account
) external view returns (uint256);
}
interface IBlast {
// configure
function configureContract(
address contractAddress,
YieldMode _yield,
GasMode gasMode,
address governor
) external;
function configure(
YieldMode _yield,
GasMode gasMode,
address governor
) external;
// base configuration options
function configureClaimableYield() external;
function configureClaimableYieldOnBehalf(address contractAddress) external;
function configureAutomaticYield() external;
function configureAutomaticYieldOnBehalf(address contractAddress) external;
function configureVoidYield() external;
function configureVoidYieldOnBehalf(address contractAddress) external;
function configureClaimableGas() external;
function configureClaimableGasOnBehalf(address contractAddress) external;
function configureVoidGas() external;
function configureVoidGasOnBehalf(address contractAddress) external;
function configureGovernor(address _governor) external;
function configureGovernorOnBehalf(
address _newGovernor,
address contractAddress
) external;
// claim yield
function claimYield(
address contractAddress,
address recipientOfYield,
uint256 amount
) external returns (uint256);
function claimAllYield(
address contractAddress,
address recipientOfYield
) external returns (uint256);
// claim gas
function claimAllGas(
address contractAddress,
address recipientOfGas
) external returns (uint256);
function claimGasAtMinClaimRate(
address contractAddress,
address recipientOfGas,
uint256 minClaimRateBips
) external returns (uint256);
function claimMaxGas(
address contractAddress,
address recipientOfGas
) external returns (uint256);
function claimGas(
address contractAddress,
address recipientOfGas,
uint256 gasToClaim,
uint256 gasSecondsToConsume
) external returns (uint256);
// read functions
function readClaimableYield(
address contractAddress
) external view returns (uint256);
function readYieldConfiguration(
address contractAddress
) external view returns (uint8);
function readGasParams(
address contractAddress
)
external
view
returns (
uint256 etherSeconds,
uint256 etherBalance,
uint256 lastUpdated,
GasMode
);
/**
* @notice Checks if the caller is authorized
* @param contractAddress The address of the contract
* @return A boolean indicating if the caller is authorized
*/
function isAuthorized(address contractAddress) external view returns (bool);
function isGovernor(address contractAddress) external view returns (bool);
}{
"remappings": [
"@api3/=node_modules/@api3/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 2000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_configStorage","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ContractsPausedError","type":"error"},{"inputs":[],"name":"InvalidGovernorError","type":"error"},{"inputs":[],"name":"InvalidLevelUpRequest","type":"error"},{"inputs":[],"name":"InvalidRoleError","type":"error"},{"inputs":[{"internalType":"uint16","name":"_speciesId","type":"uint16"}],"name":"NoRealmFoundError","type":"error"},{"inputs":[{"internalType":"enum MunchablesCommonLib.Rarity","name":"_rarity","type":"uint8"}],"name":"NoSpeciesFoundError","type":"error"},{"inputs":[],"name":"NoUnrevealedMunchablesError","type":"error"},{"inputs":[],"name":"NotEnoughRandomError","type":"error"},{"inputs":[],"name":"OnlyStorageError","type":"error"},{"inputs":[],"name":"PlayerNotRegisteredError","type":"error"},{"inputs":[],"name":"PrimordialNotEligibleError","type":"error"},{"inputs":[],"name":"RevealQueueEmptyError","type":"error"},{"inputs":[],"name":"RevealQueueFullError","type":"error"},{"inputs":[],"name":"UnauthorisedError","type":"error"},{"inputs":[{"internalType":"enum StorageKey","name":"_key","type":"uint8"}],"name":"UnconfiguredError","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"_fromLevel","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_toLevel","type":"uint16"},{"components":[{"internalType":"enum MunchablesCommonLib.GameAttributeType","name":"dataType","type":"uint8"},{"internalType":"bytes","name":"value","type":"bytes"}],"indexed":false,"internalType":"struct MunchablesCommonLib.NFTGameAttribute[]","name":"_gameAttributes","type":"tuple[]"}],"name":"LevelledUp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_player","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"components":[{"internalType":"enum MunchablesCommonLib.Rarity","name":"rarity","type":"uint8"},{"internalType":"uint16","name":"species","type":"uint16"},{"internalType":"enum MunchablesCommonLib.Realm","name":"realm","type":"uint8"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint32","name":"hatchedDate","type":"uint32"}],"indexed":false,"internalType":"struct MunchablesCommonLib.NFTImmutableAttributes","name":"_immutableAttributes","type":"tuple"},{"components":[{"internalType":"uint256","name":"chonks","type":"uint256"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"evolution","type":"uint16"},{"internalType":"uint256","name":"lastPettedTime","type":"uint256"}],"indexed":false,"internalType":"struct MunchablesCommonLib.NFTAttributes","name":"_attributes","type":"tuple"},{"components":[{"internalType":"enum MunchablesCommonLib.GameAttributeType","name":"dataType","type":"uint8"},{"internalType":"bytes","name":"value","type":"bytes"}],"indexed":false,"internalType":"struct MunchablesCommonLib.NFTGameAttribute[]","name":"_gameAttributes","type":"tuple[]"}],"name":"MintedForMigration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"_levelFrom","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_levelTo","type":"uint16"}],"name":"MunchableLevelUpRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"}],"name":"MunchableRevealRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"},{"components":[{"internalType":"enum MunchablesCommonLib.Rarity","name":"rarity","type":"uint8"},{"internalType":"uint16","name":"species","type":"uint16"},{"internalType":"enum MunchablesCommonLib.Realm","name":"realm","type":"uint8"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint32","name":"hatchedDate","type":"uint32"}],"indexed":false,"internalType":"struct MunchablesCommonLib.NFTImmutableAttributes","name":"_immutableAttributes","type":"tuple"}],"name":"PrimordialHatched","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"RetriggeredLevelRNG","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"components":[{"internalType":"enum MunchablesCommonLib.Rarity","name":"rarity","type":"uint8"},{"internalType":"uint16","name":"species","type":"uint16"},{"internalType":"enum MunchablesCommonLib.Realm","name":"realm","type":"uint8"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint32","name":"hatchedDate","type":"uint32"}],"indexed":false,"internalType":"struct MunchablesCommonLib.NFTImmutableAttributes","name":"_immutableAttributes","type":"tuple"}],"name":"Revealed","type":"event"},{"inputs":[],"name":"USDB","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint16","name":"_quantity","type":"uint16"}],"name":"addReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blastContract","outputs":[{"internalType":"contract IBlast","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blastPointsContract","outputs":[{"internalType":"contract IBlastPoints","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimERC20Yield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"configStorage","outputs":[{"internalType":"contract IConfigStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"configUpdated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getConfiguredGovernor","outputs":[{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chonks","type":"uint256"}],"name":"getLevelUpData","outputs":[{"internalType":"uint16","name":"_currentLevel","type":"uint16"},{"internalType":"uint256","name":"_currentLevelThreshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"}],"name":"getUnrevealedNFTs","outputs":[{"internalType":"uint16","name":"_unrevealed","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"bytes","name":"_rng","type":"bytes"}],"name":"levelUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"components":[{"internalType":"uint256","name":"chonks","type":"uint256"},{"internalType":"uint16","name":"level","type":"uint16"},{"internalType":"uint16","name":"evolution","type":"uint16"},{"internalType":"uint256","name":"lastPettedTime","type":"uint256"}],"internalType":"struct MunchablesCommonLib.NFTAttributes","name":"_attributes","type":"tuple"},{"components":[{"internalType":"enum MunchablesCommonLib.Rarity","name":"rarity","type":"uint8"},{"internalType":"uint16","name":"species","type":"uint16"},{"internalType":"enum MunchablesCommonLib.Realm","name":"realm","type":"uint8"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint32","name":"hatchedDate","type":"uint32"}],"internalType":"struct MunchablesCommonLib.NFTImmutableAttributes","name":"_immutableAttributes","type":"tuple"},{"components":[{"internalType":"enum MunchablesCommonLib.GameAttributeType","name":"dataType","type":"uint8"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct MunchablesCommonLib.NFTGameAttribute[]","name":"_gameAttributes","type":"tuple[]"}],"name":"mintForMigration","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"mintFromPrimordial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"munchableFed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"retriggerLevelRNG","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_player","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"reveal","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_player","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"revealFromPrimordial","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint16","name":"_unrevealed","type":"uint16"}],"name":"setUnrevealedNFTs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startReveal","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506040516163d83803806163d883398101604081905261002f91611046565b600080546001600160a01b0319166001600160a01b038316179055610052610058565b50611346565b60005460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061008990600a9060040161108c565b602060405180830381865afa1580156100a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ca9190611046565b600e80546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c559061010e9060149060040161108c565b602060405180830381865afa15801561012b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014f9190611046565b600f80546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c55906101939060159060040161108c565b602060405180830381865afa1580156101b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d49190611046565b601080546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c55906102189060039060040161108c565b602060405180830381865afa158015610235573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102599190611046565b601180546001600160a01b0319166001600160a01b03929092169190911790556102816103b4565b610289610618565b6000546040516001628b52a160e01b031981526001600160a01b039091169063ff74ad5f906102bd9060249060040161108c565b600060405180830381865afa1580156102da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610302919081019061110f565b805161031691600d91602090910190610f49565b5060005460405163c4c379cd60e01b81526001600160a01b039091169063c4c379cd9061034890601b9060040161108c565b602060405180830381865afa158015610365573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038991906111a4565b6006805461ffff92909216600160a01b0261ffff60a01b199092169190911790556103b2610710565b565b6040805160a081019091526000908060018152602001600281526020016003815260200160048152602001600590526040805160a08101909152909150600090806038815260200160398152602001603a8152602001603b8152602001603c90526040805160a08101909152909150600090806033815260200160348152602001603581526020016036815260200160379052905060005b60058160ff161015610612576040805180820190915260005481906001600160a01b03166342ab14dd8660ff86166005811061048a5761048a6111c7565b60200201516040518263ffffffff1660e01b81526004016104ab919061108c565b602060405180830381865afa1580156104c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ec91906111dd565b63ffffffff1681526000546020909101906001600160a01b0316638344a9268560ff861660058110610520576105206111c7565b60200201516040518263ffffffff1660e01b8152600401610541919061108c565b600060405180830381865afa15801561055e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261058691908101906111f6565b9052600b60008660ff8516600581106105a1576105a16111c7565b602002015160068111156105b7576105b7611076565b60ff1681526020808201929092526040016000208251815463ffffffff191663ffffffff90911617815582820151805191926105fb92600185019290910190610f94565b50905050808061060a906112a1565b91505061044c565b50505050565b600080546040516341a2549360e11b81526001600160a01b0390911690638344a9269061064a9060329060040161108c565b600060405180830381865afa158015610667573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261068f91908101906111f6565b905060005b81518161ffff16101561070c57600a828261ffff16815181106106b9576106b96111c7565b6020908102919091018101518254600181018455600093845292829020918304909101805460ff928316601f9094166101000a938402929093021990921617905580610704816112c0565b915050610694565b5050565b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061074290600f9060040161108c565b602060405180830381865afa15801561075f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107839190611046565b6001549091506001600160a01b0380831691161461090c57600180546001600160a01b0319166001600160a01b0383169081179091556040516301fd3f7760e71b815230600482015263fe9fbb8090602401602060405180830381865afa1580156107f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081691906112e1565b1561090c57600160009054906101000a90046001600160a01b03166001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561086b57600080fd5b505af115801561087f573d6000803e3d6000fd5b505060408051600481526024810182526020810180516001600160e01b031663784c3b3d60e11b1790529051600093506001600160a01b03851692506108c59190611303565b6000604051808303816000865af19150503d8060008114610902576040519150601f19603f3d011682016040523d82523d6000602084013e610907565b606091505b505050505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061093e9060109060040161108c565b602060405180830381865afa15801561095b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097f9190611046565b6002549091506001600160a01b03808316911614610ab257600280546001600160a01b0319166001600160a01b03838116919091179091556000805460405163bcaa0c5560e01b81529192169063bcaa0c55906109e19060119060040161108c565b602060405180830381865afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a229190611046565b6004549091506001600160a01b0316610ab0576002546040516336b91f2b60e01b81526001600160a01b038381166004830152909116906336b91f2b90602401600060405180830381600087803b158015610a7c57600080fd5b505af1158015610a90573d6000803e3d6000fd5b5050600480546001600160a01b0319166001600160a01b03851617905550505b505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c5590610ae49060129060040161108c565b602060405180830381865afa158015610b01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b259190611046565b6000805460405163bcaa0c5560e01b815292935090916001600160a01b039091169063bcaa0c5590610b5c9060139060040161108c565b602060405180830381865afa158015610b79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9d9190611046565b6005549091506001600160a01b03838116911614610c3e57600580546001600160a01b0319166001600160a01b038416908117909155604051631a33757d60e01b8152839190631a33757d90610bf890600290600401611332565b6020604051808303816000875af1158015610c17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3b91906111dd565b50505b6006546001600160a01b03828116911614610cdc57600680546001600160a01b0319166001600160a01b038316908117909155604051631a33757d60e01b8152829190631a33757d90610c9690600290600401611332565b6020604051808303816000875af1158015610cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cd991906111dd565b50505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c5590610d0e90600c9060040161108c565b602060405180830381865afa158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f9190611046565b90506001600160a01b03811615610d6957610d6981610d78565b610d71610eb9565b5050505050565b6001600160a01b038116610d9f576040516305d8ce3d60e01b815260040160405180910390fd5b6001546001600160a01b0316610db25750565b6003546001600160a01b0316610e37576001600160a01b0381163014610e3257600154604051631d70c8d360e31b81526001600160a01b0383811660048301529091169063eb86469890602401600060405180830381600087803b158015610e1957600080fd5b505af1158015610e2d573d6000803e3d6000fd5b505050505b610e97565b600354604051633a74bfd760e01b81526001600160a01b03838116600483015290911690633a74bfd790602401600060405180830381600087803b158015610e7e57600080fd5b505af1158015610e92573d6000803e3d6000fd5b505050505b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600054604051633caab1db60e21b81526001600160a01b039091169063f2aac76c90610eea9060019060040161108c565b602060405180830381865afa158015610f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2b91906112e1565b60008054911515600160a01b0260ff60a01b19909216919091179055565b828054828255906000526020600020908101928215610f84579160200282015b82811115610f84578251825591602001919060010190610f69565b50610f90929150611031565b5090565b82805482825590600052602060002090601f01602090048101928215610f845791602002820160005b83821115610ffb57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302610fbd565b80156110285782816101000a81549060ff0219169055600101602081600001049283019260010302610ffb565b5050610f909291505b5b80821115610f905760008155600101611032565b60006020828403121561105857600080fd5b81516001600160a01b038116811461106f57600080fd5b9392505050565b634e487b7160e01b600052602160045260246000fd5b60208101604083106110a0576110a0611076565b91905290565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156110e4576110e46110a6565b604052919050565b60006001600160401b03821115611105576111056110a6565b5060051b60200190565b6000602080838503121561112257600080fd5b82516001600160401b0381111561113857600080fd5b8301601f8101851361114957600080fd5b805161115c611157826110ec565b6110bc565b81815260059190911b8201830190838101908783111561117b57600080fd5b928401925b8284101561119957835182529284019290840190611180565b979650505050505050565b6000602082840312156111b657600080fd5b81518060010b811461106f57600080fd5b634e487b7160e01b600052603260045260246000fd5b6000602082840312156111ef57600080fd5b5051919050565b6000602080838503121561120957600080fd5b82516001600160401b0381111561121f57600080fd5b8301601f8101851361123057600080fd5b805161123e611157826110ec565b81815260059190911b8201830190838101908783111561125d57600080fd5b928401925b8284101561119957835160ff8116811461127c5760008081fd5b82529284019290840190611262565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff81036112b7576112b761128b565b60010192915050565b600061ffff8083168181036112d7576112d761128b565b6001019392505050565b6000602082840312156112f357600080fd5b8151801515811461106f57600080fd5b6000825160005b81811015611324576020818601810151858301520161130a565b506000920191825250919050565b60208101600383106110a0576110a0611076565b615083806113556000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c8063ad5c4648116100cd578063ce80564211610081578063facaa0b711610066578063facaa0b7146102f6578063fce14af614610309578063ff0a54ed1461031c57600080fd5b8063ce805642146102d0578063e2bc1f93146102e357600080fd5b8063b930b482116100b2578063b930b48214610284578063c091727214610297578063c7301a84146102bd57600080fd5b8063ad5c464814610269578063ad72202b1461027c57600080fd5b80634b03eeb411610124578063795792c011610109578063795792c01461023b5780637cd7f07b1461024e5780638da52e931461026157600080fd5b80634b03eeb4146101fb5780636d205afc1461020e57600080fd5b806331a0edec1161015557806331a0edec146101ac5780633cdad82c146101d7578063443b1786146101e857600080fd5b806301cb6bc3146101715780630a764c1114610186575b600080fd5b61018461017f3660046141f6565b61032f565b005b610199610194366004614305565b6108b7565b6040519081526020015b60405180910390f35b6005546101bf906001600160a01b031681565b6040516001600160a01b0390911681526020016101a3565b6003546001600160a01b03166101bf565b6000546101bf906001600160a01b031681565b610184610209366004614364565b610bec565b61022161021c366004614390565b610dbf565b6040805161ffff90931683526020830191909152016101a3565b610184610249366004614305565b610e26565b61018461025c3660046143b9565b611562565b610184611684565b6006546101bf906001600160a01b031681565b6101846116d2565b6002546101bf906001600160a01b031681565b6102aa6102a53660046143f2565b6119a4565b60405161ffff90911681526020016101a3565b6101846102cb366004614416565b611a3b565b6101996102de366004614305565b611c61565b6101846102f13660046143f2565b611f7c565b6101996103043660046145c8565b61226c565b6001546101bf906001600160a01b031681565b61018461032a3660046143b9565b6125a8565b6000546040517f6288a66c0000000000000000000000000000000000000000000000000000000081526013916001600160a01b031690636288a66c90610379908490600401614699565b602060405180830381865afa158015610396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ba91906146c3565b6001600160a01b0316336001600160a01b031614610404576040517ff7aa031600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561087b576000838281518110610424576104246146e0565b6020908102919091010151600e546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018390529192506000916001600160a01b0390911690636352211e90602401602060405180830381865afa158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb91906146c3565b601054604051634378a6e360e01b8152600481018590529192506000916001600160a01b0390911690634378a6e390602401608060405180830381865afa15801561050a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052e9190614701565b6020810180516001909152601054604051631a9c807760e31b815292935090916001600160a01b039091169063d4e403b8906105709087908690600401614758565b600060405180830381600087803b15801561058a57600080fd5b505af115801561059e573d6000803e3d6000fd5b5050601054600092506001600160a01b03169050631eef219686836040519080825280602002602001820160405280156105e2578160200160208202803683370190505b506040518363ffffffff1660e01b8152600401610600929190614797565b600060405180830381865afa15801561061d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610645919081019061481b565b905060005b81518160ff1610156107f857601054604051633042dd8360e21b815260ff831660048201526003916001600160a01b03169063c10b760c90602401602060405180830381865afa1580156106a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c6919061494f565b60058111156106d7576106d7614683565b0361072057604080516000602082015201604051602081830303815290604052828260ff168151811061070c5761070c6146e0565b6020026020010151602001819052506107e6565b601054604051633042dd8360e21b815260ff831660048201526001916001600160a01b03169063c10b760c90602401602060405180830381865afa15801561076c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610790919061494f565b60058111156107a1576107a1614683565b036107e657604080516001602082015201604051602081830303815290604052828260ff16815181106107d6576107d66146e0565b6020026020010151602001819052505b806107f081614982565b91505061064a565b5060105460405163649936fb60e11b81526001600160a01b039091169063c9326df69061082b9088908590600401614a33565b600060405180830381600087803b15801561084557600080fd5b505af1158015610859573d6000803e3d6000fd5b5050505061086a84866001856126bc565b505060019093019250610407915050565b507f2ba919605728a8fad59d025beab025fd8bc6296847ae59e360ece861bfcec808826040516108ab9190614a54565b60405180910390a15050565b6000805460405163bcaa0c5560e01b815260149183916001600160a01b039091169063bcaa0c55906108ed908590600401614a98565b602060405180830381865afa15801561090a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092e91906146c3565b90506001600160a01b038116610962578160405163092bc2cd60e41b81526004016109599190614a98565b60405180910390fd5b6001600160a01b038116331461098b576040516306923c2160e21b815260040160405180910390fd5b6001600160a01b038516600090815260086020526040812054869161ffff90911690036109e4576040517f2cad80db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e5460408051631d5e528f60e21b815290516000926001600160a01b0316916375794a3c9160048083019260209291908290030181865afa158015610a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a529190614aac565b9050610a608187600261281f565b600e546040516335313c2160e11b81526001600160a01b03848116600483015290911690636a627842906024016020604051808303816000875af1158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190614aac565b506010546040517fd20264ca000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b03169063d20264ca9060240160a060405180830381865afa158015610b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b589190614ac5565b6001600160a01b0384166000908152600860205260408120805492935091610b839061ffff16614b3f565b91906101000a81548161ffff021916908361ffff160217905550819550826001600160a01b03167f90bb8882a83659022a465f3d9d3ce3f6d29164cd23b6ea472a1e7fd49d2c797b82604051610bd99190614bd9565b60405180910390a2505050505092915050565b6000805460405163bcaa0c5560e01b8152600c92916001600160a01b03169063bcaa0c5590610c1f908590600401614a98565b602060405180830381865afa158015610c3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6091906146c3565b90506001600160a01b038116610c8b578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314610cb4576040516306923c2160e21b815260040160405180910390fd5b60005460405163bcaa0c5560e01b81526001600160a01b038087169263aad3ec969291169063bcaa0c5590610cee90600c90600401614a98565b602060405180830381865afa158015610d0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2f91906146c3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018690526044016020604051808303816000875af1158015610d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db89190614aac565b5050505050565b600080610e1c600d805480602002602001604051908101604052809291908181526020018280548015610e1157602002820191906000526020600020905b815481526020019060010190808311610dfd575b505050505084612a37565b9094909350915050565b6000805460405163bcaa0c5560e01b8152601492916001600160a01b03169063bcaa0c5590610e59908590600401614a98565b602060405180830381865afa158015610e76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9a91906146c3565b90506001600160a01b038116610ec5578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314610eee576040516306923c2160e21b815260040160405180910390fd5b6000848152600c6020908152604091829020825160808101845281546001600160a01b031680825260018301549382019390935260029091015461ffff808216948301949094526201000090049092166060830152610f6057604051632f828a7f60e21b815260040160405180910390fd5b60608101516010546020830151604051634378a6e360e01b815260048101919091526000916001600160a01b031690634378a6e390602401608060405180830381865afa158015610fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd99190614701565b9050826040015161ffff16816020015161ffff161461100b57604051632f828a7f60e21b815260040160405180910390fd5b826040015161ffff16836060015161ffff161161103b57604051632f828a7f60e21b815260040160405180910390fd5b601054602084810151604080516000808252938101918290527f1eef21960000000000000000000000000000000000000000000000000000000090915291926001600160a01b031691631eef2196916110979160248101614797565b600060405180830381865afa1580156110b4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110dc919081019061481b565b905080518751101561111a576040517fa793379500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606084015160408501516000906001906111349084614bed565b61ffff16111561115457604086015161114e906001614c0f565b91508190505b6000805b84518160ff1610156113d657601054604051633042dd8360e21b815260ff831660048201526003916001600160a01b03169063c10b760c90602401602060405180830381865afa1580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d4919061494f565b60058111156111e5576111e5614683565b036113c4576000858260ff1681518110611201576112016146e0565b602002602001015160000151600581111561121e5761121e614683565b036112b0576003858260ff168151811061123a5761123a6146e0565b602002602001015160000190600581111561125757611257614683565b9081600581111561126a5761126a614683565b90525060408051600184900b602082015201604051602081830303815290604052858260ff16815181106112a0576112a06146e0565b6020026020010151602001819052505b6000858260ff16815181106112c7576112c76146e0565b6020026020010151602001515160200361131257858260ff16815181106112f0576112f06146e0565b60200260200101516020015180602001905181019061130f9190614c2a565b90505b600060038d8460ff168151811061132b5761132b6146e0565b016020015161133d919060f81c614c63565b60ff1611156113c25760038c8360ff168151811061135d5761135d6146e0565b016020015161136f919060f81c614c63565b61137c9060000b82614c85565b60408051600183900b602082015291925001604051602081830303815290604052868360ff16815181106113b2576113b26146e0565b6020026020010151602001819052505b505b806113ce81614982565b915050611158565b5061ffff831660208087019190915260105490880151604051631a9c807760e31b81526001600160a01b039092169163d4e403b891611419918990600401614758565b600060405180830381600087803b15801561143357600080fd5b505af1158015611447573d6000803e3d6000fd5b505060105460208a015160405163649936fb60e11b81526001600160a01b03909216935063c9326df69250611480918890600401614a33565b600060405180830381600087803b15801561149a57600080fd5b505af11580156114ae573d6000803e3d6000fd5b505050508261ffff168661ffff16146114d9576114d987600001518860200151848a606001516126bc565b60008b8152600c6020908152604080832080546001600160a01b031916815560018101939093556002909201805463ffffffff191690558851908901518983015192517fd07d90a96ab58cc93681e6c09b6a3f560bd5662a139d3987a1d809c4f9bdb3a79361154d93929188908a90614cc5565b60405180910390a15050505050505050505050565b6000546040517f6288a66c0000000000000000000000000000000000000000000000000000000081526013916001600160a01b031690636288a66c906115ac908490600401614699565b602060405180830381865afa1580156115c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ed91906146c3565b6001600160a01b0316336001600160a01b031614611637576040517ff7aa031600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b0391909116600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff909216919091179055565b6000546001600160a01b031633146116c8576040517fe101028000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0612b56565b565b600054600160a01b900460ff1615611716576040517f8f85eea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061172133612eda565b506001600160a01b03811660009081526007602052604081205491925061ffff909116900361177c576040517fafdc47b100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546001600160a01b03821660009081526008602052604090205461ffff600160a01b90920482169116106117de576040517f493ebfde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526009602090815260408083205460079092528220805460a09290921b6001600160a01b0319169093179261ffff9091169161182783614b3f565b82546101009290920a61ffff8181021990931691831602179091556001600160a01b03841660009081526008602052604081208054909216925061186a83614d01565b825461ffff9182166101009390930a9283029190920219909116179055506001600160a01b038216600090815260096020526040812080546bffffffffffffffffffffffff16916118ba83614d22565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550600f5460405163193f45af60e31b81523060048201527fce805642000000000000000000000000000000000000000000000000000000006024820152604481018390526001600160a01b039091169063c9fa2d7890606401600060405180830381600087803b15801561195457600080fd5b505af1158015611968573d6000803e3d6000fd5b50506040516001600160a01b03851692507fcb0847659726c8fa5b29896bef7a8a7fbe61a6f1c1df225572ce56bedb0619929150600090a25050565b601154604051635c12cd4b60e01b81526001600160a01b0383811660048301526000928392911690635c12cd4b9060240161010060405180830381865afa1580156119f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a179190614d43565b506001600160a01b031660009081526007602052604090205461ffff169392505050565b6000805460405163bcaa0c5560e01b8152600792916001600160a01b03169063bcaa0c5590611a6e908590600401614a98565b602060405180830381865afa158015611a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aaf91906146c3565b90506001600160a01b038116611ada578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314611b03576040516306923c2160e21b815260040160405180910390fd5b601054604051634378a6e360e01b8152600481018690526000916001600160a01b031690634378a6e390602401608060405180830381865afa158015611b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b719190614701565b90506000611bd3600d805480602002602001604051908101604052809291908181526020018280548015611bc457602002820191906000526020600020905b815481526020019060010190808311611bb0575b50505050508360000151612a37565b509050816020015161ffff168161ffff161115611c5957611bfa85878460200151846126bc565b846001600160a01b03167ff8deb80dc9d6cc9f9573170eaa7e06c46024c395a2a68f51243cdac59a988b9887846020015184604051611c509392919092835261ffff918216602084015216604082015260600190565b60405180910390a25b505050505050565b6000805460405163bcaa0c5560e01b815260149183916001600160a01b039091169063bcaa0c5590611c97908590600401614a98565b602060405180830381865afa158015611cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd891906146c3565b90506001600160a01b038116611d03578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314611d2c576040516306923c2160e21b815260040160405180910390fd5b6001600160a01b038516600090815260086020526040812054869161ffff9091169003611d85576040517f2cad80db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e5460408051631d5e528f60e21b815290516000926001600160a01b0316916375794a3c9160048083019260209291908290030181865afa158015611dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df39190614aac565b9050611e018187600561281f565b600e546040516335313c2160e11b81526001600160a01b03848116600483015290911690636a627842906024016020604051808303816000875af1158015611e4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e719190614aac565b506010546040517fd20264ca000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b03169063d20264ca9060240160a060405180830381865afa158015611ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef99190614ac5565b6001600160a01b0384166000908152600860205260408120805492935091611f249061ffff16614b3f565b91906101000a81548161ffff021916908361ffff160217905550819550826001600160a01b03167f1e30f783fc5d671ab5855807724b6667c6f4b3564be57b6ef7c69740b4cc1cf98383604051610bd9929190614e00565b6000805460405163bcaa0c5560e01b8152600892916001600160a01b03169063bcaa0c5590611faf908590600401614a98565b602060405180830381865afa158015611fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff091906146c3565b90506001600160a01b03811661201b578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314612044576040516306923c2160e21b815260040160405180910390fd5b601154604051635c12cd4b60e01b81526001600160a01b0385811660048301526000921690635c12cd4b9060240161010060405180830381865afa158015612090573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b49190614d43565b506006546001600160a01b03821660009081526008602052604090205491925061ffff600160a01b909104811691161061211a576040517f493ebfde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526009602090815260408083205460089092528220805460a09290921b6001600160a01b0319169093179261ffff9091169161216383614d01565b825461ffff9182166101009390930a9283029190920219909116179055506001600160a01b038216600090815260096020526040812080546bffffffffffffffffffffffff16916121b383614d22565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550600f5460405163193f45af60e31b81523060048201527f0a764c11000000000000000000000000000000000000000000000000000000006024820152604481018390526001600160a01b039091169063c9fa2d7890606401600060405180830381600087803b15801561224d57600080fd5b505af1158015612261573d6000803e3d6000fd5b505050505050505050565b6000805460405163bcaa0c5560e01b815260059183916001600160a01b039091169063bcaa0c55906122a2908590600401614a98565b602060405180830381865afa1580156122bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e391906146c3565b90506001600160a01b03811661230e578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314612337576040516306923c2160e21b815260040160405180910390fd5b600e5460408051631d5e528f60e21b815290516000926001600160a01b0316916375794a3c9160048083019260209291908290030181865afa158015612381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a59190614aac565b6010546040517fc23ed8510000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063c23ed851906123f19084908a90600401614e00565b600060405180830381600087803b15801561240b57600080fd5b505af115801561241f573d6000803e3d6000fd5b5050601054604051631a9c807760e31b81526001600160a01b03909116925063d4e403b891506124559084908b90600401614758565b600060405180830381600087803b15801561246f57600080fd5b505af1158015612483573d6000803e3d6000fd5b505060105460405163649936fb60e11b81526001600160a01b03909116925063c9326df691506124b99084908990600401614a33565b600060405180830381600087803b1580156124d357600080fd5b505af11580156124e7573d6000803e3d6000fd5b5050600e546040516335313c2160e11b81526001600160a01b038c811660048301529091169250636a62784291506024016020604051808303816000875af1158015612537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061255b9190614aac565b50809350807f2d4209cb05428f87d9b454ef8466c0fc64a91ce45adeb3e672a6a524e71c141689888a896040516125959493929190614e14565b60405180910390a2505050949350505050565b6000805460405163bcaa0c5560e01b8152600292916001600160a01b03169063bcaa0c55906125db908590600401614a98565b602060405180830381865afa1580156125f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261c91906146c3565b90506001600160a01b038116612647578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314612670576040516306923c2160e21b815260040160405180910390fd5b6001600160a01b0384166000908152600760205260408120805485929061269c90849061ffff16614c0f565b92506101000a81548161ffff021916908361ffff16021790555050505050565b604080516001600160a01b038616602082015290810184905261ffff80841660608301528216608082015260009060a001604051602081830303815290604052805190602001209050600061270e8290565b604080516080810182526001600160a01b03898116825260208083018a815261ffff8a81168587019081528a8216606087019081526000898152600c90955293879020955186549086166001600160a01b03199091161786559151600186015590516002909401805492518216620100000263ffffffff19909316949091169390931717909155600f54915163193f45af60e31b81523060048201527f795792c000000000000000000000000000000000000000000000000000000000602482015260448101849052929350169063c9fa2d7890606401600060405180830381600087803b1580156127ff57600080fd5b505af1158015612813573d6000803e3d6000fd5b50505050505050505050565b60008061282c8484612fcc565b600a54919350915061ffff821610612876576040517fd8e1e3c600000000000000000000000000000000000000000000000000000000815261ffff82166004820152602401610959565b60006040518060a0016040528084600681111561289557612895614683565b81526020018361ffff168152602001600a8461ffff16815481106128bb576128bb6146e0565b60009182526020918290209181049091015460ff601f9092166101000a90041660058111156128ec576128ec614683565b60058111156128fd576128fd614683565b81526002602082015263ffffffff421660409182015260105490517fc23ed8510000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063c23ed8519061295e9089908590600401614e00565b600060405180830381600087803b15801561297857600080fd5b505af115801561298c573d6000803e3d6000fd5b505050506129c3604051806080016040528060008152602001600061ffff168152602001600061ffff168152602001600081525090565b60016020820152601054604051631a9c807760e31b81526001600160a01b039091169063d4e403b8906129fc908a908590600401614758565b600060405180830381600087803b158015612a1657600080fd5b505af1158015612a2a573d6000803e3d6000fd5b5050505050505050505050565b60008083606381518110612a4d57612a4d6146e0565b60200260200101518310612a8157606584606381518110612a7057612a706146e0565b602002602001015191509150612b4f565b83600081518110612a9457612a946146e0565b6020026020010151831015612aaf5750600190506000612b4f565b835160009081805b82841015612b13576002612acb8486614e73565b612ad59190614e86565b915086888381518110612aea57612aea6146e0565b602002602001015111612b0957612b02826001614e73565b9350612ab7565b5090508080612ab7565b612b1e816001614c0f565b955087612b2c600183614bed565b61ffff1681518110612b4057612b406146e0565b60200260200101519450505050505b9250929050565b60005460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c5590612b8790600a90600401614a98565b602060405180830381865afa158015612ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc891906146c3565b600e80546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c5590612c0c90601490600401614a98565b602060405180830381865afa158015612c29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4d91906146c3565b600f80546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c5590612c9190601590600401614a98565b602060405180830381865afa158015612cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd291906146c3565b601080546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c5590612d1690600390600401614a98565b602060405180830381865afa158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5791906146c3565b601180546001600160a01b0319166001600160a01b0392909216919091179055612d7f6131e0565b612d87613444565b6000546040517fff74ad5f0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063ff74ad5f90612dd190602490600401614a98565b600060405180830381865afa158015612dee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e169190810190614e9a565b8051612e2a91600d91602090910190613ffc565b506000546040517fc4c379cd0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063c4c379cd90612e7590601b90600401614a98565b602060405180830381865afa158015612e92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb69190614c2a565b600660146101000a81548161ffff021916908361ffff1602179055506116d0613555565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101829052601154604051635c12cd4b60e01b81526001600160a01b03858116600483015290911690635c12cd4b9060240161010060405180830381865afa158015612f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f819190614d43565b8051919350915063ffffffff16600003612fc7576040517f3e3a049f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b915091565b600080600080612fdb86613c48565b909250905060066000808060015b600560ff8216116131cf5760ff81166000908152600b60205260409020546130179063ffffffff1684614e73565b92508663ffffffff1683106131bd5789600681111561303857613038614683565b60ff168160ff16111561304d57899450613065565b8060ff16600681111561306257613062614683565b94505b6000600b600087600681111561307d5761307d614683565b60ff168152602081019190915260400160009081206001015491508190036130d357856040517f35183fd30000000000000000000000000000000000000000000000000000000081526004016109599190614f20565b6130e38163ffffffff8916614f2e565b9250600b60008760068111156130fb576130fb614683565b60ff1681526020810191909152604001600020600101548303613154576001600b600088600681111561313057613130614683565b60ff1681526020810191909152604001600020600101546131519190614f42565b92505b600b600087600681111561316a5761316a614683565b60ff1660ff1681526020019081526020016000206001018381548110613192576131926146e0565b90600052602060002090602091828204019190069054906101000a900460ff1660ff169450506131cf565b806131c781614982565b915050612fe9565b509299919850909650505050505050565b6040805160a081019091526000908060018152602001600281526020016003815260200160048152602001600590526040805160a08101909152909150600090806038815260200160398152602001603a8152602001603b8152602001603c90526040805160a08101909152909150600090806033815260200160348152602001603581526020016036815260200160379052905060005b60058160ff16101561343e576040805180820190915260005481906001600160a01b03166342ab14dd8660ff8616600581106132b6576132b66146e0565b60200201516040518263ffffffff1660e01b81526004016132d79190614a98565b602060405180830381865afa1580156132f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133189190614aac565b63ffffffff1681526000546020909101906001600160a01b0316638344a9268560ff86166005811061334c5761334c6146e0565b60200201516040518263ffffffff1660e01b815260040161336d9190614a98565b600060405180830381865afa15801561338a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133b29190810190614f55565b9052600b60008660ff8516600581106133cd576133cd6146e0565b602002015160068111156133e3576133e3614683565b60ff1681526020808201929092526040016000208251815463ffffffff191663ffffffff909116178155828201518051919261342792600185019290910190614047565b50905050808061343690614982565b915050613278565b50505050565b600080546040517f8344a9260000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690638344a9269061348f90603290600401614a98565b600060405180830381865afa1580156134ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134d49190810190614f55565b905060005b81518161ffff16101561355157600a828261ffff16815181106134fe576134fe6146e0565b6020908102919091018101518254600181018455600093845292829020918304909101805460ff928316601f9094166101000a93840292909302199092161790558061354981614d01565b9150506134d9565b5050565b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061358790600f90600401614a98565b602060405180830381865afa1580156135a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c891906146c3565b6001549091506001600160a01b0380831691161461379857600180546001600160a01b0319166001600160a01b0383169081179091556040517ffe9fbb8000000000000000000000000000000000000000000000000000000000815230600482015263fe9fbb8090602401602060405180830381865afa158015613650573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136749190614fe4565b1561379857600160009054906101000a90046001600160a01b03166001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156136c957600080fd5b505af11580156136dd573d6000803e3d6000fd5b505060408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff098767a000000000000000000000000000000000000000000000000000000001790529051600093506001600160a01b03851692506137519190615006565b6000604051808303816000865af19150503d806000811461378e576040519150601f19603f3d011682016040523d82523d6000602084013e613793565b606091505b505050505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c55906137ca90601090600401614a98565b602060405180830381865afa1580156137e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380b91906146c3565b6002549091506001600160a01b0380831691161461395757600280546001600160a01b0319166001600160a01b03838116919091179091556000805460405163bcaa0c5560e01b81529192169063bcaa0c559061386d90601190600401614a98565b602060405180830381865afa15801561388a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ae91906146c3565b6004549091506001600160a01b0316613955576002546040517f36b91f2b0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152909116906336b91f2b90602401600060405180830381600087803b15801561392157600080fd5b505af1158015613935573d6000803e3d6000fd5b5050600480546001600160a01b0319166001600160a01b03851617905550505b505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061398990601290600401614a98565b602060405180830381865afa1580156139a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ca91906146c3565b6000805460405163bcaa0c5560e01b815292935090916001600160a01b039091169063bcaa0c5590613a0190601390600401614a98565b602060405180830381865afa158015613a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a4291906146c3565b6005549091506001600160a01b03838116911614613afc57600580546001600160a01b0319166001600160a01b0384169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152839190631a33757d90613ab690600290600401615022565b6020604051808303816000875af1158015613ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af99190614aac565b50505b6006546001600160a01b03828116911614613bb357600680546001600160a01b0319166001600160a01b0383169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152829190631a33757d90613b6d90600290600401615022565b6020604051808303816000875af1158015613b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb09190614aac565b50505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c5590613be590600c90600401614a98565b602060405180830381865afa158015613c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2691906146c3565b90506001600160a01b03811615613c4057613c4081613dac565b610db8613f38565b600080600583511015613c87576040517fa793379500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008086600381518110613ca057613ca06146e0565b602001015160f81c60f81b60f81c60ff16600888600281518110613cc657613cc66146e0565b602001015160f81c60f81b60f81c60ff1663ffffffff16901b601089600181518110613cf457613cf46146e0565b602001015160f81c60f81b60f81c60ff1663ffffffff16901b60188a600081518110613d2257613d226146e0565b602001015160f81c60f81b60f81c60ff1663ffffffff16901b171717935086600481518110613d5357613d536146e0565b016020015160f81c9250600063ffffffff613d73868216620f4240615036565b613d7d9190614e86565b9050600060ff613d92868216620f4240615036565b613d9c9190614e86565b9199919850909650505050505050565b6001600160a01b038116613dec576040517f05d8ce3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546001600160a01b0316613dff5750565b6003546001600160a01b0316613e9d576001600160a01b0381163014613e98576001546040517feb8646980000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301529091169063eb86469890602401600060405180830381600087803b158015613e7f57600080fd5b505af1158015613e93573d6000803e3d6000fd5b505050505b613f16565b6003546040517f3a74bfd70000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015290911690633a74bfd790602401600060405180830381600087803b158015613efd57600080fd5b505af1158015613f11573d6000803e3d6000fd5b505050505b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546040517ff2aac76c0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063f2aac76c90613f8290600190600401614a98565b602060405180830381865afa158015613f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fc39190614fe4565b60008054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b828054828255906000526020600020908101928215614037579160200282015b8281111561403757825182559160200191906001019061401c565b506140439291506140e4565b5090565b82805482825590600052602060002090601f016020900481019282156140375791602002820160005b838211156140ae57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614070565b80156140db5782816101000a81549060ff02191690556001016020816000010492830192600103026140ae565b50506140439291505b5b8082111561404357600081556001016140e5565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614132576141326140f9565b60405290565b6040805190810167ffffffffffffffff81118282101715614132576141326140f9565b6040516080810167ffffffffffffffff81118282101715614132576141326140f9565b60405160e0810167ffffffffffffffff81118282101715614132576141326140f9565b604051601f8201601f1916810167ffffffffffffffff811182821017156141ca576141ca6140f9565b604052919050565b600067ffffffffffffffff8211156141ec576141ec6140f9565b5060051b60200190565b6000602080838503121561420957600080fd5b823567ffffffffffffffff81111561422057600080fd5b8301601f8101851361423157600080fd5b803561424461423f826141d2565b6141a1565b81815260059190911b8201830190838101908783111561426357600080fd5b928401925b8284101561428157833582529284019290840190614268565b979650505050505050565b600067ffffffffffffffff8211156142a6576142a66140f9565b50601f01601f191660200190565b600082601f8301126142c557600080fd5b81356142d361423f8261428c565b8181528460208386010111156142e857600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561431857600080fd5b82359150602083013567ffffffffffffffff81111561433657600080fd5b614342858286016142b4565b9150509250929050565b6001600160a01b038116811461436157600080fd5b50565b6000806040838503121561437757600080fd5b82356143828161434c565b946020939093013593505050565b6000602082840312156143a257600080fd5b5035919050565b61ffff8116811461436157600080fd5b600080604083850312156143cc57600080fd5b82356143d78161434c565b915060208301356143e7816143a9565b809150509250929050565b60006020828403121561440457600080fd5b813561440f8161434c565b9392505050565b6000806040838503121561442957600080fd5b8235915060208301356143e78161434c565b6007811061436157600080fd5b6006811061436157600080fd5b60ff8116811461436157600080fd5b63ffffffff8116811461436157600080fd5b600060a0828403121561448857600080fd5b61449061410f565b9050813561449d8161443b565b815260208201356144ad816143a9565b602082015260408201356144c081614448565b604082015260608201356144d381614455565b606082015260808201356144e681614464565b608082015292915050565b600082601f83011261450257600080fd5b8135602061451261423f836141d2565b82815260059290921b8401810191818101908684111561453157600080fd5b8286015b848110156145bd57803567ffffffffffffffff808211156145565760008081fd5b8189019150604080601f19848d030112156145715760008081fd5b614579614138565b8784013561458681614448565b815290830135908282111561459b5760008081fd5b6145a98c89848701016142b4565b818901528652505050918301918301614535565b509695505050505050565b6000806000808486036101608112156145e057600080fd5b85356145eb8161434c565b94506080601f19820112156145ff57600080fd5b5061460861415b565b60208601358152604086013561461d816143a9565b60208201526060860135614630816143a9565b604082015260808601356060820152925061464e8660a08701614476565b915061014085013567ffffffffffffffff81111561466b57600080fd5b614677878288016144f1565b91505092959194509250565b634e487b7160e01b600052602160045260246000fd5b60208101601583106146ad576146ad614683565b91905290565b80516146be8161434c565b919050565b6000602082840312156146d557600080fd5b815161440f8161434c565b634e487b7160e01b600052603260045260246000fd5b80516146be816143a9565b60006080828403121561471357600080fd5b61471b61415b565b82518152602083015161472d816143a9565b60208201526040830151614740816143a9565b60408201526060928301519281019290925250919050565b82815260a0810161440f602083018480518252602081015161ffff80821660208501528060408401511660408501525050606081015160608301525050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b818110156147ea578451601181106147d8576147d8614683565b835293830193918301916001016147be565b5090979650505050505050565b60005b838110156148125781810151838201526020016147fa565b50506000910152565b6000602080838503121561482e57600080fd5b825167ffffffffffffffff8082111561484657600080fd5b818501915085601f83011261485a57600080fd5b815161486861423f826141d2565b81815260059190911b8301840190848101908883111561488757600080fd5b8585015b83811015614942578051858111156148a35760008081fd5b86016040818c03601f19018113156148bb5760008081fd5b6148c3614138565b898301516148d081614448565b815282820151888111156148e45760008081fd5b8084019350508c603f8401126148fa5760008081fd5b8983015161490a61423f8261428c565b8181528e8483870101111561491f5760008081fd5b61492e828d83018688016147f7565b828c0152508552505091860191860161488b565b5098975050505050505050565b60006020828403121561496157600080fd5b815161440f81614448565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff81036149985761499861496c565b60010192915050565b6006811061436157614361614683565b600082825180855260208086019550808260051b84010181860160005b848110156147ea57601f1980878503018a528251604081516149ef816149a1565b865290860151868601829052805191860182905290606090614a1681838901858b016147f7565b9b87019b601f0190921694909401019250908301906001016149ce565b828152604060208201526000614a4c60408301846149b1565b949350505050565b6020808252825182820181905260009190848201906040850190845b81811015614a8c57835183529284019291840191600101614a70565b50909695505050505050565b60208101604083106146ad576146ad614683565b600060208284031215614abe57600080fd5b5051919050565b600060a08284031215614ad757600080fd5b614adf61410f565b8251614aea8161443b565b81526020830151614afa816143a9565b60208201526040830151614b0d81614448565b60408201526060830151614b2081614455565b60608201526080830151614b3381614464565b60808201529392505050565b600061ffff821680614b5357614b5361496c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b60078110614b8b57614b8b614683565b9052565b614b9a828251614b7b565b61ffff60208201511660208301526040810151614bb6816149a1565b604083015260608181015160ff169083015260809081015163ffffffff16910152565b60a08101614be78284614b8f565b92915050565b61ffff828116828216039080821115614c0857614c0861496c565b5092915050565b61ffff818116838216019080821115614c0857614c0861496c565b600060208284031215614c3c57600080fd5b81518060010b811461440f57600080fd5b634e487b7160e01b600052601260045260246000fd5b600060ff831680614c7657614c76614c4d565b8060ff84160691505092915050565b600181810b9083900b01617fff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800082121715614be757614be761496c565b6001600160a01b0386168152846020820152600061ffff808616604084015280851660608401525060a0608083015261428160a08301846149b1565b600061ffff808316818103614d1857614d1861496c565b6001019392505050565b60006bffffffffffffffffffffffff808316818103614d1857614d1861496c565b600080828403610100811215614d5857600080fd5b8351614d638161434c565b925060e0601f1982011215614d7757600080fd5b50614d8061417e565b6020840151614d8e81614464565b81526040840151614d9e81614464565b60208201526060840151614db181614464565b60408201526080840151614dc481614448565b6060820152614dd560a085016146f6565b608082015260c084015160a0820152614df060e085016146b3565b60c0820152809150509250929050565b82815260c0810161440f6020830184614b8f565b60006101606001600160a01b0387168352614e326020840187614b8f565b845160c0840152602085015161ffff90811660e0850152604086015116610100840152606085015161012084015280610140840152614281818401856149b1565b80820180821115614be757614be761496c565b600082614e9557614e95614c4d565b500490565b60006020808385031215614ead57600080fd5b825167ffffffffffffffff811115614ec457600080fd5b8301601f81018513614ed557600080fd5b8051614ee361423f826141d2565b81815260059190911b82018301908381019087831115614f0257600080fd5b928401925b8284101561428157835182529284019290840190614f07565b60208101614be78284614b7b565b600082614f3d57614f3d614c4d565b500690565b81810381811115614be757614be761496c565b60006020808385031215614f6857600080fd5b825167ffffffffffffffff811115614f7f57600080fd5b8301601f81018513614f9057600080fd5b8051614f9e61423f826141d2565b81815260059190911b82018301908381019087831115614fbd57600080fd5b928401925b82841015614281578351614fd581614455565b82529284019290840190614fc2565b600060208284031215614ff657600080fd5b8151801515811461440f57600080fd5b600082516150188184602087016147f7565b9190910192915050565b60208101600383106146ad576146ad614683565b8082028115828204841417614be757614be761496c56fea264697066735822122028961595bdd55fa1cac20f1e9e4e8f60026e559282770d815ce91bbda4a13d2d64736f6c63430008190033000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061016c5760003560e01c8063ad5c4648116100cd578063ce80564211610081578063facaa0b711610066578063facaa0b7146102f6578063fce14af614610309578063ff0a54ed1461031c57600080fd5b8063ce805642146102d0578063e2bc1f93146102e357600080fd5b8063b930b482116100b2578063b930b48214610284578063c091727214610297578063c7301a84146102bd57600080fd5b8063ad5c464814610269578063ad72202b1461027c57600080fd5b80634b03eeb411610124578063795792c011610109578063795792c01461023b5780637cd7f07b1461024e5780638da52e931461026157600080fd5b80634b03eeb4146101fb5780636d205afc1461020e57600080fd5b806331a0edec1161015557806331a0edec146101ac5780633cdad82c146101d7578063443b1786146101e857600080fd5b806301cb6bc3146101715780630a764c1114610186575b600080fd5b61018461017f3660046141f6565b61032f565b005b610199610194366004614305565b6108b7565b6040519081526020015b60405180910390f35b6005546101bf906001600160a01b031681565b6040516001600160a01b0390911681526020016101a3565b6003546001600160a01b03166101bf565b6000546101bf906001600160a01b031681565b610184610209366004614364565b610bec565b61022161021c366004614390565b610dbf565b6040805161ffff90931683526020830191909152016101a3565b610184610249366004614305565b610e26565b61018461025c3660046143b9565b611562565b610184611684565b6006546101bf906001600160a01b031681565b6101846116d2565b6002546101bf906001600160a01b031681565b6102aa6102a53660046143f2565b6119a4565b60405161ffff90911681526020016101a3565b6101846102cb366004614416565b611a3b565b6101996102de366004614305565b611c61565b6101846102f13660046143f2565b611f7c565b6101996103043660046145c8565b61226c565b6001546101bf906001600160a01b031681565b61018461032a3660046143b9565b6125a8565b6000546040517f6288a66c0000000000000000000000000000000000000000000000000000000081526013916001600160a01b031690636288a66c90610379908490600401614699565b602060405180830381865afa158015610396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ba91906146c3565b6001600160a01b0316336001600160a01b031614610404576040517ff7aa031600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561087b576000838281518110610424576104246146e0565b6020908102919091010151600e546040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018390529192506000916001600160a01b0390911690636352211e90602401602060405180830381865afa158015610497573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bb91906146c3565b601054604051634378a6e360e01b8152600481018590529192506000916001600160a01b0390911690634378a6e390602401608060405180830381865afa15801561050a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052e9190614701565b6020810180516001909152601054604051631a9c807760e31b815292935090916001600160a01b039091169063d4e403b8906105709087908690600401614758565b600060405180830381600087803b15801561058a57600080fd5b505af115801561059e573d6000803e3d6000fd5b5050601054600092506001600160a01b03169050631eef219686836040519080825280602002602001820160405280156105e2578160200160208202803683370190505b506040518363ffffffff1660e01b8152600401610600929190614797565b600060405180830381865afa15801561061d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610645919081019061481b565b905060005b81518160ff1610156107f857601054604051633042dd8360e21b815260ff831660048201526003916001600160a01b03169063c10b760c90602401602060405180830381865afa1580156106a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106c6919061494f565b60058111156106d7576106d7614683565b0361072057604080516000602082015201604051602081830303815290604052828260ff168151811061070c5761070c6146e0565b6020026020010151602001819052506107e6565b601054604051633042dd8360e21b815260ff831660048201526001916001600160a01b03169063c10b760c90602401602060405180830381865afa15801561076c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610790919061494f565b60058111156107a1576107a1614683565b036107e657604080516001602082015201604051602081830303815290604052828260ff16815181106107d6576107d66146e0565b6020026020010151602001819052505b806107f081614982565b91505061064a565b5060105460405163649936fb60e11b81526001600160a01b039091169063c9326df69061082b9088908590600401614a33565b600060405180830381600087803b15801561084557600080fd5b505af1158015610859573d6000803e3d6000fd5b5050505061086a84866001856126bc565b505060019093019250610407915050565b507f2ba919605728a8fad59d025beab025fd8bc6296847ae59e360ece861bfcec808826040516108ab9190614a54565b60405180910390a15050565b6000805460405163bcaa0c5560e01b815260149183916001600160a01b039091169063bcaa0c55906108ed908590600401614a98565b602060405180830381865afa15801561090a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092e91906146c3565b90506001600160a01b038116610962578160405163092bc2cd60e41b81526004016109599190614a98565b60405180910390fd5b6001600160a01b038116331461098b576040516306923c2160e21b815260040160405180910390fd5b6001600160a01b038516600090815260086020526040812054869161ffff90911690036109e4576040517f2cad80db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e5460408051631d5e528f60e21b815290516000926001600160a01b0316916375794a3c9160048083019260209291908290030181865afa158015610a2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a529190614aac565b9050610a608187600261281f565b600e546040516335313c2160e11b81526001600160a01b03848116600483015290911690636a627842906024016020604051808303816000875af1158015610aac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad09190614aac565b506010546040517fd20264ca000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b03169063d20264ca9060240160a060405180830381865afa158015610b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b589190614ac5565b6001600160a01b0384166000908152600860205260408120805492935091610b839061ffff16614b3f565b91906101000a81548161ffff021916908361ffff160217905550819550826001600160a01b03167f90bb8882a83659022a465f3d9d3ce3f6d29164cd23b6ea472a1e7fd49d2c797b82604051610bd99190614bd9565b60405180910390a2505050505092915050565b6000805460405163bcaa0c5560e01b8152600c92916001600160a01b03169063bcaa0c5590610c1f908590600401614a98565b602060405180830381865afa158015610c3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6091906146c3565b90506001600160a01b038116610c8b578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314610cb4576040516306923c2160e21b815260040160405180910390fd5b60005460405163bcaa0c5560e01b81526001600160a01b038087169263aad3ec969291169063bcaa0c5590610cee90600c90600401614a98565b602060405180830381865afa158015610d0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2f91906146c3565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018690526044016020604051808303816000875af1158015610d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db89190614aac565b5050505050565b600080610e1c600d805480602002602001604051908101604052809291908181526020018280548015610e1157602002820191906000526020600020905b815481526020019060010190808311610dfd575b505050505084612a37565b9094909350915050565b6000805460405163bcaa0c5560e01b8152601492916001600160a01b03169063bcaa0c5590610e59908590600401614a98565b602060405180830381865afa158015610e76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9a91906146c3565b90506001600160a01b038116610ec5578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314610eee576040516306923c2160e21b815260040160405180910390fd5b6000848152600c6020908152604091829020825160808101845281546001600160a01b031680825260018301549382019390935260029091015461ffff808216948301949094526201000090049092166060830152610f6057604051632f828a7f60e21b815260040160405180910390fd5b60608101516010546020830151604051634378a6e360e01b815260048101919091526000916001600160a01b031690634378a6e390602401608060405180830381865afa158015610fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd99190614701565b9050826040015161ffff16816020015161ffff161461100b57604051632f828a7f60e21b815260040160405180910390fd5b826040015161ffff16836060015161ffff161161103b57604051632f828a7f60e21b815260040160405180910390fd5b601054602084810151604080516000808252938101918290527f1eef21960000000000000000000000000000000000000000000000000000000090915291926001600160a01b031691631eef2196916110979160248101614797565b600060405180830381865afa1580156110b4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110dc919081019061481b565b905080518751101561111a576040517fa793379500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606084015160408501516000906001906111349084614bed565b61ffff16111561115457604086015161114e906001614c0f565b91508190505b6000805b84518160ff1610156113d657601054604051633042dd8360e21b815260ff831660048201526003916001600160a01b03169063c10b760c90602401602060405180830381865afa1580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d4919061494f565b60058111156111e5576111e5614683565b036113c4576000858260ff1681518110611201576112016146e0565b602002602001015160000151600581111561121e5761121e614683565b036112b0576003858260ff168151811061123a5761123a6146e0565b602002602001015160000190600581111561125757611257614683565b9081600581111561126a5761126a614683565b90525060408051600184900b602082015201604051602081830303815290604052858260ff16815181106112a0576112a06146e0565b6020026020010151602001819052505b6000858260ff16815181106112c7576112c76146e0565b6020026020010151602001515160200361131257858260ff16815181106112f0576112f06146e0565b60200260200101516020015180602001905181019061130f9190614c2a565b90505b600060038d8460ff168151811061132b5761132b6146e0565b016020015161133d919060f81c614c63565b60ff1611156113c25760038c8360ff168151811061135d5761135d6146e0565b016020015161136f919060f81c614c63565b61137c9060000b82614c85565b60408051600183900b602082015291925001604051602081830303815290604052868360ff16815181106113b2576113b26146e0565b6020026020010151602001819052505b505b806113ce81614982565b915050611158565b5061ffff831660208087019190915260105490880151604051631a9c807760e31b81526001600160a01b039092169163d4e403b891611419918990600401614758565b600060405180830381600087803b15801561143357600080fd5b505af1158015611447573d6000803e3d6000fd5b505060105460208a015160405163649936fb60e11b81526001600160a01b03909216935063c9326df69250611480918890600401614a33565b600060405180830381600087803b15801561149a57600080fd5b505af11580156114ae573d6000803e3d6000fd5b505050508261ffff168661ffff16146114d9576114d987600001518860200151848a606001516126bc565b60008b8152600c6020908152604080832080546001600160a01b031916815560018101939093556002909201805463ffffffff191690558851908901518983015192517fd07d90a96ab58cc93681e6c09b6a3f560bd5662a139d3987a1d809c4f9bdb3a79361154d93929188908a90614cc5565b60405180910390a15050505050505050505050565b6000546040517f6288a66c0000000000000000000000000000000000000000000000000000000081526013916001600160a01b031690636288a66c906115ac908490600401614699565b602060405180830381865afa1580156115c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115ed91906146c3565b6001600160a01b0316336001600160a01b031614611637576040517ff7aa031600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b0391909116600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff909216919091179055565b6000546001600160a01b031633146116c8576040517fe101028000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d0612b56565b565b600054600160a01b900460ff1615611716576040517f8f85eea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061172133612eda565b506001600160a01b03811660009081526007602052604081205491925061ffff909116900361177c576040517fafdc47b100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006546001600160a01b03821660009081526008602052604090205461ffff600160a01b90920482169116106117de576040517f493ebfde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526009602090815260408083205460079092528220805460a09290921b6001600160a01b0319169093179261ffff9091169161182783614b3f565b82546101009290920a61ffff8181021990931691831602179091556001600160a01b03841660009081526008602052604081208054909216925061186a83614d01565b825461ffff9182166101009390930a9283029190920219909116179055506001600160a01b038216600090815260096020526040812080546bffffffffffffffffffffffff16916118ba83614d22565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550600f5460405163193f45af60e31b81523060048201527fce805642000000000000000000000000000000000000000000000000000000006024820152604481018390526001600160a01b039091169063c9fa2d7890606401600060405180830381600087803b15801561195457600080fd5b505af1158015611968573d6000803e3d6000fd5b50506040516001600160a01b03851692507fcb0847659726c8fa5b29896bef7a8a7fbe61a6f1c1df225572ce56bedb0619929150600090a25050565b601154604051635c12cd4b60e01b81526001600160a01b0383811660048301526000928392911690635c12cd4b9060240161010060405180830381865afa1580156119f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a179190614d43565b506001600160a01b031660009081526007602052604090205461ffff169392505050565b6000805460405163bcaa0c5560e01b8152600792916001600160a01b03169063bcaa0c5590611a6e908590600401614a98565b602060405180830381865afa158015611a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aaf91906146c3565b90506001600160a01b038116611ada578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314611b03576040516306923c2160e21b815260040160405180910390fd5b601054604051634378a6e360e01b8152600481018690526000916001600160a01b031690634378a6e390602401608060405180830381865afa158015611b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b719190614701565b90506000611bd3600d805480602002602001604051908101604052809291908181526020018280548015611bc457602002820191906000526020600020905b815481526020019060010190808311611bb0575b50505050508360000151612a37565b509050816020015161ffff168161ffff161115611c5957611bfa85878460200151846126bc565b846001600160a01b03167ff8deb80dc9d6cc9f9573170eaa7e06c46024c395a2a68f51243cdac59a988b9887846020015184604051611c509392919092835261ffff918216602084015216604082015260600190565b60405180910390a25b505050505050565b6000805460405163bcaa0c5560e01b815260149183916001600160a01b039091169063bcaa0c5590611c97908590600401614a98565b602060405180830381865afa158015611cb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd891906146c3565b90506001600160a01b038116611d03578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314611d2c576040516306923c2160e21b815260040160405180910390fd5b6001600160a01b038516600090815260086020526040812054869161ffff9091169003611d85576040517f2cad80db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e5460408051631d5e528f60e21b815290516000926001600160a01b0316916375794a3c9160048083019260209291908290030181865afa158015611dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df39190614aac565b9050611e018187600561281f565b600e546040516335313c2160e11b81526001600160a01b03848116600483015290911690636a627842906024016020604051808303816000875af1158015611e4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e719190614aac565b506010546040517fd20264ca000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b03169063d20264ca9060240160a060405180830381865afa158015611ed5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef99190614ac5565b6001600160a01b0384166000908152600860205260408120805492935091611f249061ffff16614b3f565b91906101000a81548161ffff021916908361ffff160217905550819550826001600160a01b03167f1e30f783fc5d671ab5855807724b6667c6f4b3564be57b6ef7c69740b4cc1cf98383604051610bd9929190614e00565b6000805460405163bcaa0c5560e01b8152600892916001600160a01b03169063bcaa0c5590611faf908590600401614a98565b602060405180830381865afa158015611fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff091906146c3565b90506001600160a01b03811661201b578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314612044576040516306923c2160e21b815260040160405180910390fd5b601154604051635c12cd4b60e01b81526001600160a01b0385811660048301526000921690635c12cd4b9060240161010060405180830381865afa158015612090573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b49190614d43565b506006546001600160a01b03821660009081526008602052604090205491925061ffff600160a01b909104811691161061211a576040517f493ebfde00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03811660008181526009602090815260408083205460089092528220805460a09290921b6001600160a01b0319169093179261ffff9091169161216383614d01565b825461ffff9182166101009390930a9283029190920219909116179055506001600160a01b038216600090815260096020526040812080546bffffffffffffffffffffffff16916121b383614d22565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550600f5460405163193f45af60e31b81523060048201527f0a764c11000000000000000000000000000000000000000000000000000000006024820152604481018390526001600160a01b039091169063c9fa2d7890606401600060405180830381600087803b15801561224d57600080fd5b505af1158015612261573d6000803e3d6000fd5b505050505050505050565b6000805460405163bcaa0c5560e01b815260059183916001600160a01b039091169063bcaa0c55906122a2908590600401614a98565b602060405180830381865afa1580156122bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e391906146c3565b90506001600160a01b03811661230e578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314612337576040516306923c2160e21b815260040160405180910390fd5b600e5460408051631d5e528f60e21b815290516000926001600160a01b0316916375794a3c9160048083019260209291908290030181865afa158015612381573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a59190614aac565b6010546040517fc23ed8510000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063c23ed851906123f19084908a90600401614e00565b600060405180830381600087803b15801561240b57600080fd5b505af115801561241f573d6000803e3d6000fd5b5050601054604051631a9c807760e31b81526001600160a01b03909116925063d4e403b891506124559084908b90600401614758565b600060405180830381600087803b15801561246f57600080fd5b505af1158015612483573d6000803e3d6000fd5b505060105460405163649936fb60e11b81526001600160a01b03909116925063c9326df691506124b99084908990600401614a33565b600060405180830381600087803b1580156124d357600080fd5b505af11580156124e7573d6000803e3d6000fd5b5050600e546040516335313c2160e11b81526001600160a01b038c811660048301529091169250636a62784291506024016020604051808303816000875af1158015612537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061255b9190614aac565b50809350807f2d4209cb05428f87d9b454ef8466c0fc64a91ce45adeb3e672a6a524e71c141689888a896040516125959493929190614e14565b60405180910390a2505050949350505050565b6000805460405163bcaa0c5560e01b8152600292916001600160a01b03169063bcaa0c55906125db908590600401614a98565b602060405180830381865afa1580156125f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261c91906146c3565b90506001600160a01b038116612647578160405163092bc2cd60e41b81526004016109599190614a98565b6001600160a01b0381163314612670576040516306923c2160e21b815260040160405180910390fd5b6001600160a01b0384166000908152600760205260408120805485929061269c90849061ffff16614c0f565b92506101000a81548161ffff021916908361ffff16021790555050505050565b604080516001600160a01b038616602082015290810184905261ffff80841660608301528216608082015260009060a001604051602081830303815290604052805190602001209050600061270e8290565b604080516080810182526001600160a01b03898116825260208083018a815261ffff8a81168587019081528a8216606087019081526000898152600c90955293879020955186549086166001600160a01b03199091161786559151600186015590516002909401805492518216620100000263ffffffff19909316949091169390931717909155600f54915163193f45af60e31b81523060048201527f795792c000000000000000000000000000000000000000000000000000000000602482015260448101849052929350169063c9fa2d7890606401600060405180830381600087803b1580156127ff57600080fd5b505af1158015612813573d6000803e3d6000fd5b50505050505050505050565b60008061282c8484612fcc565b600a54919350915061ffff821610612876576040517fd8e1e3c600000000000000000000000000000000000000000000000000000000815261ffff82166004820152602401610959565b60006040518060a0016040528084600681111561289557612895614683565b81526020018361ffff168152602001600a8461ffff16815481106128bb576128bb6146e0565b60009182526020918290209181049091015460ff601f9092166101000a90041660058111156128ec576128ec614683565b60058111156128fd576128fd614683565b81526002602082015263ffffffff421660409182015260105490517fc23ed8510000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063c23ed8519061295e9089908590600401614e00565b600060405180830381600087803b15801561297857600080fd5b505af115801561298c573d6000803e3d6000fd5b505050506129c3604051806080016040528060008152602001600061ffff168152602001600061ffff168152602001600081525090565b60016020820152601054604051631a9c807760e31b81526001600160a01b039091169063d4e403b8906129fc908a908590600401614758565b600060405180830381600087803b158015612a1657600080fd5b505af1158015612a2a573d6000803e3d6000fd5b5050505050505050505050565b60008083606381518110612a4d57612a4d6146e0565b60200260200101518310612a8157606584606381518110612a7057612a706146e0565b602002602001015191509150612b4f565b83600081518110612a9457612a946146e0565b6020026020010151831015612aaf5750600190506000612b4f565b835160009081805b82841015612b13576002612acb8486614e73565b612ad59190614e86565b915086888381518110612aea57612aea6146e0565b602002602001015111612b0957612b02826001614e73565b9350612ab7565b5090508080612ab7565b612b1e816001614c0f565b955087612b2c600183614bed565b61ffff1681518110612b4057612b406146e0565b60200260200101519450505050505b9250929050565b60005460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c5590612b8790600a90600401614a98565b602060405180830381865afa158015612ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc891906146c3565b600e80546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c5590612c0c90601490600401614a98565b602060405180830381865afa158015612c29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4d91906146c3565b600f80546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c5590612c9190601590600401614a98565b602060405180830381865afa158015612cae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd291906146c3565b601080546001600160a01b0319166001600160a01b0392831617905560005460405163bcaa0c5560e01b815291169063bcaa0c5590612d1690600390600401614a98565b602060405180830381865afa158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5791906146c3565b601180546001600160a01b0319166001600160a01b0392909216919091179055612d7f6131e0565b612d87613444565b6000546040517fff74ad5f0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063ff74ad5f90612dd190602490600401614a98565b600060405180830381865afa158015612dee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e169190810190614e9a565b8051612e2a91600d91602090910190613ffc565b506000546040517fc4c379cd0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063c4c379cd90612e7590601b90600401614a98565b602060405180830381865afa158015612e92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eb69190614c2a565b600660146101000a81548161ffff021916908361ffff1602179055506116d0613555565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101829052601154604051635c12cd4b60e01b81526001600160a01b03858116600483015290911690635c12cd4b9060240161010060405180830381865afa158015612f5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f819190614d43565b8051919350915063ffffffff16600003612fc7576040517f3e3a049f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b915091565b600080600080612fdb86613c48565b909250905060066000808060015b600560ff8216116131cf5760ff81166000908152600b60205260409020546130179063ffffffff1684614e73565b92508663ffffffff1683106131bd5789600681111561303857613038614683565b60ff168160ff16111561304d57899450613065565b8060ff16600681111561306257613062614683565b94505b6000600b600087600681111561307d5761307d614683565b60ff168152602081019190915260400160009081206001015491508190036130d357856040517f35183fd30000000000000000000000000000000000000000000000000000000081526004016109599190614f20565b6130e38163ffffffff8916614f2e565b9250600b60008760068111156130fb576130fb614683565b60ff1681526020810191909152604001600020600101548303613154576001600b600088600681111561313057613130614683565b60ff1681526020810191909152604001600020600101546131519190614f42565b92505b600b600087600681111561316a5761316a614683565b60ff1660ff1681526020019081526020016000206001018381548110613192576131926146e0565b90600052602060002090602091828204019190069054906101000a900460ff1660ff169450506131cf565b806131c781614982565b915050612fe9565b509299919850909650505050505050565b6040805160a081019091526000908060018152602001600281526020016003815260200160048152602001600590526040805160a08101909152909150600090806038815260200160398152602001603a8152602001603b8152602001603c90526040805160a08101909152909150600090806033815260200160348152602001603581526020016036815260200160379052905060005b60058160ff16101561343e576040805180820190915260005481906001600160a01b03166342ab14dd8660ff8616600581106132b6576132b66146e0565b60200201516040518263ffffffff1660e01b81526004016132d79190614a98565b602060405180830381865afa1580156132f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133189190614aac565b63ffffffff1681526000546020909101906001600160a01b0316638344a9268560ff86166005811061334c5761334c6146e0565b60200201516040518263ffffffff1660e01b815260040161336d9190614a98565b600060405180830381865afa15801561338a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133b29190810190614f55565b9052600b60008660ff8516600581106133cd576133cd6146e0565b602002015160068111156133e3576133e3614683565b60ff1681526020808201929092526040016000208251815463ffffffff191663ffffffff909116178155828201518051919261342792600185019290910190614047565b50905050808061343690614982565b915050613278565b50505050565b600080546040517f8344a9260000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690638344a9269061348f90603290600401614a98565b600060405180830381865afa1580156134ac573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134d49190810190614f55565b905060005b81518161ffff16101561355157600a828261ffff16815181106134fe576134fe6146e0565b6020908102919091018101518254600181018455600093845292829020918304909101805460ff928316601f9094166101000a93840292909302199092161790558061354981614d01565b9150506134d9565b5050565b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061358790600f90600401614a98565b602060405180830381865afa1580156135a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c891906146c3565b6001549091506001600160a01b0380831691161461379857600180546001600160a01b0319166001600160a01b0383169081179091556040517ffe9fbb8000000000000000000000000000000000000000000000000000000000815230600482015263fe9fbb8090602401602060405180830381865afa158015613650573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136749190614fe4565b1561379857600160009054906101000a90046001600160a01b03166001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156136c957600080fd5b505af11580156136dd573d6000803e3d6000fd5b505060408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff098767a000000000000000000000000000000000000000000000000000000001790529051600093506001600160a01b03851692506137519190615006565b6000604051808303816000865af19150503d806000811461378e576040519150601f19603f3d011682016040523d82523d6000602084013e613793565b606091505b505050505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c55906137ca90601090600401614a98565b602060405180830381865afa1580156137e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061380b91906146c3565b6002549091506001600160a01b0380831691161461395757600280546001600160a01b0319166001600160a01b03838116919091179091556000805460405163bcaa0c5560e01b81529192169063bcaa0c559061386d90601190600401614a98565b602060405180830381865afa15801561388a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ae91906146c3565b6004549091506001600160a01b0316613955576002546040517f36b91f2b0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152909116906336b91f2b90602401600060405180830381600087803b15801561392157600080fd5b505af1158015613935573d6000803e3d6000fd5b5050600480546001600160a01b0319166001600160a01b03851617905550505b505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c559061398990601290600401614a98565b602060405180830381865afa1580156139a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139ca91906146c3565b6000805460405163bcaa0c5560e01b815292935090916001600160a01b039091169063bcaa0c5590613a0190601390600401614a98565b602060405180830381865afa158015613a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a4291906146c3565b6005549091506001600160a01b03838116911614613afc57600580546001600160a01b0319166001600160a01b0384169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152839190631a33757d90613ab690600290600401615022565b6020604051808303816000875af1158015613ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af99190614aac565b50505b6006546001600160a01b03828116911614613bb357600680546001600160a01b0319166001600160a01b0383169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152829190631a33757d90613b6d90600290600401615022565b6020604051808303816000875af1158015613b8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb09190614aac565b50505b6000805460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c5590613be590600c90600401614a98565b602060405180830381865afa158015613c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2691906146c3565b90506001600160a01b03811615613c4057613c4081613dac565b610db8613f38565b600080600583511015613c87576040517fa793379500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008086600381518110613ca057613ca06146e0565b602001015160f81c60f81b60f81c60ff16600888600281518110613cc657613cc66146e0565b602001015160f81c60f81b60f81c60ff1663ffffffff16901b601089600181518110613cf457613cf46146e0565b602001015160f81c60f81b60f81c60ff1663ffffffff16901b60188a600081518110613d2257613d226146e0565b602001015160f81c60f81b60f81c60ff1663ffffffff16901b171717935086600481518110613d5357613d536146e0565b016020015160f81c9250600063ffffffff613d73868216620f4240615036565b613d7d9190614e86565b9050600060ff613d92868216620f4240615036565b613d9c9190614e86565b9199919850909650505050505050565b6001600160a01b038116613dec576040517f05d8ce3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001546001600160a01b0316613dff5750565b6003546001600160a01b0316613e9d576001600160a01b0381163014613e98576001546040517feb8646980000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301529091169063eb86469890602401600060405180830381600087803b158015613e7f57600080fd5b505af1158015613e93573d6000803e3d6000fd5b505050505b613f16565b6003546040517f3a74bfd70000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015290911690633a74bfd790602401600060405180830381600087803b158015613efd57600080fd5b505af1158015613f11573d6000803e3d6000fd5b505050505b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6000546040517ff2aac76c0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063f2aac76c90613f8290600190600401614a98565b602060405180830381865afa158015613f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fc39190614fe4565b60008054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b828054828255906000526020600020908101928215614037579160200282015b8281111561403757825182559160200191906001019061401c565b506140439291506140e4565b5090565b82805482825590600052602060002090601f016020900481019282156140375791602002820160005b838211156140ae57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614070565b80156140db5782816101000a81549060ff02191690556001016020816000010492830192600103026140ae565b50506140439291505b5b8082111561404357600081556001016140e5565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715614132576141326140f9565b60405290565b6040805190810167ffffffffffffffff81118282101715614132576141326140f9565b6040516080810167ffffffffffffffff81118282101715614132576141326140f9565b60405160e0810167ffffffffffffffff81118282101715614132576141326140f9565b604051601f8201601f1916810167ffffffffffffffff811182821017156141ca576141ca6140f9565b604052919050565b600067ffffffffffffffff8211156141ec576141ec6140f9565b5060051b60200190565b6000602080838503121561420957600080fd5b823567ffffffffffffffff81111561422057600080fd5b8301601f8101851361423157600080fd5b803561424461423f826141d2565b6141a1565b81815260059190911b8201830190838101908783111561426357600080fd5b928401925b8284101561428157833582529284019290840190614268565b979650505050505050565b600067ffffffffffffffff8211156142a6576142a66140f9565b50601f01601f191660200190565b600082601f8301126142c557600080fd5b81356142d361423f8261428c565b8181528460208386010111156142e857600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561431857600080fd5b82359150602083013567ffffffffffffffff81111561433657600080fd5b614342858286016142b4565b9150509250929050565b6001600160a01b038116811461436157600080fd5b50565b6000806040838503121561437757600080fd5b82356143828161434c565b946020939093013593505050565b6000602082840312156143a257600080fd5b5035919050565b61ffff8116811461436157600080fd5b600080604083850312156143cc57600080fd5b82356143d78161434c565b915060208301356143e7816143a9565b809150509250929050565b60006020828403121561440457600080fd5b813561440f8161434c565b9392505050565b6000806040838503121561442957600080fd5b8235915060208301356143e78161434c565b6007811061436157600080fd5b6006811061436157600080fd5b60ff8116811461436157600080fd5b63ffffffff8116811461436157600080fd5b600060a0828403121561448857600080fd5b61449061410f565b9050813561449d8161443b565b815260208201356144ad816143a9565b602082015260408201356144c081614448565b604082015260608201356144d381614455565b606082015260808201356144e681614464565b608082015292915050565b600082601f83011261450257600080fd5b8135602061451261423f836141d2565b82815260059290921b8401810191818101908684111561453157600080fd5b8286015b848110156145bd57803567ffffffffffffffff808211156145565760008081fd5b8189019150604080601f19848d030112156145715760008081fd5b614579614138565b8784013561458681614448565b815290830135908282111561459b5760008081fd5b6145a98c89848701016142b4565b818901528652505050918301918301614535565b509695505050505050565b6000806000808486036101608112156145e057600080fd5b85356145eb8161434c565b94506080601f19820112156145ff57600080fd5b5061460861415b565b60208601358152604086013561461d816143a9565b60208201526060860135614630816143a9565b604082015260808601356060820152925061464e8660a08701614476565b915061014085013567ffffffffffffffff81111561466b57600080fd5b614677878288016144f1565b91505092959194509250565b634e487b7160e01b600052602160045260246000fd5b60208101601583106146ad576146ad614683565b91905290565b80516146be8161434c565b919050565b6000602082840312156146d557600080fd5b815161440f8161434c565b634e487b7160e01b600052603260045260246000fd5b80516146be816143a9565b60006080828403121561471357600080fd5b61471b61415b565b82518152602083015161472d816143a9565b60208201526040830151614740816143a9565b60408201526060928301519281019290925250919050565b82815260a0810161440f602083018480518252602081015161ffff80821660208501528060408401511660408501525050606081015160608301525050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b818110156147ea578451601181106147d8576147d8614683565b835293830193918301916001016147be565b5090979650505050505050565b60005b838110156148125781810151838201526020016147fa565b50506000910152565b6000602080838503121561482e57600080fd5b825167ffffffffffffffff8082111561484657600080fd5b818501915085601f83011261485a57600080fd5b815161486861423f826141d2565b81815260059190911b8301840190848101908883111561488757600080fd5b8585015b83811015614942578051858111156148a35760008081fd5b86016040818c03601f19018113156148bb5760008081fd5b6148c3614138565b898301516148d081614448565b815282820151888111156148e45760008081fd5b8084019350508c603f8401126148fa5760008081fd5b8983015161490a61423f8261428c565b8181528e8483870101111561491f5760008081fd5b61492e828d83018688016147f7565b828c0152508552505091860191860161488b565b5098975050505050505050565b60006020828403121561496157600080fd5b815161440f81614448565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff81036149985761499861496c565b60010192915050565b6006811061436157614361614683565b600082825180855260208086019550808260051b84010181860160005b848110156147ea57601f1980878503018a528251604081516149ef816149a1565b865290860151868601829052805191860182905290606090614a1681838901858b016147f7565b9b87019b601f0190921694909401019250908301906001016149ce565b828152604060208201526000614a4c60408301846149b1565b949350505050565b6020808252825182820181905260009190848201906040850190845b81811015614a8c57835183529284019291840191600101614a70565b50909695505050505050565b60208101604083106146ad576146ad614683565b600060208284031215614abe57600080fd5b5051919050565b600060a08284031215614ad757600080fd5b614adf61410f565b8251614aea8161443b565b81526020830151614afa816143a9565b60208201526040830151614b0d81614448565b60408201526060830151614b2081614455565b60608201526080830151614b3381614464565b60808201529392505050565b600061ffff821680614b5357614b5361496c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b60078110614b8b57614b8b614683565b9052565b614b9a828251614b7b565b61ffff60208201511660208301526040810151614bb6816149a1565b604083015260608181015160ff169083015260809081015163ffffffff16910152565b60a08101614be78284614b8f565b92915050565b61ffff828116828216039080821115614c0857614c0861496c565b5092915050565b61ffff818116838216019080821115614c0857614c0861496c565b600060208284031215614c3c57600080fd5b81518060010b811461440f57600080fd5b634e487b7160e01b600052601260045260246000fd5b600060ff831680614c7657614c76614c4d565b8060ff84160691505092915050565b600181810b9083900b01617fff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800082121715614be757614be761496c565b6001600160a01b0386168152846020820152600061ffff808616604084015280851660608401525060a0608083015261428160a08301846149b1565b600061ffff808316818103614d1857614d1861496c565b6001019392505050565b60006bffffffffffffffffffffffff808316818103614d1857614d1861496c565b600080828403610100811215614d5857600080fd5b8351614d638161434c565b925060e0601f1982011215614d7757600080fd5b50614d8061417e565b6020840151614d8e81614464565b81526040840151614d9e81614464565b60208201526060840151614db181614464565b60408201526080840151614dc481614448565b6060820152614dd560a085016146f6565b608082015260c084015160a0820152614df060e085016146b3565b60c0820152809150509250929050565b82815260c0810161440f6020830184614b8f565b60006101606001600160a01b0387168352614e326020840187614b8f565b845160c0840152602085015161ffff90811660e0850152604086015116610100840152606085015161012084015280610140840152614281818401856149b1565b80820180821115614be757614be761496c565b600082614e9557614e95614c4d565b500490565b60006020808385031215614ead57600080fd5b825167ffffffffffffffff811115614ec457600080fd5b8301601f81018513614ed557600080fd5b8051614ee361423f826141d2565b81815260059190911b82018301908381019087831115614f0257600080fd5b928401925b8284101561428157835182529284019290840190614f07565b60208101614be78284614b7b565b600082614f3d57614f3d614c4d565b500690565b81810381811115614be757614be761496c565b60006020808385031215614f6857600080fd5b825167ffffffffffffffff811115614f7f57600080fd5b8301601f81018513614f9057600080fd5b8051614f9e61423f826141d2565b81815260059190911b82018301908381019087831115614fbd57600080fd5b928401925b82841015614281578351614fd581614455565b82529284019290840190614fc2565b600060208284031215614ff657600080fd5b8151801515811461440f57600080fd5b600082516150188184602087016147f7565b9190910192915050565b60208101600383106146ad576146ad614683565b8082028115828204841417614be757614be761496c56fea264697066735822122028961595bdd55fa1cac20f1e9e4e8f60026e559282770d815ce91bbda4a13d2d64736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
-----Decoded View---------------
Arg [0] : _configStorage (address): 0xEf173BB4b36525974BF6711357D2c6C12b8001eC
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.