Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Guardians
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./libraries/GuardianTimeMath.sol"; import "./interfaces/IERC11554K.sol"; import "./interfaces/IFeesManager.sol"; import "./interfaces/IERC11554KController.sol"; /** * @dev Guardians management contract version 0.2.2 * Sets guardians parameters, fees, info * by guardians themselves and the protocol. */ contract Guardians is Initializable, OwnableUpgradeable { /// @dev Guardian Info struct. struct GuardianInfo { /// @notice Hashed physical address of a guardian. bytes32 addressHash; //0 /// @notice Logo of a guardian. string logo; //1 /// @notice Name of a guardian. string name; //2 /// @notice A guardian's redirect URI for future authentication flows. string redirect; //3 /// @notice Guardian's policy. string policy; //4 /// @notice Active status for a guardian bool isActive; //5 /// @notice Private status for a guardian. bool isPrivate; //6 } enum GuardianFeeRatePeriods { SECONDS, MINUTES, HOURS, DAYS } /// @dev Guardian class struct. struct GuardianClass { /// @notice Maximum insurance on-chain coverage. uint256 maximumCoverage; //0 /// @notice Minting fee. Stored scaled by 10^18. uint256 mintingFee; //1 /// @notice Redemption fee. Stored scaled by 10^18. uint256 redemptionFee; //2 /// @notice The base unit for the guardian fee rate. uint256 guardianFeeRatePeriod; //3 /// @notice Guardian fee rate per period. Stored scaled by 10^18. uint256 guardianFeeRate; //4 /// @notice Guardian fee rate historic minimum. uint256 guardianFeeRateMinimum; //5 /// @notice Last Guardian fee rate increase update timestamp. uint256 lastGuardianFeeRateIncrease; //6 /// @notice Is guardian class active. bool isActive; //7 /// @notice Guardian URI for metadata. string uri; //8 } uint256 public constant SECOND = 1; uint256 public constant MINUTE = 60; uint256 public constant HOUR = MINUTE * 60; uint256 public constant DAY = HOUR * 24; /// @notice Fee manager contract. IFeesManager public feesManager; /// @notice Controller contract. IERC11554KController public controller; /// @notice Percentage factor with 0.01% precision. For internal float calculations. uint256 public constant PERCENTAGE_FACTOR = 10000; /// @notice Minimum minting request fee. uint256 public minimumRequestFee; /// @notice Minimum time window for guardian fee rate increase. uint256 public guardianFeeSetWindow; /// @notice Maximum guardian fee rate percentage increase during single fee set, 0.01% precision. uint256 public maximumGuardianFeeSet; /// @notice Minimum storage time an item needs to have for transfers. uint256 public minStorageTime; /// @notice Is an address a 4K whitelisted guardian. mapping(address => bool) public isWhitelisted; /// @notice Metadata info about a guardian mapping(address => GuardianInfo) public guardianInfo; /// @notice Guardians whitelisted users for services. mapping(address => mapping(address => bool)) public guardianWhitelist; /// @notice To whom (if) guardian delegated functions to execute mapping(address => address) public delegated; /// @notice Guardian classes of a particular guardian. mapping(address => GuardianClass[]) public guardiansClasses; /// @notice How much items with id guardian keeps. /// guardian -> collection -> id -> amount mapping(address => mapping(IERC11554K => mapping(uint256 => uint256))) public stored; /// @notice At which guardian is each item stored. /// collection address -> item id -> guardian address mapping(IERC11554K => mapping(uint256 => address)) public whereItemStored; /// @notice In which guardian class is the item? (within the context of the guardian where the item is stored) /// collection address -> item id -> guardian class index mapping(IERC11554K => mapping(uint256 => uint256)) public itemGuardianClass; /// @notice Mapping from a token holder address to a collection to an item id, to the date until storage has been paid. mapping(address => mapping(IERC11554K => mapping(uint256 => uint256))) public guardianFeePaidUntil; /// @notice Mapping from a collection, to item id, to the date until storage has been paid (globally, collectively for all users). /// @dev DEPRECATED mapping(IERC11554K => mapping(uint256 => uint256)) public globalItemGuardianFeePaidUntil; /// @notice user -> collection -> item id -> num items in repossession /// @notice Number of items in a collection that a user has in repossession. mapping(address => mapping(IERC11554K => mapping(uint256 => uint256))) public inRepossession; /// @notice guardian => delegatee => true if guardian delegates some functions to delegatee. mapping(address => mapping(address => bool)) public delegatedAll; /// @notice guardian => collection => delegatee if guardian delegates some functions to delegatee. mapping(address => mapping(IERC11554K => address)) public delegatedCollection; /// @notice Version of the contract bytes32 public version; /// @dev Guardian has been added. event GuardianAdded(address indexed guardian, GuardianInfo newGuardianInfo); /// @dev Guardian has been removed. event GuardianRemoved(address indexed guardian); /// @dev Guardian has been modified event GuardianModified( address indexed guardian, uint8 fieldIndexModified, GuardianInfo newGuardianInfo ); /// @dev Guardian class has been added. event GuardianClassAdded( address indexed guardian, uint256 classID, GuardianClass newGuardianClass ); /// @dev Guardian class has been modified. event GuardianClassModified( address indexed guardian, uint256 classID, uint8 fieldIndexModified, GuardianClass newGuardianClass ); /// @dev Item has been stored by the guardian event ItemStored( address indexed guardian, uint256 classID, uint256 tokenId, IERC11554K collection ); /// @dev Item has been moved from one guardian to another event ItemMoved( address indexed fromGuardian, address indexed toGuardian, uint256 toGuardianClassId, uint256 tokenId, IERC11554K collection ); /// @dev Storage time has been purchased for an item. event StorageTimeAdded( uint256 indexed id, address indexed guardian, uint256 timeAmount, address beneficiary, IERC11554K collection ); /// @dev Item(s) have been set for repossession. event SetForRepossession( uint256 indexed id, IERC11554K indexed collection, address indexed guardian, uint256 amount ); /// @dev Guardian has been added - with metadata. event GuardianRegistered( address indexed guardian, GuardianInfo newGuardianInfo ); /// @dev Errors error GuardianNotWhitelisted(); error CallerNotController(); error NotCallersGuardianData(); error MinStorageTimeTooLow(); error TooManyReposessionItems(); error OldGuardianAvailable(); error NewGuardianUnavailable(); error ClassNotActive(); error NotGuardianOfItems(); error FreeStorageItemsCantBeRepossessed(); error GuardianFeePaidUntilStillInFuture(); error NoItemsToRepossess(); error MintingFeeTooLow(); error DifferentPeriodRequired(); error CollectionIsNotActiveOrLinked(); error GuardianClassFeeRateTooLow(); error GuardianFeeTooLow(); error BeneficiaryDoesNotOwnItem(); error GuardianDoesNotStoreItem(); error ItemNotYetMinted(); error GuardianFeeNotChangeableOnFreeStorageClass(); error GuardianFeeWindowHasntPassed(); error GuardianFeeRateLimitExceeded(); /** * @dev Only whitelisted guardian modifier. */ modifier onlyWhitelisted(address guardian) { if (!isWhitelisted[guardian]) { revert GuardianNotWhitelisted(); } _; } /** * @dev Only controller modifier. */ modifier onlyController() { if (_msgSender() != address(controller)) { revert CallerNotController(); } _; } /** * @dev Only controller modifier. */ modifier ifNotOwnerGuardianIsCaller(address guardian) { if (_msgSender() != owner()) { if (_msgSender() != guardian) { revert NotCallersGuardianData(); } } _; } /** * @notice Initialize Guardians contract. * @param minimumRequestFee_ The minimum mint request fee. * @param guardianFeeSetWindow_ The window of time in seconds within a guardian is allowed to increase a guardian fee rate. * @param maximumGuardianFeeSet_ The max percentage increase that a guardian can increase a guardian fee rate by. Numerator that generates percentage, over the PERCENTAGE_FACTOR. * @param feesManager_ Fees manager contract address. * @param controller_ Controller contract address. * @param version_ Version of contract */ function initialize( uint256 minimumRequestFee_, uint256 guardianFeeSetWindow_, uint256 maximumGuardianFeeSet_, IFeesManager feesManager_, IERC11554KController controller_, bytes32 version_ ) external initializer { __Ownable_init(); minimumRequestFee = minimumRequestFee_; guardianFeeSetWindow = guardianFeeSetWindow_; maximumGuardianFeeSet = maximumGuardianFeeSet_; minStorageTime = 7776000; // default 90 days feesManager = feesManager_; controller = controller_; version = version_; } /** * @notice Set controller. * * Requirements: * * 1) The caller must be a contract admin. * @param controller_ New address of controller contract. */ function setController( IERC11554KController controller_ ) external virtual onlyOwner { controller = controller_; } /** * @notice Set fees manager. * * Requirements: * * 1) The caller must be a contract admin. @param feesManager_ New address of fees manager contract. */ function setFeesManager( IFeesManager feesManager_ ) external virtual onlyOwner { feesManager = feesManager_; } /** * @notice Sets new min storage time. * * Requirements: * * 1) The caller must be a contract admin. * @param minStorageTime_ New minimum storage time that items require to have, in seconds. */ function setMinStorageTime( uint256 minStorageTime_ ) external virtual onlyOwner { if (minStorageTime_ == 0) { revert MinStorageTimeTooLow(); } minStorageTime = minStorageTime_; } /** * @notice Sets minimum mining fee. * * Requirements: * * 1) The caller must be a contract owner. * @param minimumRequestFee_ New minumum mint request fee. */ function setMinimumRequestFee( uint256 minimumRequestFee_ ) external onlyOwner { minimumRequestFee = minimumRequestFee_; } /** * @notice Sets maximum Guardian fee rate set percentage. * * Requirements: * * 1) The caller must be a contract owner. * @param maximumGuardianFeeSet_ New max percentage increase that a guardian can increase a guardian fee rate by. Numerator that generates percentage, over the PERCENTAGE_FACTOR */ function setMaximumGuardianFeeSet( uint256 maximumGuardianFeeSet_ ) external onlyOwner { maximumGuardianFeeSet = maximumGuardianFeeSet_; } /** * @notice Sets minimum Guardian fee. * * Requirements: * * 1) The caller must be a contract owner. * @param guardianFeeSetWindow_ New window of time in seconds within a guardian is allowed to increase a guardian fee rate */ function setGuardianFeeSetWindow( uint256 guardianFeeSetWindow_ ) external onlyOwner { guardianFeeSetWindow = guardianFeeSetWindow_; } /** * @notice Does a batch adding of storage for all the items passed. * @param collections Array of collections that contain the items for which guardian time will be purchased. * @param beneficiaries Array of addresses that will be receiving the purchased guardian time. * @param ids Array of item ids for which guardian time will be purchased. * @param guardianFeeAmounts Array of guardian fee inputs for purchasing guardian time. */ function batchAddStorageTime( IERC11554K[] calldata collections, address[] calldata beneficiaries, uint256[] calldata ids, uint256[] calldata guardianFeeAmounts ) external virtual { for (uint256 i = 0; i < ids.length; i++) { addStorageTime( collections[i], beneficiaries[i], ids[i], guardianFeeAmounts[i] ); } } /** * @dev Externally called store item function by controller. * @param collection Address of the collection that the item being stored belongs to. * @param mintAddress Address of entity receiving the token(s). * @param id Item id of the item being stored. * @param guardian Address of guardian the item will be stored in. * @param guardianClassIndex Index of the guardian class the item will be stored in. * @param guardianFeeAmount Amount of fee that is being paid to purchase guardian time. * @param numItems Number of items being stored * @param feePayer The address of the entity paying the guardian fee. */ function controllerStoreItem( IERC11554K collection, address mintAddress, uint256 id, address guardian, uint256 guardianClassIndex, uint256 guardianFeeAmount, uint256 numItems, address feePayer, IERC20Upgradeable paymentAsset ) external virtual onlyController { stored[guardian][collection][id] += numItems; whereItemStored[collection][id] = guardian; itemGuardianClass[collection][id] = guardianClassIndex; // Only needs to be done in non-free guardian classes if ( guardiansClasses[guardian][guardianClassIndex].guardianFeeRate > 0 ) { // Initialize paid until timelines on first ever mints if (guardianFeePaidUntil[mintAddress][collection][id] == 0) { guardianFeePaidUntil[mintAddress][collection][id] = block .timestamp; } { uint256 addedStorageTime = GuardianTimeMath .calculateAddedGuardianTime( guardianFeeAmount, guardiansClasses[guardian][guardianClassIndex] .guardianFeeRate, guardiansClasses[guardian][guardianClassIndex] .guardianFeeRatePeriod, numItems ); guardianFeePaidUntil[mintAddress][collection][ id ] += addedStorageTime; emit StorageTimeAdded( id, guardian, addedStorageTime, mintAddress, collection ); } feesManager.payGuardianFee( guardianFeeAmount, (guardiansClasses[guardian][guardianClassIndex] .guardianFeeRate * numItems) / getGuardianFeeRatePeriod(guardian, guardianClassIndex), guardian, guardianFeePaidUntil[mintAddress][collection][id], feePayer, paymentAsset ); emit ItemStored(guardian, guardianClassIndex, id, collection); } } /** * @dev Externally called take item out function by controller. * @param guardian Address of guardian the item is being stored in. * @param collection Address of the collection that the item being stored belongs to. * @param id Item id of the item being stored. * @param numItems Number of items that are being taken out of the guardian. * @param from Address of the entity requesting the redemption/removal of the item(s). */ function controllerTakeItemOut( address guardian, IERC11554K collection, uint256 id, uint256 numItems, address from ) external virtual onlyController { if (inRepossession[from][collection][id] >= numItems) { revert TooManyReposessionItems(); } uint256 guardianClassFeeRate = getGuardianFeeRate( guardian, itemGuardianClass[collection][id] ); uint256 guardianFeeRatePeriod = getGuardianFeeRatePeriod( guardian, itemGuardianClass[collection][id] ); // No refunds // uint256 previousPaidUntil = guardianFeePaidUntil[from][collection][id]; // uint256 guardianFeeRefundAmount; if (guardianClassFeeRate > 0) { // No refunds // guardianFeeRefundAmount = _shiftGuardianFeesOnTokenRedeem( from, collection, id, numItems, guardianClassFeeRate, guardianFeeRatePeriod ); } stored[guardian][collection][id] -= numItems; if (stored[guardian][collection][id] == 0) { whereItemStored[collection][id] = address(0); } // No refunds /* uint256 guardianClassFeeRateMin = getGuardianFeeRateMinimum(guardian, itemGuardianClass[collection][id]); if (guardianClassFeeRate > 0) { feesManager.refundGuardianFee( guardianFeeRefundAmount, (guardianClassFeeRateMin * numItems) / guardianFeeRatePeriod, guardian, previousPaidUntil, from, paymentAsset ); } */ } /** * @notice Moves items from inactive guardian to active guardian. Move ALL items, * in the case of semi-fungibles. Must pass a guardian classe for each item for the new guardian. * * Requirements: * * 1) The caller must be 4K. * 2) Old guardian must be inactive. * 3) New guardian must be active. * 4) Each class passed for each item for the new guardian must be active. * 5) Must only be used to move ALL items and have movement of guardian fees after moving ALL items. * @param collection Address of the collection that includes the items being moved. * @param ids Array of item ids being moved. * @param oldGuardian Address of the guardian items are being moved from. * @param newGuardian Address of the guardian items are being moved to. * @param newGuardianClassIndeces Array of the newGuardian's guardian class indices the items will be moved to. */ function moveItems( IERC11554K collection, uint256[] calldata ids, address oldGuardian, address newGuardian, uint256[] calldata newGuardianClassIndeces ) external virtual onlyOwner { if (isAvailable(oldGuardian)) { revert OldGuardianAvailable(); } if (!isAvailable(newGuardian)) { revert NewGuardianUnavailable(); } for (uint256 i = 0; i < ids.length; ++i) { if (!isClassActive(newGuardian, newGuardianClassIndeces[i])) { revert ClassNotActive(); } _moveSingleItem( collection, ids[i], oldGuardian, newGuardian, newGuardianClassIndeces[i] ); } } /** * @notice Copies all guardian classes from one guardian to another. * @dev If new guardian has no guardian classes before this, class indeces will be the same. If not, copies classes will have new indeces. * * @param oldGuardian Address of the guardian whose classes will be moved. * @param newGuardian Address of the guardian that will be receiving the classes. */ function copyGuardianClasses( address oldGuardian, address newGuardian ) external virtual onlyOwner { for (uint256 i = 0; i < guardiansClasses[oldGuardian].length; i++) { _copyGuardianClass(oldGuardian, newGuardian, i); } } /** * @notice Function for the guardian to set item(s) to be flagged for repossession. * @param collection Collection that contains the item to be repossessed. * @param itemId Id of item(s) being reposessed. * @param owner Current owner of the item(s). */ function setItemsToRepossessed( IERC11554K collection, uint256 itemId, address owner ) external { if (whereItemStored[collection][itemId] != _msgSender()) { revert NotGuardianOfItems(); } if (getGuardianFeeRateByCollectionItem(collection, itemId) == 0) { revert FreeStorageItemsCantBeRepossessed(); } if ( guardianFeePaidUntil[owner][collection][itemId] >= block.timestamp ) { revert GuardianFeePaidUntilStillInFuture(); } uint256 currAmount = IERC11554K(collection).balanceOf(owner, itemId); if (currAmount == 0) { revert NoItemsToRepossess(); } uint256 prevInReposession = inRepossession[owner][collection][itemId]; inRepossession[owner][collection][itemId] = currAmount; emit SetForRepossession( itemId, collection, _msgSender(), currAmount - prevInReposession ); } /** * @notice Sets activity mode for the guardian. Either active or not. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose activity mode will be set. * @param activity Boolean for guardian activity mode. */ function setActivity( address guardian, bool activity ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].isActive = activity; emit GuardianModified(guardian, 5, guardianInfo[guardian]); } /** * @notice Sets privacy mode for the guardian. Either public false or private true. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose privacy mode will be set. * @param privacy Boolean for guardian privacy mode. */ function setPrivacy( address guardian, bool privacy ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].isPrivate = privacy; emit GuardianModified(guardian, 4, guardianInfo[guardian]); } /** * @notice Sets logo for the guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian address of guardian whose logo will be set. * @param logo URI of logo for guardian. */ function setLogo( address guardian, string calldata logo ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].logo = logo; emit GuardianModified(guardian, 1, guardianInfo[guardian]); } /** * @notice Sets name for the guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose name will be set. * @param name Name of guardian. */ function setName( address guardian, string calldata name ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].name = name; emit GuardianModified(guardian, 2, guardianInfo[guardian]); } /** * @notice Sets physical address hash for the guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose physical address will be set. * @param physicalAddressHash Bytes hash of physical address of the guardian. */ function setPhysicalAddressHash( address guardian, bytes32 physicalAddressHash ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].addressHash = physicalAddressHash; emit GuardianModified(guardian, 0, guardianInfo[guardian]); } /** * @notice Sets policy for the guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose policy will be set. * @param policy Guardian policy. */ function setPolicy( address guardian, string calldata policy ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].policy = policy; emit GuardianModified(guardian, 4, guardianInfo[guardian]); } /** * @notice Sets redirects for the guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose redirect URI will be set. * @param redirect Redirect URI for guardian. */ function setRedirect( address guardian, string calldata redirect ) external onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardianInfo[guardian].redirect = redirect; emit GuardianModified(guardian, 3, guardianInfo[guardian]); } /** * @notice Adds or removes users addresses to guardian whitelist. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian whose users whitelist status will be modified. * @param users Array of user addresses whose whitelist status will be modified. * @param whitelistStatus Boolean for the whitelisted status of the users. */ function changeWhitelistUsersStatus( address guardian, address[] calldata users, bool whitelistStatus ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { for (uint256 i = 0; i < users.length; ++i) { guardianWhitelist[guardian][users[i]] = whitelistStatus; } } /** * @notice Removes guardian from the whitelist. * * Requirements: * * 1) The caller must be a contract owner. * @param guardian address of guardian who will be removed. */ function removeGuardian(address guardian) external virtual onlyOwner { isWhitelisted[guardian] = false; guardianInfo[guardian].isActive = false; emit GuardianRemoved(guardian); } /** * @notice Sets minting fee for guardian class by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or the owner. * @param guardian Address of the guardian whose guardian class minting fee will be modified. * @param classID Guardian's guardian class index whose minting fee will be modified. * @param mintingFee New minting fee. Minting fee must be passed as already scaled by 10^18 from real life value. */ function setGuardianClassMintingFee( address guardian, uint256 classID, uint256 mintingFee ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { if (mintingFee < minimumRequestFee) { revert MintingFeeTooLow(); } guardiansClasses[guardian][classID].mintingFee = mintingFee; emit GuardianClassModified( guardian, classID, 1, guardiansClasses[guardian][classID] ); } /** * @notice Sets redemption fee for guardian class by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or the owner * @param guardian Address of the guardian whose guardian class redemption fee will be modified. * @param classID Guardian's guardian class index whose redemption fee will be modified. * @param redemptionFee New redemption fee. Redemption fee must be passed as already scaled by 10^18 from real life value. */ function setGuardianClassRedemptionFee( address guardian, uint256 classID, uint256 redemptionFee ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardiansClasses[guardian][classID].redemptionFee = redemptionFee; emit GuardianClassModified( guardian, classID, 2, guardiansClasses[guardian][classID] ); } /** * @notice Sets Guardian fee rate for guardian class by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or the owner. * @param guardian Address of the guardian whose guardian class guardian fee rate will be modified. * @param classID Guardian's guardian class index whose guardian fee rate will be modified. * @param guardianFeeRate New guardian fee rate. Guardain fee rate must be passed as already scaled by 10^18 from real life value. */ function setGuardianClassGuardianFeeRate( address guardian, uint256 classID, uint256 guardianFeeRate ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { _setGuardianClassGuardianFeeRate( guardian, classID, guardianFeeRate, guardiansClasses[guardian][classID].guardianFeeRatePeriod ); } /** * @notice Sets Guardian fee rate and guardian fee rate period for guardian class by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or the owner. * @param guardian Address of the guardian whose guardian class guardian fee rate will be modified. * @param classID Guardian's guardian class index whose guardian fee rate will be modified. * @param guardianFeeRatePeriod New guardian fee rate period. * @param guardianFeeRate New guardian fee rate. Guardain fee rate must be passed as already scaled by 10^18 from real life value. */ function setGuardianClassGuardianFeePeriodAndRate( address guardian, uint256 classID, GuardianFeeRatePeriods guardianFeeRatePeriod, uint256 guardianFeeRate ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { uint256 newPeriodMultiple; if (guardianFeeRatePeriod == GuardianFeeRatePeriods.SECONDS) { newPeriodMultiple = SECOND; } else if (guardianFeeRatePeriod == GuardianFeeRatePeriods.MINUTES) { newPeriodMultiple = MINUTE; } else if (guardianFeeRatePeriod == GuardianFeeRatePeriods.HOURS) { newPeriodMultiple = HOUR; } else if (guardianFeeRatePeriod == GuardianFeeRatePeriods.DAYS) { newPeriodMultiple = DAY; } if ( guardiansClasses[guardian][classID].guardianFeeRatePeriod == newPeriodMultiple ) { revert DifferentPeriodRequired(); } _setGuardianClassGuardianFeeRate( guardian, classID, guardianFeeRate, newPeriodMultiple ); guardiansClasses[guardian][classID] .guardianFeeRatePeriod = newPeriodMultiple; emit GuardianClassModified( guardian, classID, 3, guardiansClasses[guardian][classID] ); } /** * @notice Sets URI for guardian class by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or owner. * @param guardian Address of the guardian whose guardian class URI will be modified. * @param classID Guardian's guardian class index whose class URI will be modified. * @param uri New URI. */ function setGuardianClassURI( address guardian, uint256 classID, string calldata uri ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardiansClasses[guardian][classID].uri = uri; emit GuardianClassModified( guardian, classID, 8, guardiansClasses[guardian][classID] ); } /** * @notice Sets guardian class as active or not active by guardian or owner * * Requirements: * * 1) The caller must be a whitelisted guardian or owner. * @param guardian Address of the guardian whose guardian class active status will be modified. * @param classID Guardian's guardian class index whose guardian class active status will be modified. * @param activeStatus New guardian class active status. */ function setGuardianClassActiveStatus( address guardian, uint256 classID, bool activeStatus ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardiansClasses[guardian][classID].isActive = activeStatus; emit GuardianClassModified( guardian, classID, 7, guardiansClasses[guardian][classID] ); } /** * @notice Sets maximum insurance coverage for guardian class by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian. * @param guardian Address of the guardian whose guardian class maximum coverage will be modified. * @param classID Guardian's guardian class index whose guardian class maximum coverage will be modified. * @param maximumCoverage New guardian class maximum coverage. */ function setGuardianClassMaximumCoverage( address guardian, uint256 classID, uint256 maximumCoverage ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) { guardiansClasses[guardian][classID].maximumCoverage = maximumCoverage; emit GuardianClassModified( guardian, classID, 0, guardiansClasses[guardian][classID] ); } /** * @dev Sets the version of the contract. * @param version_ New version of contract. */ function setVersion(bytes32 version_) external virtual onlyOwner { version = version_; } /** * @dev Externally called store item function by controller to update Guardian fees on token transfer. Complex logic needed for semi-fungibles. * @param from Address of entity sending token(s). * @param to Address of entity receiving token(s). * @param id Token id of token(s) being sent. * @param amount Amount of tokens being sent. */ function shiftGuardianFeesOnTokenMove( address from, address to, uint256 id, uint256 amount ) external virtual { if ( !controller.isActiveCollection(_msgSender()) || !controller.isLinkedCollection(_msgSender()) ) { revert CollectionIsNotActiveOrLinked(); } IERC11554K collection = IERC11554K(_msgSender()); uint256 guardianClassFeeRate = getGuardianFeeRateByCollectionItem( collection, id ); uint256 guardianClassFeeRatePeriod = getGuardianFeeRatePeriodByCollectionItem( collection, id ); uint256 guardianFeeShiftAmount = GuardianTimeMath .calculateRemainingFeeAmount( guardianFeePaidUntil[from][collection][id], guardianClassFeeRate, guardianClassFeeRatePeriod, amount ); uint256 remainingFeeAmountFrom = GuardianTimeMath .calculateRemainingFeeAmount( guardianFeePaidUntil[from][collection][id], guardianClassFeeRate, guardianClassFeeRatePeriod, collection.balanceOf(from, id) ); uint256 remainingFeeAmountTo = GuardianTimeMath .calculateRemainingFeeAmount( guardianFeePaidUntil[to][collection][id], guardianClassFeeRate, guardianClassFeeRatePeriod, collection.balanceOf(to, id) ); // Recalculate the remaining time with new params for FROM uint256 newAmountFrom = collection.balanceOf(from, id) - amount; if (newAmountFrom == 0) { guardianFeePaidUntil[from][collection][id] = 0; //default } else { guardianFeePaidUntil[from][collection][id] = block.timestamp + GuardianTimeMath.calculateAddedGuardianTime( remainingFeeAmountFrom - guardianFeeShiftAmount, guardianClassFeeRate, guardianClassFeeRatePeriod, newAmountFrom ); } // Recalculate the remaining time with new params for TO uint256 newAmountTo = collection.balanceOf(to, id) + amount; guardianFeePaidUntil[to][collection][id] = block.timestamp + GuardianTimeMath.calculateAddedGuardianTime( remainingFeeAmountTo + guardianFeeShiftAmount, guardianClassFeeRate, guardianClassFeeRatePeriod, newAmountTo ); } /** * @notice Adds guardian class to guardian by guardian. * * Requirements: * * 1) The caller must be a whitelisted guardian or contract owner. * @param guardian Address of guardian who is adding a new class. * @param maximumCoverage Max coverage of new guardian class. * @param mintingFee Minting fee of new guardian class. Minting fee must be passed as already scaled by 10^18 from real life value. * @param redemptionFee Redemption fee of new guardian class. Redemption fee must be passed as already scaled by 10^18 from real life value. * @param guardianFeeRate Guardian fee rate of new guardian class. Guardian fee rate must be passed as already scaled by 10^18 from real life value. * @param guardianFeeRatePeriod The size of the period unit for the guardian fee rate: per second, minute, hour, or day. */ function addGuardianClass( address guardian, uint256 maximumCoverage, uint256 mintingFee, uint256 redemptionFee, uint256 guardianFeeRate, GuardianFeeRatePeriods guardianFeeRatePeriod, string calldata uri ) external virtual onlyWhitelisted(guardian) ifNotOwnerGuardianIsCaller(guardian) returns (uint256 classID) { classID = _addGuardianClass( guardian, maximumCoverage, mintingFee, redemptionFee, guardianFeeRate, guardianFeeRatePeriod, uri ); } /** * @notice Registers guardian. * * Requirements: * * 1) The caller must be a contract owner. * @param guardian Address of the new guardian. * @param name Name of new guardian. * @param logo URI of new guardian logo. * @param policy Policy of new guardian. * @param redirect Redirect URI of new guardian. * @param physicalAddressHash physical address hash of new guardian. * @param privacy Boolean - is the new guardian private or not. */ function registerGuardian( address guardian, string calldata name, string calldata logo, string calldata policy, string calldata redirect, bytes32 physicalAddressHash, bool privacy ) external virtual { guardianInfo[guardian].isActive = true; guardianInfo[guardian].name = name; guardianInfo[guardian].logo = logo; guardianInfo[guardian].policy = policy; guardianInfo[guardian].isPrivate = privacy; guardianInfo[guardian].redirect = redirect; guardianInfo[guardian].addressHash = physicalAddressHash; addGuardian(guardian); emit GuardianRegistered(guardian, guardianInfo[guardian]); } /** * @notice Delegates whole minting/redemption for all or single collection to `delegatee` * @param delegatee Address to which the calling guardian will delegate to. * @param collection If not zero address, then delegates processes only for this collection. */ function delegate( address delegatee, IERC11554K collection ) external virtual onlyWhitelisted(_msgSender()) { if (address(collection) == address(0)) { delegatedAll[_msgSender()][delegatee] = true; } else { delegatedCollection[_msgSender()][collection] = delegatee; } } /** * @notice Undelegates whole minting/redemption for all or single collection from `delegatee` * @param delegatee Address to which the calling guardian will undelegate from. * @param collection If not zero address, then undelegates processes only for this collection. */ function undelegate( address delegatee, IERC11554K collection ) external virtual onlyWhitelisted(_msgSender()) { if (address(collection) == address(0)) { delegatedAll[_msgSender()][delegatee] = false; } else { delegatedCollection[_msgSender()][collection] = address(0); } } /** * @notice Queries if the amount of guardian fee provided purchases the minimum guardian time for a particular guardian class. * @param guardianFeeAmount the amount of guardian fee being queried. * @param numItems Number of total items the guardian would be storing. * @param guardian Address of the guardian that would be doing the storing. * @param guardianClassIndex Index of guardian class that would be doing the storing. */ function isFeeAboveMinimum( uint256 guardianFeeAmount, uint256 numItems, address guardian, uint256 guardianClassIndex ) external view virtual returns (bool) { uint256 guardianClassFeeRate = getGuardianFeeRate( guardian, guardianClassIndex ); uint256 guardianFeeRatePeriod = getGuardianFeeRatePeriod( guardian, guardianClassIndex ); if (guardianClassFeeRate == 0) { revert GuardianClassFeeRateTooLow(); } return minStorageTime <= GuardianTimeMath.calculateAddedGuardianTime( guardianFeeAmount, guardianClassFeeRate, guardianFeeRatePeriod, numItems ); } /** * @notice Returns guardian class redemption fee. * @param guardian Address of guardian whose guardian class is being queried. * @param classID Guardian's guardian class index being queried. * @return redemptionFee Guardian class's redemption fee. Returns scaled by 10^18 real life value. */ function getRedemptionFee( address guardian, uint256 classID ) external view virtual returns (uint256) { return guardiansClasses[guardian][classID].redemptionFee; } /** * @notice Returns guardian class minting fee. * @param guardian Address of guardian whose guardian class is being queried. * @param classID Guardian's guardian class index being queried. * @return mintingFee Guardian class's minting fee. Returns scaled by 10^18 real life value. */ function getMintingFee( address guardian, uint256 classID ) external view virtual returns (uint256) { return guardiansClasses[guardian][classID].mintingFee; } /** * @notice Returns guardian classes number. * @param guardian Address of guardian whose guardian classes are being queried. * @return count How many guardian classes the guardian has. */ function guardianClassesCount( address guardian ) external view virtual returns (uint256) { return guardiansClasses[guardian].length; } /** * @notice Checks if delegator delegated collection handling to delegatee. * @param collection Delegator guardian address. * @param delegatee Delegatee address. * @param collection Collection address. * @return true if delegated, false otherwise. */ function isDelegated( address delegator, address delegatee, IERC11554K collection ) external view virtual returns (bool) { return delegatedCollection[delegator][collection] == delegatee || delegatedAll[delegator][delegatee]; } /** * @notice Adds guardian to the whitelist. * * Requirements: * * 1) The caller must be a contract owner. * @param guardian Address of the new guardian. */ function addGuardian(address guardian) public virtual onlyOwner { isWhitelisted[guardian] = true; guardianInfo[guardian].isActive = true; emit GuardianAdded(guardian, guardianInfo[guardian]); } /** * @notice Anyone can add Guardian fees to a guardian holding an item. * @param collection Address of the collection the item belongs to. * @param beneficiary The address of the holder of the item. * @param itemId Id of the item. * @param guardianFeeAmount The amount of guardian fee being paid. */ function addStorageTime( IERC11554K collection, address beneficiary, uint256 itemId, uint256 guardianFeeAmount ) public virtual { uint256 currAmount = collection.balanceOf(beneficiary, itemId); address guardian = whereItemStored[collection][itemId]; uint256 guardianClassIndex = itemGuardianClass[collection][itemId]; uint256 guardianClassFeeRate = getGuardianFeeRate( guardian, guardianClassIndex ); if (guardianClassFeeRate == 0) { revert GuardianClassFeeRateTooLow(); } if (guardianFeeAmount == 0) { revert GuardianFeeTooLow(); } if (currAmount == 0) { revert BeneficiaryDoesNotOwnItem(); } if (guardian == address(0)) { revert GuardianDoesNotStoreItem(); } { uint256 addedStorageTime = GuardianTimeMath .calculateAddedGuardianTime( guardianFeeAmount, guardianClassFeeRate, getGuardianFeeRatePeriod(guardian, guardianClassIndex), currAmount ); guardianFeePaidUntil[beneficiary][collection][ itemId ] += addedStorageTime; emit StorageTimeAdded( itemId, guardian, addedStorageTime, beneficiary, collection ); } feesManager.payGuardianFee( guardianFeeAmount, (guardianClassFeeRate * currAmount) / getGuardianFeeRatePeriod(guardian, guardianClassIndex), guardian, guardianFeePaidUntil[beneficiary][collection][itemId], _msgSender(), controller.paymentToken() ); } /** * @notice Returns guardian class guardian fee rate of the stored item in collection with itemId. * @param collection Address of the collection where the item being queried belongs to. * @param itemId Item id of item whose guardian fee rate is being queried. * @return guardianFeeRate Fee rate of the item being queried (of guardian class it's in). Returns scaled by 10^18 real life value. */ function getGuardianFeeRateByCollectionItem( IERC11554K collection, uint256 itemId ) public view virtual returns (uint256) { if (collection.totalSupply(itemId) == 0) { revert ItemNotYetMinted(); } return guardiansClasses[whereItemStored[collection][itemId]][ itemGuardianClass[collection][itemId] ].guardianFeeRate; } /** * @notice Returns guardian class guardian fee rate period size of the stored item in collection with itemId. * @param collection Address of the collection where the item being queried belongs to. * @param itemId Item id of item whose guardian fee rate is being queried. * @return guardianFeeRatePeriod Size of the item being queried (of guardian class it's in). */ function getGuardianFeeRatePeriodByCollectionItem( IERC11554K collection, uint256 itemId ) public view virtual returns (uint256) { if (collection.totalSupply(itemId) == 0) { revert ItemNotYetMinted(); } return guardiansClasses[whereItemStored[collection][itemId]][ itemGuardianClass[collection][itemId] ].guardianFeeRatePeriod; } /** * @notice Returns true if the guardian is active and whitelisted. * @param guardian Address of guardian whose guardian class is being queried. * @return boolean Is the guardian active and whitelisted. */ function isAvailable(address guardian) public view returns (bool) { return isWhitelisted[guardian] && guardianInfo[guardian].isActive; } /** * @notice Returns guardian class classID guardian fee rate. * @param guardian Address of guardian whose guardian class is being queried. * @param classID Guardian's class index for class being queried. * @return guardianFeeRate The guardian class guardian fee rate. Returns scaled by 10^18 real life value. */ function getGuardianFeeRate( address guardian, uint256 classID ) public view virtual returns (uint256) { return guardiansClasses[guardian][classID].guardianFeeRate; } /** * @notice Returns guardian class classID guardian fee rate period size. * @param guardian Address of guardian whose guardian class is being queried. * @param classID Guardian's class index for class being queried. * @return guardianFeeRatePeriod The unit of time for the guardian fee rate. */ function getGuardianFeeRatePeriod( address guardian, uint256 classID ) public view virtual returns (uint256) { return guardiansClasses[guardian][classID].guardianFeeRatePeriod; } /** * @notice Returns guardian class classID activity true/false. * @param guardian Address of guardian whose guardian class is being queried. * @param classID Guardian's class index for class being queried. * @return activeStatus Boolean - is the class active or not. */ function isClassActive( address guardian, uint256 classID ) public view virtual returns (bool) { return guardiansClasses[guardian][classID].isActive; } /** * @dev Internal call, adds guardian class. */ function _addGuardianClass( address guardian, uint256 maximumCoverage, uint256 mintingFee, uint256 redemptionFee, uint256 guardianFeeRate, GuardianFeeRatePeriods guardianFeeRatePeriod, string calldata uri ) internal virtual returns (uint256 classID) { classID = guardiansClasses[guardian].length; uint256 periodMultiple; if (guardianFeeRatePeriod == GuardianFeeRatePeriods.SECONDS) { periodMultiple = SECOND; } else if (guardianFeeRatePeriod == GuardianFeeRatePeriods.MINUTES) { periodMultiple = MINUTE; } else if (guardianFeeRatePeriod == GuardianFeeRatePeriods.HOURS) { periodMultiple = HOUR; } else if (guardianFeeRatePeriod == GuardianFeeRatePeriods.DAYS) { periodMultiple = DAY; } guardiansClasses[guardian].push( GuardianClass( maximumCoverage, mintingFee, redemptionFee, periodMultiple, guardianFeeRate, guardianFeeRate, block.timestamp, true, uri ) ); emit GuardianClassAdded( guardian, classID, guardiansClasses[guardian][classID] ); } /** * @dev Internal call, copies an ENTIRE guardian class from one guardian to another. Note: same data but DIFFERENT index. */ function _copyGuardianClass( address oldGuardian, address newGuardian, uint256 oldGuardianClassIndex ) internal returns (uint256 classID) { classID = guardiansClasses[newGuardian].length; guardiansClasses[newGuardian].push( GuardianClass( guardiansClasses[oldGuardian][oldGuardianClassIndex] .maximumCoverage, guardiansClasses[oldGuardian][oldGuardianClassIndex].mintingFee, guardiansClasses[oldGuardian][oldGuardianClassIndex] .redemptionFee, guardiansClasses[oldGuardian][oldGuardianClassIndex] .guardianFeeRatePeriod, guardiansClasses[oldGuardian][oldGuardianClassIndex] .guardianFeeRate, guardiansClasses[oldGuardian][oldGuardianClassIndex] .guardianFeeRateMinimum, guardiansClasses[oldGuardian][oldGuardianClassIndex] .lastGuardianFeeRateIncrease, guardiansClasses[oldGuardian][oldGuardianClassIndex].isActive, guardiansClasses[oldGuardian][oldGuardianClassIndex].uri ) ); emit GuardianClassAdded( newGuardian, classID, guardiansClasses[newGuardian][classID] ); } /** * @dev Internal call, sets a new guardian class guardian fee rate, with several checks. Compensates for a different period multiple */ function _setGuardianClassGuardianFeeRate( address guardian, uint256 classID, uint256 guardianFeeRate, uint256 newPeriodMultiple ) internal virtual { if (guardianFeeRate == 0) { revert GuardianClassFeeRateTooLow(); } if (guardiansClasses[guardian][classID].guardianFeeRate == 0) { revert GuardianFeeNotChangeableOnFreeStorageClass(); } uint256 currentPeriodMultiple = guardiansClasses[guardian][classID] .guardianFeeRatePeriod; if ( (guardianFeeRate / newPeriodMultiple) > (guardiansClasses[guardian][classID].guardianFeeRate / currentPeriodMultiple) ) { if ( block.timestamp < guardiansClasses[guardian][classID] .lastGuardianFeeRateIncrease + guardianFeeSetWindow ) { revert GuardianFeeWindowHasntPassed(); } if ( (guardianFeeRate / newPeriodMultiple) > (guardiansClasses[guardian][classID].guardianFeeRate * maximumGuardianFeeSet) / (currentPeriodMultiple * PERCENTAGE_FACTOR) ) { revert GuardianFeeRateLimitExceeded(); } guardiansClasses[guardian][classID] .lastGuardianFeeRateIncrease = block.timestamp; } guardiansClasses[guardian][classID].guardianFeeRate = guardianFeeRate; if ( (guardianFeeRate / newPeriodMultiple) < (guardiansClasses[guardian][classID].guardianFeeRateMinimum / currentPeriodMultiple) ) { guardiansClasses[guardian][classID] .guardianFeeRateMinimum = guardianFeeRate; } emit GuardianClassModified( guardian, classID, 4, guardiansClasses[guardian][classID] ); } /** * @dev Internal call that is done on each item token redeem to * relaculate paid storage time, guardian fees. */ function _shiftGuardianFeesOnTokenRedeem( address from, IERC11554K collection, uint256 id, uint256 redeemAmount, uint256 guardianClassFeeRate, uint256 guardianFeeRatePeriod ) internal virtual returns (uint256) { // Recalculate the remaining time with new params uint256 bal = IERC11554K(collection).balanceOf(from, id); // Total fee that remains uint256 remainingFeeAmount = GuardianTimeMath .calculateRemainingFeeAmount( guardianFeePaidUntil[from][collection][id], guardianClassFeeRate, guardianFeeRatePeriod, bal ); // Portion of fee we're giving back, for refund. uint256 guardianFeeRefundAmount = GuardianTimeMath .calculateRemainingFeeAmount( guardianFeePaidUntil[from][collection][id], guardianClassFeeRate, guardianFeeRatePeriod, redeemAmount ); if (bal - redeemAmount == 0) { guardianFeePaidUntil[from][collection][id] = 0; //back to default,0 } else { uint256 recalculatedTime = GuardianTimeMath .calculateAddedGuardianTime( remainingFeeAmount - guardianFeeRefundAmount, guardianClassFeeRate, guardianFeeRatePeriod, bal - redeemAmount ); guardianFeePaidUntil[from][collection][id] = block.timestamp + recalculatedTime; } return guardianFeeRefundAmount; } function _moveSingleItem( IERC11554K collection, uint256 itemId, address oldGuardian, address newGuardian, uint256 newGuardianClassIndex ) internal virtual { uint256 amount = stored[oldGuardian][collection][itemId]; stored[oldGuardian][collection][itemId] = 0; stored[newGuardian][collection][itemId] += amount; whereItemStored[collection][itemId] = newGuardian; itemGuardianClass[collection][itemId] = newGuardianClassIndex; emit ItemMoved( oldGuardian, newGuardian, newGuardianClassIndex, itemId, collection ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "./IGuardians.sol"; /** * @dev {IERC11554K} interface: */ interface IERC11554K { function controllerMint( address mintAddress, uint256 tokenId, uint256 amount ) external; function controllerBurn( address burnAddress, uint256 tokenId, uint256 amount ) external; function setGuardians(IGuardians guardians_) external; function setURI(string calldata newuri) external; function setCollectionURI(string calldata collectionURI_) external; function setVerificationStatus(bool _isVerified) external; function setGlobalRoyalty(address receiver, uint96 feeNumerator) external; function owner() external view returns (address); function balanceOf( address user, uint256 item ) external view returns (uint256); function royaltyInfo( uint256 _tokenId, uint256 _salePrice ) external view returns (address, uint256); function totalSupply(uint256 _tokenId) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "./IERC11554K.sol"; import "./IGuardians.sol"; /** * @dev {IERC11554KController} interface: */ interface IERC11554KController { /// @dev Batch minting request data structure. struct BatchRequestMintData { /// @dev Collection address. IERC11554K collection; /// @dev Item id. uint256 id; /// @dev Guardian address. address guardianAddress; /// @dev Amount to mint. uint256 amount; /// @dev Service fee to guardian. uint256 serviceFee; /// @dev Is item supply expandable. bool isExpandable; /// @dev Recipient address. address mintAddress; /// @dev Guardian class index. uint256 guardianClassIndex; /// @dev Guardian fee amount to pay. uint256 guardianFeeAmount; } function requestMint( IERC11554K collection, uint256 id, address guardian, uint256 amount, uint256 serviceFee, bool expandable, address mintAddress, uint256 guardianClassIndex, uint256 guardianFeeAmount ) external returns (uint256); function mint(IERC11554K collection, uint256 id) external; function owner() external returns (address); function originators( address collection, uint256 tokenId ) external returns (address); function isActiveCollection(address collection) external returns (bool); function isLinkedCollection(address collection) external returns (bool); function paymentToken() external returns (IERC20Upgradeable); function maxMintPeriod() external returns (uint256); function remediationBurn( IERC11554K collection, address owner, uint256 id, uint256 amount ) external; function setMaxMintPeriod(uint256 maxMintPeriod_) external; function setRemediator(address _remediator) external; function setCollectionFee(uint256 collectionFee_) external; function setBeneficiary(address beneficiary_) external; function setGuardians(IGuardians guardians_) external; function setPaymentToken(IERC20Upgradeable paymentToken_) external; function transferOwnership(address newOwner) external; function setVersion(bytes32 version_) external; function guardians() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "./IERC11554K.sol"; import "./IGuardians.sol"; import "./IERC11554KController.sol"; /** * @dev {IFeesManager} interface: */ interface IFeesManager { function receiveFees( IERC11554K erc11554k, uint256 id, IERC20Upgradeable asset, uint256 _salePrice ) external; function calculateTotalFee( IERC11554K erc11554k, uint256 id, uint256 _salePrice ) external returns (uint256); function payGuardianFee( uint256 guardianFeeAmount, uint256 guardianClassFeeRateMultiplied, address guardian, uint256 storagePaidUntil, address payer, IERC20Upgradeable paymentAsset ) external; function refundGuardianFee( uint256 guardianFeeAmount, uint256 guardianClassFeeRateMultiplied, address guardian, uint256 storagePaidUntil, address recipient, IERC20Upgradeable paymentAsset ) external; function moveFeesBetweenGuardians( address guardianFrom, address guardianTo, IERC20Upgradeable asset ) external; function setGuardians(IGuardians guardians_) external; function setController(IERC11554KController controller_) external; function setGlobalTradingFee(uint256 globalTradingFee_) external; function setTradingFeeSplit( uint256 protocolSplit, uint256 guardianSplit ) external; function setExchange(address exchange_) external; function setVersion(bytes32 version_) external; function transferOwnership(address newOwner) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "./IERC11554K.sol"; import "./IERC11554KController.sol"; import "./IFeesManager.sol"; /** * @dev {IGuardians} interface: */ interface IGuardians { enum GuardianFeeRatePeriods { SECONDS, MINUTES, HOURS, DAYS } function controllerStoreItem( IERC11554K collection, address mintAddress, uint256 id, address guardian, uint256 guardianClassIndex, uint256 guardianFeeAmount, uint256 numItems, address feePayer, IERC20Upgradeable paymentAsset ) external; function controllerTakeItemOut( address guardian, IERC11554K collection, uint256 id, uint256 numItems, address from ) external; function shiftGuardianFeesOnTokenMove( address from, address to, uint256 id, uint256 amount ) external; function setController(IERC11554KController controller_) external; function setFeesManager(IFeesManager feesManager_) external; function setMinStorageTime(uint256 minStorageTime_) external; function setMinimumRequestFee(uint256 minimumRequestFee_) external; function setMaximumGuardianFeeSet(uint256 maximumGuardianFeeSet_) external; function setGuardianFeeSetWindow(uint256 guardianFeeSetWindow_) external; function moveItems( IERC11554K collection, uint256[] calldata ids, address oldGuardian, address newGuardian, uint256[] calldata newGuardianClassIndeces ) external; function copyGuardianClasses( address oldGuardian, address newGuardian ) external; function setActivity(address guardian, bool activity) external; function setPrivacy(address guardian, bool privacy) external; function setLogo(address guardian, string calldata logo) external; function setName(address guardian, string calldata name) external; function setPhysicalAddressHash( address guardian, bytes32 physicalAddressHash ) external; function setPolicy(address guardian, string calldata policy) external; function setRedirect(address guardian, string calldata redirect) external; function changeWhitelistUsersStatus( address guardian, address[] calldata users, bool whitelistStatus ) external; function removeGuardian(address guardian) external; function setGuardianClassMintingFee( address guardian, uint256 classID, uint256 mintingFee ) external; function setGuardianClassRedemptionFee( address guardian, uint256 classID, uint256 redemptionFee ) external; function setGuardianClassGuardianFeeRate( address guardian, uint256 classID, uint256 guardianFeeRate ) external; function setGuardianClassGuardianFeePeriodAndRate( address guardian, uint256 classID, GuardianFeeRatePeriods guardianFeeRatePeriod, uint256 guardianFeeRate ) external; function setGuardianClassURI( address guardian, uint256 classID, string calldata uri ) external; function setGuardianClassActiveStatus( address guardian, uint256 classID, bool activeStatus ) external; function setGuardianClassMaximumCoverage( address guardian, uint256 classID, uint256 maximumCoverage ) external; function addGuardianClass( address guardian, uint256 maximumCoverage, uint256 mintingFee, uint256 redemptionFee, uint256 guardianFeeRate, GuardianFeeRatePeriods guardianFeeRatePeriod, string calldata uri ) external; function registerGuardian( address guardian, string calldata name, string calldata logo, string calldata policy, string calldata redirect, bytes32 physicalAddressHash, bool privacy ) external; function transferOwnership(address newOwner) external; function setVersion(bytes32 version_) external; function isAvailable(address guardian) external view returns (bool); function guardianInfo( address guardian ) external view returns ( bytes32, string memory, string memory, string memory, string memory, bool, bool ); function guardianWhitelist( address guardian, address user ) external view returns (bool); function delegated(address guardian) external view returns (address); function getRedemptionFee( address guardian, uint256 classID ) external view returns (uint256); function getMintingFee( address guardian, uint256 classID ) external view returns (uint256); function isClassActive( address guardian, uint256 classID ) external view returns (bool); function minStorageTime() external view returns (uint256); function feesManager() external view returns (address); function stored( address guardian, IERC11554K collection, uint256 id ) external view returns (uint256); function whereItemStored( IERC11554K collection, uint256 id ) external view returns (address); function itemGuardianClass( IERC11554K collection, uint256 id ) external view returns (uint256); function guardianFeePaidUntil( address user, address collection, uint256 id ) external view returns (uint256); function isFeeAboveMinimum( uint256 guardianFeeAmount, uint256 numItems, address guardian, uint256 guardianClassIndex ) external view returns (bool); function getGuardianFeeRateByCollectionItem( IERC11554K collection, uint256 itemId ) external view returns (uint256); function getGuardianFeeRate( address guardian, uint256 guardianClassIndex ) external view returns (uint256); function isWhitelisted(address guardian) external view returns (bool); function inRepossession( address user, IERC11554K collection, uint256 id ) external view returns (uint256); function isDelegated( address guardian, address delegatee, IERC11554K collection ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @dev GuardianTimeMath library. Provides support for converting between guardian fees and purchased storage time */ library GuardianTimeMath { /** * @dev Calculates the fee amount associated with the items * scaledByNumItems based on currGuardianFeePaidUntil guardianClassFeeRate * (scaled by the number being moved, for semi-fungibles). * @param currGuardianFeePaidUntil a timestamp that describes until when storage has been paid. * @param guardianClassFeeRate a guardian's guardian fee rate. Amount per second. * @param scaledByNumItems the number of items that are being stored by a guardian at the time of the query. * @return the remaining amount of guardian fee that is left within the `currGuardianFeePaidUntil` at the `guardianClassFeeRate` rate for `scaledByNumItems` items */ function calculateRemainingFeeAmount( uint256 currGuardianFeePaidUntil, uint256 guardianClassFeeRate, uint256 guardianFeeRatePeriod, uint256 scaledByNumItems ) internal view returns (uint256) { if (currGuardianFeePaidUntil <= block.timestamp) { return 0; } else { return ((((currGuardianFeePaidUntil - block.timestamp) * guardianClassFeeRate) * scaledByNumItems) / guardianFeeRatePeriod); } } /** * @dev Calculates added guardian storage time based on * guardianFeePaid guardianClassFeeRate and numItems * (scaled by the number being moved, for semi-fungibles). * @param guardianFeePaid the amount of guardian fee that is being paid. * @param guardianClassFeeRate a guardian's guardian fee rate. Amount per time period. * @param guardianFeeRatePeriod the size of the period used in the guardian fee rate. * @param numItems the number of items that are being stored by a guardian at the time of the query. * @return the amount of guardian time that can be purchased from `guardianFeePaid` fee amount at the `guardianClassFeeRate` rate for `numItems` items */ function calculateAddedGuardianTime( uint256 guardianFeePaid, uint256 guardianClassFeeRate, uint256 guardianFeeRatePeriod, uint256 numItems ) internal pure returns (uint256) { return (guardianFeePaid * guardianFeeRatePeriod) / (guardianClassFeeRate * numItems); } /** * @dev Function that allows us to transform an amount from the internal, 18 decimal format, to one that has another decimal precision. * @param internalAmount the amount in 18 decimal represenation. * @param toDecimals the amount of decimal precision we want the amount to have */ function transformDecimalPrecision( uint256 internalAmount, uint256 toDecimals ) internal pure returns (uint256) { return (internalAmount / (10 ** (18 - toDecimals))); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"BeneficiaryDoesNotOwnItem","type":"error"},{"inputs":[],"name":"CallerNotController","type":"error"},{"inputs":[],"name":"ClassNotActive","type":"error"},{"inputs":[],"name":"CollectionIsNotActiveOrLinked","type":"error"},{"inputs":[],"name":"DifferentPeriodRequired","type":"error"},{"inputs":[],"name":"FreeStorageItemsCantBeRepossessed","type":"error"},{"inputs":[],"name":"GuardianClassFeeRateTooLow","type":"error"},{"inputs":[],"name":"GuardianDoesNotStoreItem","type":"error"},{"inputs":[],"name":"GuardianFeeNotChangeableOnFreeStorageClass","type":"error"},{"inputs":[],"name":"GuardianFeePaidUntilStillInFuture","type":"error"},{"inputs":[],"name":"GuardianFeeRateLimitExceeded","type":"error"},{"inputs":[],"name":"GuardianFeeTooLow","type":"error"},{"inputs":[],"name":"GuardianFeeWindowHasntPassed","type":"error"},{"inputs":[],"name":"GuardianNotWhitelisted","type":"error"},{"inputs":[],"name":"ItemNotYetMinted","type":"error"},{"inputs":[],"name":"MinStorageTimeTooLow","type":"error"},{"inputs":[],"name":"MintingFeeTooLow","type":"error"},{"inputs":[],"name":"NewGuardianUnavailable","type":"error"},{"inputs":[],"name":"NoItemsToRepossess","type":"error"},{"inputs":[],"name":"NotCallersGuardianData","type":"error"},{"inputs":[],"name":"NotGuardianOfItems","type":"error"},{"inputs":[],"name":"OldGuardianAvailable","type":"error"},{"inputs":[],"name":"TooManyReposessionItems","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"components":[{"internalType":"bytes32","name":"addressHash","type":"bytes32"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"redirect","type":"string"},{"internalType":"string","name":"policy","type":"string"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"isPrivate","type":"bool"}],"indexed":false,"internalType":"struct Guardians.GuardianInfo","name":"newGuardianInfo","type":"tuple"}],"name":"GuardianAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"classID","type":"uint256"},{"components":[{"internalType":"uint256","name":"maximumCoverage","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"},{"internalType":"uint256","name":"redemptionFee","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRatePeriod","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRate","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRateMinimum","type":"uint256"},{"internalType":"uint256","name":"lastGuardianFeeRateIncrease","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"string","name":"uri","type":"string"}],"indexed":false,"internalType":"struct Guardians.GuardianClass","name":"newGuardianClass","type":"tuple"}],"name":"GuardianClassAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"classID","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"fieldIndexModified","type":"uint8"},{"components":[{"internalType":"uint256","name":"maximumCoverage","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"},{"internalType":"uint256","name":"redemptionFee","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRatePeriod","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRate","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRateMinimum","type":"uint256"},{"internalType":"uint256","name":"lastGuardianFeeRateIncrease","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"string","name":"uri","type":"string"}],"indexed":false,"internalType":"struct Guardians.GuardianClass","name":"newGuardianClass","type":"tuple"}],"name":"GuardianClassModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint8","name":"fieldIndexModified","type":"uint8"},{"components":[{"internalType":"bytes32","name":"addressHash","type":"bytes32"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"redirect","type":"string"},{"internalType":"string","name":"policy","type":"string"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"isPrivate","type":"bool"}],"indexed":false,"internalType":"struct Guardians.GuardianInfo","name":"newGuardianInfo","type":"tuple"}],"name":"GuardianModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"components":[{"internalType":"bytes32","name":"addressHash","type":"bytes32"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"redirect","type":"string"},{"internalType":"string","name":"policy","type":"string"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"isPrivate","type":"bool"}],"indexed":false,"internalType":"struct Guardians.GuardianInfo","name":"newGuardianInfo","type":"tuple"}],"name":"GuardianRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fromGuardian","type":"address"},{"indexed":true,"internalType":"address","name":"toGuardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"toGuardianClassId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"contract IERC11554K","name":"collection","type":"address"}],"name":"ItemMoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"classID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"contract IERC11554K","name":"collection","type":"address"}],"name":"ItemStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"contract IERC11554K","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SetForRepossession","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"guardian","type":"address"},{"indexed":false,"internalType":"uint256","name":"timeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"contract IERC11554K","name":"collection","type":"address"}],"name":"StorageTimeAdded","type":"event"},{"inputs":[],"name":"DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HOUR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINUTE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENTAGE_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECOND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"}],"name":"addGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"maximumCoverage","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"},{"internalType":"uint256","name":"redemptionFee","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRate","type":"uint256"},{"internalType":"enum Guardians.GuardianFeeRatePeriods","name":"guardianFeeRatePeriod","type":"uint8"},{"internalType":"string","name":"uri","type":"string"}],"name":"addGuardianClass","outputs":[{"internalType":"uint256","name":"classID","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"guardianFeeAmount","type":"uint256"}],"name":"addStorageTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC11554K[]","name":"collections","type":"address[]"},{"internalType":"address[]","name":"beneficiaries","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"guardianFeeAmounts","type":"uint256[]"}],"name":"batchAddStorageTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"bool","name":"whitelistStatus","type":"bool"}],"name":"changeWhitelistUsersStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IERC11554KController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"address","name":"mintAddress","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"guardianClassIndex","type":"uint256"},{"internalType":"uint256","name":"guardianFeeAmount","type":"uint256"},{"internalType":"uint256","name":"numItems","type":"uint256"},{"internalType":"address","name":"feePayer","type":"address"},{"internalType":"contract IERC20Upgradeable","name":"paymentAsset","type":"address"}],"name":"controllerStoreItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"numItems","type":"uint256"},{"internalType":"address","name":"from","type":"address"}],"name":"controllerTakeItemOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oldGuardian","type":"address"},{"internalType":"address","name":"newGuardian","type":"address"}],"name":"copyGuardianClasses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"contract IERC11554K","name":"collection","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegated","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"delegatedAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IERC11554K","name":"","type":"address"}],"name":"delegatedCollection","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesManager","outputs":[{"internalType":"contract IFeesManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"}],"name":"getGuardianFeeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getGuardianFeeRateByCollectionItem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"}],"name":"getGuardianFeeRatePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getGuardianFeeRatePeriodByCollectionItem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"}],"name":"getMintingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"}],"name":"getRedemptionFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"globalItemGuardianFeePaidUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"}],"name":"guardianClassesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IERC11554K","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"guardianFeePaidUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardianFeeSetWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"guardianInfo","outputs":[{"internalType":"bytes32","name":"addressHash","type":"bytes32"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"redirect","type":"string"},{"internalType":"string","name":"policy","type":"string"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"isPrivate","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"guardianWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"guardiansClasses","outputs":[{"internalType":"uint256","name":"maximumCoverage","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"},{"internalType":"uint256","name":"redemptionFee","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRatePeriod","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRate","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRateMinimum","type":"uint256"},{"internalType":"uint256","name":"lastGuardianFeeRateIncrease","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IERC11554K","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"inRepossession","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"minimumRequestFee_","type":"uint256"},{"internalType":"uint256","name":"guardianFeeSetWindow_","type":"uint256"},{"internalType":"uint256","name":"maximumGuardianFeeSet_","type":"uint256"},{"internalType":"contract IFeesManager","name":"feesManager_","type":"address"},{"internalType":"contract IERC11554KController","name":"controller_","type":"address"},{"internalType":"bytes32","name":"version_","type":"bytes32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"}],"name":"isAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"}],"name":"isClassActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"},{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"contract IERC11554K","name":"collection","type":"address"}],"name":"isDelegated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"guardianFeeAmount","type":"uint256"},{"internalType":"uint256","name":"numItems","type":"uint256"},{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"guardianClassIndex","type":"uint256"}],"name":"isFeeAboveMinimum","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"itemGuardianClass","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumGuardianFeeSet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minStorageTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumRequestFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"oldGuardian","type":"address"},{"internalType":"address","name":"newGuardian","type":"address"},{"internalType":"uint256[]","name":"newGuardianClassIndeces","type":"uint256[]"}],"name":"moveItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"policy","type":"string"},{"internalType":"string","name":"redirect","type":"string"},{"internalType":"bytes32","name":"physicalAddressHash","type":"bytes32"},{"internalType":"bool","name":"privacy","type":"bool"}],"name":"registerGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"}],"name":"removeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"bool","name":"activity","type":"bool"}],"name":"setActivity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC11554KController","name":"controller_","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IFeesManager","name":"feesManager_","type":"address"}],"name":"setFeesManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"bool","name":"activeStatus","type":"bool"}],"name":"setGuardianClassActiveStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"enum Guardians.GuardianFeeRatePeriods","name":"guardianFeeRatePeriod","type":"uint8"},{"internalType":"uint256","name":"guardianFeeRate","type":"uint256"}],"name":"setGuardianClassGuardianFeePeriodAndRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"uint256","name":"guardianFeeRate","type":"uint256"}],"name":"setGuardianClassGuardianFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"uint256","name":"maximumCoverage","type":"uint256"}],"name":"setGuardianClassMaximumCoverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"}],"name":"setGuardianClassMintingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"uint256","name":"redemptionFee","type":"uint256"}],"name":"setGuardianClassRedemptionFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"uint256","name":"classID","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"setGuardianClassURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"guardianFeeSetWindow_","type":"uint256"}],"name":"setGuardianFeeSetWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"collection","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"setItemsToRepossessed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"string","name":"logo","type":"string"}],"name":"setLogo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maximumGuardianFeeSet_","type":"uint256"}],"name":"setMaximumGuardianFeeSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minStorageTime_","type":"uint256"}],"name":"setMinStorageTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minimumRequestFee_","type":"uint256"}],"name":"setMinimumRequestFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"bytes32","name":"physicalAddressHash","type":"bytes32"}],"name":"setPhysicalAddressHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"string","name":"policy","type":"string"}],"name":"setPolicy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"bool","name":"privacy","type":"bool"}],"name":"setPrivacy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian","type":"address"},{"internalType":"string","name":"redirect","type":"string"}],"name":"setRedirect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"version_","type":"bytes32"}],"name":"setVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"shiftGuardianFeesOnTokenMove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"contract IERC11554K","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"contract IERC11554K","name":"collection","type":"address"}],"name":"undelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC11554K","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"whereItemStored","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506159bf80620000216000396000f3fe608060405234801561001057600080fd5b50600436106104535760003560e01c8063715018a611610241578063bc302c881161013b578063ec9cd925116100c3578063fbdfc81511610087578063fbdfc81514610a92578063fc113aa514610aa5578063fca6bab014610ab8578063fdd264fb14610acb578063fe8020ba14610aff57600080fd5b8063ec9cd92514610a27578063ee01e5e714610a3a578063f2fde38b14610a43578063f3598ad914610a56578063f77c479114610a7f57600080fd5b8063ca5f81b51161010a578063ca5f81b5146109b4578063cd6740e5146109c7578063d78a3845146109f8578063de14e54d14610a01578063e63f366414610a1457600080fd5b8063bc302c8814610968578063bd2127841461097b578063bdb343721461098e578063be1f7828146109a157600080fd5b80638f5c81a1116101c9578063a526d83b1161018d578063a526d83b146108d8578063a54bc0b2146108eb578063abcac6bc146108fe578063b4a90fc71461092f578063b54d01da1461096057600080fd5b80638f5c81a11461086e578063923313771461088157806392eefe9b146108aa5780639da254ad146108bd578063a39dc9be146108d057600080fd5b806385cc313c1161021057806385cc313c146107f657806389d29297146108095780638ab656861461081c5780638d57c2031461082f5780638da5cb5b1461085d57600080fd5b8063715018a6146107c957806372539511146107d15780637c25509d146107e4578063800375a7146107ed57600080fd5b806335fa4384116103525780634cf31905116102da5780635e31b0731161029e5780635e31b07314610749578063667d3fb41461075c5780636cf667d41461076f5780636e2a42651461078257806371404156146107b657600080fd5b80634cf31905146106f4578063512f87781461070757806354fd4d501461071a5780635879fa92146107235780635b8afb701461073657600080fd5b806344ab1ee81161032157806344ab1ee814610662578063462b972514610675578063479f43651461068857806348d378561461069b578063497adbcb146106c657600080fd5b806335fa4384146105f1578063399ef453146106045780633af32abf1461062c5780634390c4ee1461064f57600080fd5b80631c89382a116103e05780632896f60b116103a45780632896f60b1461059257806328b047c8146105a557806328edec8e146105b85780633121db1c146105cb57806334a07d10146105de57600080fd5b80631c89382a1461053e5780631d21d4d9146105515780631ee9211f146105645780632750738f1461057757806327cfe8561461058a57600080fd5b806314f2101f1161042757806314f2101f146104da578063183e1a24146104fd578063197a2a7714610510578063198a8f65146105235780631ab3995a1461052b57600080fd5b80621f8a8b1461045857806305a9e0731461046d578063092d79c21461049d57806310bfbaea146104c3575b600080fd5b61046b610466366004614a40565b610b2a565b005b606554610480906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6104b06104ab366004614a79565b610c15565b6040516104949796959493929190614ae3565b6104cc606a5481565b604051908152602001610494565b6104ed6104e8366004614b52565b610e76565b6040519015158152602001610494565b6104cc61050b366004614b9d565b610edd565b6104ed61051e366004614bc9565b610fd9565b6104cc603c81565b61046b610539366004614b9d565b611033565b61046b61054c366004614a79565b6110fb565b61046b61055f366004614c08565b611125565b6104cc610572366004614b9d565b61128c565b61046b610585366004614c66565b6112d0565b6104cc6112fe565b6104ed6105a0366004614a79565b611317565b61046b6105b3366004614cc8565b61135c565b61046b6105c6366004614d1d565b61145a565b61046b6105d9366004614cc8565b611596565b61046b6105ec366004614d54565b611685565b61046b6105ff366004614d89565b611793565b610617610612366004614b9d565b611864565b60405161049499989796959493929190614db7565b6104ed61063a366004614a79565b606b6020526000908152604090205460ff1681565b61046b61065d366004614e53565b611964565b61046b610670366004614d54565b611a5a565b6104cc610683366004614b9d565b611b7d565b61046b610696366004614d54565b611bc1565b6104cc6106a9366004614b9d565b607260209081526000928352604080842090915290825290205481565b6104ed6106d4366004614d89565b606d60209081526000928352604080842090915290825290205460ff1681565b61046b610702366004614c66565b611caa565b61046b610715366004614eff565b611cb7565b6104cc60785481565b61046b610731366004614cc8565b612131565b61046b610744366004614c66565b612220565b61046b610757366004614f45565b61222d565b6104cc61076a366004614b9d565b612340565b61046b61077d366004614fad565b61243b565b610480610790366004614d89565b60776020908152600092835260408084209091529082529020546001600160a01b031681565b61046b6107c4366004614a79565b612584565b61046b6125ed565b6104cc6107df366004614b9d565b612601565b6104cc60685481565b6104cc60695481565b61046b610804366004614d54565b61262b565b61046b610817366004614eff565b612771565b61046b61082a366004614d89565b612afe565b6104ed61083d366004614d89565b607660209081526000928352604080842090915290825290205460ff1681565b6033546001600160a01b0316610480565b61046b61087c366004615009565b612b53565b6104cc61088f366004614a79565b6001600160a01b03166000908152606f602052604090205490565b61046b6108b8366004614a79565b612d22565b61046b6108cb366004615040565b612d4c565b6104cc612e8c565b61046b6108e6366004614a79565b612e97565b61046b6108f9366004614d89565b612f18565b6104cc61090c366004615133565b607360209081526000938452604080852082529284528284209052825290205481565b6104cc61093d366004615133565b607060209081526000938452604080852082529284528284209052825290205481565b6104cc600181565b61046b610976366004615174565b612f61565b6104cc61098936600461521b565b613395565b61046b61099c366004614c66565b613443565b6104cc6109af366004614b9d565b613450565b61046b6109c2366004614c66565b61347a565b6104cc6109d5366004615133565b607560209081526000938452604080852082529284528284209052825290205481565b6104cc60675481565b61046b610a0f366004614a40565b613487565b6104ed610a22366004614b9d565b61355e565b61046b610a35366004614cc8565b6135a6565b6104cc61271081565b61046b610a51366004614a79565b613695565b610480610a64366004614a79565b606e602052600090815260409020546001600160a01b031681565b606654610480906001600160a01b031681565b61046b610aa03660046152a8565b61370e565b61046b610ab33660046152de565b613968565b61046b610ac636600461538e565b613a0d565b610480610ad9366004614b9d565b60716020908152600092835260408084209091529082529020546001600160a01b031681565b6104cc610b0d366004614b9d565b607460209081526000928352604080842090915290825290205481565b6001600160a01b0382166000908152606b6020526040902054829060ff16610b65576040516371d42f3560e11b815260040160405180910390fd5b82610b786033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614610bb957336001600160a01b03821614610bb9576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0384166000818152606c60205260409081902060058101805461ff00191661010088151502179055905160008051602061594a83398151915291610c079160049190615532565b60405180910390a250505050565b606c6020526000908152604090208054600182018054919291610c37906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610c63906153ed565b8015610cb05780601f10610c8557610100808354040283529160200191610cb0565b820191906000526020600020905b815481529060010190602001808311610c9357829003601f168201915b505050505090806002018054610cc5906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf1906153ed565b8015610d3e5780601f10610d1357610100808354040283529160200191610d3e565b820191906000526020600020905b815481529060010190602001808311610d2157829003601f168201915b505050505090806003018054610d53906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7f906153ed565b8015610dcc5780601f10610da157610100808354040283529160200191610dcc565b820191906000526020600020905b815481529060010190602001808311610daf57829003601f168201915b505050505090806004018054610de1906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0d906153ed565b8015610e5a5780601f10610e2f57610100808354040283529160200191610e5a565b820191906000526020600020905b815481529060010190602001808311610e3d57829003601f168201915b5050506005909301549192505060ff8082169161010090041687565b6001600160a01b0383811660009081526077602090815260408083208585168452909152812054909184811691161480610ed557506001600160a01b0380851660009081526076602090815260408083209387168352929052205460ff165b949350505050565b60405163bd85b03960e01b8152600481018290526000906001600160a01b0384169063bd85b03990602401602060405180830381865afa158015610f25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f49919061554e565b600003610f6957604051633b41868f60e21b815260040160405180910390fd5b6001600160a01b0380841660008181526071602090815260408083208784528252808320549094168252606f8152838220928252607281528382208683529052919091205481548110610fbe57610fbe615567565b90600052602060002090600902016004015490505b92915050565b600080610fe68484612601565b90506000610ff48585613450565b905081600003611017576040516333adb20360e11b815260040160405180910390fd5b61102387838389613bbb565b606a541115979650505050505050565b6001600160a01b0382166000908152606b6020526040902054829060ff1661106e576040516371d42f3560e11b815260040160405180910390fd5b826110816033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146110c257336001600160a01b038216146110c2576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0384166000818152606c6020526040808220868155905160008051602061594a83398151915292610c07929091615532565b611103613be4565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16158080156111455750600054600160ff909116105b8061115f5750303b15801561115f575060005460ff166001145b6111c75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156111ea576000805461ff0019166101001790555b6111f2613c3e565b6067879055606886905560698590556276a700606a55606580546001600160a01b038087166001600160a01b031992831617909255606680549286169290911691909117905560788290558015611283576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b6001600160a01b0382166000908152606f602052604081208054839081106112b6576112b6615567565b906000526020600020906009020160020154905092915050565b6112d8613be4565b806000036112f957604051637beed6ff60e11b815260040160405180910390fd5b606a55565b611309603c80615593565b611314906018615593565b81565b6001600160a01b0381166000908152606b602052604081205460ff168015610fd35750506001600160a01b03166000908152606c602052604090206005015460ff1690565b6001600160a01b0383166000908152606b6020526040902054839060ff16611397576040516371d42f3560e11b815260040160405180910390fd5b836113aa6033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146113eb57336001600160a01b038216146113eb576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c6020526040902060010161141184868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160019190615532565b60405180910390a25050505050565b6001600160a01b0383166000908152606b6020526040902054839060ff16611495576040516371d42f3560e11b815260040160405180910390fd5b836114a86033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146114e957336001600160a01b038216146114e9576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f6020526040902080548491908690811061151657611516615567565b6000918252602080832060076009909302018201805494151560ff19909516949094179093556001600160a01b038816808352606f9093526040909120805460008051602061596a83398151915292889290918390811061157957611579615567565b906000526020600020906009020160405161144b9392919061573f565b6001600160a01b0383166000908152606b6020526040902054839060ff166115d1576040516371d42f3560e11b815260040160405180910390fd5b836115e46033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461162557336001600160a01b03821614611625576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c6020526040902060020161164b84868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160029190615532565b6001600160a01b0383166000908152606b6020526040902054839060ff166116c0576040516371d42f3560e11b815260040160405180910390fd5b836116d36033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461171457336001600160a01b03821614611714576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f6020526040902080548491908690811061174157611741615567565b600091825260208083206009909202909101929092556001600160a01b038716808252606f90925260408120805460008051602061596a83398151915292889290918390811061157957611579615567565b336000818152606b602052604090205460ff166117c3576040516371d42f3560e11b815260040160405180910390fd5b6001600160a01b038216611817576000607681335b6001600160a01b03908116825260208083019390935260409182016000908120918816815292529020805491151560ff19909216919091179055505050565b6000607781335b6001600160a01b039081168252602080830193909352604091820160009081208783168252909352912080546001600160a01b031916929091169190911790555b505050565b606f602052816000526040600020818154811061188057600080fd5b9060005260206000209060090201600091509150508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070160009054906101000a900460ff16908060080180546118e1906153ed565b80601f016020809104026020016040519081016040528092919081815260200182805461190d906153ed565b801561195a5780601f1061192f5761010080835404028352916020019161195a565b820191906000526020600020905b81548152906001019060200180831161193d57829003601f168201915b5050505050905089565b61196c613be4565b61197584611317565b1561199357604051634c620c3f60e11b815260040160405180910390fd5b61199c83611317565b6119b95760405163cedb19a160e01b815260040160405180910390fd5b60005b85811015611a50576119e6848484848181106119da576119da615567565b9050602002013561355e565b611a03576040516339cf183d60e11b815260040160405180910390fd5b611a4088888884818110611a1957611a19615567565b905060200201358787878787818110611a3457611a34615567565b90506020020135613c6d565b611a4981615761565b90506119bc565b5050505050505050565b6001600160a01b0383166000908152606b6020526040902054839060ff16611a95576040516371d42f3560e11b815260040160405180910390fd5b83611aa86033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614611ae957336001600160a01b03821614611ae9576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f60205260409020805484919086908110611b1657611b16615567565b906000526020600020906009020160020181905550846001600160a01b031660008051602061596a833981519152856002606f60008a6001600160a01b03166001600160a01b03168152602001908152602001600020888154811061157957611579615567565b6001600160a01b0382166000908152606f60205260408120805483908110611ba757611ba7615567565b906000526020600020906009020160010154905092915050565b6001600160a01b0383166000908152606b6020526040902054839060ff16611bfc576040516371d42f3560e11b815260040160405180910390fd5b83611c0f6033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614611c5057336001600160a01b03821614611c50576040516305fa117f60e11b815260040160405180910390fd5b611ca3858585606f60008a6001600160a01b03166001600160a01b031681526020019081526020016000208881548110611c8c57611c8c615567565b906000526020600020906009020160030154613d6c565b5050505050565b611cb2613be4565b606955565b6066546001600160a01b031663aee3d144336040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015611d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d33919061577a565b1580611db857506066546001600160a01b031663236d64a3336040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015611d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db6919061577a565b155b15611dd657604051632ed58dfb60e21b815260040160405180910390fd5b336000611de38285610edd565b90506000611df18386612340565b6001600160a01b038089166000908152607360209081526040808320938816835292815282822089835290529081205491925090611e31908484886140e6565b6001600160a01b03808a166000818152607360209081526040808320948a168084529482528083208c8452909152808220549051627eeac760e11b81526004810193909352602483018b905293945092611eda9290918791879162fdd58e906044015b602060405180830381865afa158015611eb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed5919061554e565b6140e6565b6001600160a01b03808a166000818152607360209081526040808320948b168084529482528083208d8452909152808220549051627eeac760e11b81526004810193909352602483018c905293945092611f419290918891889162fdd58e90604401611e94565b604051627eeac760e11b81526001600160a01b038c81166004830152602482018b905291925060009189919089169062fdd58e90604401602060405180830381865afa158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb9919061554e565b611fc39190615797565b905080600003612002576001600160a01b03808c166000908152607360209081526040808320938b1683529281528282208c8352905290812055612050565b61201761200f8585615797565b878784613bbb565b61202190426157aa565b6001600160a01b03808d166000908152607360209081526040808320938c1683529281528282208d8352905220555b604051627eeac760e11b81526001600160a01b038b81166004830152602482018b90526000918a918a169062fdd58e90604401602060405180830381865afa1580156120a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c4919061554e565b6120ce91906157aa565b90506120e56120dd86856157aa565b888884613bbb565b6120ef90426157aa565b6001600160a01b039b8c1660009081526073602090815260408083209b909e168252998a528c81209b81529a9098525050509690952092909255505050505050565b6001600160a01b0383166000908152606b6020526040902054839060ff1661216c576040516371d42f3560e11b815260040160405180910390fd5b8361217f6033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146121c057336001600160a01b038216146121c0576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c602052604090206003016121e684868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160039190615532565b612228613be4565b606755565b6001600160a01b0384166000908152606b6020526040902054849060ff16612268576040516371d42f3560e11b815260040160405180910390fd5b8461227b6033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146122bc57336001600160a01b038216146122bc576040516305fa117f60e11b815260040160405180910390fd5b60005b84811015611283576001600160a01b0387166000908152606d6020526040812085918888858181106122f3576122f3615567565b90506020020160208101906123089190614a79565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905561233981615761565b90506122bf565b60405163bd85b03960e01b8152600481018290526000906001600160a01b0384169063bd85b03990602401602060405180830381865afa158015612388573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ac919061554e565b6000036123cc57604051633b41868f60e21b815260040160405180910390fd5b6001600160a01b0380841660008181526071602090815260408083208784528252808320549094168252606f815283822092825260728152838220868352905291909120548154811061242157612421615567565b906000526020600020906009020160030154905092915050565b6001600160a01b0384166000908152606b6020526040902054849060ff16612476576040516371d42f3560e11b815260040160405180910390fd5b846124896033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146124ca57336001600160a01b038216146124ca576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0386166000908152606f60205260409020805485918591889081106124f8576124f8615567565b9060005260206000209060090201600801918261251692919061560e565b506001600160a01b0386166000818152606f60205260409020805460008051602061596a833981519152918891600891908390811061255757612557615567565b90600052602060002090600902016040516125749392919061573f565b60405180910390a2505050505050565b61258c613be4565b6001600160a01b0381166000818152606b60209081526040808320805460ff19908116909155606c9092528083206005018054909216909155517fb8107d0c6b40be480ce3172ee66ba6d64b71f6b1685a851340036e6e2e3e3c529190a250565b6125f5613be4565b6125ff6000614129565b565b6001600160a01b0382166000908152606f60205260408120805483908110610fbe57610fbe615567565b6001600160a01b0383166000908152606b6020526040902054839060ff16612666576040516371d42f3560e11b815260040160405180910390fd5b836126796033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146126ba57336001600160a01b038216146126ba576040516305fa117f60e11b815260040160405180910390fd5b6067548310156126dd5760405163522036bf60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f6020526040902080548491908690811061270a5761270a615567565b906000526020600020906009020160010181905550846001600160a01b031660008051602061596a833981519152856001606f60008a6001600160a01b03166001600160a01b03168152602001908152602001600020888154811061157957611579615567565b604051627eeac760e11b81526001600160a01b038481166004830152602482018490526000919086169062fdd58e90604401602060405180830381865afa1580156127c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e4919061554e565b6001600160a01b038087166000818152607160209081526040808320898452825280832054938352607282528083208984529091528120549394509116919061282d8383612601565b905080600003612850576040516333adb20360e11b815260040160405180910390fd5b84600003612871576040516306c95d7d60e41b815260040160405180910390fd5b83600003612892576040516369bdf96560e11b815260040160405180910390fd5b6001600160a01b0383166128b95760405163137849f160e11b815260040160405180910390fd5b60006128d086836128ca8787613450565b88613bbb565b6001600160a01b03808a166000908152607360209081526040808320938e1683529281528282208b83529052908120805492935083929091906129149084906157aa565b9091555050604080518281526001600160a01b038a811660208301528b81168284015291519186169189917f29de542d58d5280b82118289d7236d2b096f3e56797fd3bc4228f19a3c476947919081900360600190a3506065546001600160a01b031663348709b4866129878686613450565b6129918886615593565b61299b91906157bd565b86607360008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008c8152602001908152602001600020546129fd3390565b606660009054906101000a90046001600160a01b03166001600160a01b0316633013ce296040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7691906157df565b6040516001600160e01b031960e089901b168152600481019690965260248601949094526001600160a01b0392831660448601526064850191909152811660848401521660a482015260c401600060405180830381600087803b158015612adc57600080fd5b505af1158015612af0573d6000803e3d6000fd5b505050505050505050505050565b336000818152606b602052604090205460ff16612b2e576040516371d42f3560e11b815260040160405180910390fd5b6001600160a01b038216612b4857600160766000336117d8565b82607760003361181e565b6001600160a01b038381166000908152607160209081526040808320868452909152902054163314612b985760405163bc1a99ad60e01b815260040160405180910390fd5b612ba28383610edd565b600003612bc25760405163da9335d560e01b815260040160405180910390fd5b6001600160a01b0380821660009081526073602090815260408083209387168352928152828220858352905220544211612c0f576040516341f6b9a560e01b815260040160405180910390fd5b604051627eeac760e11b81526001600160a01b038281166004830152602482018490526000919085169062fdd58e90604401602060405180830381865afa158015612c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c82919061554e565b905080600003612ca5576040516305319efb60e41b815260040160405180910390fd5b6001600160a01b0382811660009081526075602090815260408083209388168084529382528083208784529091529020805490839055903390857feef808aafa779451f3107a5033b5d50922fbd85286781c04ba9a3a88b7f27d77612d0a8587615797565b60405190815260200160405180910390a45050505050565b612d2a613be4565b606680546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038b166000908152606c6020526040902060058101805460ff19166001179055600201612d818a8c8361560e565b506001600160a01b038b166000908152606c60205260409020600101612da8888a8361560e565b506001600160a01b038b166000908152606c60205260409020600401612dcf86888361560e565b506001600160a01b038b166000908152606c6020526040902060058101805461ff00191661010084151502179055600301612e0b84868361560e565b506001600160a01b038b166000908152606c60205260409020829055612e308b612e97565b6001600160a01b038b166000818152606c60205260409081902090517f40a85abf2e067de420759997226b243a11146e32797c459e0ae521c164b3ef7c91612e77916157fc565b60405180910390a25050505050505050505050565b611314603c80615593565b612e9f613be4565b6001600160a01b0381166000818152606b602090815260408083208054600160ff199182168117909255606c90935292819020600581018054909316909317909155517fa08c78c5ffa2e84c547405de8308d3981bfc147bbe8186049de946adf23bedf291612f0d916157fc565b60405180910390a250565b612f20613be4565b60005b6001600160a01b0383166000908152606f602052604090205481101561185f57612f4e83838361417b565b5080612f5981615761565b915050612f23565b6066546001600160a01b0316336001600160a01b031614612f9557604051632d5fb10f60e01b815260040160405180910390fd5b6001600160a01b038087166000908152607060209081526040808320938d1683529281528282208a835290529081208054859290612fd49084906157aa565b90915550506001600160a01b0389811660008181526071602090815260408083208c8452825280832080546001600160a01b031916958c169586179055928252607281528282208b83528152828220899055928152606f909252812080548790811061304257613042615567565b906000526020600020906009020160040154111561338a576001600160a01b038089166000908152607360209081526040808320938d1683529281528282208a835290529081205490036130c1576001600160a01b038089166000908152607360209081526040808320938d1683529281528282208a83529052204290555b6001600160a01b0386166000908152606f602052604081208054613151918791899081106130f1576130f1615567565b906000526020600020906009020160040154606f60008b6001600160a01b03166001600160a01b03168152602001908152602001600020898154811061313957613139615567565b90600052602060002090600902016003015487613bbb565b6001600160a01b03808b166000908152607360209081526040808320938f1683529281528282208c83529052908120805492935083929091906131959084906157aa565b9091555050604080518281526001600160a01b038b811660208301528c8116828401529151918916918a917f29de542d58d5280b82118289d7236d2b096f3e56797fd3bc4228f19a3c476947919081900360600190a3506065546001600160a01b031663348709b4856132088989613450565b6001600160a01b038a166000908152606f6020526040902080548891908b90811061323557613235615567565b9060005260206000209060090201600401546132519190615593565b61325b91906157bd565b89607360008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008d81526020019081526020016000205487876040518763ffffffff1660e01b815260040161330a9695949392919095865260208601949094526001600160a01b0392831660408601526060850191909152811660808401521660a082015260c00190565b600060405180830381600087803b15801561332457600080fd5b505af1158015613338573d6000803e3d6000fd5b505060408051888152602081018b90526001600160a01b038d8116828401529151918a1693507f9137dbe71594712b8c41002a261f3818dd6e951587d83c552606f4c53100f62b925081900360600190a25b505050505050505050565b6001600160a01b0388166000908152606b6020526040812054899060ff166133d0576040516371d42f3560e11b815260040160405180910390fd5b896133e36033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461342457336001600160a01b03821614613424576040516305fa117f60e11b815260040160405180910390fd5b6134348b8b8b8b8b8b8b8b6145cc565b9b9a5050505050505050505050565b61344b613be4565b606855565b6001600160a01b0382166000908152606f6020526040812080548390811061242157612421615567565b613482613be4565b607855565b6001600160a01b0382166000908152606b6020526040902054829060ff166134c2576040516371d42f3560e11b815260040160405180910390fd5b826134d56033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461351657336001600160a01b03821614613516576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0384166000818152606c6020526040908190206005808201805460ff1916881515179055915160008051602061594a83398151915292610c07929091615532565b6001600160a01b0382166000908152606f6020526040812080548390811061358857613588615567565b600091825260209091206009909102016007015460ff169392505050565b6001600160a01b0383166000908152606b6020526040902054839060ff166135e1576040516371d42f3560e11b815260040160405180910390fd5b836135f46033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461363557336001600160a01b03821614613635576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c6020526040902060040161365b84868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160049190615532565b61369d613be4565b6001600160a01b0381166137025760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016111be565b61370b81614129565b50565b6001600160a01b0384166000908152606b6020526040902054849060ff16613749576040516371d42f3560e11b815260040160405180910390fd5b8461375c6033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461379d57336001600160a01b0382161461379d576040516305fa117f60e11b815260040160405180910390fd5b6000808560038111156137b2576137b261580f565b036137bf5750600161383d565b60018560038111156137d3576137d361580f565b036137e05750603c61383d565b60028560038111156137f4576137f461580f565b0361380b57613804603c80615593565b905061383d565b600385600381111561381f5761381f61580f565b0361383d5761382f603c80615593565b61383a906018615593565b90505b6001600160a01b0387166000908152606f6020526040902080548291908890811061386a5761386a615567565b9060005260206000209060090201600301540361389a5760405163842cebc360e01b815260040160405180910390fd5b6138a687878684613d6c565b6001600160a01b0387166000908152606f602052604090208054829190889081106138d3576138d3615567565b906000526020600020906009020160030181905550866001600160a01b031660008051602061596a833981519152876003606f60008c6001600160a01b03166001600160a01b031681526020019081526020016000208a8154811061393a5761393a615567565b90600052602060002090600902016040516139579392919061573f565b60405180910390a250505050505050565b60005b8381101561338a576139fb89898381811061398857613988615567565b905060200201602081019061399d9190614a79565b8888848181106139af576139af615567565b90506020020160208101906139c49190614a79565b8787858181106139d6576139d6615567565b905060200201358686868181106139ef576139ef615567565b90506020020135612771565b80613a0581615761565b91505061396b565b6066546001600160a01b0316336001600160a01b031614613a4157604051632d5fb10f60e01b815260040160405180910390fd5b6001600160a01b0380821660009081526075602090815260408083209388168352928152828220868352905220548211613a8e5760405163481ae58160e01b815260040160405180910390fd5b6001600160a01b0384166000908152607260209081526040808320868452909152812054613abd908790612601565b6001600160a01b038616600090815260726020908152604080832088845290915281205491925090613af0908890613450565b90508115613b0857613b0683878787868661482d565b505b6001600160a01b038088166000908152607060209081526040808320938a16835292815282822088835290529081208054869290613b47908490615797565b90915550506001600160a01b038088166000908152607060209081526040808320938a168352928152828220888352905290812054900361128357505050506001600160a01b039190911660009081526071602090815260408083209383529290522080546001600160a01b031916905550565b6000613bc78285615593565b613bd18487615593565b613bdb91906157bd565b95945050505050565b6033546001600160a01b031633146125ff5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016111be565b600054610100900460ff16613c655760405162461bcd60e51b81526004016111be90615825565b6125ff6149d2565b6001600160a01b0380841660009081526070602081815260408084208a86168086529083528185208a865283528185208054908690559588168552928252808420928452918152818320888452905281208054839290613cce9084906157aa565b90915550506001600160a01b0386811660008181526071602090815260408083208a8452825280832080546001600160a01b031916898716908117909155848452607283528184208b855283529281902087905580518781529182018a9052810192909252918616907fa6beab620e184a03527e5ae53cfcf2bcc0a561f7fe957d28839a116e45ef70379060600160405180910390a3505050505050565b81600003613d8d576040516333adb20360e11b815260040160405180910390fd5b6001600160a01b0384166000908152606f60205260409020805484908110613db757613db7615567565b906000526020600020906009020160040154600003613de95760405163031fbaf760e41b815260040160405180910390fd5b6001600160a01b0384166000908152606f60205260408120805485908110613e1357613e13615567565b906000526020600020906009020160030154905080606f6000876001600160a01b03166001600160a01b031681526020019081526020016000208581548110613e5e57613e5e615567565b906000526020600020906009020160040154613e7a91906157bd565b613e8483856157bd565b1115613fbe576068546001600160a01b0386166000908152606f60205260409020805486908110613eb757613eb7615567565b906000526020600020906009020160060154613ed391906157aa565b421015613ef3576040516304caab9960e31b815260040160405180910390fd5b613eff61271082615593565b6069546001600160a01b0387166000908152606f60205260409020805487908110613f2c57613f2c615567565b906000526020600020906009020160040154613f489190615593565b613f5291906157bd565b613f5c83856157bd565b1115613f7b5760405163eb10300160e01b815260040160405180910390fd5b6001600160a01b0385166000908152606f60205260409020805442919086908110613fa857613fa8615567565b9060005260206000209060090201600601819055505b6001600160a01b0385166000908152606f60205260409020805484919086908110613feb57613feb615567565b90600052602060002090600902016004018190555080606f6000876001600160a01b03166001600160a01b03168152602001908152602001600020858154811061403757614037615567565b90600052602060002090600902016005015461405391906157bd565b61405d83856157bd565b10156140a6576001600160a01b0385166000908152606f6020526040902080548491908690811061409057614090615567565b9060005260206000209060090201600501819055505b6001600160a01b0385166000818152606f60205260409020805460008051602061596a833981519152918791600491908390811061157957611579615567565b60004285116140f757506000610ed5565b8282856141044289615797565b61410e9190615593565b6141189190615593565b61412291906157bd565b9050610ed5565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038083166000908152606f602052604080822080548251610120810184529488168452919092208054919391829190869081106141c1576141c1615567565b9060005260206000209060090201600001548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061420e5761420e615567565b9060005260206000209060090201600101548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061425b5761425b615567565b9060005260206000209060090201600201548152602001606f6000886001600160a01b03166001600160a01b0316815260200190815260200160002085815481106142a8576142a8615567565b9060005260206000209060090201600301548152602001606f6000886001600160a01b03166001600160a01b0316815260200190815260200160002085815481106142f5576142f5615567565b9060005260206000209060090201600401548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061434257614342615567565b9060005260206000209060090201600501548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061438f5761438f615567565b9060005260206000209060090201600601548152602001606f6000886001600160a01b03166001600160a01b0316815260200190815260200160002085815481106143dc576143dc615567565b600091825260208083206007600990930201919091015460ff16151583526001600160a01b0389168252606f81526040909120805492909101918690811061442657614426615567565b90600052602060002090600902016008018054614442906153ed565b80601f016020809104026020016040519081016040528092919081815260200182805461446e906153ed565b80156144bb5780601f10614490576101008083540402835291602001916144bb565b820191906000526020600020905b81548152906001019060200180831161449e57829003601f168201915b50505091909252505081546001808201845560009384526020938490208351600990930201918255928201519281019290925560408101516002830155606081015160038301556080810151600483015560a0810151600583015560c0810151600683015560e081015160078301805460ff191691151591909117905561010081015190919060088201906145509082615870565b5050506001600160a01b0383166000818152606f6020526040902080547f1d50952dd79441da39cded51d73c41faef52bb4929b6f9d51cc0e004842630e2918491829081106145a1576145a1615567565b90600052602060002090600902016040516145bd929190615930565b60405180910390a29392505050565b6001600160a01b0388166000908152606f602052604081205490808560038111156145f9576145f961580f565b0361460657506001614684565b600185600381111561461a5761461a61580f565b036146275750603c614684565b600285600381111561463b5761463b61580f565b036146525761464b603c80615593565b9050614684565b60038560038111156146665761466661580f565b0361468457614676603c80615593565b614681906018615593565b90505b606f60008b6001600160a01b03166001600160a01b031681526020019081526020016000206040518061012001604052808b81526020018a815260200189815260200183815260200188815260200188815260200142815260200160011515815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525050835460018082018655948252602091829020845160099092020190815590830151938101939093555060408101516002830155606081015160038301556080810151600483015560a0810151600583015560c0810151600683015560e081015160078301805460ff191691151591909117905561010081015190919060088201906147ab9082615870565b5050506001600160a01b038a166000818152606f6020526040902080547f1d50952dd79441da39cded51d73c41faef52bb4929b6f9d51cc0e004842630e2918591829081106147fc576147fc615567565b9060005260206000209060090201604051614818929190615930565b60405180910390a25098975050505050505050565b604051627eeac760e11b81526001600160a01b03878116600483015260248201869052600091829188169062fdd58e90604401602060405180830381865afa15801561487d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a1919061554e565b6001600160a01b03808a166000908152607360209081526040808320938c1683529281528282208a8352905290812054919250906148e1908686856140e6565b6001600160a01b03808b166000908152607360209081526040808320938d1683529281528282208b8352905290812054919250906149219087878a6140e6565b905061492d8784615797565b600003614969576001600160a01b03808b166000908152607360209081526040808320938d1683529281528282208b83529052908120556149c5565b60006149896149788385615797565b88886149848c89615797565b613bbb565b905061499581426157aa565b6001600160a01b03808d166000908152607360209081526040808320938f1683529281528282208d835290522055505b9998505050505050505050565b600054610100900460ff166149f95760405162461bcd60e51b81526004016111be90615825565b6125ff33614129565b6001600160a01b038116811461370b57600080fd5b8035614a2281614a02565b919050565b801515811461370b57600080fd5b8035614a2281614a27565b60008060408385031215614a5357600080fd5b8235614a5e81614a02565b91506020830135614a6e81614a27565b809150509250929050565b600060208284031215614a8b57600080fd5b8135614a9681614a02565b9392505050565b6000815180845260005b81811015614ac357602081850181015186830182015201614aa7565b506000602082860101526020601f19601f83011685010191505092915050565b87815260e060208201526000614afc60e0830189614a9d565b8281036040840152614b0e8189614a9d565b90508281036060840152614b228188614a9d565b90508281036080840152614b368187614a9d565b94151560a0840152505090151560c09091015295945050505050565b600080600060608486031215614b6757600080fd5b8335614b7281614a02565b92506020840135614b8281614a02565b91506040840135614b9281614a02565b809150509250925092565b60008060408385031215614bb057600080fd5b8235614bbb81614a02565b946020939093013593505050565b60008060008060808587031215614bdf57600080fd5b84359350602085013592506040850135614bf881614a02565b9396929550929360600135925050565b60008060008060008060c08789031215614c2157600080fd5b8635955060208701359450604087013593506060870135614c4181614a02565b92506080870135614c5181614a02565b8092505060a087013590509295509295509295565b600060208284031215614c7857600080fd5b5035919050565b60008083601f840112614c9157600080fd5b50813567ffffffffffffffff811115614ca957600080fd5b602083019150836020828501011115614cc157600080fd5b9250929050565b600080600060408486031215614cdd57600080fd5b8335614ce881614a02565b9250602084013567ffffffffffffffff811115614d0457600080fd5b614d1086828701614c7f565b9497909650939450505050565b600080600060608486031215614d3257600080fd5b8335614d3d81614a02565b9250602084013591506040840135614b9281614a27565b600080600060608486031215614d6957600080fd5b8335614d7481614a02565b95602085013595506040909401359392505050565b60008060408385031215614d9c57600080fd5b8235614da781614a02565b91506020830135614a6e81614a02565b60006101208b83528a60208401528960408401528860608401528760808401528660a08401528560c084015284151560e084015280610100840152614dfe81840185614a9d565b9c9b505050505050505050505050565b60008083601f840112614e2057600080fd5b50813567ffffffffffffffff811115614e3857600080fd5b6020830191508360208260051b8501011115614cc157600080fd5b600080600080600080600060a0888a031215614e6e57600080fd5b8735614e7981614a02565b9650602088013567ffffffffffffffff80821115614e9657600080fd5b614ea28b838c01614e0e565b909850965060408a01359150614eb782614a02565b909450606089013590614ec982614a02565b90935060808901359080821115614edf57600080fd5b50614eec8a828b01614e0e565b989b979a50959850939692959293505050565b60008060008060808587031215614f1557600080fd5b8435614f2081614a02565b93506020850135614f3081614a02565b93969395505050506040820135916060013590565b60008060008060608587031215614f5b57600080fd5b8435614f6681614a02565b9350602085013567ffffffffffffffff811115614f8257600080fd5b614f8e87828801614e0e565b9094509250506040850135614fa281614a27565b939692955090935050565b60008060008060608587031215614fc357600080fd5b8435614fce81614a02565b935060208501359250604085013567ffffffffffffffff811115614ff157600080fd5b614ffd87828801614c7f565b95989497509550505050565b60008060006060848603121561501e57600080fd5b833561502981614a02565b9250602084013591506040840135614b9281614a02565b600080600080600080600080600080600060e08c8e03121561506157600080fd5b61506a8c614a17565b9a5067ffffffffffffffff8060208e0135111561508657600080fd5b6150968e60208f01358f01614c7f565b909b50995060408d01358110156150ac57600080fd5b6150bc8e60408f01358f01614c7f565b909950975060608d01358110156150d257600080fd5b6150e28e60608f01358f01614c7f565b909750955060808d01358110156150f857600080fd5b506151098d60808e01358e01614c7f565b909450925060a08c0135915061512160c08d01614a35565b90509295989b509295989b9093969950565b60008060006060848603121561514857600080fd5b833561515381614a02565b9250602084013561516381614a02565b929592945050506040919091013590565b60008060008060008060008060006101208a8c03121561519357600080fd5b893561519e81614a02565b985060208a01356151ae81614a02565b975060408a0135965060608a01356151c581614a02565b955060808a0135945060a08a0135935060c08a0135925060e08a01356151ea81614a02565b91506101008a01356151fb81614a02565b809150509295985092959850929598565b803560048110614a2257600080fd5b60008060008060008060008060e0898b03121561523757600080fd5b883561524281614a02565b97506020890135965060408901359550606089013594506080890135935061526c60a08a0161520c565b925060c089013567ffffffffffffffff81111561528857600080fd5b6152948b828c01614c7f565b999c989b5096995094979396929594505050565b600080600080608085870312156152be57600080fd5b84356152c981614a02565b935060208501359250614bf86040860161520c565b6000806000806000806000806080898b0312156152fa57600080fd5b883567ffffffffffffffff8082111561531257600080fd5b61531e8c838d01614e0e565b909a50985060208b013591508082111561533757600080fd5b6153438c838d01614e0e565b909850965060408b013591508082111561535c57600080fd5b6153688c838d01614e0e565b909650945060608b013591508082111561538157600080fd5b506152948b828c01614e0e565b600080600080600060a086880312156153a657600080fd5b85356153b181614a02565b945060208601356153c181614a02565b9350604086013592506060860135915060808601356153df81614a02565b809150509295509295909350565b600181811c9082168061540157607f821691505b60208210810361542157634e487b7160e01b600052602260045260246000fd5b50919050565b60008154615434816153ed565b808552602060018381168015615451576001811461546b57615499565b60ff1985168884015283151560051b880183019550615499565b866000528260002060005b858110156154915781548a8201860152908301908401615476565b890184019650505b505050505092915050565b8054825260e0602083015260006154c160e0840160018401615427565b83810360408501526154d68160028501615427565b905083810360608501526154ed8160038501615427565b905083810360808501526155048160048501615427565b9050600583015460ff8116151560a086015261552a60c0860160ff8360081c1615159052565b509392505050565b60ff83168152604060208201526000610ed560408301846154a4565b60006020828403121561556057600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610fd357610fd361557d565b634e487b7160e01b600052604160045260246000fd5b601f82111561185f57600081815260208120601f850160051c810160208610156155e75750805b601f850160051c820191505b81811015615606578281556001016155f3565b505050505050565b67ffffffffffffffff831115615626576156266155aa565b61563a8361563483546153ed565b836155c0565b6000601f84116001811461566e57600085156156565750838201355b600019600387901b1c1916600186901b178355611ca3565b600083815260209020601f19861690835b8281101561569f578685013582556020948501946001909201910161567f565b50868210156156bc5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006101208254845260018301546020850152600283015460408501526003830154606085015260048301546080850152600583015460a0850152600683015460c0850152615721600784015460ff1690565b151560e08501526101008401819052610ed581850160088501615427565b83815260ff83166020820152606060408201526000613bdb60608301846156ce565b6000600182016157735761577361557d565b5060010190565b60006020828403121561578c57600080fd5b8151614a9681614a27565b81810381811115610fd357610fd361557d565b80820180821115610fd357610fd361557d565b6000826157da57634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156157f157600080fd5b8151614a9681614a02565b602081526000614a9660208301846154a4565b634e487b7160e01b600052602160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b815167ffffffffffffffff81111561588a5761588a6155aa565b61589e8161589884546153ed565b846155c0565b602080601f8311600181146158d357600084156158bb5750858301515b600019600386901b1c1916600185901b178555615606565b600085815260208120601f198616915b82811015615902578886015182559484019460019091019084016158e3565b50858210156159205787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b828152604060208201526000610ed560408301846156ce56fe5fff5779f55d71041c8a8dac64fd1d4394cf4b41d7ef502baf7bbeabad381b37be670b8146f19d76b44fcaf05a819ec7dfe1d8265e48858e044fbed8126b0a23a2646970667358221220e6af59b87b4cc7646ac1b838eedb18bafe8df2c1b610dc63fc557a354bf136d064736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104535760003560e01c8063715018a611610241578063bc302c881161013b578063ec9cd925116100c3578063fbdfc81511610087578063fbdfc81514610a92578063fc113aa514610aa5578063fca6bab014610ab8578063fdd264fb14610acb578063fe8020ba14610aff57600080fd5b8063ec9cd92514610a27578063ee01e5e714610a3a578063f2fde38b14610a43578063f3598ad914610a56578063f77c479114610a7f57600080fd5b8063ca5f81b51161010a578063ca5f81b5146109b4578063cd6740e5146109c7578063d78a3845146109f8578063de14e54d14610a01578063e63f366414610a1457600080fd5b8063bc302c8814610968578063bd2127841461097b578063bdb343721461098e578063be1f7828146109a157600080fd5b80638f5c81a1116101c9578063a526d83b1161018d578063a526d83b146108d8578063a54bc0b2146108eb578063abcac6bc146108fe578063b4a90fc71461092f578063b54d01da1461096057600080fd5b80638f5c81a11461086e578063923313771461088157806392eefe9b146108aa5780639da254ad146108bd578063a39dc9be146108d057600080fd5b806385cc313c1161021057806385cc313c146107f657806389d29297146108095780638ab656861461081c5780638d57c2031461082f5780638da5cb5b1461085d57600080fd5b8063715018a6146107c957806372539511146107d15780637c25509d146107e4578063800375a7146107ed57600080fd5b806335fa4384116103525780634cf31905116102da5780635e31b0731161029e5780635e31b07314610749578063667d3fb41461075c5780636cf667d41461076f5780636e2a42651461078257806371404156146107b657600080fd5b80634cf31905146106f4578063512f87781461070757806354fd4d501461071a5780635879fa92146107235780635b8afb701461073657600080fd5b806344ab1ee81161032157806344ab1ee814610662578063462b972514610675578063479f43651461068857806348d378561461069b578063497adbcb146106c657600080fd5b806335fa4384146105f1578063399ef453146106045780633af32abf1461062c5780634390c4ee1461064f57600080fd5b80631c89382a116103e05780632896f60b116103a45780632896f60b1461059257806328b047c8146105a557806328edec8e146105b85780633121db1c146105cb57806334a07d10146105de57600080fd5b80631c89382a1461053e5780631d21d4d9146105515780631ee9211f146105645780632750738f1461057757806327cfe8561461058a57600080fd5b806314f2101f1161042757806314f2101f146104da578063183e1a24146104fd578063197a2a7714610510578063198a8f65146105235780631ab3995a1461052b57600080fd5b80621f8a8b1461045857806305a9e0731461046d578063092d79c21461049d57806310bfbaea146104c3575b600080fd5b61046b610466366004614a40565b610b2a565b005b606554610480906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6104b06104ab366004614a79565b610c15565b6040516104949796959493929190614ae3565b6104cc606a5481565b604051908152602001610494565b6104ed6104e8366004614b52565b610e76565b6040519015158152602001610494565b6104cc61050b366004614b9d565b610edd565b6104ed61051e366004614bc9565b610fd9565b6104cc603c81565b61046b610539366004614b9d565b611033565b61046b61054c366004614a79565b6110fb565b61046b61055f366004614c08565b611125565b6104cc610572366004614b9d565b61128c565b61046b610585366004614c66565b6112d0565b6104cc6112fe565b6104ed6105a0366004614a79565b611317565b61046b6105b3366004614cc8565b61135c565b61046b6105c6366004614d1d565b61145a565b61046b6105d9366004614cc8565b611596565b61046b6105ec366004614d54565b611685565b61046b6105ff366004614d89565b611793565b610617610612366004614b9d565b611864565b60405161049499989796959493929190614db7565b6104ed61063a366004614a79565b606b6020526000908152604090205460ff1681565b61046b61065d366004614e53565b611964565b61046b610670366004614d54565b611a5a565b6104cc610683366004614b9d565b611b7d565b61046b610696366004614d54565b611bc1565b6104cc6106a9366004614b9d565b607260209081526000928352604080842090915290825290205481565b6104ed6106d4366004614d89565b606d60209081526000928352604080842090915290825290205460ff1681565b61046b610702366004614c66565b611caa565b61046b610715366004614eff565b611cb7565b6104cc60785481565b61046b610731366004614cc8565b612131565b61046b610744366004614c66565b612220565b61046b610757366004614f45565b61222d565b6104cc61076a366004614b9d565b612340565b61046b61077d366004614fad565b61243b565b610480610790366004614d89565b60776020908152600092835260408084209091529082529020546001600160a01b031681565b61046b6107c4366004614a79565b612584565b61046b6125ed565b6104cc6107df366004614b9d565b612601565b6104cc60685481565b6104cc60695481565b61046b610804366004614d54565b61262b565b61046b610817366004614eff565b612771565b61046b61082a366004614d89565b612afe565b6104ed61083d366004614d89565b607660209081526000928352604080842090915290825290205460ff1681565b6033546001600160a01b0316610480565b61046b61087c366004615009565b612b53565b6104cc61088f366004614a79565b6001600160a01b03166000908152606f602052604090205490565b61046b6108b8366004614a79565b612d22565b61046b6108cb366004615040565b612d4c565b6104cc612e8c565b61046b6108e6366004614a79565b612e97565b61046b6108f9366004614d89565b612f18565b6104cc61090c366004615133565b607360209081526000938452604080852082529284528284209052825290205481565b6104cc61093d366004615133565b607060209081526000938452604080852082529284528284209052825290205481565b6104cc600181565b61046b610976366004615174565b612f61565b6104cc61098936600461521b565b613395565b61046b61099c366004614c66565b613443565b6104cc6109af366004614b9d565b613450565b61046b6109c2366004614c66565b61347a565b6104cc6109d5366004615133565b607560209081526000938452604080852082529284528284209052825290205481565b6104cc60675481565b61046b610a0f366004614a40565b613487565b6104ed610a22366004614b9d565b61355e565b61046b610a35366004614cc8565b6135a6565b6104cc61271081565b61046b610a51366004614a79565b613695565b610480610a64366004614a79565b606e602052600090815260409020546001600160a01b031681565b606654610480906001600160a01b031681565b61046b610aa03660046152a8565b61370e565b61046b610ab33660046152de565b613968565b61046b610ac636600461538e565b613a0d565b610480610ad9366004614b9d565b60716020908152600092835260408084209091529082529020546001600160a01b031681565b6104cc610b0d366004614b9d565b607460209081526000928352604080842090915290825290205481565b6001600160a01b0382166000908152606b6020526040902054829060ff16610b65576040516371d42f3560e11b815260040160405180910390fd5b82610b786033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614610bb957336001600160a01b03821614610bb9576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0384166000818152606c60205260409081902060058101805461ff00191661010088151502179055905160008051602061594a83398151915291610c079160049190615532565b60405180910390a250505050565b606c6020526000908152604090208054600182018054919291610c37906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610c63906153ed565b8015610cb05780601f10610c8557610100808354040283529160200191610cb0565b820191906000526020600020905b815481529060010190602001808311610c9357829003601f168201915b505050505090806002018054610cc5906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf1906153ed565b8015610d3e5780601f10610d1357610100808354040283529160200191610d3e565b820191906000526020600020905b815481529060010190602001808311610d2157829003601f168201915b505050505090806003018054610d53906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7f906153ed565b8015610dcc5780601f10610da157610100808354040283529160200191610dcc565b820191906000526020600020905b815481529060010190602001808311610daf57829003601f168201915b505050505090806004018054610de1906153ed565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0d906153ed565b8015610e5a5780601f10610e2f57610100808354040283529160200191610e5a565b820191906000526020600020905b815481529060010190602001808311610e3d57829003601f168201915b5050506005909301549192505060ff8082169161010090041687565b6001600160a01b0383811660009081526077602090815260408083208585168452909152812054909184811691161480610ed557506001600160a01b0380851660009081526076602090815260408083209387168352929052205460ff165b949350505050565b60405163bd85b03960e01b8152600481018290526000906001600160a01b0384169063bd85b03990602401602060405180830381865afa158015610f25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f49919061554e565b600003610f6957604051633b41868f60e21b815260040160405180910390fd5b6001600160a01b0380841660008181526071602090815260408083208784528252808320549094168252606f8152838220928252607281528382208683529052919091205481548110610fbe57610fbe615567565b90600052602060002090600902016004015490505b92915050565b600080610fe68484612601565b90506000610ff48585613450565b905081600003611017576040516333adb20360e11b815260040160405180910390fd5b61102387838389613bbb565b606a541115979650505050505050565b6001600160a01b0382166000908152606b6020526040902054829060ff1661106e576040516371d42f3560e11b815260040160405180910390fd5b826110816033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146110c257336001600160a01b038216146110c2576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0384166000818152606c6020526040808220868155905160008051602061594a83398151915292610c07929091615532565b611103613be4565b606580546001600160a01b0319166001600160a01b0392909216919091179055565b600054610100900460ff16158080156111455750600054600160ff909116105b8061115f5750303b15801561115f575060005460ff166001145b6111c75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156111ea576000805461ff0019166101001790555b6111f2613c3e565b6067879055606886905560698590556276a700606a55606580546001600160a01b038087166001600160a01b031992831617909255606680549286169290911691909117905560788290558015611283576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b6001600160a01b0382166000908152606f602052604081208054839081106112b6576112b6615567565b906000526020600020906009020160020154905092915050565b6112d8613be4565b806000036112f957604051637beed6ff60e11b815260040160405180910390fd5b606a55565b611309603c80615593565b611314906018615593565b81565b6001600160a01b0381166000908152606b602052604081205460ff168015610fd35750506001600160a01b03166000908152606c602052604090206005015460ff1690565b6001600160a01b0383166000908152606b6020526040902054839060ff16611397576040516371d42f3560e11b815260040160405180910390fd5b836113aa6033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146113eb57336001600160a01b038216146113eb576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c6020526040902060010161141184868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160019190615532565b60405180910390a25050505050565b6001600160a01b0383166000908152606b6020526040902054839060ff16611495576040516371d42f3560e11b815260040160405180910390fd5b836114a86033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146114e957336001600160a01b038216146114e9576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f6020526040902080548491908690811061151657611516615567565b6000918252602080832060076009909302018201805494151560ff19909516949094179093556001600160a01b038816808352606f9093526040909120805460008051602061596a83398151915292889290918390811061157957611579615567565b906000526020600020906009020160405161144b9392919061573f565b6001600160a01b0383166000908152606b6020526040902054839060ff166115d1576040516371d42f3560e11b815260040160405180910390fd5b836115e46033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461162557336001600160a01b03821614611625576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c6020526040902060020161164b84868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160029190615532565b6001600160a01b0383166000908152606b6020526040902054839060ff166116c0576040516371d42f3560e11b815260040160405180910390fd5b836116d36033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461171457336001600160a01b03821614611714576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f6020526040902080548491908690811061174157611741615567565b600091825260208083206009909202909101929092556001600160a01b038716808252606f90925260408120805460008051602061596a83398151915292889290918390811061157957611579615567565b336000818152606b602052604090205460ff166117c3576040516371d42f3560e11b815260040160405180910390fd5b6001600160a01b038216611817576000607681335b6001600160a01b03908116825260208083019390935260409182016000908120918816815292529020805491151560ff19909216919091179055505050565b6000607781335b6001600160a01b039081168252602080830193909352604091820160009081208783168252909352912080546001600160a01b031916929091169190911790555b505050565b606f602052816000526040600020818154811061188057600080fd5b9060005260206000209060090201600091509150508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070160009054906101000a900460ff16908060080180546118e1906153ed565b80601f016020809104026020016040519081016040528092919081815260200182805461190d906153ed565b801561195a5780601f1061192f5761010080835404028352916020019161195a565b820191906000526020600020905b81548152906001019060200180831161193d57829003601f168201915b5050505050905089565b61196c613be4565b61197584611317565b1561199357604051634c620c3f60e11b815260040160405180910390fd5b61199c83611317565b6119b95760405163cedb19a160e01b815260040160405180910390fd5b60005b85811015611a50576119e6848484848181106119da576119da615567565b9050602002013561355e565b611a03576040516339cf183d60e11b815260040160405180910390fd5b611a4088888884818110611a1957611a19615567565b905060200201358787878787818110611a3457611a34615567565b90506020020135613c6d565b611a4981615761565b90506119bc565b5050505050505050565b6001600160a01b0383166000908152606b6020526040902054839060ff16611a95576040516371d42f3560e11b815260040160405180910390fd5b83611aa86033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614611ae957336001600160a01b03821614611ae9576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f60205260409020805484919086908110611b1657611b16615567565b906000526020600020906009020160020181905550846001600160a01b031660008051602061596a833981519152856002606f60008a6001600160a01b03166001600160a01b03168152602001908152602001600020888154811061157957611579615567565b6001600160a01b0382166000908152606f60205260408120805483908110611ba757611ba7615567565b906000526020600020906009020160010154905092915050565b6001600160a01b0383166000908152606b6020526040902054839060ff16611bfc576040516371d42f3560e11b815260040160405180910390fd5b83611c0f6033546001600160a01b031690565b6001600160a01b0316336001600160a01b031614611c5057336001600160a01b03821614611c50576040516305fa117f60e11b815260040160405180910390fd5b611ca3858585606f60008a6001600160a01b03166001600160a01b031681526020019081526020016000208881548110611c8c57611c8c615567565b906000526020600020906009020160030154613d6c565b5050505050565b611cb2613be4565b606955565b6066546001600160a01b031663aee3d144336040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015611d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d33919061577a565b1580611db857506066546001600160a01b031663236d64a3336040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024016020604051808303816000875af1158015611d92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db6919061577a565b155b15611dd657604051632ed58dfb60e21b815260040160405180910390fd5b336000611de38285610edd565b90506000611df18386612340565b6001600160a01b038089166000908152607360209081526040808320938816835292815282822089835290529081205491925090611e31908484886140e6565b6001600160a01b03808a166000818152607360209081526040808320948a168084529482528083208c8452909152808220549051627eeac760e11b81526004810193909352602483018b905293945092611eda9290918791879162fdd58e906044015b602060405180830381865afa158015611eb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed5919061554e565b6140e6565b6001600160a01b03808a166000818152607360209081526040808320948b168084529482528083208d8452909152808220549051627eeac760e11b81526004810193909352602483018c905293945092611f419290918891889162fdd58e90604401611e94565b604051627eeac760e11b81526001600160a01b038c81166004830152602482018b905291925060009189919089169062fdd58e90604401602060405180830381865afa158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb9919061554e565b611fc39190615797565b905080600003612002576001600160a01b03808c166000908152607360209081526040808320938b1683529281528282208c8352905290812055612050565b61201761200f8585615797565b878784613bbb565b61202190426157aa565b6001600160a01b03808d166000908152607360209081526040808320938c1683529281528282208d8352905220555b604051627eeac760e11b81526001600160a01b038b81166004830152602482018b90526000918a918a169062fdd58e90604401602060405180830381865afa1580156120a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c4919061554e565b6120ce91906157aa565b90506120e56120dd86856157aa565b888884613bbb565b6120ef90426157aa565b6001600160a01b039b8c1660009081526073602090815260408083209b909e168252998a528c81209b81529a9098525050509690952092909255505050505050565b6001600160a01b0383166000908152606b6020526040902054839060ff1661216c576040516371d42f3560e11b815260040160405180910390fd5b8361217f6033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146121c057336001600160a01b038216146121c0576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c602052604090206003016121e684868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160039190615532565b612228613be4565b606755565b6001600160a01b0384166000908152606b6020526040902054849060ff16612268576040516371d42f3560e11b815260040160405180910390fd5b8461227b6033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146122bc57336001600160a01b038216146122bc576040516305fa117f60e11b815260040160405180910390fd5b60005b84811015611283576001600160a01b0387166000908152606d6020526040812085918888858181106122f3576122f3615567565b90506020020160208101906123089190614a79565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905561233981615761565b90506122bf565b60405163bd85b03960e01b8152600481018290526000906001600160a01b0384169063bd85b03990602401602060405180830381865afa158015612388573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ac919061554e565b6000036123cc57604051633b41868f60e21b815260040160405180910390fd5b6001600160a01b0380841660008181526071602090815260408083208784528252808320549094168252606f815283822092825260728152838220868352905291909120548154811061242157612421615567565b906000526020600020906009020160030154905092915050565b6001600160a01b0384166000908152606b6020526040902054849060ff16612476576040516371d42f3560e11b815260040160405180910390fd5b846124896033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146124ca57336001600160a01b038216146124ca576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0386166000908152606f60205260409020805485918591889081106124f8576124f8615567565b9060005260206000209060090201600801918261251692919061560e565b506001600160a01b0386166000818152606f60205260409020805460008051602061596a833981519152918891600891908390811061255757612557615567565b90600052602060002090600902016040516125749392919061573f565b60405180910390a2505050505050565b61258c613be4565b6001600160a01b0381166000818152606b60209081526040808320805460ff19908116909155606c9092528083206005018054909216909155517fb8107d0c6b40be480ce3172ee66ba6d64b71f6b1685a851340036e6e2e3e3c529190a250565b6125f5613be4565b6125ff6000614129565b565b6001600160a01b0382166000908152606f60205260408120805483908110610fbe57610fbe615567565b6001600160a01b0383166000908152606b6020526040902054839060ff16612666576040516371d42f3560e11b815260040160405180910390fd5b836126796033546001600160a01b031690565b6001600160a01b0316336001600160a01b0316146126ba57336001600160a01b038216146126ba576040516305fa117f60e11b815260040160405180910390fd5b6067548310156126dd5760405163522036bf60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606f6020526040902080548491908690811061270a5761270a615567565b906000526020600020906009020160010181905550846001600160a01b031660008051602061596a833981519152856001606f60008a6001600160a01b03166001600160a01b03168152602001908152602001600020888154811061157957611579615567565b604051627eeac760e11b81526001600160a01b038481166004830152602482018490526000919086169062fdd58e90604401602060405180830381865afa1580156127c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127e4919061554e565b6001600160a01b038087166000818152607160209081526040808320898452825280832054938352607282528083208984529091528120549394509116919061282d8383612601565b905080600003612850576040516333adb20360e11b815260040160405180910390fd5b84600003612871576040516306c95d7d60e41b815260040160405180910390fd5b83600003612892576040516369bdf96560e11b815260040160405180910390fd5b6001600160a01b0383166128b95760405163137849f160e11b815260040160405180910390fd5b60006128d086836128ca8787613450565b88613bbb565b6001600160a01b03808a166000908152607360209081526040808320938e1683529281528282208b83529052908120805492935083929091906129149084906157aa565b9091555050604080518281526001600160a01b038a811660208301528b81168284015291519186169189917f29de542d58d5280b82118289d7236d2b096f3e56797fd3bc4228f19a3c476947919081900360600190a3506065546001600160a01b031663348709b4866129878686613450565b6129918886615593565b61299b91906157bd565b86607360008d6001600160a01b03166001600160a01b0316815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008c8152602001908152602001600020546129fd3390565b606660009054906101000a90046001600160a01b03166001600160a01b0316633013ce296040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7691906157df565b6040516001600160e01b031960e089901b168152600481019690965260248601949094526001600160a01b0392831660448601526064850191909152811660848401521660a482015260c401600060405180830381600087803b158015612adc57600080fd5b505af1158015612af0573d6000803e3d6000fd5b505050505050505050505050565b336000818152606b602052604090205460ff16612b2e576040516371d42f3560e11b815260040160405180910390fd5b6001600160a01b038216612b4857600160766000336117d8565b82607760003361181e565b6001600160a01b038381166000908152607160209081526040808320868452909152902054163314612b985760405163bc1a99ad60e01b815260040160405180910390fd5b612ba28383610edd565b600003612bc25760405163da9335d560e01b815260040160405180910390fd5b6001600160a01b0380821660009081526073602090815260408083209387168352928152828220858352905220544211612c0f576040516341f6b9a560e01b815260040160405180910390fd5b604051627eeac760e11b81526001600160a01b038281166004830152602482018490526000919085169062fdd58e90604401602060405180830381865afa158015612c5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c82919061554e565b905080600003612ca5576040516305319efb60e41b815260040160405180910390fd5b6001600160a01b0382811660009081526075602090815260408083209388168084529382528083208784529091529020805490839055903390857feef808aafa779451f3107a5033b5d50922fbd85286781c04ba9a3a88b7f27d77612d0a8587615797565b60405190815260200160405180910390a45050505050565b612d2a613be4565b606680546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038b166000908152606c6020526040902060058101805460ff19166001179055600201612d818a8c8361560e565b506001600160a01b038b166000908152606c60205260409020600101612da8888a8361560e565b506001600160a01b038b166000908152606c60205260409020600401612dcf86888361560e565b506001600160a01b038b166000908152606c6020526040902060058101805461ff00191661010084151502179055600301612e0b84868361560e565b506001600160a01b038b166000908152606c60205260409020829055612e308b612e97565b6001600160a01b038b166000818152606c60205260409081902090517f40a85abf2e067de420759997226b243a11146e32797c459e0ae521c164b3ef7c91612e77916157fc565b60405180910390a25050505050505050505050565b611314603c80615593565b612e9f613be4565b6001600160a01b0381166000818152606b602090815260408083208054600160ff199182168117909255606c90935292819020600581018054909316909317909155517fa08c78c5ffa2e84c547405de8308d3981bfc147bbe8186049de946adf23bedf291612f0d916157fc565b60405180910390a250565b612f20613be4565b60005b6001600160a01b0383166000908152606f602052604090205481101561185f57612f4e83838361417b565b5080612f5981615761565b915050612f23565b6066546001600160a01b0316336001600160a01b031614612f9557604051632d5fb10f60e01b815260040160405180910390fd5b6001600160a01b038087166000908152607060209081526040808320938d1683529281528282208a835290529081208054859290612fd49084906157aa565b90915550506001600160a01b0389811660008181526071602090815260408083208c8452825280832080546001600160a01b031916958c169586179055928252607281528282208b83528152828220899055928152606f909252812080548790811061304257613042615567565b906000526020600020906009020160040154111561338a576001600160a01b038089166000908152607360209081526040808320938d1683529281528282208a835290529081205490036130c1576001600160a01b038089166000908152607360209081526040808320938d1683529281528282208a83529052204290555b6001600160a01b0386166000908152606f602052604081208054613151918791899081106130f1576130f1615567565b906000526020600020906009020160040154606f60008b6001600160a01b03166001600160a01b03168152602001908152602001600020898154811061313957613139615567565b90600052602060002090600902016003015487613bbb565b6001600160a01b03808b166000908152607360209081526040808320938f1683529281528282208c83529052908120805492935083929091906131959084906157aa565b9091555050604080518281526001600160a01b038b811660208301528c8116828401529151918916918a917f29de542d58d5280b82118289d7236d2b096f3e56797fd3bc4228f19a3c476947919081900360600190a3506065546001600160a01b031663348709b4856132088989613450565b6001600160a01b038a166000908152606f6020526040902080548891908b90811061323557613235615567565b9060005260206000209060090201600401546132519190615593565b61325b91906157bd565b89607360008e6001600160a01b03166001600160a01b0316815260200190815260200160002060008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008d81526020019081526020016000205487876040518763ffffffff1660e01b815260040161330a9695949392919095865260208601949094526001600160a01b0392831660408601526060850191909152811660808401521660a082015260c00190565b600060405180830381600087803b15801561332457600080fd5b505af1158015613338573d6000803e3d6000fd5b505060408051888152602081018b90526001600160a01b038d8116828401529151918a1693507f9137dbe71594712b8c41002a261f3818dd6e951587d83c552606f4c53100f62b925081900360600190a25b505050505050505050565b6001600160a01b0388166000908152606b6020526040812054899060ff166133d0576040516371d42f3560e11b815260040160405180910390fd5b896133e36033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461342457336001600160a01b03821614613424576040516305fa117f60e11b815260040160405180910390fd5b6134348b8b8b8b8b8b8b8b6145cc565b9b9a5050505050505050505050565b61344b613be4565b606855565b6001600160a01b0382166000908152606f6020526040812080548390811061242157612421615567565b613482613be4565b607855565b6001600160a01b0382166000908152606b6020526040902054829060ff166134c2576040516371d42f3560e11b815260040160405180910390fd5b826134d56033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461351657336001600160a01b03821614613516576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0384166000818152606c6020526040908190206005808201805460ff1916881515179055915160008051602061594a83398151915292610c07929091615532565b6001600160a01b0382166000908152606f6020526040812080548390811061358857613588615567565b600091825260209091206009909102016007015460ff169392505050565b6001600160a01b0383166000908152606b6020526040902054839060ff166135e1576040516371d42f3560e11b815260040160405180910390fd5b836135f46033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461363557336001600160a01b03821614613635576040516305fa117f60e11b815260040160405180910390fd5b6001600160a01b0385166000908152606c6020526040902060040161365b84868361560e565b506001600160a01b0385166000818152606c602052604090819020905160008051602061594a8339815191529161144b9160049190615532565b61369d613be4565b6001600160a01b0381166137025760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016111be565b61370b81614129565b50565b6001600160a01b0384166000908152606b6020526040902054849060ff16613749576040516371d42f3560e11b815260040160405180910390fd5b8461375c6033546001600160a01b031690565b6001600160a01b0316336001600160a01b03161461379d57336001600160a01b0382161461379d576040516305fa117f60e11b815260040160405180910390fd5b6000808560038111156137b2576137b261580f565b036137bf5750600161383d565b60018560038111156137d3576137d361580f565b036137e05750603c61383d565b60028560038111156137f4576137f461580f565b0361380b57613804603c80615593565b905061383d565b600385600381111561381f5761381f61580f565b0361383d5761382f603c80615593565b61383a906018615593565b90505b6001600160a01b0387166000908152606f6020526040902080548291908890811061386a5761386a615567565b9060005260206000209060090201600301540361389a5760405163842cebc360e01b815260040160405180910390fd5b6138a687878684613d6c565b6001600160a01b0387166000908152606f602052604090208054829190889081106138d3576138d3615567565b906000526020600020906009020160030181905550866001600160a01b031660008051602061596a833981519152876003606f60008c6001600160a01b03166001600160a01b031681526020019081526020016000208a8154811061393a5761393a615567565b90600052602060002090600902016040516139579392919061573f565b60405180910390a250505050505050565b60005b8381101561338a576139fb89898381811061398857613988615567565b905060200201602081019061399d9190614a79565b8888848181106139af576139af615567565b90506020020160208101906139c49190614a79565b8787858181106139d6576139d6615567565b905060200201358686868181106139ef576139ef615567565b90506020020135612771565b80613a0581615761565b91505061396b565b6066546001600160a01b0316336001600160a01b031614613a4157604051632d5fb10f60e01b815260040160405180910390fd5b6001600160a01b0380821660009081526075602090815260408083209388168352928152828220868352905220548211613a8e5760405163481ae58160e01b815260040160405180910390fd5b6001600160a01b0384166000908152607260209081526040808320868452909152812054613abd908790612601565b6001600160a01b038616600090815260726020908152604080832088845290915281205491925090613af0908890613450565b90508115613b0857613b0683878787868661482d565b505b6001600160a01b038088166000908152607060209081526040808320938a16835292815282822088835290529081208054869290613b47908490615797565b90915550506001600160a01b038088166000908152607060209081526040808320938a168352928152828220888352905290812054900361128357505050506001600160a01b039190911660009081526071602090815260408083209383529290522080546001600160a01b031916905550565b6000613bc78285615593565b613bd18487615593565b613bdb91906157bd565b95945050505050565b6033546001600160a01b031633146125ff5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016111be565b600054610100900460ff16613c655760405162461bcd60e51b81526004016111be90615825565b6125ff6149d2565b6001600160a01b0380841660009081526070602081815260408084208a86168086529083528185208a865283528185208054908690559588168552928252808420928452918152818320888452905281208054839290613cce9084906157aa565b90915550506001600160a01b0386811660008181526071602090815260408083208a8452825280832080546001600160a01b031916898716908117909155848452607283528184208b855283529281902087905580518781529182018a9052810192909252918616907fa6beab620e184a03527e5ae53cfcf2bcc0a561f7fe957d28839a116e45ef70379060600160405180910390a3505050505050565b81600003613d8d576040516333adb20360e11b815260040160405180910390fd5b6001600160a01b0384166000908152606f60205260409020805484908110613db757613db7615567565b906000526020600020906009020160040154600003613de95760405163031fbaf760e41b815260040160405180910390fd5b6001600160a01b0384166000908152606f60205260408120805485908110613e1357613e13615567565b906000526020600020906009020160030154905080606f6000876001600160a01b03166001600160a01b031681526020019081526020016000208581548110613e5e57613e5e615567565b906000526020600020906009020160040154613e7a91906157bd565b613e8483856157bd565b1115613fbe576068546001600160a01b0386166000908152606f60205260409020805486908110613eb757613eb7615567565b906000526020600020906009020160060154613ed391906157aa565b421015613ef3576040516304caab9960e31b815260040160405180910390fd5b613eff61271082615593565b6069546001600160a01b0387166000908152606f60205260409020805487908110613f2c57613f2c615567565b906000526020600020906009020160040154613f489190615593565b613f5291906157bd565b613f5c83856157bd565b1115613f7b5760405163eb10300160e01b815260040160405180910390fd5b6001600160a01b0385166000908152606f60205260409020805442919086908110613fa857613fa8615567565b9060005260206000209060090201600601819055505b6001600160a01b0385166000908152606f60205260409020805484919086908110613feb57613feb615567565b90600052602060002090600902016004018190555080606f6000876001600160a01b03166001600160a01b03168152602001908152602001600020858154811061403757614037615567565b90600052602060002090600902016005015461405391906157bd565b61405d83856157bd565b10156140a6576001600160a01b0385166000908152606f6020526040902080548491908690811061409057614090615567565b9060005260206000209060090201600501819055505b6001600160a01b0385166000818152606f60205260409020805460008051602061596a833981519152918791600491908390811061157957611579615567565b60004285116140f757506000610ed5565b8282856141044289615797565b61410e9190615593565b6141189190615593565b61412291906157bd565b9050610ed5565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038083166000908152606f602052604080822080548251610120810184529488168452919092208054919391829190869081106141c1576141c1615567565b9060005260206000209060090201600001548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061420e5761420e615567565b9060005260206000209060090201600101548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061425b5761425b615567565b9060005260206000209060090201600201548152602001606f6000886001600160a01b03166001600160a01b0316815260200190815260200160002085815481106142a8576142a8615567565b9060005260206000209060090201600301548152602001606f6000886001600160a01b03166001600160a01b0316815260200190815260200160002085815481106142f5576142f5615567565b9060005260206000209060090201600401548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061434257614342615567565b9060005260206000209060090201600501548152602001606f6000886001600160a01b03166001600160a01b03168152602001908152602001600020858154811061438f5761438f615567565b9060005260206000209060090201600601548152602001606f6000886001600160a01b03166001600160a01b0316815260200190815260200160002085815481106143dc576143dc615567565b600091825260208083206007600990930201919091015460ff16151583526001600160a01b0389168252606f81526040909120805492909101918690811061442657614426615567565b90600052602060002090600902016008018054614442906153ed565b80601f016020809104026020016040519081016040528092919081815260200182805461446e906153ed565b80156144bb5780601f10614490576101008083540402835291602001916144bb565b820191906000526020600020905b81548152906001019060200180831161449e57829003601f168201915b50505091909252505081546001808201845560009384526020938490208351600990930201918255928201519281019290925560408101516002830155606081015160038301556080810151600483015560a0810151600583015560c0810151600683015560e081015160078301805460ff191691151591909117905561010081015190919060088201906145509082615870565b5050506001600160a01b0383166000818152606f6020526040902080547f1d50952dd79441da39cded51d73c41faef52bb4929b6f9d51cc0e004842630e2918491829081106145a1576145a1615567565b90600052602060002090600902016040516145bd929190615930565b60405180910390a29392505050565b6001600160a01b0388166000908152606f602052604081205490808560038111156145f9576145f961580f565b0361460657506001614684565b600185600381111561461a5761461a61580f565b036146275750603c614684565b600285600381111561463b5761463b61580f565b036146525761464b603c80615593565b9050614684565b60038560038111156146665761466661580f565b0361468457614676603c80615593565b614681906018615593565b90505b606f60008b6001600160a01b03166001600160a01b031681526020019081526020016000206040518061012001604052808b81526020018a815260200189815260200183815260200188815260200188815260200142815260200160011515815260200186868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525050835460018082018655948252602091829020845160099092020190815590830151938101939093555060408101516002830155606081015160038301556080810151600483015560a0810151600583015560c0810151600683015560e081015160078301805460ff191691151591909117905561010081015190919060088201906147ab9082615870565b5050506001600160a01b038a166000818152606f6020526040902080547f1d50952dd79441da39cded51d73c41faef52bb4929b6f9d51cc0e004842630e2918591829081106147fc576147fc615567565b9060005260206000209060090201604051614818929190615930565b60405180910390a25098975050505050505050565b604051627eeac760e11b81526001600160a01b03878116600483015260248201869052600091829188169062fdd58e90604401602060405180830381865afa15801561487d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a1919061554e565b6001600160a01b03808a166000908152607360209081526040808320938c1683529281528282208a8352905290812054919250906148e1908686856140e6565b6001600160a01b03808b166000908152607360209081526040808320938d1683529281528282208b8352905290812054919250906149219087878a6140e6565b905061492d8784615797565b600003614969576001600160a01b03808b166000908152607360209081526040808320938d1683529281528282208b83529052908120556149c5565b60006149896149788385615797565b88886149848c89615797565b613bbb565b905061499581426157aa565b6001600160a01b03808d166000908152607360209081526040808320938f1683529281528282208d835290522055505b9998505050505050505050565b600054610100900460ff166149f95760405162461bcd60e51b81526004016111be90615825565b6125ff33614129565b6001600160a01b038116811461370b57600080fd5b8035614a2281614a02565b919050565b801515811461370b57600080fd5b8035614a2281614a27565b60008060408385031215614a5357600080fd5b8235614a5e81614a02565b91506020830135614a6e81614a27565b809150509250929050565b600060208284031215614a8b57600080fd5b8135614a9681614a02565b9392505050565b6000815180845260005b81811015614ac357602081850181015186830182015201614aa7565b506000602082860101526020601f19601f83011685010191505092915050565b87815260e060208201526000614afc60e0830189614a9d565b8281036040840152614b0e8189614a9d565b90508281036060840152614b228188614a9d565b90508281036080840152614b368187614a9d565b94151560a0840152505090151560c09091015295945050505050565b600080600060608486031215614b6757600080fd5b8335614b7281614a02565b92506020840135614b8281614a02565b91506040840135614b9281614a02565b809150509250925092565b60008060408385031215614bb057600080fd5b8235614bbb81614a02565b946020939093013593505050565b60008060008060808587031215614bdf57600080fd5b84359350602085013592506040850135614bf881614a02565b9396929550929360600135925050565b60008060008060008060c08789031215614c2157600080fd5b8635955060208701359450604087013593506060870135614c4181614a02565b92506080870135614c5181614a02565b8092505060a087013590509295509295509295565b600060208284031215614c7857600080fd5b5035919050565b60008083601f840112614c9157600080fd5b50813567ffffffffffffffff811115614ca957600080fd5b602083019150836020828501011115614cc157600080fd5b9250929050565b600080600060408486031215614cdd57600080fd5b8335614ce881614a02565b9250602084013567ffffffffffffffff811115614d0457600080fd5b614d1086828701614c7f565b9497909650939450505050565b600080600060608486031215614d3257600080fd5b8335614d3d81614a02565b9250602084013591506040840135614b9281614a27565b600080600060608486031215614d6957600080fd5b8335614d7481614a02565b95602085013595506040909401359392505050565b60008060408385031215614d9c57600080fd5b8235614da781614a02565b91506020830135614a6e81614a02565b60006101208b83528a60208401528960408401528860608401528760808401528660a08401528560c084015284151560e084015280610100840152614dfe81840185614a9d565b9c9b505050505050505050505050565b60008083601f840112614e2057600080fd5b50813567ffffffffffffffff811115614e3857600080fd5b6020830191508360208260051b8501011115614cc157600080fd5b600080600080600080600060a0888a031215614e6e57600080fd5b8735614e7981614a02565b9650602088013567ffffffffffffffff80821115614e9657600080fd5b614ea28b838c01614e0e565b909850965060408a01359150614eb782614a02565b909450606089013590614ec982614a02565b90935060808901359080821115614edf57600080fd5b50614eec8a828b01614e0e565b989b979a50959850939692959293505050565b60008060008060808587031215614f1557600080fd5b8435614f2081614a02565b93506020850135614f3081614a02565b93969395505050506040820135916060013590565b60008060008060608587031215614f5b57600080fd5b8435614f6681614a02565b9350602085013567ffffffffffffffff811115614f8257600080fd5b614f8e87828801614e0e565b9094509250506040850135614fa281614a27565b939692955090935050565b60008060008060608587031215614fc357600080fd5b8435614fce81614a02565b935060208501359250604085013567ffffffffffffffff811115614ff157600080fd5b614ffd87828801614c7f565b95989497509550505050565b60008060006060848603121561501e57600080fd5b833561502981614a02565b9250602084013591506040840135614b9281614a02565b600080600080600080600080600080600060e08c8e03121561506157600080fd5b61506a8c614a17565b9a5067ffffffffffffffff8060208e0135111561508657600080fd5b6150968e60208f01358f01614c7f565b909b50995060408d01358110156150ac57600080fd5b6150bc8e60408f01358f01614c7f565b909950975060608d01358110156150d257600080fd5b6150e28e60608f01358f01614c7f565b909750955060808d01358110156150f857600080fd5b506151098d60808e01358e01614c7f565b909450925060a08c0135915061512160c08d01614a35565b90509295989b509295989b9093969950565b60008060006060848603121561514857600080fd5b833561515381614a02565b9250602084013561516381614a02565b929592945050506040919091013590565b60008060008060008060008060006101208a8c03121561519357600080fd5b893561519e81614a02565b985060208a01356151ae81614a02565b975060408a0135965060608a01356151c581614a02565b955060808a0135945060a08a0135935060c08a0135925060e08a01356151ea81614a02565b91506101008a01356151fb81614a02565b809150509295985092959850929598565b803560048110614a2257600080fd5b60008060008060008060008060e0898b03121561523757600080fd5b883561524281614a02565b97506020890135965060408901359550606089013594506080890135935061526c60a08a0161520c565b925060c089013567ffffffffffffffff81111561528857600080fd5b6152948b828c01614c7f565b999c989b5096995094979396929594505050565b600080600080608085870312156152be57600080fd5b84356152c981614a02565b935060208501359250614bf86040860161520c565b6000806000806000806000806080898b0312156152fa57600080fd5b883567ffffffffffffffff8082111561531257600080fd5b61531e8c838d01614e0e565b909a50985060208b013591508082111561533757600080fd5b6153438c838d01614e0e565b909850965060408b013591508082111561535c57600080fd5b6153688c838d01614e0e565b909650945060608b013591508082111561538157600080fd5b506152948b828c01614e0e565b600080600080600060a086880312156153a657600080fd5b85356153b181614a02565b945060208601356153c181614a02565b9350604086013592506060860135915060808601356153df81614a02565b809150509295509295909350565b600181811c9082168061540157607f821691505b60208210810361542157634e487b7160e01b600052602260045260246000fd5b50919050565b60008154615434816153ed565b808552602060018381168015615451576001811461546b57615499565b60ff1985168884015283151560051b880183019550615499565b866000528260002060005b858110156154915781548a8201860152908301908401615476565b890184019650505b505050505092915050565b8054825260e0602083015260006154c160e0840160018401615427565b83810360408501526154d68160028501615427565b905083810360608501526154ed8160038501615427565b905083810360808501526155048160048501615427565b9050600583015460ff8116151560a086015261552a60c0860160ff8360081c1615159052565b509392505050565b60ff83168152604060208201526000610ed560408301846154a4565b60006020828403121561556057600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610fd357610fd361557d565b634e487b7160e01b600052604160045260246000fd5b601f82111561185f57600081815260208120601f850160051c810160208610156155e75750805b601f850160051c820191505b81811015615606578281556001016155f3565b505050505050565b67ffffffffffffffff831115615626576156266155aa565b61563a8361563483546153ed565b836155c0565b6000601f84116001811461566e57600085156156565750838201355b600019600387901b1c1916600186901b178355611ca3565b600083815260209020601f19861690835b8281101561569f578685013582556020948501946001909201910161567f565b50868210156156bc5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006101208254845260018301546020850152600283015460408501526003830154606085015260048301546080850152600583015460a0850152600683015460c0850152615721600784015460ff1690565b151560e08501526101008401819052610ed581850160088501615427565b83815260ff83166020820152606060408201526000613bdb60608301846156ce565b6000600182016157735761577361557d565b5060010190565b60006020828403121561578c57600080fd5b8151614a9681614a27565b81810381811115610fd357610fd361557d565b80820180821115610fd357610fd361557d565b6000826157da57634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156157f157600080fd5b8151614a9681614a02565b602081526000614a9660208301846154a4565b634e487b7160e01b600052602160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b815167ffffffffffffffff81111561588a5761588a6155aa565b61589e8161589884546153ed565b846155c0565b602080601f8311600181146158d357600084156158bb5750858301515b600019600386901b1c1916600185901b178555615606565b600085815260208120601f198616915b82811015615902578886015182559484019460019091019084016158e3565b50858210156159205787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b828152604060208201526000610ed560408301846156ce56fe5fff5779f55d71041c8a8dac64fd1d4394cf4b41d7ef502baf7bbeabad381b37be670b8146f19d76b44fcaf05a819ec7dfe1d8265e48858e044fbed8126b0a23a2646970667358221220e6af59b87b4cc7646ac1b838eedb18bafe8df2c1b610dc63fc557a354bf136d064736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.