More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Latest 25 from a total of 18,481 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Burn NF Ts | 10388341 | 183 days ago | IN | 0 ETH | 0.00000038 | ||||
Burn NF Ts | 10333889 | 184 days ago | IN | 0 ETH | 0.00000053 | ||||
Burn NF Ts | 10333888 | 184 days ago | IN | 0 ETH | 0.00000034 | ||||
Burn NF Ts | 10333882 | 184 days ago | IN | 0 ETH | 0.00000093 | ||||
Burn Remaining P... | 10319875 | 184 days ago | IN | 0 ETH | 0.00000322 | ||||
Burn NF Ts | 10319873 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn Remaining P... | 10319842 | 184 days ago | IN | 0 ETH | 0.00000327 | ||||
Burn Remaining P... | 10319839 | 184 days ago | IN | 0 ETH | 0.00000327 | ||||
Burn Remaining P... | 10319836 | 184 days ago | IN | 0 ETH | 0.00000328 | ||||
Burn Remaining P... | 10319833 | 184 days ago | IN | 0 ETH | 0.00000328 | ||||
Burn Remaining P... | 10319830 | 184 days ago | IN | 0 ETH | 0.00000327 | ||||
Burn Remaining P... | 10319828 | 184 days ago | IN | 0 ETH | 0.00000324 | ||||
Burn Remaining P... | 10319825 | 184 days ago | IN | 0 ETH | 0.00000324 | ||||
Burn NF Ts | 10319821 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn NF Ts | 10319714 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn NF Ts | 10319712 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn NF Ts | 10319709 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn NF Ts | 10319707 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn NF Ts | 10319704 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Burn NF Ts | 10319702 | 184 days ago | IN | 0 ETH | 0.00000043 | ||||
Migrate All NF T... | 10224737 | 187 days ago | IN | 0 ETH | 0.00000077 | ||||
Migrate All NF T... | 10224734 | 187 days ago | IN | 0 ETH | 0.00000306 | ||||
Migrate All NF T... | 10224715 | 187 days ago | IN | 0 ETH | 0.00000078 | ||||
Migrate All NF T... | 10224712 | 187 days ago | IN | 0 ETH | 0.00000313 | ||||
Migrate All NF T... | 10224710 | 187 days ago | IN | 0 ETH | 0.00000313 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
9783283 | 197 days ago | 2.5 ETH | ||||
9783272 | 197 days ago | 1.5 ETH | ||||
9783270 | 197 days ago | 1.5 ETH | ||||
9783268 | 197 days ago | 2.5 ETH | ||||
9783264 | 197 days ago | 2.5 ETH | ||||
9783259 | 197 days ago | 2.5 ETH | ||||
9783255 | 197 days ago | 2.5 ETH | ||||
9783250 | 197 days ago | 2.5 ETH | ||||
9783245 | 197 days ago | 2.5 ETH | ||||
9783241 | 197 days ago | 2.5 ETH | ||||
9783235 | 197 days ago | 2.5 ETH | ||||
9783231 | 197 days ago | 2.5 ETH | ||||
9783226 | 197 days ago | 2.5 ETH | ||||
9783221 | 197 days ago | 2.5 ETH | ||||
9783218 | 197 days ago | 2.5 ETH | ||||
9783214 | 197 days ago | 2.5 ETH | ||||
9783211 | 197 days ago | 2.5 ETH | ||||
9783208 | 197 days ago | 2.5 ETH | ||||
9783204 | 197 days ago | 2.5 ETH | ||||
9783199 | 197 days ago | 2.5 ETH | ||||
9783195 | 197 days ago | 2.5 ETH | ||||
8580869 | 225 days ago | 1 ETH | ||||
8039480 | 237 days ago | 2.5 ETH | ||||
8039475 | 237 days ago | 2.5 ETH | ||||
6063884 | 283 days ago | 0.5 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MigrationManager
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/interfaces/IERC721.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "../interfaces/IMigrationManager.sol"; import "../interfaces/IMunchNFT.sol"; import "../interfaces/INFTAttributesManager.sol"; import "../interfaces/ILockManager.sol"; import "./BaseBlastManager.sol"; import "../interfaces/ISnuggeryManager.sol"; import "../interfaces/IClaimManager.sol"; import "../interfaces/INFTOverlord.sol"; contract MigrationManager is IMigrationManager, ReentrancyGuard, BaseBlastManager { uint8 constant SKIP_AMOUNT = 5; uint256 public discountFactor; uint256 public purchasedUnlockPrice = 2 ether; bool public seal; IOldNFT _oldNFTContract; INFTAttributesManager _attributesManager; ILockManager _lockManager; ISnuggeryManager _snuggeryManager; IClaimManager _claimManager; INFTOverlord _nftOverlord; mapping(bytes32 => MigrationSnapshotData) _migrationSnapshots; mapping(address => bool) _userClaimedOnce; mapping(address => uint256[]) _userTokenIds; mapping(address => uint16) _unrevealed; mapping(address => UserLockedChoice) _userLockedAction; mapping(address => UserLockedChoice) _userPurchasedAction; mapping(address => MigrationTotals) _userLockedAmounts; address LOCAL_ADMIN; modifier onlyLocalAdmin() { if (msg.sender != LOCAL_ADMIN) revert InvalidRoleError(); _; } constructor(address _configStorage) { __BaseConfigStorage_setConfigStorage(_configStorage); _reconfigure(); LOCAL_ADMIN = msg.sender; } function _reconfigure() internal { // load config from the config storage contract and configure myself, USDB/WETH config is handled by base _lockManager = ILockManager( configStorage.getAddress(StorageKey.LockManager) ); _oldNFTContract = IOldNFT( configStorage.getAddress(StorageKey.OldMunchNFT) ); _attributesManager = INFTAttributesManager( configStorage.getAddress(StorageKey.NFTAttributesManager) ); _claimManager = IClaimManager( configStorage.getAddress(StorageKey.ClaimManager) ); _nftOverlord = INFTOverlord( configStorage.getAddress(StorageKey.NFTOverlord) ); discountFactor = configStorage.getUint( StorageKey.MigrationDiscountFactor ); super.__BaseBlastManager_reconfigure(); } function configUpdated() external override onlyConfigStorage { _reconfigure(); } function loadMigrationSnapshot( address[] calldata users, MigrationSnapshotData[] calldata data ) external override onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); if (users.length != data.length) revert InvalidDataLengthError(); address _user; uint256 _tokenId; bytes32 key; for (uint256 i = 0; i < users.length; i++) { if ( data[i].token != address(USDB) && data[i].token != address(WETH) && data[i].token != address(0) ) revert InvalidMigrationTokenError(); if (data[i].tokenId == 0) revert InvalidMigrationTokenIdError(); _user = users[i]; _tokenId = data[i].tokenId; key = keccak256(abi.encodePacked(_user, _tokenId)); if (_migrationSnapshots[key].tokenId != 0) revert DataAlreadyLoadedError(); _migrationSnapshots[key] = data[i]; if (data[i].lockAmount != 0) { _userLockedAmounts[_user].totalLockedAmount += data[i] .lockAmount; _userLockedAmounts[_user].tokenLocked = data[i].token; } else { if (data[i].token != address(0)) revert InvalidMigrationTokenError(); _userLockedAmounts[_user] .totalPurchasedAmount += purchasedUnlockPrice; } _userTokenIds[_user].push(_tokenId); } emit MigrationSnapshotLoaded(users, data); } event TokenClaimed(bytes32[] _snapshot, bool[] claimed); function setTokenClaimed( bytes32[] calldata _snapshot, bool[] calldata claimed ) external onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); if (_snapshot.length != claimed.length) revert InvalidDataLengthError(); for (uint256 i = 0; i < _snapshot.length; i++) { bytes32 key = _snapshot[i]; if (_migrationSnapshots[key].tokenId == 0) revert NoMigrationExistsError(); _migrationSnapshots[key].claimed = claimed[i]; } emit TokenClaimed(_snapshot, claimed); } event UserClaimedOnce(address[] users, bool[] setter); function setUserClaimedOnce( address[] calldata users, bool[] calldata setter ) external onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); if (users.length != setter.length) revert InvalidDataLengthError(); for (uint256 i = 0; i < users.length; i++) { _userClaimedOnce[users[i]] = setter[i]; } emit UserClaimedOnce(users, setter); } event UserClaimedLockedAction(address[] users, UserLockedChoice[] setter); function setUserLockedAction( address[] calldata users, UserLockedChoice[] calldata setter ) external onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); if (users.length != setter.length) revert InvalidDataLengthError(); for (uint256 i = 0; i < users.length; i++) { _userLockedAction[users[i]] = setter[i]; } emit UserClaimedLockedAction(users, setter); } event UserPurchasedLockedAction(address[] users, UserLockedChoice[] setter); function setUserPurchasedAction( address[] calldata users, UserLockedChoice[] calldata setter ) external onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); if (users.length != setter.length) revert InvalidDataLengthError(); for (uint256 i = 0; i < users.length; i++) { _userPurchasedAction[users[i]] = setter[i]; } emit UserPurchasedLockedAction(users, setter); } function sealData() external override onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); seal = true; emit MigrationDataSealed(); } function loadUnrevealedSnapshot( address[] calldata users, uint16[] calldata unrevealed ) external onlyLocalAdmin { if (seal) revert MigrationDataSealedError(); if (users.length != unrevealed.length) revert InvalidDataLengthError(); for (uint256 i = 0; i < users.length; i++) { _unrevealed[users[i]] = unrevealed[i]; } emit UnrevealedSnapshotLoaded(users, unrevealed); } function burnUnrevealedForPoints() external { if (!seal) revert MigrationDataNotSealedError(); if (_unrevealed[msg.sender] == 0) revert NoUnrevealedError(); uint256 amountToSwap = uint256(_unrevealed[msg.sender]); _claimManager.burnUnrevealedForPoints(msg.sender, amountToSwap); delete _unrevealed[msg.sender]; emit UnrevealedSwapSucceeded(msg.sender, amountToSwap); } function burnNFTs(address _user, uint32 _skip) external override { if (!seal) revert MigrationDataNotSealedError(); if ( _user != msg.sender && _userLockedAction[_user] == UserLockedChoice.NONE ) revert SelfNeedsToChooseError(); if (_userLockedAction[_user] == UserLockedChoice.LOCKED_FULL_MIGRATION) revert DifferentLockActionError(); uint256[] memory tokenIds = _userTokenIds[_user]; if (tokenIds.length == 0) revert NoNFTsToBurnError(); uint8[] memory tokenIdsByRarity = new uint8[](7); uint256 tokenId; MigrationSnapshotData storage snapshot; uint256 maxLength = _skip + SKIP_AMOUNT > tokenIds.length ? tokenIds.length : _skip + SKIP_AMOUNT; uint256[] memory burnedTokenIds = new uint256[](maxLength - _skip); for (uint256 i = _skip; i < maxLength; i++) { tokenId = tokenIds[i]; snapshot = _migrationSnapshots[ keccak256(abi.encodePacked(_user, tokenId)) ]; if (snapshot.lockAmount == 0 || snapshot.claimed) continue; if (snapshot.tokenId == 0) revert NoMigrationExistsError(); snapshot.claimed = true; tokenIdsByRarity[uint8(snapshot.immutableAttributes.rarity)]++; _oldNFTContract.burn(tokenId); burnedTokenIds[i - _skip] = tokenId; } _claimManager.burnNFTsForPoints(_user, tokenIdsByRarity); _userLockedAction[_user] = UserLockedChoice.LOCKED_BURN; emit BurnSucceeded(_user, burnedTokenIds); } function burnRemainingPurchasedNFTs( address _user, uint32 _skip ) external override { if (!seal) revert MigrationDataNotSealedError(); if ( _user != msg.sender && _userPurchasedAction[_user] == UserLockedChoice.NONE ) revert SelfNeedsToChooseError(); _userPurchasedAction[_user] = UserLockedChoice.LOCKED_BURN; uint256[] memory tokenIds = _userTokenIds[_user]; if (tokenIds.length == 0) revert NoNFTsToBurnError(); uint8[] memory tokenIdsByRarity = new uint8[](7); uint256 maxLength = _skip + SKIP_AMOUNT > tokenIds.length ? tokenIds.length : _skip + SKIP_AMOUNT; uint256[] memory burnedTokens = new uint256[](maxLength - _skip); uint256 tokenId; bytes32 key; MigrationSnapshotData memory snapshot; for (uint256 i = _skip; i < maxLength; i++) { tokenId = tokenIds[i]; key = keccak256(abi.encodePacked(_user, tokenId)); snapshot = _migrationSnapshots[key]; if (snapshot.lockAmount != 0 || snapshot.claimed) continue; if (snapshot.tokenId == 0) revert NoMigrationExistsError(); _migrationSnapshots[key].claimed = true; tokenIdsByRarity[uint8(snapshot.immutableAttributes.rarity)]++; _oldNFTContract.burn(tokenId); burnedTokens[i - _skip] = tokenId; } _claimManager.burnNFTsForPoints(_user, tokenIdsByRarity); emit BurnPurchasedSucceeded(_user, burnedTokens); } function lockFundsForAllMigration() external payable override nonReentrant { if (!seal) revert MigrationDataNotSealedError(); if (_userLockedAction[msg.sender] != UserLockedChoice.NONE) revert DifferentLockActionError(); _userClaimedOnce[msg.sender] = true; (uint256 totalLockAmount, ) = getUserMigrateQuantityAll(msg.sender); if (totalLockAmount == 0) revert NoMigrationExistsError(); if (_userTokenIds[msg.sender].length == 0) revert NoNFTsToBurnError(); address tokenContract = _userLockedAmounts[msg.sender].tokenLocked; if (tokenContract == address(0)) { if (msg.value != totalLockAmount) revert InvalidMigrationAmountError(); } else { if (msg.value != 0) revert InvalidMigrationAmountError(); IERC20(tokenContract).transferFrom( msg.sender, address(this), totalLockAmount ); } _userLockedAction[msg.sender] = UserLockedChoice.LOCKED_FULL_MIGRATION; emit LockedForMigration(msg.sender, totalLockAmount, tokenContract); } function migrateAllNFTs(address _user, uint32 _skip) external override { if (_userLockedAction[_user] != UserLockedChoice.LOCKED_FULL_MIGRATION) revert DifferentLockActionError(); uint256 maxSize = _userTokenIds[_user].length; if (_skip >= maxSize) revert InvalidSkipAmountError(); uint256 maxLengthArray = _skip + SKIP_AMOUNT > maxSize ? maxSize : _skip + SKIP_AMOUNT; uint256[] memory tokenIds = new uint256[](maxLengthArray - _skip); MigrationSnapshotData memory snapshot; for (uint256 i = _skip; i < maxLengthArray; i++) { snapshot = _migrationSnapshots[ keccak256(abi.encodePacked(_user, _userTokenIds[_user][i])) ]; if (snapshot.lockAmount != 0) { tokenIds[i - _skip] = _userTokenIds[_user][i]; } } _migrateNFTs(_user, _userLockedAmounts[_user].tokenLocked, tokenIds); } function migratePurchasedNFTs( uint256[] memory tokenIds ) external payable override nonReentrant { if (_userPurchasedAction[msg.sender] != UserLockedChoice.NONE) revert DifferentLockActionError(); MigrationSnapshotData memory snapshot; uint256 quantity; for (uint256 i = 0; i < tokenIds.length; i++) { if (tokenIds[i] == 0) continue; snapshot = _migrationSnapshots[ keccak256(abi.encodePacked(msg.sender, tokenIds[i])) ]; if (snapshot.lockAmount != 0) revert NotBoughtNFTError(); if (snapshot.token != address(0)) revert NFTPurchasedContractError(); if (snapshot.claimed) continue; quantity += purchasedUnlockPrice; } _migrateNFTs(msg.sender, address(0), tokenIds); if (msg.value != (quantity * discountFactor) / 10e12) revert InvalidMigrationAmountError(); } function rescue( address _tokenContract, uint256 _quantity, address _returnAddress ) external onlyAdmin { if (_tokenContract == address(0)) { bool res = payable(_returnAddress).send(_quantity); if (!res) revert RescueTransferError(); } else { IERC20(_tokenContract).transferFrom( address(this), _returnAddress, _quantity ); } } function _migrateNFTs( address _user, address _tokenLocked, uint256[] memory tokenIds ) internal { if (!seal) revert MigrationDataNotSealedError(); uint256 totalLockAmount; uint256 tokenId; bytes32 key; MigrationSnapshotData storage snapshot; uint256[] memory newTokenIds = new uint256[](tokenIds.length); uint256[] memory migratedTokenIds = new uint256[](tokenIds.length); uint8 i; for (; i < tokenIds.length; i++) { tokenId = tokenIds[i]; if (tokenId == 0) continue; key = keccak256(abi.encodePacked(_user, tokenId)); // We re-use the snapshot variable here to save on gas snapshot = _migrationSnapshots[key]; if (snapshot.tokenId == 0) revert NoMigrationExistsError(); if (snapshot.claimed) continue; snapshot.claimed = true; uint256 lockAmount = snapshot.lockAmount; if (lockAmount == 0) { totalLockAmount += purchasedUnlockPrice; } else { totalLockAmount += lockAmount; } snapshot.immutableAttributes.hatchedDate = uint32(block.timestamp); newTokenIds[i] = _nftOverlord.mintForMigration( _user, snapshot.attributes, snapshot.immutableAttributes, snapshot.gameAttributes ); migratedTokenIds[i] = snapshot.tokenId; _oldNFTContract.burn(tokenId); } uint256 quantity = (totalLockAmount * discountFactor) / 10e12; if (quantity > 0) { if (_tokenLocked == address(0)) { _lockManager.lockOnBehalf{value: quantity}( _tokenLocked, quantity, _user ); } else if (_tokenLocked == address(WETH)) { WETH.approve(address(_lockManager), quantity); _lockManager.lockOnBehalf(_tokenLocked, quantity, _user); } else if (_tokenLocked == address(USDB)) { USDB.approve(address(_lockManager), quantity); _lockManager.lockOnBehalf(_tokenLocked, quantity, _user); } } emit MigrationSucceeded(_user, migratedTokenIds, newTokenIds); } function getUserMigrateQuantityAll( address _user ) public view returns (uint256 totalLockAmount, uint256 totalPurchaseAmount) { totalLockAmount = (_userLockedAmounts[_user].totalLockedAmount * discountFactor) / 10e12; totalPurchaseAmount = (_userLockedAmounts[_user].totalPurchasedAmount * discountFactor) / 10e12; } function getUserMigrationData( address _user, uint256 _tokenId ) external view returns (MigrationSnapshotData memory) { bytes32 key = keccak256(abi.encodePacked(_user, _tokenId)); return _migrationSnapshots[key]; } function getUserMigrationCompletedData( address _user ) external view override returns (bool, MigrationTotals memory) { return (_userClaimedOnce[_user], _userLockedAmounts[_user]); } function getUserUnrevealedData( address _user ) external view returns (uint16) { return _unrevealed[_user]; } function getUserNFTsLength(address _user) external view returns (uint256) { return _userTokenIds[_user].length; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.25; import "../libraries/MunchablesCommonLib.sol"; interface IOldNFT { // This function needs to be added when upgrading the old NFT contract function burn(uint256 _tokenId) external; } /// @title Interface for Migration Manager /// @notice Handles the migration of NFTs with specific attributes and immutable attributes interface IMigrationManager { enum UserLockedChoice { NONE, LOCKED_FULL_MIGRATION, LOCKED_BURN } /// @dev Struct to hold data during migration /// @param tokenId The ID of the token being migrated /// @param lockAmount Amount of tokens to lock during migration /// @param lockDuration Duration for which tokens will be locked /// @param tokenType Type of the token /// @param attributes Attributes of the NFT /// @param immutableAttributes Immutable attributes of the NFT /// @param claimed Status of the NFT claim struct MigrationSnapshotData { uint256 tokenId; uint256 lockAmount; address token; MunchablesCommonLib.NFTAttributes attributes; MunchablesCommonLib.NFTImmutableAttributes immutableAttributes; MunchablesCommonLib.NFTGameAttribute[] gameAttributes; bool claimed; } struct MigrationTotals { uint256 totalPurchasedAmount; uint256 totalLockedAmount; address tokenLocked; } /// @notice Load the migration snapshot for a batch of users /// @dev This function sets up migration data for users /// @param users Array of user addresses /// @param data Array of migration data corresponding to each user function loadMigrationSnapshot( address[] calldata users, MigrationSnapshotData[] calldata data ) external; /// @notice Load the unrevealed snapshot for a batch of users /// @dev This function sets up unrevealed data for users /// @param users Array of user addresses /// @param unrevealed Array of number of unrevealed for each user function loadUnrevealedSnapshot( address[] calldata users, uint16[] calldata unrevealed ) external; /// @notice Seals migration data loading function sealData() external; // onlyRole(DEFAULT_ADMIN_ROLE) /// @notice Burns NFTs /// @dev This function handles multiple NFT burn process function burnNFTs(address _user, uint32 _skip) external; /// @notice Burns remaining purchased NFTs /// @dev This function handles burning all remaining purchased NFTs function burnRemainingPurchasedNFTs(address _user, uint32 _skip) external; /// @notice Lock funds for migration /// @dev This function handles locking funds and changing state to migrate function lockFundsForAllMigration() external payable; /// @notice Migrates all NFTs to the new version /// @dev This function handles multiple NFT migration processes. They need to lock funds first before migrating. function migrateAllNFTs(address _user, uint32 _skip) external; /// @notice Migrates purchased NFTs to the new version /// @dev This function handles multiple NFT migration processes function migratePurchasedNFTs(uint256[] memory tokenIds) external payable; /// @notice Burn unrevealed NFTs for points function burnUnrevealedForPoints() external; /// @notice Return funds which are stuck in the contract (admin only) /// @param _tokenContract The token contract address(0) for ETH /// @param _quantity Amount to return /// @param _returnAddress Address to return to function rescue( address _tokenContract, uint256 _quantity, address _returnAddress ) external; /// @notice Gets the migration data for a user and token ID /// @param _user The user address /// @param _tokenId The token ID function getUserMigrationData( address _user, uint256 _tokenId ) external view returns (MigrationSnapshotData memory); /// @notice Gets the overall migration data for a user /// @param _user The user address function getUserMigrationCompletedData( address _user ) external view returns (bool, MigrationTotals memory); /// @notice Gets the total number of NFTs owned by a user /// @param _user The user address function getUserNFTsLength(address _user) external view returns (uint256); /// @notice Emitted when the migration snapshot is loaded /// @param users The array of user addresses involved in the migration /// @param data The migration data corresponding to each user event MigrationSnapshotLoaded( address[] users, MigrationSnapshotData[] data ); /// @notice Emitted when unreveal data is loaded /// @param users The accounts /// @param unrevealed Number of unrevealed NFTs event UnrevealedSnapshotLoaded(address[] users, uint16[] unrevealed); /// @notice Emitted when an NFT migration is successful /// @param user The user who owns the NFTs /// @param _oldTokenIds The token IDs of the old NFTs /// @param _newTokenIds The token IDs of the new NFTs event MigrationSucceeded( address user, uint256[] _oldTokenIds, uint256[] _newTokenIds ); /// @notice Emitted when an NFT burn is successful /// @param user The user who owns the NFTs /// @param _oldTokenIds The token IDs of the old NFTs event BurnSucceeded(address user, uint256[] _oldTokenIds); /// @notice Emitted when an NFT burn is successful /// @param user The user who owns the NFTs /// @param _oldTokenIds The token IDs of the old NFTs event BurnPurchasedSucceeded(address user, uint256[] _oldTokenIds); /// @notice Emitted after a player swaps unrevealed NFTs for points /// @param user The account that swapped the unrevealed NFTS /// @param amountSwapped The amount of unrevealed NFTs which will be swapped for points event UnrevealedSwapSucceeded(address user, uint256 amountSwapped); /// @notice Emitted when the migration data is sealed event MigrationDataSealed(); /// @notice Emitted when a user locks their funds for a full migration event LockedForMigration(address user, uint256 amount, address token); error NotBoughtNFTError(); error NFTPurchasedContractError(); error UnrevealedNFTError(); error NoMigrationExistsError(); error InvalidMigrationOwnerError(address _owner, address _sender); error InvalidMigrationAmountError(); error InvalidMigrationTokenError(); error AllowanceTooLowError(); error MigrationDataSealedError(); error MigrationDataNotSealedError(); error NoUnrevealedError(); error NoNFTsToBurnError(); error InvalidDataLengthError(); error DataAlreadyLoadedError(); error DifferentLockActionError(); error SelfNeedsToChooseError(); error InvalidSkipAmountError(); error InvalidMigrationTokenIdError(); error RescueTransferError(); }
// 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: 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; /// @title ILockManager interface /// @notice Provides an interface for managing token locks, including price updates, lock configurations, and user interactions. interface ILockManager { /// @notice Struct representing a lockdrop event /// @param start Unix timestamp for when the lockdrop starts /// @param end Unix timestamp for when the lockdrop ends /// @param minLockDuration Minimum lock duration allowed when locking a token struct Lockdrop { uint32 start; uint32 end; uint32 minLockDuration; } /// @notice Struct holding details about tokens that can be locked /// @param usdPrice USD price per token /// @param nftCost Cost of the NFT associated with locking this token /// @param decimals Number of decimals for the token /// @param active Boolean indicating if the token is currently active for locking struct ConfiguredToken { uint256 usdPrice; uint256 nftCost; uint8 decimals; bool active; } /// @notice Struct describing tokens locked by a player /// @param quantity Amount of tokens locked /// @param remainder Tokens left over after locking, not meeting the full NFT cost /// @param lastLockTime The last time tokens were locked /// @param unlockTime When the tokens will be unlocked struct LockedToken { uint256 quantity; uint256 remainder; uint32 lastLockTime; uint32 unlockTime; } /// @notice Struct to hold locked tokens and their metadata /// @param lockedToken LockedToken struct containing lock details /// @param tokenContract Address of the token contract struct LockedTokenWithMetadata { LockedToken lockedToken; address tokenContract; } /// @notice Struct to keep player-specific settings /// @param lockDuration Duration in seconds for which tokens are locked struct PlayerSettings { uint32 lockDuration; } /// @notice Struct to manage USD price update proposals /// @param proposedDate Timestamp when the price was proposed /// @param proposer Address of the oracle proposing the new price /// @param contracts Array of contracts whose prices are proposed to be updated /// @param proposedPrice New proposed price in USD struct USDUpdateProposal { uint32 proposedDate; address proposer; address[] contracts; uint256 proposedPrice; mapping(address => uint32) approvals; mapping(address => uint32) disapprovals; uint8 approvalsCount; uint8 disapprovalsCount; } /// @notice Configures the start and end times for a lockdrop event /// @param _lockdropData Struct containing the start and end times function configureLockdrop(Lockdrop calldata _lockdropData) external; /// @notice Adds or updates a token configuration for locking purposes /// @param _tokenContract The contract address of the token to configure /// @param _tokenData The configuration data for the token function configureToken( address _tokenContract, ConfiguredToken memory _tokenData ) external; /// @notice Sets the thresholds for approving or disapproving USD price updates /// @param _approve Number of approvals required to accept a price update /// @param _disapprove Number of disapprovals required to reject a price update function setUSDThresholds(uint8 _approve, uint8 _disapprove) external; /// @notice Proposes a new USD price for one or more tokens /// @param _price The new proposed price in USD /// @param _contracts Array of token contract addresses to update function proposeUSDPrice( uint256 _price, address[] calldata _contracts ) external; /// @notice Approves a proposed USD price update /// @param _price The price that needs to be approved function approveUSDPrice(uint256 _price) external; /// @notice Disapproves a proposed USD price update /// @param _price The price that needs to be disapproved function disapproveUSDPrice(uint256 _price) external; /// @notice Sets the lock duration for a player's tokens /// @param _duration The lock duration in seconds function setLockDuration(uint256 _duration) external; /// @notice Locks tokens on behalf of a player /// @param _tokenContract Contract address of the token to be locked /// @param _quantity Amount of tokens to lock /// @param _onBehalfOf Address of the player for whom tokens are being locked function lockOnBehalf( address _tokenContract, uint256 _quantity, address _onBehalfOf ) external payable; /// @notice Locks tokens /// @param _tokenContract Contract address of the token to be locked /// @param _quantity Amount of tokens to lock function lock(address _tokenContract, uint256 _quantity) external payable; /// @notice Unlocks the player's tokens /// @param _tokenContract Contract address of the token to be unlocked /// @param _quantity Amount of tokens to unlock function unlock(address _tokenContract, uint256 _quantity) external; /// @notice Retrieves locked tokens for a player /// @param _player Address of the player /// @return _lockedTokens Array of LockedTokenWithMetadata structs for all tokens configured function getLocked( address _player ) external view returns (LockedTokenWithMetadata[] memory _lockedTokens); /// @notice Calculates the USD value of all tokens locked by a player, weighted by their yield /// @param _player Address of the player /// @return _lockedWeightedValue Total weighted USD value of locked tokens function getLockedWeightedValue( address _player ) external view returns (uint256 _lockedWeightedValue); /// @notice Retrieves configuration for a token given its contract address /// @param _tokenContract The contract address of the token /// @return _token Struct containing the token's configuration function getConfiguredToken( address _tokenContract ) external view returns (ConfiguredToken memory _token); /// @notice Retrieves lock settings for a player /// @param _player Address of the player /// @return _settings PlayerSettings struct containing the player's lock settings function getPlayerSettings( address _player ) external view returns (PlayerSettings calldata _settings); /// @notice Emitted when a new token is configured /// @param _tokenContract The token contract being configured /// @param _tokenData ConfiguredToken struct with new config event TokenConfigured(address _tokenContract, ConfiguredToken _tokenData); /// @notice Emitted when a new lockdrop has been configured /// @param _lockdrop_data Lockdrop struct containing the new lockdrop configuration event LockDropConfigured(Lockdrop _lockdrop_data); /// @notice Emitted when a new USD price has been proposed by one of the oracles /// @param _proposer The oracle proposing the new price /// @param _price New proposed price, specified in whole dollars event ProposedUSDPrice(address _proposer, uint256 _price); /// @notice Emitted when a USD price proposal has been approved by the required number of oracles /// @param _approver The oracle who approved the new price event ApprovedUSDPrice(address _approver); /// @notice Emitted when an oracle disapproves of the proposed USD price /// @param _disapprover The oracle disapproving of the new price event DisapprovedUSDPrice(address _disapprover); /// @notice Emitted when a USD price proposal is removed after receiving sufficient disapprovals event RemovedUSDProposal(); /// @notice Emitted when the thresholds for USD oracle approvals and disapprovals are updated /// @param _approve New threshold for approvals /// @param _disapprove New threshold for disapprovals event USDThresholdUpdated(uint8 _approve, uint8 _disapprove); /// @notice Emitted when a player updates their lock duration /// @param _player The player whose lock duration is updated /// @param _duration New lock duration, specified in seconds event LockDuration(address indexed _player, uint256 _duration); /// @notice Emitted when a player locks tokens /// @param _player The player locking the tokens /// @param _sender The sender of the lock transaction /// @param _tokenContract The contract address of the locked token /// @param _quantity The amount of tokens locked /// @param _remainder The remainder of tokens left after locking (not reaching an NFT cost) /// @param _numberNFTs The number of NFTs the player is entitled to due to the lock event Locked( address indexed _player, address _sender, address _tokenContract, uint256 _quantity, uint256 _remainder, uint256 _numberNFTs, uint256 _lockDuration ); /// @notice Emitted when a player unlocks tokens /// @param _player The player unlocking the tokens /// @param _tokenContract The contract address of the unlocked token /// @param _quantity The amount of tokens unlocked event Unlocked( address indexed _player, address _tokenContract, uint256 _quantity ); /// @notice Emitted when the discount factor for token locking is updated /// @param discountFactor The new discount factor event DiscountFactorUpdated(uint256 discountFactor); /// @notice Emitted when the USD price is updated for a token /// @param _tokenContract The token contract updated /// @param _newPrice The new USD price event USDPriceUpdated(address _tokenContract, uint256 _newPrice); /// @notice Error thrown when an action is attempted by an entity other than the Account Manager error OnlyAccountManagerError(); /// @notice Error thrown when an operation is attempted on a token that is not configured error TokenNotConfiguredError(); /// @notice Error thrown when an action is attempted after the lockdrop period has ended /// @param end The ending time of the lockdrop period /// @param block_timestamp The current block timestamp, indicating the time of the error error LockdropEndedError(uint32 end, uint32 block_timestamp); /// @notice Error thrown when the lockdrop configuration is invalid error LockdropInvalidError(); /// @notice Error thrown when the NFT cost specified is invalid or not allowed error NFTCostInvalidError(); /// @notice Error thrown when the USD price proposed is deemed invalid error USDPriceInvalidError(); /// @notice Error thrown when there is already a proposal in progress and another cannot be started error ProposalInProgressError(); /// @notice Error thrown when the contracts specified in a proposal are invalid error ProposalInvalidContractsError(); /// @notice Error thrown when there is no active proposal to operate on error NoProposalError(); /// @notice Error thrown when the proposer is not allowed to approve their own proposal error ProposerCannotApproveError(); /// @notice Error thrown when a proposal has already been approved error ProposalAlreadyApprovedError(); /// @notice Error thrown when a proposal has already been disapproved error ProposalAlreadyDisapprovedError(); /// @notice Error thrown when the price specified does not match the price in the active proposal error ProposalPriceNotMatchedError(); /// @notice Error thrown when the lock duration specified exceeds the maximum allowed limit error MaximumLockDurationError(); /// @notice Error thrown when the ETH value provided in a transaction is incorrect for the intended operation error ETHValueIncorrectError(); /// @notice Error thrown when the message value provided in a call is invalid error InvalidMessageValueError(); /// @notice Error thrown when the allowance provided for an operation is insufficient error InsufficientAllowanceError(); /// @notice Error thrown when the amount locked is insufficient for the intended operation error InsufficientLockAmountError(); /// @notice Error thrown when tokens are still locked and cannot be unlocked due to the lock period not expiring error TokenStillLockedError(); /// @notice Error thrown when an invalid call is made to the Lock Manager error LockManagerInvalidCallError(); /// @notice Error thrown when the Lock Manager refuses to accept ETH for a transaction error LockManagerRefuseETHError(); /// @notice Error thrown when an invalid token contract address is provided for an operation error InvalidTokenContractError(); /// @notice Lock duration out of range error InvalidLockDurationError(); /// @notice User tries to reduce the unlock time error LockDurationReducedError(); /// @notice If a sub account tries to lock tokens error SubAccountCannotLockError(); /// @notice Account not registered with AccountManager error AccountNotRegisteredError(); /// @notice If the player tries to lock too many tokens resulting in too many NFTs being minted error TooManyNFTsError(); /// @notice Failed to transfer ETH error FailedTransferError(); }
// 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 the Account Manager /// @notice This interface manages player accounts including their snuggery, schibbles, chonks, and sub-accounts interface ISnuggeryManager { /// @notice Imports a munchable to the player's snuggery /// @dev Check that the NFT is approved to transfer by this contract /// @param _tokenId The token ID to import /// @custom:frontend Import a munchable function importMunchable(uint256 _tokenId) external; /// @notice Exports a munchable from the player's snuggery, the munchable will be returned directly /// @param _tokenId The token ID to export /// @custom:frontend Export a munchable function exportMunchable(uint256 _tokenId) external; /// @notice Feed a munchable to increase its chonks, chonks will be schnibbles multiplied by any feed bonus /// @param _tokenId Token ID of the munchable to feed /// @param _schnibbles Amount of schnibbles to feed /// @custom:frontend Feed a munchable, use event data to show how much chonk was added function feed(uint256 _tokenId, uint256 _schnibbles) external; /// @notice Increase the number of slots in a player's snuggery /// @param _quantity Quantity to increase the snuggery size by function increaseSnuggerySize(uint8 _quantity) external; /// @notice Pet another player's munchable to give both petter and petted some schnibbles /// @param _pettedOwner The owner of the token being petted (the token must be in that player's snuggery) /// @param _tokenId Token ID of the munchable to pet /// @custom:frontend Pet another user's munchable. Check last pet and petted times to see if this function /// should be available function pet(address _pettedOwner, uint256 _tokenId) external; /// @notice Retrieve the total schnibbles count for a player's snuggery /// @param _player Address of the player /// @return _totalChonk Total schnibbles count function getTotalChonk( address _player ) external view returns (uint256 _totalChonk); /// @notice Retrieve the global total schnibbles count across all snuggeries function getGlobalTotalChonk() external view returns (uint256 _totalGlobalChonk); /// @notice Gets a snuggery (array of SnuggeryNFT) /// @param _player Address of the player to get snuggery for /// @return _snuggery Array of SnuggeryNFT items function getSnuggery( address _player ) external view returns (MunchablesCommonLib.SnuggeryNFT[] memory _snuggery); /// @notice Emitted when a munchable is imported into a player's snuggery /// @param _player The address of the player who imported the munchable /// @param _tokenId The token ID of the munchable that was imported /// @custom:frontend Listen for events for the mainAccount, when it is received update your snuggery data event MunchableImported(address indexed _player, uint256 _tokenId); /// @notice Emitted when a munchable is exported from a player's snuggery /// @param _player The address of the player who exported the munchable /// @param _tokenId The token ID of the munchable that was exported /// @custom:frontend Listen for events for the mainAccount, when it is received update your snuggery data event MunchableExported(address indexed _player, uint256 _tokenId); /// @notice Emitted when a munchable is fed schnibbles /// @param _player The address of the player who fed the munchable /// @param _tokenId The token ID of the munchable that was fed /// @param _baseChonks The base amount of chonks that were gained by feeding, will be equal to the schnibbles fed /// @param _bonusChonks The additional bonus chonks that were awarded during the feeding /// @custom:frontend Listen for events for your mainAccount and when this is received update the particular token /// in the snuggery by reloading the NFT data event MunchableFed( address indexed _player, uint256 _tokenId, uint256 _baseChonks, int256 _bonusChonks ); /// @notice Emitted when a munchable is petted, distributing schnibbles to both the petter and the petted /// @param _petter The address of the player who petted the munchable /// @param _petted The address of the player who owns the petted munchable /// @param _tokenId The token ID of the munchable that was petted /// @param _petterSchnibbles The amount of schnibbles awarded to the petter /// @param _pettedSchnibbles The amount of schnibbles awarded to the owner of the petted munchable /// @custom:frontend Listen for events where your mainAccount petted and where it was pet /// - If your mainAccount was petted, update the unfedMunchables total /// - If your account was petted then, update the unfedMunchables total, also optionally load the /// lastPetTime for the munchable if you use that event MunchablePetted( address indexed _petter, address indexed _petted, uint256 _tokenId, uint256 _petterSchnibbles, uint256 _pettedSchnibbles ); /// @notice Event emitted when a snuggery size is increased event SnuggerySizeIncreased( address _player, uint16 _previousSize, uint16 _newSize ); /// @notice Error thrown when a token ID is not found in the snuggery error TokenNotFoundInSnuggeryError(); /// @notice Error thrown when a player's snuggery is already full and cannot accept more munchables error SnuggeryFullError(); /// @notice Someone tries to import a munchable they do not own error IncorrectOwnerError(); /// @notice Error if user tries to import someone else's NFT error InvalidOwnerError(); /// @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 a munchable is not found in a player's snuggery error MunchableNotInSnuggeryError(); /// @notice Error thrown when a player attempts to pet their own munchable error CannotPetOwnError(); /// @notice Error thrown when a munchable is petted too soon after the last petting error PettedTooSoonError(); /// @notice Error thrown when a player attempts to pet too soon after their last petting action error PetTooSoonError(); /// @notice Error thrown when a player tries to feed a munchable but does not have enough schnibbles /// @param _currentUnfedSchnibbles The current amount of unfed schnibbles available to the player error InsufficientSchnibblesError(uint256 _currentUnfedSchnibbles); /// @notice Error thrown when a player attempts swap a primordial but they dont have one error NoPrimordialInSnuggeryError(); /// @notice Invalid token id passed (normally if 0) error InvalidTokenIDError(); /// @notice Contract is not approved to transfer NFT on behalf of user error NotApprovedError(); /// @notice Something not configured error NotConfiguredError(); /// @notice This is thrown by the claim manager but we need it here to decode selector error NotEnoughPointsError(); /// @notice When petting the user petting must supply the main account being petted error PettedIsSubAccount(); /// @notice Player tries to increase their snuggery size beyond global max size error SnuggeryMaxSizeError(); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.25; import "../libraries/MunchablesCommonLib.sol"; interface IClaimManager { struct Period { uint32 id; uint32 startTime; uint32 endTime; uint256 available; uint256 claimed; uint256 globalTotalChonk; } /// @notice Starts a new periods /// @dev This will start a new period if the previous one has ended function newPeriod() external; // onlyRole(NEW_PERIOD_ROLE) /// @notice Claims points for the current period /// @dev This will claim the sender's points for the current period function claimPoints() external; // onlyValidPeriod /// @notice Used by the account manager to force a claim before doing anything which would affect the total chonks /// for the player function forceClaimPoints(address _player) external; // onlyValidPeriod only SnuggeryManager.sol /// @notice Spends points for the _player /// @dev This will spend the _player's points /// @param _player The player to spend the points for /// @param _spendPoints The number of points to spend function spendPoints(address _player, uint256 _spendPoints) external; // only SnuggeryManager.sol /// @notice Convert accumulated points to tokens /// @dev This will convert the sender's accumulated points to tokens /// @param _points The number of points to convert function convertPointsToTokens(uint256 _points) external; // onlySwapEnabled // @notice If the player chooses to not migrate over their NFTs, they can burn them for points /// @dev This will burn the player's NFTs for points. Can only be called by Migration Manager /// @param _player The player to burn the NFTs for /// @param _tokenIdsByRarity List of token IDs separated by rarity function burnNFTsForPoints( address _player, uint8[] memory _tokenIdsByRarity ) external returns (uint256 _receivedPoints); // OnlyMigrationManager /// @notice Called by MigrationManager to give the player points from their unrevealed NFTs /// @param _player The address of the player /// @param _unrevealed Number of unrevealed NFTs which are being swapped function burnUnrevealedForPoints( address _player, uint256 _unrevealed ) external returns (uint256 _receivedPoints); // OnlyMigrationManager /// @notice Gets the current period data /// @return _period The current period data function getCurrentPeriod() external view returns (Period memory _period); /// @notice Gets the current points for a player /// @param _player The player to get the points for function getPoints(address _player) external view returns (uint256 _points); event Claimed( address indexed _sender, address indexed _player, uint32 _periodId, uint256 _pointsClaimed, address indexed _referrer, uint256 _referralBonus ); event PointsPerPeriodSet(uint256 _oldPoints, uint256 _newPoints); event AccountManagerSet( address _oldAccountManager, address _newAccountManager ); event LockManagerSet(address _oldLockManager, address _newLockManager); event NewPeriodStarted( uint32 _periodId, uint32 _startTime, uint32 _endTime, uint256 _availablePoints, uint256 _prevPeriodPointsClaimed, uint256 _excessPoints, uint256 _totalGlobalChonk ); event ClaimModuleSet(address _claimModule, bool _isValid); event YieldClaimed( address _claimModule, address _tokenContract, uint256 _yieldClaimed ); event SwapEnabled(bool _enabled); event PointsPerTokenSet( uint256 _oldPointsPerToken, uint256 _newPointsPerToken ); event MunchTokenSet(address _oldMunchToken, address _newMunchToken); event PointsConverted( address indexed _player, uint256 _points, uint256 _tokens ); event ReferralBonusSet(uint256 _oldReferralBonus, uint256 _referralBonus); event PointsSpent(address indexed _player, uint256 _pointsSpent); event NFTsBurnedForPoints( address indexed _player, uint8[] _tokenIdsByRarity, uint256 _points ); event UnrevealedSwappedForPoints( address indexed _player, uint256 _unrevealed, uint256 _points ); event ClaimPeriodHit( address indexed _player, uint32 _lastClaimPeriod, uint32 _currentPeriod ); error InvalidSnapshotDataError(); error SnapshotIsFinalizedError(); error SnapshotIsNotFinalizedError(); error NotAccountManagerError(); error InvalidPeriodError(uint32 _now, uint32 _startTime, uint32 _endTime); error CurrentPeriodNotEndedError(); error AlreadyClaimedError(); error NoClaimablePointsError(); error NotEnoughPointsError(); error SwapDisabledError(); error PointsPerTokenNotSetError(); error NoSnapshotDataError(); error PointAmountToSmallError(); }
// 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: 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: 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: 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 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); }
// 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); }
{ "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":"AllowanceTooLowError","type":"error"},{"inputs":[],"name":"ContractsPausedError","type":"error"},{"inputs":[],"name":"DataAlreadyLoadedError","type":"error"},{"inputs":[],"name":"DifferentLockActionError","type":"error"},{"inputs":[],"name":"InvalidDataLengthError","type":"error"},{"inputs":[],"name":"InvalidGovernorError","type":"error"},{"inputs":[],"name":"InvalidMigrationAmountError","type":"error"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_sender","type":"address"}],"name":"InvalidMigrationOwnerError","type":"error"},{"inputs":[],"name":"InvalidMigrationTokenError","type":"error"},{"inputs":[],"name":"InvalidMigrationTokenIdError","type":"error"},{"inputs":[],"name":"InvalidRoleError","type":"error"},{"inputs":[],"name":"InvalidSkipAmountError","type":"error"},{"inputs":[],"name":"MigrationDataNotSealedError","type":"error"},{"inputs":[],"name":"MigrationDataSealedError","type":"error"},{"inputs":[],"name":"NFTPurchasedContractError","type":"error"},{"inputs":[],"name":"NoMigrationExistsError","type":"error"},{"inputs":[],"name":"NoNFTsToBurnError","type":"error"},{"inputs":[],"name":"NoUnrevealedError","type":"error"},{"inputs":[],"name":"NotBoughtNFTError","type":"error"},{"inputs":[],"name":"OnlyStorageError","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"RescueTransferError","type":"error"},{"inputs":[],"name":"SelfNeedsToChooseError","type":"error"},{"inputs":[],"name":"UnauthorisedError","type":"error"},{"inputs":[{"internalType":"enum StorageKey","name":"_key","type":"uint8"}],"name":"UnconfiguredError","type":"error"},{"inputs":[],"name":"UnrevealedNFTError","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_oldTokenIds","type":"uint256[]"}],"name":"BurnPurchasedSucceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_oldTokenIds","type":"uint256[]"}],"name":"BurnSucceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"LockedForMigration","type":"event"},{"anonymous":false,"inputs":[],"name":"MigrationDataSealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"lockAmount","type":"uint256"},{"internalType":"address","name":"token","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[]"},{"internalType":"bool","name":"claimed","type":"bool"}],"indexed":false,"internalType":"struct IMigrationManager.MigrationSnapshotData[]","name":"data","type":"tuple[]"}],"name":"MigrationSnapshotLoaded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_oldTokenIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_newTokenIds","type":"uint256[]"}],"name":"MigrationSucceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"_snapshot","type":"bytes32[]"},{"indexed":false,"internalType":"bool[]","name":"claimed","type":"bool[]"}],"name":"TokenClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"indexed":false,"internalType":"uint16[]","name":"unrevealed","type":"uint16[]"}],"name":"UnrevealedSnapshotLoaded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSwapped","type":"uint256"}],"name":"UnrevealedSwapSucceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"indexed":false,"internalType":"enum IMigrationManager.UserLockedChoice[]","name":"setter","type":"uint8[]"}],"name":"UserClaimedLockedAction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"indexed":false,"internalType":"bool[]","name":"setter","type":"bool[]"}],"name":"UserClaimedOnce","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"indexed":false,"internalType":"enum IMigrationManager.UserLockedChoice[]","name":"setter","type":"uint8[]"}],"name":"UserPurchasedLockedAction","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":[],"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":"_user","type":"address"},{"internalType":"uint32","name":"_skip","type":"uint32"}],"name":"burnNFTs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint32","name":"_skip","type":"uint32"}],"name":"burnRemainingPurchasedNFTs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnUnrevealedForPoints","outputs":[],"stateMutability":"nonpayable","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":"discountFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConfiguredGovernor","outputs":[{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserMigrateQuantityAll","outputs":[{"internalType":"uint256","name":"totalLockAmount","type":"uint256"},{"internalType":"uint256","name":"totalPurchaseAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserMigrationCompletedData","outputs":[{"internalType":"bool","name":"","type":"bool"},{"components":[{"internalType":"uint256","name":"totalPurchasedAmount","type":"uint256"},{"internalType":"uint256","name":"totalLockedAmount","type":"uint256"},{"internalType":"address","name":"tokenLocked","type":"address"}],"internalType":"struct IMigrationManager.MigrationTotals","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getUserMigrationData","outputs":[{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"lockAmount","type":"uint256"},{"internalType":"address","name":"token","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[]"},{"internalType":"bool","name":"claimed","type":"bool"}],"internalType":"struct IMigrationManager.MigrationSnapshotData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserNFTsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserUnrevealedData","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"components":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"lockAmount","type":"uint256"},{"internalType":"address","name":"token","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[]"},{"internalType":"bool","name":"claimed","type":"bool"}],"internalType":"struct IMigrationManager.MigrationSnapshotData[]","name":"data","type":"tuple[]"}],"name":"loadMigrationSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"uint16[]","name":"unrevealed","type":"uint16[]"}],"name":"loadUnrevealedSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockFundsForAllMigration","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint32","name":"_skip","type":"uint32"}],"name":"migrateAllNFTs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"migratePurchasedNFTs","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"purchasedUnlockPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"address","name":"_returnAddress","type":"address"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"seal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sealData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_snapshot","type":"bytes32[]"},{"internalType":"bool[]","name":"claimed","type":"bool[]"}],"name":"setTokenClaimed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"bool[]","name":"setter","type":"bool[]"}],"name":"setUserClaimedOnce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum IMigrationManager.UserLockedChoice[]","name":"setter","type":"uint8[]"}],"name":"setUserLockedAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum IMigrationManager.UserLockedChoice[]","name":"setter","type":"uint8[]"}],"name":"setUserPurchasedAction","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052671bc16d674ec8000060095534801561001c57600080fd5b5060405161660d38038061660d83398101604081905261003b91610bd4565b6001600081905580546001600160a01b0319166001600160a01b03831617905561006361007b565b50601780546001600160a01b03191633179055610cb2565b60015460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c55906100ac90600290600401610c1a565b602060405180830381865afa1580156100c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ed9190610bd4565b600c80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c559061013190601790600401610c1a565b602060405180830381865afa15801561014e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101729190610bd4565b600a8054610100600160a81b0319166101006001600160a01b039384160217905560015460405163bcaa0c5560e01b815291169063bcaa0c55906101bb90601590600401610c1a565b602060405180830381865afa1580156101d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101fc9190610bd4565b600b80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c559061023f906004908101610c1a565b602060405180830381865afa15801561025c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102809190610bd4565b600e80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c55906102c490600690600401610c1a565b602060405180830381865afa1580156102e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103059190610bd4565b600f80546001600160a01b0319166001600160a01b039283161790556001546040516342ab14dd60e01b81529116906342ab14dd9061034990603f90600401610c1a565b602060405180830381865afa158015610366573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038a9190610c34565b600855610395610397565b565b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c55906103c990600f90600401610c1a565b602060405180830381865afa1580156103e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040a9190610bd4565b6002549091506001600160a01b0380831691161461059357600280546001600160a01b0319166001600160a01b0383169081179091556040516301fd3f7760e71b815230600482015263fe9fbb8090602401602060405180830381865afa158015610479573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049d9190610c4d565b1561059357600260009054906101000a90046001600160a01b03166001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104f257600080fd5b505af1158015610506573d6000803e3d6000fd5b505060408051600481526024810182526020810180516001600160e01b031663784c3b3d60e11b1790529051600093506001600160a01b038516925061054c9190610c6f565b6000604051808303816000865af19150503d8060008114610589576040519150601f19603f3d011682016040523d82523d6000602084013e61058e565b606091505b505050505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c55906105c590601090600401610c1a565b602060405180830381865afa1580156105e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106069190610bd4565b6003549091506001600160a01b0380831691161461073c57600380546001600160a01b0319166001600160a01b038381169190911790915560015460405163bcaa0c5560e01b8152600092919091169063bcaa0c559061066b90601190600401610c1a565b602060405180830381865afa158015610688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ac9190610bd4565b6005549091506001600160a01b031661073a576003546040516336b91f2b60e01b81526001600160a01b038381166004830152909116906336b91f2b90602401600060405180830381600087803b15801561070657600080fd5b505af115801561071a573d6000803e3d6000fd5b5050600580546001600160a01b0319166001600160a01b03851617905550505b505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c559061076e90601290600401610c1a565b602060405180830381865afa15801561078b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107af9190610bd4565b60015460405163bcaa0c5560e01b81529192506000916001600160a01b039091169063bcaa0c55906107e690601390600401610c1a565b602060405180830381865afa158015610803573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190610bd4565b6006549091506001600160a01b038381169116146108c857600680546001600160a01b0319166001600160a01b038416908117909155604051631a33757d60e01b8152839190631a33757d9061088290600290600401610c9e565b6020604051808303816000875af11580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c59190610c34565b50505b6007546001600160a01b0382811691161461096657600780546001600160a01b0319166001600160a01b038316908117909155604051631a33757d60e01b8152829190631a33757d9061092090600290600401610c9e565b6020604051808303816000875af115801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190610c34565b50505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c559061099890600c90600401610c1a565b602060405180830381865afa1580156109b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d99190610bd4565b90506001600160a01b038116156109f3576109f381610a02565b6109fb610b45565b5050505050565b6001600160a01b038116610a29576040516305d8ce3d60e01b815260040160405180910390fd5b6002546001600160a01b0316610a3c5750565b6004546001600160a01b0316610ac1576001600160a01b0381163014610abc57600254604051631d70c8d360e31b81526001600160a01b0383811660048301529091169063eb86469890602401600060405180830381600087803b158015610aa357600080fd5b505af1158015610ab7573d6000803e3d6000fd5b505050505b610b23565b60048054604051633a74bfd760e01b81526001600160a01b0384811693820193909352911690633a74bfd790602401600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505050505b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60018054604051633caab1db60e21b81526001600160a01b039091169163f2aac76c91610b759190600401610c1a565b602060405180830381865afa158015610b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb69190610c4d565b60018054911515600160a01b0260ff60a01b19909216919091179055565b600060208284031215610be657600080fd5b81516001600160a01b0381168114610bfd57600080fd5b9392505050565b634e487b7160e01b600052602160045260246000fd5b6020810160408310610c2e57610c2e610c04565b91905290565b600060208284031215610c4657600080fd5b5051919050565b600060208284031215610c5f57600080fd5b81518015158114610bfd57600080fd5b6000825160005b81811015610c905760208186018101518583015201610c76565b506000920191825250919050565b6020810160038310610c2e57610c2e610c04565b61594c80610cc16000396000f3fe6080604052600436106101cd5760003560e01c8063664d8884116100f75780638da52e9311610095578063b930b48211610064578063b930b482146105f9578063bbb1a27914610619578063dae6902f1461062c578063fce14af61461064c57600080fd5b80638da52e931461056f578063992a1c3e14610584578063ad5c4648146105a4578063b0da6e67146105c457600080fd5b806375a3b381116100d157806375a3b381146104f15780637aa7e55c146104f95780637b7e6b06146105195780638671d23b1461054f57600080fd5b8063664d8884146103ce5780636f48568f146104845780636f5589e2146104a457600080fd5b80633cdad82c1161016f5780634b03eeb41161013e5780634b03eeb414610363578063510295a6146103835780635e062657146103a35780635e4a1e01146103b857600080fd5b80633cdad82c146102db5780633fb27b85146102f9578063443b178614610323578063448639211461034357600080fd5b80631e63c6a3116101ab5780631e63c6a31461024e57806325ba98fa1461026e57806331a0edec1461028e57806333271e3e146102c657600080fd5b806301f3bc79146101d257806307c895a7146102085780630da8610d1461022c575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046145f5565b61066c565b6040516101ff9190614758565b60405180910390f35b34801561021457600080fd5b5061021e60095481565b6040519081526020016101ff565b34801561023857600080fd5b5061024c610247366004614852565b610914565b005b34801561025a57600080fd5b5061024c610269366004614852565b610a59565b34801561027a57600080fd5b5061024c6102893660046148d0565b610b9b565b34801561029a57600080fd5b506006546102ae906001600160a01b031681565b6040516001600160a01b0390911681526020016101ff565b3480156102d257600080fd5b5061024c611071565b3480156102e757600080fd5b506004546001600160a01b03166102ae565b34801561030557600080fd5b50600a546103139060ff1681565b60405190151581526020016101ff565b34801561032f57600080fd5b506001546102ae906001600160a01b031681565b34801561034f57600080fd5b5061024c61035e366004614852565b6110f8565b34801561036f57600080fd5b5061024c61037e3660046145f5565b61162a565b34801561038f57600080fd5b5061024c61039e3660046148d0565b61183b565b3480156103af57600080fd5b5061024c611d04565b3480156103c457600080fd5b5061021e60085481565b3480156103da57600080fd5b506104516103e9366004614909565b6040805160608082018352600080835260208084018290529284018190526001600160a01b0394851681526011835283812054601684529084902084519283018552805483526001810154938301939093526002909201549093169183019190915260ff1691565b60408051921515835281516020808501919091528201518382015201516001600160a01b031660608201526080016101ff565b34801561049057600080fd5b5061024c61049f3660046148d0565b611e6e565b3480156104b057600080fd5b506104de6104bf366004614909565b6001600160a01b031660009081526013602052604090205461ffff1690565b60405161ffff90911681526020016101ff565b61024c612537565b34801561050557600080fd5b5061024c610514366004614852565b612782565b34801561052557600080fd5b5061021e610534366004614909565b6001600160a01b031660009081526012602052604090205490565b34801561055b57600080fd5b5061024c61056a36600461492d565b6128c4565b34801561057b57600080fd5b5061024c612a8b565b34801561059057600080fd5b5061024c61059f366004614852565b612ad7565b3480156105b057600080fd5b506007546102ae906001600160a01b031681565b3480156105d057600080fd5b506105e46105df366004614909565b612c2b565b604080519283526020830191909152016101ff565b34801561060557600080fd5b506003546102ae906001600160a01b031681565b61024c610627366004614985565b612cab565b34801561063857600080fd5b5061024c610647366004614852565b6130e5565b34801561065857600080fd5b506002546102ae906001600160a01b031681565b610674614542565b6040516bffffffffffffffffffffffff19606085901b1660208201526034810183905260009060540160408051601f19818403018152828252805160209182012060008181526010835283902060e0850184528054855260018101548584015260028101546001600160a01b03168585015283516080808201865260038301548252600483015461ffff80821696840196909652620100009004909416818601526005820154606082810191909152860152835160a081019094526006808201805493975091949386019392839160ff9091169081111561075757610757614621565b600681111561076857610768614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff16600581111561079b5761079b614621565b60058111156107ac576107ac614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b828210156108f15760008481526020902060408051808201909152600284029091018054829060ff16600581111561083b5761083b614621565b600581111561084c5761084c614621565b815260200160018201805461086090614a43565b80601f016020809104026020016040519081016040528092919081815260200182805461088c90614a43565b80156108d95780601f106108ae576101008083540402835291602001916108d9565b820191906000526020600020905b8154815290600101906020018083116108bc57829003601f168201915b50505050508152505081526020019060010190610801565b505050908252506008919091015460ff1615156020909101529150505b92915050565b6017546001600160a01b0316331461093f57604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156109635760405163a4e2119b60e01b815260040160405180910390fd5b82811461098357604051633cbac2d960e11b815260040160405180910390fd5b60005b83811015610a15578282828181106109a0576109a0614a7d565b90506020020160208101906109b59190614aa3565b601360008787858181106109cb576109cb614a7d565b90506020020160208101906109e09190614909565b6001600160a01b031681526020810191909152604001600020805461ffff191661ffff92909216919091179055600101610986565b507fa9886e35f88b1a31bf2b47240b3a64f3d10e4f8ba3fd5b554e36ba15c74c6f1b84848484604051610a4b9493929190614b09565b60405180910390a150505050565b6017546001600160a01b03163314610a8457604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff1615610aa85760405163a4e2119b60e01b815260040160405180910390fd5b828114610ac857604051633cbac2d960e11b815260040160405180910390fd5b60005b83811015610b6557828282818110610ae557610ae5614a7d565b9050602002016020810190610afa9190614b7d565b60146000878785818110610b1057610b10614a7d565b9050602002016020810190610b259190614909565b6001600160a01b031681526020810191909152604001600020805460ff19166001836002811115610b5857610b58614621565b0217905550600101610acb565b507f174b79b1053487f0cce24fcceca584a4347ba1ecdee4d34998987ab60aa5a82484848484604051610a4b9493929190614ba8565b600a5460ff16610bbe57604051630345b96360e41b815260040160405180910390fd5b6001600160a01b0382163314801590610c0157506001600160a01b03821660009081526014602052604081205460ff166002811115610bff57610bff614621565b145b15610c38576040517fdf3fb3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016001600160a01b03831660009081526014602052604090205460ff166002811115610c6757610c67614621565b03610c845760405162aab53f60e81b815260040160405180910390fd5b6001600160a01b038216600090815260126020908152604080832080548251818502810185019093528083529192909190830182828015610ce457602002820191906000526020600020905b815481526020019060010190808311610cd0575b505050505090508051600003610d0d5760405163355a170b60e01b815260040160405180910390fd5b60408051600780825261010082019092526000916020820160e080368337505083519192506000918291508190610d45600588614c14565b63ffffffff1611610d6657610d5b600587614c14565b63ffffffff16610d69565b84515b90506000610d7d63ffffffff881683614c38565b67ffffffffffffffff811115610d9557610d9561496f565b604051908082528060200260200182016040528015610dbe578160200160208202803683370190505b50905063ffffffff87165b82811015610f7a57868181518110610de357610de3614a7d565b60200260200101519450601060008a87604051602001610e2192919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6040516020818303038152906040528051906020012081526020019081526020016000209350836001015460001480610e5e5750600884015460ff165b610f72578354600003610e845760405163aeebaa7360e01b815260040160405180910390fd5b60088401805460ff19166001179055600680850154879160ff9190911690811115610eb157610eb1614621565b60ff1681518110610ec457610ec4614a7d565b602002602001018051809190610ed990614c4b565b60ff16905250600a54604051630852cd8d60e31b8152600481018790526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b158015610f2957600080fd5b505af1158015610f3d573d6000803e3d6000fd5b5050505084828963ffffffff1683610f559190614c38565b81518110610f6557610f65614a7d565b6020026020010181815250505b600101610dc9565b50600e546040517f1b5045640000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690631b50456490610fc6908b908990600401614c6a565b6020604051808303816000875af1158015610fe5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110099190614cb9565b506001600160a01b03881660009081526014602052604090819020805460ff19166002179055517f70e47b186223984b3180782e79b09d10da97155f6aa25c9404d4ccd567dbc9fa9061105f908a908490614d03565b60405180910390a15050505050505050565b6017546001600160a01b0316331461109c57604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156110c05760405163a4e2119b60e01b815260040160405180910390fd5b600a805460ff191660011790556040517ff109e3a410f1d684de81b8a1c25a024283fdb20c4c91f1e4d2cd2c6f9bfde5d790600090a1565b6017546001600160a01b0316331461112357604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156111475760405163a4e2119b60e01b815260040160405180910390fd5b82811461116757604051633cbac2d960e11b815260040160405180910390fd5b60008080805b868110156115e3576006546001600160a01b031686868381811061119357611193614a7d565b90506020028101906111a59190614d2d565b6111b6906060810190604001614909565b6001600160a01b03161415801561121557506007546001600160a01b03168686838181106111e6576111e6614a7d565b90506020028101906111f89190614d2d565b611209906060810190604001614909565b6001600160a01b031614155b801561125f5750600086868381811061123057611230614a7d565b90506020028101906112429190614d2d565b611253906060810190604001614909565b6001600160a01b031614155b15611296576040517fe2ad907700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8585828181106112a8576112a8614a7d565b90506020028101906112ba9190614d2d565b356000036112f4576040517fac99966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87878281811061130657611306614a7d565b905060200201602081019061131b9190614909565b935085858281811061132f5761132f614a7d565b90506020028101906113419190614d2d565b6040516bffffffffffffffffffffffff19606087901b166020820152903560348201819052935060540160408051601f19818403018152918152815160209283012060008181526010909352912054909250156113ca576040517fc471fc6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8585828181106113dc576113dc614a7d565b90506020028101906113ee9190614d2d565b600083815260106020526040902061140682826151e1565b90505085858281811061141b5761141b614a7d565b905060200281019061142d9190614d2d565b60200135156115075785858281811061144857611448614a7d565b905060200281019061145a9190614d2d565b6020013560166000866001600160a01b03166001600160a01b03168152602001908152602001600020600101600082825461149591906152c8565b9091555086905085828181106114ad576114ad614a7d565b90506020028101906114bf9190614d2d565b6114d0906060810190604001614909565b6001600160a01b03858116600090815260166020526040902060020180546001600160a01b031916929091169190911790556115af565b600086868381811061151b5761151b614a7d565b905060200281019061152d9190614d2d565b61153e906060810190604001614909565b6001600160a01b03161461157e576040517fe2ad907700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6009546001600160a01b038516600090815260166020526040812080549091906115a99084906152c8565b90915550505b6001600160a01b0384166000908152601260209081526040822080546001818101835591845291909220018490550161116d565b507f560543aa868240b36de3b93c5d6785c1e0ec73406daadfaa5ba8b7f5dac8148a878787876040516116199493929190615482565b60405180910390a150505050505050565b60015460405163bcaa0c5560e01b8152600c916000916001600160a01b039091169063bcaa0c55906116609085906004016155bb565b602060405180830381865afa15801561167d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a191906155d5565b90506001600160a01b0381166116ee57816040517f92bc2cd00000000000000000000000000000000000000000000000000000000081526004016116e591906155bb565b60405180910390fd5b6001600160a01b0381163314611730576040517f1a48f08400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405163bcaa0c5560e01b81526001600160a01b038087169263aad3ec969291169063bcaa0c559061176a90600c906004016155bb565b602060405180830381865afa158015611787573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ab91906155d5565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018690526044016020604051808303816000875af1158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190614cb9565b5050505050565b60016001600160a01b03831660009081526014602052604090205460ff16600281111561186a5761186a614621565b146118875760405162aab53f60e81b815260040160405180910390fd5b6001600160a01b03821660009081526012602052604090205463ffffffff821681116118df576040517fd53d9ca900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816118ed600585614c14565b63ffffffff161161190e57611903600584614c14565b63ffffffff16611910565b815b9050600061192463ffffffff851683614c38565b67ffffffffffffffff81111561193c5761193c61496f565b604051908082528060200260200182016040528015611965578160200160208202803683370190505b509050611970614542565b63ffffffff85165b83811015611cd1576001600160a01b03871660009081526012602052604081208054601092918a91859081106119b0576119b0614a7d565b90600052602060002001546040516020016119e992919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b60408051601f198184030181529181528151602092830120835282820193909352908201600020825160e0810184528154815260018201548184015260028201546001600160a01b03168185015283516080808201865260038401548252600484015461ffff80821696840196909652620100009004909416818601526005830154606082810191909152820152835160a081019094526006808301805492959394860193929091839160ff1690811115611aa657611aa6614621565b6006811115611ab757611ab7614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff166005811115611aea57611aea614621565b6005811115611afb57611afb614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b82821015611c405760008481526020902060408051808201909152600284029091018054829060ff166005811115611b8a57611b8a614621565b6005811115611b9b57611b9b614621565b8152602001600182018054611baf90614a43565b80601f0160208091040260200160405190810160405280929190818152602001828054611bdb90614a43565b8015611c285780601f10611bfd57610100808354040283529160200191611c28565b820191906000526020600020905b815481529060010190602001808311611c0b57829003601f168201915b50505050508152505081526020019060010190611b50565b505050908252506008919091015460ff16151560209182015281015190925015611cc9576001600160a01b0387166000908152601260205260409020805482908110611c8e57611c8e614a7d565b9060005260206000200154838763ffffffff1683611cac9190614c38565b81518110611cbc57611cbc614a7d565b6020026020010181815250505b600101611978565b506001600160a01b03808716600090815260166020526040902060020154611cfc9188911684613217565b505050505050565b600a5460ff16611d2757604051630345b96360e41b815260040160405180910390fd5b3360009081526013602052604081205461ffff169003611d73576040517f4a5b8ec600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152601360205260409081902054600e5491517f6455c6fc000000000000000000000000000000000000000000000000000000008152600481019390935261ffff1660248301819052916001600160a01b0390911690636455c6fc906044016020604051808303816000875af1158015611df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e199190614cb9565b5033600081815260136020908152604091829020805461ffff19169055815192835282018390527f91ee8398834bad350334445ec5760d3d4419521bc8238a7417d13d2ad52ce206910160405180910390a150565b600a5460ff16611e9157604051630345b96360e41b815260040160405180910390fd5b6001600160a01b0382163314801590611ed457506001600160a01b03821660009081526015602052604081205460ff166002811115611ed257611ed2614621565b145b15611f0b576040517fdf3fb3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166000908152601560209081526040808320805460ff191660021790556012825280832080548251818502810185019093528083529192909190830182828015611f7d57602002820191906000526020600020905b815481526020019060010190808311611f69575b505050505090508051600003611fa65760405163355a170b60e01b815260040160405180910390fd5b60408051600780825261010082019092526000916020820160e080368337019050508251909150600090611fdb600586614c14565b63ffffffff1611611ffc57611ff1600585614c14565b63ffffffff16611fff565b82515b9050600061201363ffffffff861683614c38565b67ffffffffffffffff81111561202b5761202b61496f565b604051908082528060200260200182016040528015612054578160200160208202803683370190505b509050600080612062614542565b63ffffffff88165b858110156124635787818151811061208457612084614a7d565b6020026020010151935089846040516020016120be92919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b60408051601f19818403018152828252805160209182012060008181526010835283902060e0850184528054855260018101548584015260028101546001600160a01b03168585015283516080808201865260038301548252600483015461ffff80821696840196909652620100009004909416818601526005820154606082810191909152860152835160a081019094526006808201805493995091949386019392839160ff9091169081111561217857612178614621565b600681111561218957612189614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff1660058111156121bc576121bc614621565b60058111156121cd576121cd614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b828210156123125760008481526020902060408051808201909152600284029091018054829060ff16600581111561225c5761225c614621565b600581111561226d5761226d614621565b815260200160018201805461228190614a43565b80601f01602080910402602001604051908101604052809291908181526020018280546122ad90614a43565b80156122fa5780601f106122cf576101008083540402835291602001916122fa565b820191906000526020600020905b8154815290600101906020018083116122dd57829003601f168201915b50505050508152505081526020019060010190612222565b505050908252506008919091015460ff16151560209182015281015190925015158061233f57508160c001515b61245b5781516000036123655760405163aeebaa7360e01b815260040160405180910390fd5b6000838152601060205260409020600801805460ff191660011790556080820151518790600681111561239a5761239a614621565b60ff16815181106123ad576123ad614a7d565b6020026020010180518091906123c290614c4b565b60ff16905250600a54604051630852cd8d60e31b8152600481018690526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561241257600080fd5b505af1158015612426573d6000803e3d6000fd5b5050505083858a63ffffffff168361243e9190614c38565b8151811061244e5761244e614a7d565b6020026020010181815250505b60010161206a565b50600e546040517f1b5045640000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690631b504564906124af908c908a90600401614c6a565b6020604051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190614cb9565b507ff29048c0820fdab636dcb2f6c5030af9334c1ad195d421474aa8c8c34c19fdd58985604051612524929190614d03565b60405180910390a1505050505050505050565b61253f613862565b600a5460ff1661256257604051630345b96360e41b815260040160405180910390fd5b3360009081526014602052604081205460ff16600281111561258657612586614621565b146125a35760405162aab53f60e81b815260040160405180910390fd5b336000818152601160205260408120805460ff19166001179055906125c790612c2b565b509050806000036125eb5760405163aeebaa7360e01b815260040160405180910390fd5b33600090815260126020526040812054900361261a5760405163355a170b60e01b815260040160405180910390fd5b336000908152601660205260409020600201546001600160a01b0316806126605781341461265b57604051636e848b1d60e11b815260040160405180910390fd5b612711565b341561267f57604051636e848b1d60e11b815260040160405180910390fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390526001600160a01b038216906323b872dd906064016020604051808303816000875af11580156126eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270f91906155f2565b505b33600081815260146020908152604091829020805460ff19166001179055815192835282018490526001600160a01b038316908201527f7cbbc73447ae062db7eddd4894b6af2105cb58a6631da57375fa18bfa2b520649060600160405180910390a150506127806001600055565b565b6017546001600160a01b031633146127ad57604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156127d15760405163a4e2119b60e01b815260040160405180910390fd5b8281146127f157604051633cbac2d960e11b815260040160405180910390fd5b60005b8381101561288e5782828281811061280e5761280e614a7d565b90506020020160208101906128239190614b7d565b6015600087878581811061283957612839614a7d565b905060200201602081019061284e9190614909565b6001600160a01b031681526020810191909152604001600020805460ff1916600183600281111561288157612881614621565b02179055506001016127f4565b507f78700a1e1dc8b51ad86bb898af740f89cb8855b1b0523062c9e0d953aa89095484848484604051610a4b9493929190614ba8565b6001546040517fd91078070000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063d91078079061290e9060009060040161560f565b602060405180830381865afa15801561292b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294f91906155d5565b6001600160a01b0316336001600160a01b03161461298057604051637bd5018b60e11b815260040160405180910390fd5b6001600160a01b0383166129f4576040516000906001600160a01b0383169084156108fc0290859084818181858888f193505050509050806129ee576040517f83cedb1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038281166024830152604482018490528416906323b872dd906064016020604051808303816000875af1158015612a62573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ee91906155f2565b505050565b6001546001600160a01b03163314612acf576040517fe101028000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127806138a5565b6017546001600160a01b03163314612b0257604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff1615612b265760405163a4e2119b60e01b815260040160405180910390fd5b828114612b4657604051633cbac2d960e11b815260040160405180910390fd5b60005b83811015612bf5576000858583818110612b6557612b65614a7d565b9050602002013590506010600082815260200190815260200160002060000154600003612ba55760405163aeebaa7360e01b815260040160405180910390fd5b838383818110612bb757612bb7614a7d565b9050602002016020810190612bcc9190615623565b600091825260106020526040909120600801805460ff1916911515919091179055600101612b49565b507f2ff50a1c5c809242b9dfa6e0232a781429e9793ace8e9e91099f85276f5c9ea184848484604051610a4b9493929190615677565b6008546001600160a01b038216600090815260166020526040812060010154909182916509184e72a00091612c5f91614f0f565b612c6991906156e2565b6008546001600160a01b0385166000908152601660205260409020549193506509184e72a00091612c9a9190614f0f565b612ca491906156e2565b9050915091565b612cb3613862565b3360009081526015602052604081205460ff166002811115612cd757612cd7614621565b14612cf45760405162aab53f60e81b815260040160405180910390fd5b612cfc614542565b6000805b835181101561308b57838181518110612d1b57612d1b614a7d565b602002602001015160000315613083576010600033868481518110612d4257612d42614a7d565b6020026020010151604051602001612d7892919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b60408051601f198184030181529181528151602092830120835282820193909352908201600020825160e0810184528154815260018201548184015260028201546001600160a01b03168185015283516080808201865260038401548252600484015461ffff80821696840196909652620100009004909416818601526005830154606082810191909152820152835160a081019094526006808301805492959394860193929091839160ff1690811115612e3557612e35614621565b6006811115612e4657612e46614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff166005811115612e7957612e79614621565b6005811115612e8a57612e8a614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b82821015612fcf5760008481526020902060408051808201909152600284029091018054829060ff166005811115612f1957612f19614621565b6005811115612f2a57612f2a614621565b8152602001600182018054612f3e90614a43565b80601f0160208091040260200160405190810160405280929190818152602001828054612f6a90614a43565b8015612fb75780601f10612f8c57610100808354040283529160200191612fb7565b820191906000526020600020905b815481529060010190602001808311612f9a57829003601f168201915b50505050508152505081526020019060010190612edf565b505050908252506008919091015460ff16151560209182015281015190935015613025576040517fa037845500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408301516001600160a01b03161561306a576040517f10a1a01400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c001516130835760095461308090836152c8565b91505b600101612d00565b5061309833600085613217565b6509184e72a000600854826130ad9190614f0f565b6130b791906156e2565b34146130d657604051636e848b1d60e11b815260040160405180910390fd5b50506130e26001600055565b50565b6017546001600160a01b0316331461311057604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156131345760405163a4e2119b60e01b815260040160405180910390fd5b82811461315457604051633cbac2d960e11b815260040160405180910390fd5b60005b838110156131e15782828281811061317157613171614a7d565b90506020020160208101906131869190615623565b6011600087878581811061319c5761319c614a7d565b90506020020160208101906131b19190614909565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101613157565b507f397670419d1417ee84841806f025ae55d66489f90a2effce6ee276852bbf70b384848484604051610a4b9493929190615704565b600a5460ff1661323a57604051630345b96360e41b815260040160405180910390fd5b6000806000806000855167ffffffffffffffff81111561325c5761325c61496f565b604051908082528060200260200182016040528015613285578160200160208202803683370190505b5090506000865167ffffffffffffffff8111156132a4576132a461496f565b6040519080825280602002602001820160405280156132cd578160200160208202803683370190505b50905060005b87518160ff16101561353a57878160ff16815181106132f4576132f4614a7d565b602002602001015195508560000315613528576040516bffffffffffffffffffffffff1960608c901b1660208201526034810187905260540160408051601f198184030181529181528151602092830120600081815260109093529082208054919750955090036133785760405163aeebaa7360e01b815260040160405180910390fd5b600884015460ff166135285760088401805460ff1916600190811790915584015460008190036133b6576009546133af90896152c8565b97506133c3565b6133c081896152c8565b97505b60068501805468ffffffff00000000001916650100000000004263ffffffff1602178155600f546040517ffacaa0b70000000000000000000000000000000000000000000000000000000081526001600160a01b039091169163facaa0b79161343b918f9160038b01919060078c0190600401615816565b6020604051808303816000875af115801561345a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347e9190614cb9565b848360ff168151811061349357613493614a7d565b6020026020010181815250508460000154838360ff16815181106134b9576134b9614a7d565b6020908102919091010152600a54604051630852cd8d60e31b8152600481018990526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561350e57600080fd5b505af1158015613522573d6000803e3d6000fd5b50505050505b8061353281614c4b565b9150506132d3565b60006509184e72a000600854896135519190614f0f565b61355b91906156e2565b9050801561381a576001600160a01b038a166135e657600c546040516353b7775b60e01b81526001600160a01b038c81166004830152602482018490528d81166044830152909116906353b7775b9083906064016000604051808303818588803b1580156135c857600080fd5b505af11580156135dc573d6000803e3d6000fd5b505050505061381a565b6007546001600160a01b03908116908b160361370257600754600c546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303816000875af115801561366a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368e91906155f2565b50600c546040516353b7775b60e01b81526001600160a01b038c81166004830152602482018490528d81166044830152909116906353b7775b90606401600060405180830381600087803b1580156136e557600080fd5b505af11580156136f9573d6000803e3d6000fd5b5050505061381a565b6006546001600160a01b03908116908b160361381a57600654600c546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303816000875af1158015613786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137aa91906155f2565b50600c546040516353b7775b60e01b81526001600160a01b038c81166004830152602482018490528d81166044830152909116906353b7775b90606401600060405180830381600087803b15801561380157600080fd5b505af1158015613815573d6000803e3d6000fd5b505050505b7f998fa338b6602e5daf44326e2cde0a5f5e2261085f50fc8882cbc3680b9cbf7e8b848660405161384d939291906158b9565b60405180910390a15050505050505050505050565b60026000540361389e576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600055565b60015460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c55906138d6906002906004016155bb565b602060405180830381865afa1580156138f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391791906155d5565b600c80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c559061395b906017906004016155bb565b602060405180830381865afa158015613978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061399c91906155d5565b600a80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b039384160217905560015460405163bcaa0c5560e01b815291169063bcaa0c55906139fc906015906004016155bb565b602060405180830381865afa158015613a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3d91906155d5565b600b80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c5590613a809060049081016155bb565b602060405180830381865afa158015613a9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac191906155d5565b600e80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c5590613b05906006906004016155bb565b602060405180830381865afa158015613b22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4691906155d5565b600f80546001600160a01b0319166001600160a01b039283161790556001546040517f42ab14dd0000000000000000000000000000000000000000000000000000000081529116906342ab14dd90613ba390603f906004016155bb565b602060405180830381865afa158015613bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613be49190614cb9565b60085561278060015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c5590613c1c90600f906004016155bb565b602060405180830381865afa158015613c39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5d91906155d5565b6002549091506001600160a01b03808316911614613e2d57600280546001600160a01b0319166001600160a01b0383169081179091556040517ffe9fbb8000000000000000000000000000000000000000000000000000000000815230600482015263fe9fbb8090602401602060405180830381865afa158015613ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0991906155f2565b15613e2d57600260009054906101000a90046001600160a01b03166001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d5e57600080fd5b505af1158015613d72573d6000803e3d6000fd5b505060408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff098767a000000000000000000000000000000000000000000000000000000001790529051600093506001600160a01b0385169250613de691906158f7565b6000604051808303816000865af19150503d8060008114613e23576040519150601f19603f3d011682016040523d82523d6000602084013e613e28565b606091505b505050505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c5590613e5f906010906004016155bb565b602060405180830381865afa158015613e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea091906155d5565b6003549091506001600160a01b03808316911614613fef57600380546001600160a01b0319166001600160a01b038381169190911790915560015460405163bcaa0c5560e01b8152600092919091169063bcaa0c5590613f05906011906004016155bb565b602060405180830381865afa158015613f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4691906155d5565b6005549091506001600160a01b0316613fed576003546040517f36b91f2b0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152909116906336b91f2b90602401600060405180830381600087803b158015613fb957600080fd5b505af1158015613fcd573d6000803e3d6000fd5b5050600580546001600160a01b0319166001600160a01b03851617905550505b505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c5590614021906012906004016155bb565b602060405180830381865afa15801561403e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061406291906155d5565b60015460405163bcaa0c5560e01b81529192506000916001600160a01b039091169063bcaa0c5590614099906013906004016155bb565b602060405180830381865afa1580156140b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140da91906155d5565b6006549091506001600160a01b0383811691161461419457600680546001600160a01b0319166001600160a01b0384169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152839190631a33757d9061414e90600290600401615909565b6020604051808303816000875af115801561416d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141919190614cb9565b50505b6007546001600160a01b0382811691161461424b57600780546001600160a01b0319166001600160a01b0383169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152829190631a33757d9061420590600290600401615909565b6020604051808303816000875af1158015614224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142489190614cb9565b50505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c559061427d90600c906004016155bb565b602060405180830381865afa15801561429a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142be91906155d5565b90506001600160a01b038116156142d8576142d8816142e0565b61183461446e565b6001600160a01b038116614320576040517f05d8ce3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002546001600160a01b03166143335750565b6004546001600160a01b03166143d1576001600160a01b03811630146143cc576002546040517feb8646980000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301529091169063eb86469890602401600060405180830381600087803b1580156143b357600080fd5b505af11580156143c7573d6000803e3d6000fd5b505050505b61444c565b600480546040517f3a74bfd70000000000000000000000000000000000000000000000000000000081526001600160a01b0384811693820193909352911690633a74bfd790602401600060405180830381600087803b15801561443357600080fd5b505af1158015614447573d6000803e3d6000fd5b505050505b600480546001600160a01b0319166001600160a01b0392909216919091179055565b600180546040517ff2aac76c0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169163f2aac76c916144b791906004016155bb565b602060405180830381865afa1580156144d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144f891906155f2565b6001805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6040518060e00160405280600081526020016000815260200160006001600160a01b0316815260200161459e604051806080016040528060008152602001600061ffff168152602001600061ffff168152602001600081525090565b81526040805160a08101825260008082526020828101829052928201819052606082018190526080820152910190815260606020820152600060409091015290565b6001600160a01b03811681146130e257600080fd5b6000806040838503121561460857600080fd5b8235614613816145e0565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6007811061464757614647614621565b9052565b600681106130e2576130e2614621565b614666828251614637565b61ffff602082015116602083015260408101516146828161464b565b604083015260608181015160ff169083015260809081015163ffffffff16910152565b60005b838110156146c05781810151838201526020016146a8565b50506000910152565b600082825180855260208086019550808260051b84010181860160005b8481101561474b57601f1980878503018a528251604081516147078161464b565b86529086015186860182905280519186018290529060609061472e81838901858b016146a5565b9b87019b601f0190921694909401019250908301906001016146e6565b5090979650505050505050565b6020815281516020820152602082015160408201526001600160a01b0360408301511660608201526000606083015180516080840152602081015161ffff80821660a08601528060408401511660c08601525050606081015160e08401525060808301516147ca61010084018261465b565b5060a08301516101c0806101a08501526147e86101e08501836146c9565b915060c08501516147fc8286018215159052565b5090949350505050565b60008083601f84011261481857600080fd5b50813567ffffffffffffffff81111561483057600080fd5b6020830191508360208260051b850101111561484b57600080fd5b9250929050565b6000806000806040858703121561486857600080fd5b843567ffffffffffffffff8082111561488057600080fd5b61488c88838901614806565b909650945060208701359150808211156148a557600080fd5b506148b287828801614806565b95989497509550505050565b63ffffffff811681146130e257600080fd5b600080604083850312156148e357600080fd5b82356148ee816145e0565b915060208301356148fe816148be565b809150509250929050565b60006020828403121561491b57600080fd5b8135614926816145e0565b9392505050565b60008060006060848603121561494257600080fd5b833561494d816145e0565b9250602084013591506040840135614964816145e0565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561499857600080fd5b823567ffffffffffffffff808211156149b057600080fd5b818501915085601f8301126149c457600080fd5b8135818111156149d6576149d661496f565b8060051b604051601f19603f830116810181811085821117156149fb576149fb61496f565b604052918252848201925083810185019188831115614a1957600080fd5b938501935b82851015614a3757843584529385019392850192614a1e565b98975050505050505050565b600181811c90821680614a5757607f821691505b602082108103614a7757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b61ffff811681146130e257600080fd5b600060208284031215614ab557600080fd5b813561492681614a93565b8183526000602080850194508260005b85811015614afe578135614ae3816145e0565b6001600160a01b031687529582019590820190600101614ad0565b509495945050505050565b604081526000614b1d604083018688614ac0565b8281036020848101919091528482528591810160005b86811015614b5c578335614b4681614a93565b61ffff1682529282019290820190600101614b33565b5098975050505050505050565b803560038110614b7857600080fd5b919050565b600060208284031215614b8f57600080fd5b61492682614b69565b600381106130e2576130e2614621565b604081526000614bbc604083018688614ac0565b8281036020848101919091528482528591810160005b86811015614b5c57614be384614b69565b614bec81614b98565b82529282019290820190600101614bd2565b634e487b7160e01b600052601160045260246000fd5b63ffffffff818116838216019080821115614c3157614c31614bfe565b5092915050565b8181038181111561090e5761090e614bfe565b600060ff821660ff8103614c6157614c61614bfe565b60010192915050565b6000604082016001600160a01b038516835260206040602085015281855180845260608601915060208701935060005b8181101561474b57845160ff1683529383019391830191600101614c9a565b600060208284031215614ccb57600080fd5b5051919050565b60008151808452602080850194506020840160005b83811015614afe57815187529582019590820190600101614ce7565b6001600160a01b0383168152604060208201526000614d256040830184614cd2565b949350505050565b600082356101be19833603018112614d4457600080fd5b9190910192915050565b600781106130e257600080fd5b600681106130e257600080fd5b60ff811681146130e257600080fd5b6000813561090e81614d68565b6000813561090e816148be565b8135614d9c81614d4e565b60078110614dac57614dac614621565b815460ff821691508160ff1982161783556020840135614dcb81614a93565b62ffff008160081b16905080837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416171784556040850135614e0d81614d5b565b614e168161464b565b63ff0000008160181b168463ffffffff19851617831717855550505050614e78614e4260608401614d77565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1660209190911b64ff0000000016178255565b614eab614e8760808401614d84565b825468ffffffff0000000000191660289190911b68ffffffff000000000016178255565b5050565b6000808335601e19843603018112614ec657600080fd5b83018035915067ffffffffffffffff821115614ee157600080fd5b6020019150600581901b360382131561484b57600080fd5b60008235603e19833603018112614d4457600080fd5b808202811582820484141761090e5761090e614bfe565b5b81811015614eab5760008155600101614f27565b601f821115612a8657806000526020600020601f840160051c81016020851015614f625750805b611834601f850160051c830182614f26565b8135614f7f81614d5b565b614f888161464b565b60ff1982541660ff82168117835550506001808201602080850135601e19863603018112614fb557600080fd5b8501803567ffffffffffffffff811115614fce57600080fd5b8036038383011315614fdf57600080fd5b614ff381614fed8654614a43565b86614f3b565b6000601f821160018114615029576000831561501157508382018501355b600019600385901b1c1916600184901b178655615084565b600086815260209020601f19841690835b828110156150595786850188013582559387019390890190870161503a565b50848210156150785760001960f88660031b161c198785880101351681555b505060018360011b0186555b505050505050505050565b680100000000000000008311156150a8576150a861496f565b8054838255808410156151885760017f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80831683146150e9576150e9614bfe565b80861686146150fa576150fa614bfe565b5060008360005260206000208360011b81018760011b820191505b808210156151835782825583820161512d8154614a43565b801561517657601f8082116001811461514857868455615173565b60008481526020902061516483850160051c82018a8301614f26565b50600084815260208120818655555b50505b5050600282019150615115565b505050505b5060008181526020812083915b85811015611cfc576151b06151aa8487614ef9565b83614f74565b6020929092019160029190910190600101615195565b80151581146130e257600080fd5b6000813561090e816151c6565b8135815560208201356001820155600281016040830135615201816145e0565b6001600160a01b0381166001600160a01b031983541617825550506060820135600382015560048101608083013561523881614a93565b815460a085013561524881614a93565b63ffff00008160101b1661ffff841663ffffffff198416171784555050505060c0820135600582015561528160e0830160068301614d91565b61528f610180830183614eaf565b61529d81836007860161508f565b5050614eab6152af6101a084016151d4565b6008830160ff1981541660ff8315151681178255505050565b8082018082111561090e5761090e614bfe565b80356152e681614d4e565b6152f08382614637565b5060208101356152ff81614a93565b61ffff166020830152604081013561531681614d5b565b61531f8161464b565b6040830152606081013561533281614d68565b60ff1660608301526080810135615348816148be565b63ffffffff81166080840152505050565b6000808335601e1984360301811261537057600080fd5b830160208101925035905067ffffffffffffffff81111561539057600080fd5b8060051b360382131561484b57600080fd5b60008383855260208086019550808560051b8301018460005b8781101561474b57601f1980868503018a528235603e198936030181126153e157600080fd5b8801604081356153f081614d5b565b6153f98161464b565b86528187013536839003601e1901811261541257600080fd5b90910186810191903567ffffffffffffffff81111561543057600080fd5b80360383131561543f57600080fd5b818888015280828801526060915080838389013760008782018301529b87019b601f01909216909401019250908301906001016153bb565b8035614b78816151c6565b60006040808352615497604084018789614ac0565b602084820381860152818683528183019050818760051b840101886000805b8a8110156155a957601f1987850301855282356101be198d36030181126154db578283fd5b8c018035855286810135878601526101c0898201356154f9816145e0565b6001600160a01b0316868b01526060828101359087015260808083013561551f81614a93565b61ffff808216838a015260a0925082850135915061553c82614a93565b169087015260c0828101359087015260e061555b8188018285016152db565b5061018061556b81840184615359565b83838a015261557d848a0182846153a2565b93505050506101a0615590818401615477565b15159601959095525093850193918501916001016154b6565b50919c9b505050505050505050505050565b60208101604083106155cf576155cf614621565b91905290565b6000602082840312156155e757600080fd5b8151614926816145e0565b60006020828403121561560457600080fd5b8151614926816151c6565b60208101601583106155cf576155cf614621565b60006020828403121561563557600080fd5b8135614926816151c6565b8183526000602080850194508260005b85811015614afe578135615663816151c6565b151587529582019590820190600101615650565b6040815283604082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8511156156b057600080fd5b8460051b808760608501378201828103606090810160208501526156d79082018587615640565b979650505050505050565b6000826156ff57634e487b7160e01b600052601260045260246000fd5b500490565b604081526000615718604083018688614ac0565b82810360208401526156d7818587615640565b6000828254808552602080860195506005818360051b8501016000878152838120815b8681101561580757601f19888503018b52604060ff83541661576f8161464b565b808652506001808401828988015285815461578981614a43565b94890185905260609481851680156157a857600181146157c1576157ec565b60ff198316878c0152868215158d1b8c010193506157ec565b848a528c8a208a5b838110156157e45781548d82018a0152908701908e016157c9565b8c0188019450505b5050509d89019d96505050600292909201915060010161574e565b50919998505050505050505050565b60006101606001600160a01b038716835285546020840152600186015461ffff8082166040860152808260101c166060860152600288015460808601528654915061586760a0860160ff8416614637565b808260081c1660c08601525060ff8160181c166158838161464b565b60e0850152602081901c60ff1661010085015260281c63ffffffff1661012084015261014083018190526156d78184018561572b565b6001600160a01b03841681526060602082015260006158db6060830185614cd2565b82810360408401526158ed8185614cd2565b9695505050505050565b60008251614d448184602087016146a5565b602081016155cf83614b9856fea2646970667358221220eff9c7c53a7a3ba387864c86bdda7aff4f561426ac204da2677f149feb80931564736f6c63430008190033000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
Deployed Bytecode
0x6080604052600436106101cd5760003560e01c8063664d8884116100f75780638da52e9311610095578063b930b48211610064578063b930b482146105f9578063bbb1a27914610619578063dae6902f1461062c578063fce14af61461064c57600080fd5b80638da52e931461056f578063992a1c3e14610584578063ad5c4648146105a4578063b0da6e67146105c457600080fd5b806375a3b381116100d157806375a3b381146104f15780637aa7e55c146104f95780637b7e6b06146105195780638671d23b1461054f57600080fd5b8063664d8884146103ce5780636f48568f146104845780636f5589e2146104a457600080fd5b80633cdad82c1161016f5780634b03eeb41161013e5780634b03eeb414610363578063510295a6146103835780635e062657146103a35780635e4a1e01146103b857600080fd5b80633cdad82c146102db5780633fb27b85146102f9578063443b178614610323578063448639211461034357600080fd5b80631e63c6a3116101ab5780631e63c6a31461024e57806325ba98fa1461026e57806331a0edec1461028e57806333271e3e146102c657600080fd5b806301f3bc79146101d257806307c895a7146102085780630da8610d1461022c575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046145f5565b61066c565b6040516101ff9190614758565b60405180910390f35b34801561021457600080fd5b5061021e60095481565b6040519081526020016101ff565b34801561023857600080fd5b5061024c610247366004614852565b610914565b005b34801561025a57600080fd5b5061024c610269366004614852565b610a59565b34801561027a57600080fd5b5061024c6102893660046148d0565b610b9b565b34801561029a57600080fd5b506006546102ae906001600160a01b031681565b6040516001600160a01b0390911681526020016101ff565b3480156102d257600080fd5b5061024c611071565b3480156102e757600080fd5b506004546001600160a01b03166102ae565b34801561030557600080fd5b50600a546103139060ff1681565b60405190151581526020016101ff565b34801561032f57600080fd5b506001546102ae906001600160a01b031681565b34801561034f57600080fd5b5061024c61035e366004614852565b6110f8565b34801561036f57600080fd5b5061024c61037e3660046145f5565b61162a565b34801561038f57600080fd5b5061024c61039e3660046148d0565b61183b565b3480156103af57600080fd5b5061024c611d04565b3480156103c457600080fd5b5061021e60085481565b3480156103da57600080fd5b506104516103e9366004614909565b6040805160608082018352600080835260208084018290529284018190526001600160a01b0394851681526011835283812054601684529084902084519283018552805483526001810154938301939093526002909201549093169183019190915260ff1691565b60408051921515835281516020808501919091528201518382015201516001600160a01b031660608201526080016101ff565b34801561049057600080fd5b5061024c61049f3660046148d0565b611e6e565b3480156104b057600080fd5b506104de6104bf366004614909565b6001600160a01b031660009081526013602052604090205461ffff1690565b60405161ffff90911681526020016101ff565b61024c612537565b34801561050557600080fd5b5061024c610514366004614852565b612782565b34801561052557600080fd5b5061021e610534366004614909565b6001600160a01b031660009081526012602052604090205490565b34801561055b57600080fd5b5061024c61056a36600461492d565b6128c4565b34801561057b57600080fd5b5061024c612a8b565b34801561059057600080fd5b5061024c61059f366004614852565b612ad7565b3480156105b057600080fd5b506007546102ae906001600160a01b031681565b3480156105d057600080fd5b506105e46105df366004614909565b612c2b565b604080519283526020830191909152016101ff565b34801561060557600080fd5b506003546102ae906001600160a01b031681565b61024c610627366004614985565b612cab565b34801561063857600080fd5b5061024c610647366004614852565b6130e5565b34801561065857600080fd5b506002546102ae906001600160a01b031681565b610674614542565b6040516bffffffffffffffffffffffff19606085901b1660208201526034810183905260009060540160408051601f19818403018152828252805160209182012060008181526010835283902060e0850184528054855260018101548584015260028101546001600160a01b03168585015283516080808201865260038301548252600483015461ffff80821696840196909652620100009004909416818601526005820154606082810191909152860152835160a081019094526006808201805493975091949386019392839160ff9091169081111561075757610757614621565b600681111561076857610768614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff16600581111561079b5761079b614621565b60058111156107ac576107ac614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b828210156108f15760008481526020902060408051808201909152600284029091018054829060ff16600581111561083b5761083b614621565b600581111561084c5761084c614621565b815260200160018201805461086090614a43565b80601f016020809104026020016040519081016040528092919081815260200182805461088c90614a43565b80156108d95780601f106108ae576101008083540402835291602001916108d9565b820191906000526020600020905b8154815290600101906020018083116108bc57829003601f168201915b50505050508152505081526020019060010190610801565b505050908252506008919091015460ff1615156020909101529150505b92915050565b6017546001600160a01b0316331461093f57604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156109635760405163a4e2119b60e01b815260040160405180910390fd5b82811461098357604051633cbac2d960e11b815260040160405180910390fd5b60005b83811015610a15578282828181106109a0576109a0614a7d565b90506020020160208101906109b59190614aa3565b601360008787858181106109cb576109cb614a7d565b90506020020160208101906109e09190614909565b6001600160a01b031681526020810191909152604001600020805461ffff191661ffff92909216919091179055600101610986565b507fa9886e35f88b1a31bf2b47240b3a64f3d10e4f8ba3fd5b554e36ba15c74c6f1b84848484604051610a4b9493929190614b09565b60405180910390a150505050565b6017546001600160a01b03163314610a8457604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff1615610aa85760405163a4e2119b60e01b815260040160405180910390fd5b828114610ac857604051633cbac2d960e11b815260040160405180910390fd5b60005b83811015610b6557828282818110610ae557610ae5614a7d565b9050602002016020810190610afa9190614b7d565b60146000878785818110610b1057610b10614a7d565b9050602002016020810190610b259190614909565b6001600160a01b031681526020810191909152604001600020805460ff19166001836002811115610b5857610b58614621565b0217905550600101610acb565b507f174b79b1053487f0cce24fcceca584a4347ba1ecdee4d34998987ab60aa5a82484848484604051610a4b9493929190614ba8565b600a5460ff16610bbe57604051630345b96360e41b815260040160405180910390fd5b6001600160a01b0382163314801590610c0157506001600160a01b03821660009081526014602052604081205460ff166002811115610bff57610bff614621565b145b15610c38576040517fdf3fb3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016001600160a01b03831660009081526014602052604090205460ff166002811115610c6757610c67614621565b03610c845760405162aab53f60e81b815260040160405180910390fd5b6001600160a01b038216600090815260126020908152604080832080548251818502810185019093528083529192909190830182828015610ce457602002820191906000526020600020905b815481526020019060010190808311610cd0575b505050505090508051600003610d0d5760405163355a170b60e01b815260040160405180910390fd5b60408051600780825261010082019092526000916020820160e080368337505083519192506000918291508190610d45600588614c14565b63ffffffff1611610d6657610d5b600587614c14565b63ffffffff16610d69565b84515b90506000610d7d63ffffffff881683614c38565b67ffffffffffffffff811115610d9557610d9561496f565b604051908082528060200260200182016040528015610dbe578160200160208202803683370190505b50905063ffffffff87165b82811015610f7a57868181518110610de357610de3614a7d565b60200260200101519450601060008a87604051602001610e2192919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6040516020818303038152906040528051906020012081526020019081526020016000209350836001015460001480610e5e5750600884015460ff165b610f72578354600003610e845760405163aeebaa7360e01b815260040160405180910390fd5b60088401805460ff19166001179055600680850154879160ff9190911690811115610eb157610eb1614621565b60ff1681518110610ec457610ec4614a7d565b602002602001018051809190610ed990614c4b565b60ff16905250600a54604051630852cd8d60e31b8152600481018790526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b158015610f2957600080fd5b505af1158015610f3d573d6000803e3d6000fd5b5050505084828963ffffffff1683610f559190614c38565b81518110610f6557610f65614a7d565b6020026020010181815250505b600101610dc9565b50600e546040517f1b5045640000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690631b50456490610fc6908b908990600401614c6a565b6020604051808303816000875af1158015610fe5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110099190614cb9565b506001600160a01b03881660009081526014602052604090819020805460ff19166002179055517f70e47b186223984b3180782e79b09d10da97155f6aa25c9404d4ccd567dbc9fa9061105f908a908490614d03565b60405180910390a15050505050505050565b6017546001600160a01b0316331461109c57604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156110c05760405163a4e2119b60e01b815260040160405180910390fd5b600a805460ff191660011790556040517ff109e3a410f1d684de81b8a1c25a024283fdb20c4c91f1e4d2cd2c6f9bfde5d790600090a1565b6017546001600160a01b0316331461112357604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156111475760405163a4e2119b60e01b815260040160405180910390fd5b82811461116757604051633cbac2d960e11b815260040160405180910390fd5b60008080805b868110156115e3576006546001600160a01b031686868381811061119357611193614a7d565b90506020028101906111a59190614d2d565b6111b6906060810190604001614909565b6001600160a01b03161415801561121557506007546001600160a01b03168686838181106111e6576111e6614a7d565b90506020028101906111f89190614d2d565b611209906060810190604001614909565b6001600160a01b031614155b801561125f5750600086868381811061123057611230614a7d565b90506020028101906112429190614d2d565b611253906060810190604001614909565b6001600160a01b031614155b15611296576040517fe2ad907700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8585828181106112a8576112a8614a7d565b90506020028101906112ba9190614d2d565b356000036112f4576040517fac99966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87878281811061130657611306614a7d565b905060200201602081019061131b9190614909565b935085858281811061132f5761132f614a7d565b90506020028101906113419190614d2d565b6040516bffffffffffffffffffffffff19606087901b166020820152903560348201819052935060540160408051601f19818403018152918152815160209283012060008181526010909352912054909250156113ca576040517fc471fc6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8585828181106113dc576113dc614a7d565b90506020028101906113ee9190614d2d565b600083815260106020526040902061140682826151e1565b90505085858281811061141b5761141b614a7d565b905060200281019061142d9190614d2d565b60200135156115075785858281811061144857611448614a7d565b905060200281019061145a9190614d2d565b6020013560166000866001600160a01b03166001600160a01b03168152602001908152602001600020600101600082825461149591906152c8565b9091555086905085828181106114ad576114ad614a7d565b90506020028101906114bf9190614d2d565b6114d0906060810190604001614909565b6001600160a01b03858116600090815260166020526040902060020180546001600160a01b031916929091169190911790556115af565b600086868381811061151b5761151b614a7d565b905060200281019061152d9190614d2d565b61153e906060810190604001614909565b6001600160a01b03161461157e576040517fe2ad907700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6009546001600160a01b038516600090815260166020526040812080549091906115a99084906152c8565b90915550505b6001600160a01b0384166000908152601260209081526040822080546001818101835591845291909220018490550161116d565b507f560543aa868240b36de3b93c5d6785c1e0ec73406daadfaa5ba8b7f5dac8148a878787876040516116199493929190615482565b60405180910390a150505050505050565b60015460405163bcaa0c5560e01b8152600c916000916001600160a01b039091169063bcaa0c55906116609085906004016155bb565b602060405180830381865afa15801561167d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a191906155d5565b90506001600160a01b0381166116ee57816040517f92bc2cd00000000000000000000000000000000000000000000000000000000081526004016116e591906155bb565b60405180910390fd5b6001600160a01b0381163314611730576040517f1a48f08400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405163bcaa0c5560e01b81526001600160a01b038087169263aad3ec969291169063bcaa0c559061176a90600c906004016155bb565b602060405180830381865afa158015611787573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ab91906155d5565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018690526044016020604051808303816000875af1158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190614cb9565b5050505050565b60016001600160a01b03831660009081526014602052604090205460ff16600281111561186a5761186a614621565b146118875760405162aab53f60e81b815260040160405180910390fd5b6001600160a01b03821660009081526012602052604090205463ffffffff821681116118df576040517fd53d9ca900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816118ed600585614c14565b63ffffffff161161190e57611903600584614c14565b63ffffffff16611910565b815b9050600061192463ffffffff851683614c38565b67ffffffffffffffff81111561193c5761193c61496f565b604051908082528060200260200182016040528015611965578160200160208202803683370190505b509050611970614542565b63ffffffff85165b83811015611cd1576001600160a01b03871660009081526012602052604081208054601092918a91859081106119b0576119b0614a7d565b90600052602060002001546040516020016119e992919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b60408051601f198184030181529181528151602092830120835282820193909352908201600020825160e0810184528154815260018201548184015260028201546001600160a01b03168185015283516080808201865260038401548252600484015461ffff80821696840196909652620100009004909416818601526005830154606082810191909152820152835160a081019094526006808301805492959394860193929091839160ff1690811115611aa657611aa6614621565b6006811115611ab757611ab7614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff166005811115611aea57611aea614621565b6005811115611afb57611afb614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b82821015611c405760008481526020902060408051808201909152600284029091018054829060ff166005811115611b8a57611b8a614621565b6005811115611b9b57611b9b614621565b8152602001600182018054611baf90614a43565b80601f0160208091040260200160405190810160405280929190818152602001828054611bdb90614a43565b8015611c285780601f10611bfd57610100808354040283529160200191611c28565b820191906000526020600020905b815481529060010190602001808311611c0b57829003601f168201915b50505050508152505081526020019060010190611b50565b505050908252506008919091015460ff16151560209182015281015190925015611cc9576001600160a01b0387166000908152601260205260409020805482908110611c8e57611c8e614a7d565b9060005260206000200154838763ffffffff1683611cac9190614c38565b81518110611cbc57611cbc614a7d565b6020026020010181815250505b600101611978565b506001600160a01b03808716600090815260166020526040902060020154611cfc9188911684613217565b505050505050565b600a5460ff16611d2757604051630345b96360e41b815260040160405180910390fd5b3360009081526013602052604081205461ffff169003611d73576040517f4a5b8ec600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000818152601360205260409081902054600e5491517f6455c6fc000000000000000000000000000000000000000000000000000000008152600481019390935261ffff1660248301819052916001600160a01b0390911690636455c6fc906044016020604051808303816000875af1158015611df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e199190614cb9565b5033600081815260136020908152604091829020805461ffff19169055815192835282018390527f91ee8398834bad350334445ec5760d3d4419521bc8238a7417d13d2ad52ce206910160405180910390a150565b600a5460ff16611e9157604051630345b96360e41b815260040160405180910390fd5b6001600160a01b0382163314801590611ed457506001600160a01b03821660009081526015602052604081205460ff166002811115611ed257611ed2614621565b145b15611f0b576040517fdf3fb3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0382166000908152601560209081526040808320805460ff191660021790556012825280832080548251818502810185019093528083529192909190830182828015611f7d57602002820191906000526020600020905b815481526020019060010190808311611f69575b505050505090508051600003611fa65760405163355a170b60e01b815260040160405180910390fd5b60408051600780825261010082019092526000916020820160e080368337019050508251909150600090611fdb600586614c14565b63ffffffff1611611ffc57611ff1600585614c14565b63ffffffff16611fff565b82515b9050600061201363ffffffff861683614c38565b67ffffffffffffffff81111561202b5761202b61496f565b604051908082528060200260200182016040528015612054578160200160208202803683370190505b509050600080612062614542565b63ffffffff88165b858110156124635787818151811061208457612084614a7d565b6020026020010151935089846040516020016120be92919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b60408051601f19818403018152828252805160209182012060008181526010835283902060e0850184528054855260018101548584015260028101546001600160a01b03168585015283516080808201865260038301548252600483015461ffff80821696840196909652620100009004909416818601526005820154606082810191909152860152835160a081019094526006808201805493995091949386019392839160ff9091169081111561217857612178614621565b600681111561218957612189614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff1660058111156121bc576121bc614621565b60058111156121cd576121cd614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b828210156123125760008481526020902060408051808201909152600284029091018054829060ff16600581111561225c5761225c614621565b600581111561226d5761226d614621565b815260200160018201805461228190614a43565b80601f01602080910402602001604051908101604052809291908181526020018280546122ad90614a43565b80156122fa5780601f106122cf576101008083540402835291602001916122fa565b820191906000526020600020905b8154815290600101906020018083116122dd57829003601f168201915b50505050508152505081526020019060010190612222565b505050908252506008919091015460ff16151560209182015281015190925015158061233f57508160c001515b61245b5781516000036123655760405163aeebaa7360e01b815260040160405180910390fd5b6000838152601060205260409020600801805460ff191660011790556080820151518790600681111561239a5761239a614621565b60ff16815181106123ad576123ad614a7d565b6020026020010180518091906123c290614c4b565b60ff16905250600a54604051630852cd8d60e31b8152600481018690526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561241257600080fd5b505af1158015612426573d6000803e3d6000fd5b5050505083858a63ffffffff168361243e9190614c38565b8151811061244e5761244e614a7d565b6020026020010181815250505b60010161206a565b50600e546040517f1b5045640000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690631b504564906124af908c908a90600401614c6a565b6020604051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f29190614cb9565b507ff29048c0820fdab636dcb2f6c5030af9334c1ad195d421474aa8c8c34c19fdd58985604051612524929190614d03565b60405180910390a1505050505050505050565b61253f613862565b600a5460ff1661256257604051630345b96360e41b815260040160405180910390fd5b3360009081526014602052604081205460ff16600281111561258657612586614621565b146125a35760405162aab53f60e81b815260040160405180910390fd5b336000818152601160205260408120805460ff19166001179055906125c790612c2b565b509050806000036125eb5760405163aeebaa7360e01b815260040160405180910390fd5b33600090815260126020526040812054900361261a5760405163355a170b60e01b815260040160405180910390fd5b336000908152601660205260409020600201546001600160a01b0316806126605781341461265b57604051636e848b1d60e11b815260040160405180910390fd5b612711565b341561267f57604051636e848b1d60e11b815260040160405180910390fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018390526001600160a01b038216906323b872dd906064016020604051808303816000875af11580156126eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061270f91906155f2565b505b33600081815260146020908152604091829020805460ff19166001179055815192835282018490526001600160a01b038316908201527f7cbbc73447ae062db7eddd4894b6af2105cb58a6631da57375fa18bfa2b520649060600160405180910390a150506127806001600055565b565b6017546001600160a01b031633146127ad57604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156127d15760405163a4e2119b60e01b815260040160405180910390fd5b8281146127f157604051633cbac2d960e11b815260040160405180910390fd5b60005b8381101561288e5782828281811061280e5761280e614a7d565b90506020020160208101906128239190614b7d565b6015600087878581811061283957612839614a7d565b905060200201602081019061284e9190614909565b6001600160a01b031681526020810191909152604001600020805460ff1916600183600281111561288157612881614621565b02179055506001016127f4565b507f78700a1e1dc8b51ad86bb898af740f89cb8855b1b0523062c9e0d953aa89095484848484604051610a4b9493929190614ba8565b6001546040517fd91078070000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063d91078079061290e9060009060040161560f565b602060405180830381865afa15801561292b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061294f91906155d5565b6001600160a01b0316336001600160a01b03161461298057604051637bd5018b60e11b815260040160405180910390fd5b6001600160a01b0383166129f4576040516000906001600160a01b0383169084156108fc0290859084818181858888f193505050509050806129ee576040517f83cedb1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038281166024830152604482018490528416906323b872dd906064016020604051808303816000875af1158015612a62573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ee91906155f2565b505050565b6001546001600160a01b03163314612acf576040517fe101028000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127806138a5565b6017546001600160a01b03163314612b0257604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff1615612b265760405163a4e2119b60e01b815260040160405180910390fd5b828114612b4657604051633cbac2d960e11b815260040160405180910390fd5b60005b83811015612bf5576000858583818110612b6557612b65614a7d565b9050602002013590506010600082815260200190815260200160002060000154600003612ba55760405163aeebaa7360e01b815260040160405180910390fd5b838383818110612bb757612bb7614a7d565b9050602002016020810190612bcc9190615623565b600091825260106020526040909120600801805460ff1916911515919091179055600101612b49565b507f2ff50a1c5c809242b9dfa6e0232a781429e9793ace8e9e91099f85276f5c9ea184848484604051610a4b9493929190615677565b6008546001600160a01b038216600090815260166020526040812060010154909182916509184e72a00091612c5f91614f0f565b612c6991906156e2565b6008546001600160a01b0385166000908152601660205260409020549193506509184e72a00091612c9a9190614f0f565b612ca491906156e2565b9050915091565b612cb3613862565b3360009081526015602052604081205460ff166002811115612cd757612cd7614621565b14612cf45760405162aab53f60e81b815260040160405180910390fd5b612cfc614542565b6000805b835181101561308b57838181518110612d1b57612d1b614a7d565b602002602001015160000315613083576010600033868481518110612d4257612d42614a7d565b6020026020010151604051602001612d7892919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b60408051601f198184030181529181528151602092830120835282820193909352908201600020825160e0810184528154815260018201548184015260028201546001600160a01b03168185015283516080808201865260038401548252600484015461ffff80821696840196909652620100009004909416818601526005830154606082810191909152820152835160a081019094526006808301805492959394860193929091839160ff1690811115612e3557612e35614621565b6006811115612e4657612e46614621565b81528154610100810461ffff1660208301526040909101906301000000900460ff166005811115612e7957612e79614621565b6005811115612e8a57612e8a614621565b81529054640100000000810460ff166020808401919091526501000000000090910463ffffffff1660409283015291835260078401805482518185028101850190935280835293830193919290919060009084015b82821015612fcf5760008481526020902060408051808201909152600284029091018054829060ff166005811115612f1957612f19614621565b6005811115612f2a57612f2a614621565b8152602001600182018054612f3e90614a43565b80601f0160208091040260200160405190810160405280929190818152602001828054612f6a90614a43565b8015612fb75780601f10612f8c57610100808354040283529160200191612fb7565b820191906000526020600020905b815481529060010190602001808311612f9a57829003601f168201915b50505050508152505081526020019060010190612edf565b505050908252506008919091015460ff16151560209182015281015190935015613025576040517fa037845500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408301516001600160a01b03161561306a576040517f10a1a01400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c001516130835760095461308090836152c8565b91505b600101612d00565b5061309833600085613217565b6509184e72a000600854826130ad9190614f0f565b6130b791906156e2565b34146130d657604051636e848b1d60e11b815260040160405180910390fd5b50506130e26001600055565b50565b6017546001600160a01b0316331461311057604051637bd5018b60e11b815260040160405180910390fd5b600a5460ff16156131345760405163a4e2119b60e01b815260040160405180910390fd5b82811461315457604051633cbac2d960e11b815260040160405180910390fd5b60005b838110156131e15782828281811061317157613171614a7d565b90506020020160208101906131869190615623565b6011600087878581811061319c5761319c614a7d565b90506020020160208101906131b19190614909565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055600101613157565b507f397670419d1417ee84841806f025ae55d66489f90a2effce6ee276852bbf70b384848484604051610a4b9493929190615704565b600a5460ff1661323a57604051630345b96360e41b815260040160405180910390fd5b6000806000806000855167ffffffffffffffff81111561325c5761325c61496f565b604051908082528060200260200182016040528015613285578160200160208202803683370190505b5090506000865167ffffffffffffffff8111156132a4576132a461496f565b6040519080825280602002602001820160405280156132cd578160200160208202803683370190505b50905060005b87518160ff16101561353a57878160ff16815181106132f4576132f4614a7d565b602002602001015195508560000315613528576040516bffffffffffffffffffffffff1960608c901b1660208201526034810187905260540160408051601f198184030181529181528151602092830120600081815260109093529082208054919750955090036133785760405163aeebaa7360e01b815260040160405180910390fd5b600884015460ff166135285760088401805460ff1916600190811790915584015460008190036133b6576009546133af90896152c8565b97506133c3565b6133c081896152c8565b97505b60068501805468ffffffff00000000001916650100000000004263ffffffff1602178155600f546040517ffacaa0b70000000000000000000000000000000000000000000000000000000081526001600160a01b039091169163facaa0b79161343b918f9160038b01919060078c0190600401615816565b6020604051808303816000875af115801561345a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347e9190614cb9565b848360ff168151811061349357613493614a7d565b6020026020010181815250508460000154838360ff16815181106134b9576134b9614a7d565b6020908102919091010152600a54604051630852cd8d60e31b8152600481018990526101009091046001600160a01b0316906342966c6890602401600060405180830381600087803b15801561350e57600080fd5b505af1158015613522573d6000803e3d6000fd5b50505050505b8061353281614c4b565b9150506132d3565b60006509184e72a000600854896135519190614f0f565b61355b91906156e2565b9050801561381a576001600160a01b038a166135e657600c546040516353b7775b60e01b81526001600160a01b038c81166004830152602482018490528d81166044830152909116906353b7775b9083906064016000604051808303818588803b1580156135c857600080fd5b505af11580156135dc573d6000803e3d6000fd5b505050505061381a565b6007546001600160a01b03908116908b160361370257600754600c546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303816000875af115801561366a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368e91906155f2565b50600c546040516353b7775b60e01b81526001600160a01b038c81166004830152602482018490528d81166044830152909116906353b7775b90606401600060405180830381600087803b1580156136e557600080fd5b505af11580156136f9573d6000803e3d6000fd5b5050505061381a565b6006546001600160a01b03908116908b160361381a57600654600c546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303816000875af1158015613786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137aa91906155f2565b50600c546040516353b7775b60e01b81526001600160a01b038c81166004830152602482018490528d81166044830152909116906353b7775b90606401600060405180830381600087803b15801561380157600080fd5b505af1158015613815573d6000803e3d6000fd5b505050505b7f998fa338b6602e5daf44326e2cde0a5f5e2261085f50fc8882cbc3680b9cbf7e8b848660405161384d939291906158b9565b60405180910390a15050505050505050505050565b60026000540361389e576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600055565b60015460405163bcaa0c5560e01b81526001600160a01b039091169063bcaa0c55906138d6906002906004016155bb565b602060405180830381865afa1580156138f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061391791906155d5565b600c80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c559061395b906017906004016155bb565b602060405180830381865afa158015613978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061399c91906155d5565b600a80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b039384160217905560015460405163bcaa0c5560e01b815291169063bcaa0c55906139fc906015906004016155bb565b602060405180830381865afa158015613a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3d91906155d5565b600b80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c5590613a809060049081016155bb565b602060405180830381865afa158015613a9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac191906155d5565b600e80546001600160a01b0319166001600160a01b0392831617905560015460405163bcaa0c5560e01b815291169063bcaa0c5590613b05906006906004016155bb565b602060405180830381865afa158015613b22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4691906155d5565b600f80546001600160a01b0319166001600160a01b039283161790556001546040517f42ab14dd0000000000000000000000000000000000000000000000000000000081529116906342ab14dd90613ba390603f906004016155bb565b602060405180830381865afa158015613bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613be49190614cb9565b60085561278060015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c5590613c1c90600f906004016155bb565b602060405180830381865afa158015613c39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5d91906155d5565b6002549091506001600160a01b03808316911614613e2d57600280546001600160a01b0319166001600160a01b0383169081179091556040517ffe9fbb8000000000000000000000000000000000000000000000000000000000815230600482015263fe9fbb8090602401602060405180830381865afa158015613ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0991906155f2565b15613e2d57600260009054906101000a90046001600160a01b03166001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d5e57600080fd5b505af1158015613d72573d6000803e3d6000fd5b505060408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff098767a000000000000000000000000000000000000000000000000000000001790529051600093506001600160a01b0385169250613de691906158f7565b6000604051808303816000865af19150503d8060008114613e23576040519150601f19603f3d011682016040523d82523d6000602084013e613e28565b606091505b505050505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c5590613e5f906010906004016155bb565b602060405180830381865afa158015613e7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ea091906155d5565b6003549091506001600160a01b03808316911614613fef57600380546001600160a01b0319166001600160a01b038381169190911790915560015460405163bcaa0c5560e01b8152600092919091169063bcaa0c5590613f05906011906004016155bb565b602060405180830381865afa158015613f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4691906155d5565b6005549091506001600160a01b0316613fed576003546040517f36b91f2b0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152909116906336b91f2b90602401600060405180830381600087803b158015613fb957600080fd5b505af1158015613fcd573d6000803e3d6000fd5b5050600580546001600160a01b0319166001600160a01b03851617905550505b505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c5590614021906012906004016155bb565b602060405180830381865afa15801561403e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061406291906155d5565b60015460405163bcaa0c5560e01b81529192506000916001600160a01b039091169063bcaa0c5590614099906013906004016155bb565b602060405180830381865afa1580156140b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140da91906155d5565b6006549091506001600160a01b0383811691161461419457600680546001600160a01b0319166001600160a01b0384169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152839190631a33757d9061414e90600290600401615909565b6020604051808303816000875af115801561416d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141919190614cb9565b50505b6007546001600160a01b0382811691161461424b57600780546001600160a01b0319166001600160a01b0383169081179091556040517f1a33757d000000000000000000000000000000000000000000000000000000008152829190631a33757d9061420590600290600401615909565b6020604051808303816000875af1158015614224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142489190614cb9565b50505b60015460405163bcaa0c5560e01b81526000916001600160a01b03169063bcaa0c559061427d90600c906004016155bb565b602060405180830381865afa15801561429a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142be91906155d5565b90506001600160a01b038116156142d8576142d8816142e0565b61183461446e565b6001600160a01b038116614320576040517f05d8ce3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002546001600160a01b03166143335750565b6004546001600160a01b03166143d1576001600160a01b03811630146143cc576002546040517feb8646980000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301529091169063eb86469890602401600060405180830381600087803b1580156143b357600080fd5b505af11580156143c7573d6000803e3d6000fd5b505050505b61444c565b600480546040517f3a74bfd70000000000000000000000000000000000000000000000000000000081526001600160a01b0384811693820193909352911690633a74bfd790602401600060405180830381600087803b15801561443357600080fd5b505af1158015614447573d6000803e3d6000fd5b505050505b600480546001600160a01b0319166001600160a01b0392909216919091179055565b600180546040517ff2aac76c0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169163f2aac76c916144b791906004016155bb565b602060405180830381865afa1580156144d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144f891906155f2565b6001805491151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6040518060e00160405280600081526020016000815260200160006001600160a01b0316815260200161459e604051806080016040528060008152602001600061ffff168152602001600061ffff168152602001600081525090565b81526040805160a08101825260008082526020828101829052928201819052606082018190526080820152910190815260606020820152600060409091015290565b6001600160a01b03811681146130e257600080fd5b6000806040838503121561460857600080fd5b8235614613816145e0565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6007811061464757614647614621565b9052565b600681106130e2576130e2614621565b614666828251614637565b61ffff602082015116602083015260408101516146828161464b565b604083015260608181015160ff169083015260809081015163ffffffff16910152565b60005b838110156146c05781810151838201526020016146a8565b50506000910152565b600082825180855260208086019550808260051b84010181860160005b8481101561474b57601f1980878503018a528251604081516147078161464b565b86529086015186860182905280519186018290529060609061472e81838901858b016146a5565b9b87019b601f0190921694909401019250908301906001016146e6565b5090979650505050505050565b6020815281516020820152602082015160408201526001600160a01b0360408301511660608201526000606083015180516080840152602081015161ffff80821660a08601528060408401511660c08601525050606081015160e08401525060808301516147ca61010084018261465b565b5060a08301516101c0806101a08501526147e86101e08501836146c9565b915060c08501516147fc8286018215159052565b5090949350505050565b60008083601f84011261481857600080fd5b50813567ffffffffffffffff81111561483057600080fd5b6020830191508360208260051b850101111561484b57600080fd5b9250929050565b6000806000806040858703121561486857600080fd5b843567ffffffffffffffff8082111561488057600080fd5b61488c88838901614806565b909650945060208701359150808211156148a557600080fd5b506148b287828801614806565b95989497509550505050565b63ffffffff811681146130e257600080fd5b600080604083850312156148e357600080fd5b82356148ee816145e0565b915060208301356148fe816148be565b809150509250929050565b60006020828403121561491b57600080fd5b8135614926816145e0565b9392505050565b60008060006060848603121561494257600080fd5b833561494d816145e0565b9250602084013591506040840135614964816145e0565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561499857600080fd5b823567ffffffffffffffff808211156149b057600080fd5b818501915085601f8301126149c457600080fd5b8135818111156149d6576149d661496f565b8060051b604051601f19603f830116810181811085821117156149fb576149fb61496f565b604052918252848201925083810185019188831115614a1957600080fd5b938501935b82851015614a3757843584529385019392850192614a1e565b98975050505050505050565b600181811c90821680614a5757607f821691505b602082108103614a7757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b61ffff811681146130e257600080fd5b600060208284031215614ab557600080fd5b813561492681614a93565b8183526000602080850194508260005b85811015614afe578135614ae3816145e0565b6001600160a01b031687529582019590820190600101614ad0565b509495945050505050565b604081526000614b1d604083018688614ac0565b8281036020848101919091528482528591810160005b86811015614b5c578335614b4681614a93565b61ffff1682529282019290820190600101614b33565b5098975050505050505050565b803560038110614b7857600080fd5b919050565b600060208284031215614b8f57600080fd5b61492682614b69565b600381106130e2576130e2614621565b604081526000614bbc604083018688614ac0565b8281036020848101919091528482528591810160005b86811015614b5c57614be384614b69565b614bec81614b98565b82529282019290820190600101614bd2565b634e487b7160e01b600052601160045260246000fd5b63ffffffff818116838216019080821115614c3157614c31614bfe565b5092915050565b8181038181111561090e5761090e614bfe565b600060ff821660ff8103614c6157614c61614bfe565b60010192915050565b6000604082016001600160a01b038516835260206040602085015281855180845260608601915060208701935060005b8181101561474b57845160ff1683529383019391830191600101614c9a565b600060208284031215614ccb57600080fd5b5051919050565b60008151808452602080850194506020840160005b83811015614afe57815187529582019590820190600101614ce7565b6001600160a01b0383168152604060208201526000614d256040830184614cd2565b949350505050565b600082356101be19833603018112614d4457600080fd5b9190910192915050565b600781106130e257600080fd5b600681106130e257600080fd5b60ff811681146130e257600080fd5b6000813561090e81614d68565b6000813561090e816148be565b8135614d9c81614d4e565b60078110614dac57614dac614621565b815460ff821691508160ff1982161783556020840135614dcb81614a93565b62ffff008160081b16905080837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416171784556040850135614e0d81614d5b565b614e168161464b565b63ff0000008160181b168463ffffffff19851617831717855550505050614e78614e4260608401614d77565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1660209190911b64ff0000000016178255565b614eab614e8760808401614d84565b825468ffffffff0000000000191660289190911b68ffffffff000000000016178255565b5050565b6000808335601e19843603018112614ec657600080fd5b83018035915067ffffffffffffffff821115614ee157600080fd5b6020019150600581901b360382131561484b57600080fd5b60008235603e19833603018112614d4457600080fd5b808202811582820484141761090e5761090e614bfe565b5b81811015614eab5760008155600101614f27565b601f821115612a8657806000526020600020601f840160051c81016020851015614f625750805b611834601f850160051c830182614f26565b8135614f7f81614d5b565b614f888161464b565b60ff1982541660ff82168117835550506001808201602080850135601e19863603018112614fb557600080fd5b8501803567ffffffffffffffff811115614fce57600080fd5b8036038383011315614fdf57600080fd5b614ff381614fed8654614a43565b86614f3b565b6000601f821160018114615029576000831561501157508382018501355b600019600385901b1c1916600184901b178655615084565b600086815260209020601f19841690835b828110156150595786850188013582559387019390890190870161503a565b50848210156150785760001960f88660031b161c198785880101351681555b505060018360011b0186555b505050505050505050565b680100000000000000008311156150a8576150a861496f565b8054838255808410156151885760017f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80831683146150e9576150e9614bfe565b80861686146150fa576150fa614bfe565b5060008360005260206000208360011b81018760011b820191505b808210156151835782825583820161512d8154614a43565b801561517657601f8082116001811461514857868455615173565b60008481526020902061516483850160051c82018a8301614f26565b50600084815260208120818655555b50505b5050600282019150615115565b505050505b5060008181526020812083915b85811015611cfc576151b06151aa8487614ef9565b83614f74565b6020929092019160029190910190600101615195565b80151581146130e257600080fd5b6000813561090e816151c6565b8135815560208201356001820155600281016040830135615201816145e0565b6001600160a01b0381166001600160a01b031983541617825550506060820135600382015560048101608083013561523881614a93565b815460a085013561524881614a93565b63ffff00008160101b1661ffff841663ffffffff198416171784555050505060c0820135600582015561528160e0830160068301614d91565b61528f610180830183614eaf565b61529d81836007860161508f565b5050614eab6152af6101a084016151d4565b6008830160ff1981541660ff8315151681178255505050565b8082018082111561090e5761090e614bfe565b80356152e681614d4e565b6152f08382614637565b5060208101356152ff81614a93565b61ffff166020830152604081013561531681614d5b565b61531f8161464b565b6040830152606081013561533281614d68565b60ff1660608301526080810135615348816148be565b63ffffffff81166080840152505050565b6000808335601e1984360301811261537057600080fd5b830160208101925035905067ffffffffffffffff81111561539057600080fd5b8060051b360382131561484b57600080fd5b60008383855260208086019550808560051b8301018460005b8781101561474b57601f1980868503018a528235603e198936030181126153e157600080fd5b8801604081356153f081614d5b565b6153f98161464b565b86528187013536839003601e1901811261541257600080fd5b90910186810191903567ffffffffffffffff81111561543057600080fd5b80360383131561543f57600080fd5b818888015280828801526060915080838389013760008782018301529b87019b601f01909216909401019250908301906001016153bb565b8035614b78816151c6565b60006040808352615497604084018789614ac0565b602084820381860152818683528183019050818760051b840101886000805b8a8110156155a957601f1987850301855282356101be198d36030181126154db578283fd5b8c018035855286810135878601526101c0898201356154f9816145e0565b6001600160a01b0316868b01526060828101359087015260808083013561551f81614a93565b61ffff808216838a015260a0925082850135915061553c82614a93565b169087015260c0828101359087015260e061555b8188018285016152db565b5061018061556b81840184615359565b83838a015261557d848a0182846153a2565b93505050506101a0615590818401615477565b15159601959095525093850193918501916001016154b6565b50919c9b505050505050505050505050565b60208101604083106155cf576155cf614621565b91905290565b6000602082840312156155e757600080fd5b8151614926816145e0565b60006020828403121561560457600080fd5b8151614926816151c6565b60208101601583106155cf576155cf614621565b60006020828403121561563557600080fd5b8135614926816151c6565b8183526000602080850194508260005b85811015614afe578135615663816151c6565b151587529582019590820190600101615650565b6040815283604082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8511156156b057600080fd5b8460051b808760608501378201828103606090810160208501526156d79082018587615640565b979650505050505050565b6000826156ff57634e487b7160e01b600052601260045260246000fd5b500490565b604081526000615718604083018688614ac0565b82810360208401526156d7818587615640565b6000828254808552602080860195506005818360051b8501016000878152838120815b8681101561580757601f19888503018b52604060ff83541661576f8161464b565b808652506001808401828988015285815461578981614a43565b94890185905260609481851680156157a857600181146157c1576157ec565b60ff198316878c0152868215158d1b8c010193506157ec565b848a528c8a208a5b838110156157e45781548d82018a0152908701908e016157c9565b8c0188019450505b5050509d89019d96505050600292909201915060010161574e565b50919998505050505050505050565b60006101606001600160a01b038716835285546020840152600186015461ffff8082166040860152808260101c166060860152600288015460808601528654915061586760a0860160ff8416614637565b808260081c1660c08601525060ff8160181c166158838161464b565b60e0850152602081901c60ff1661010085015260281c63ffffffff1661012084015261014083018190526156d78184018561572b565b6001600160a01b03841681526060602082015260006158db6060830185614cd2565b82810360408401526158ed8185614cd2565b9695505050505050565b60008251614d448184602087016146a5565b602081016155cf83614b9856fea2646970667358221220eff9c7c53a7a3ba387864c86bdda7aff4f561426ac204da2677f149feb80931564736f6c63430008190033
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
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.