Polygon Sponsored slots available. Book your slot here!
Overview
MATIC Balance
0 MATIC
MATIC Value
$0.00More Info
Private Name Tags
ContractCreator:
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 28566921 | 678 days ago | IN | Create: RealmFacet | 0 MATIC | 4.3258467 |
Loading...
Loading
Contract Name:
RealmFacet
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.9; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../../libraries/AppStorage.sol"; import "../../libraries/LibDiamond.sol"; import "../../libraries/LibStrings.sol"; import "../../libraries/LibMeta.sol"; import "../../libraries/LibERC721.sol"; import "../../libraries/LibRealm.sol"; import "../../libraries/LibAlchemica.sol"; import {InstallationDiamondInterface} from "../../interfaces/InstallationDiamondInterface.sol"; import "../../libraries/LibSignature.sol"; import "./ERC721Facet.sol"; contract RealmFacet is Modifiers { uint256 constant MAX_SUPPLY = 420069; struct MintParcelInput { uint256 coordinateX; uint256 coordinateY; uint256 district; string parcelId; string parcelAddress; uint256 size; //0=humble, 1=reasonable, 2=spacious vertical, 3=spacious horizontal, 4=partner uint256[4] boost; //fud, fomo, alpha, kek } event ResyncParcel(uint256 _realmId); event EquipInstallation(uint256 _realmId, uint256 _installationId, uint256 _x, uint256 _y); event UnequipInstallation(uint256 _realmId, uint256 _installationId, uint256 _x, uint256 _y); event EquipTile(uint256 _realmId, uint256 _tileId, uint256 _x, uint256 _y); event UnequipTile(uint256 _realmId, uint256 _tileId, uint256 _x, uint256 _y); event AavegotchiDiamondUpdated(address _aavegotchiDiamond); event InstallationUpgraded(uint256 _realmId, uint256 _prevInstallationId, uint256 _nextInstallationId, uint256 _coordinateX, uint256 _coordinateY); /// @notice Return the maximum realm supply /// @return The max realm token supply function maxSupply() external pure returns (uint256) { return MAX_SUPPLY; } /// @notice Allow the diamond owner to mint new parcels /// @param _to The address to mint the parcels to /// @param _tokenIds The identifiers of tokens to mint /// @param _metadata An array of structs containing the metadata of each parcel being minted function mintParcels( address _to, uint256[] calldata _tokenIds, MintParcelInput[] memory _metadata ) external onlyOwner { for (uint256 index = 0; index < _tokenIds.length; index++) { require(s.tokenIds.length < MAX_SUPPLY, "RealmFacet: Cannot mint more than 420,069 parcels"); uint256 tokenId = _tokenIds[index]; MintParcelInput memory metadata = _metadata[index]; require(_tokenIds.length == _metadata.length, "Inputs must be same length"); Parcel storage parcel = s.parcels[tokenId]; parcel.coordinateX = metadata.coordinateX; parcel.coordinateY = metadata.coordinateY; parcel.parcelId = metadata.parcelId; parcel.size = metadata.size; parcel.district = metadata.district; parcel.parcelAddress = metadata.parcelAddress; parcel.alchemicaBoost = metadata.boost; LibERC721.safeMint(_to, tokenId); } } /// @notice Allow a parcel owner to equip an installation /// @dev The _x and _y denote the starting coordinates of the installation and are used to make sure that slot is available on a parcel /// @param _realmId The identifier of the parcel which the installation is being equipped on /// @param _installationId The identifier of the installation being equipped /// @param _x The x(horizontal) coordinate of the installation /// @param _y The y(vertical) coordinate of the installation function equipInstallation( uint256 _realmId, uint256 _installationId, uint256 _x, uint256 _y, bytes memory _signature ) external onlyParcelOwner(_realmId) gameActive { require( LibSignature.isValid(keccak256(abi.encodePacked(_realmId, _installationId, _x, _y)), _signature, s.backendPubKey), "RealmFacet: Invalid signature" ); InstallationDiamondInterface.InstallationType memory installation = InstallationDiamondInterface(s.installationsDiamond).getInstallationType( _installationId ); if (installation.installationType == 1 || installation.installationType == 2) { require(s.parcels[_realmId].currentRound >= 1, "RealmFacet: Must survey before equipping"); } if (installation.installationType == 3) { require(s.parcels[_realmId].lodgeId == 0, "RealmFacet: Lodge already equipped"); s.parcels[_realmId].lodgeId = _installationId; } LibRealm.placeInstallation(_realmId, _installationId, _x, _y); InstallationDiamondInterface(s.installationsDiamond).equipInstallation(msg.sender, _realmId, _installationId); LibAlchemica.increaseTraits(_realmId, _installationId, false); emit EquipInstallation(_realmId, _installationId, _x, _y); } /// @notice Allow a parcel owner to unequip an installation /// @dev The _x and _y denote the starting coordinates of the installation and are used to make sure that slot is available on a parcel /// @param _realmId The identifier of the parcel which the installation is being unequipped from /// @param _installationId The identifier of the installation being unequipped /// @param _x The x(horizontal) coordinate of the installation /// @param _y The y(vertical) coordinate of the installation function unequipInstallation( uint256 _realmId, uint256 _installationId, uint256 _x, uint256 _y, bytes memory _signature ) external onlyParcelOwner(_realmId) gameActive { require( LibSignature.isValid(keccak256(abi.encodePacked(_realmId, _installationId, _x, _y)), _signature, s.backendPubKey), "RealmFacet: Invalid signature" ); InstallationDiamondInterface installationsDiamond = InstallationDiamondInterface(s.installationsDiamond); InstallationDiamondInterface.InstallationType memory installation = installationsDiamond.getInstallationType(_installationId); LibRealm.removeInstallation(_realmId, _installationId, _x, _y); for (uint256 i; i < installation.alchemicaCost.length; i++) { IERC20 alchemica = IERC20(s.alchemicaAddresses[i]); //@question : include upgrades in refund? uint256 alchemicaRefund = installation.alchemicaCost[i] / 2; alchemica.transfer(msg.sender, alchemicaRefund); } InstallationDiamondInterface(s.installationsDiamond).unequipInstallation(_realmId, _installationId); LibAlchemica.reduceTraits(_realmId, _installationId, false); emit UnequipInstallation(_realmId, _installationId, _x, _y); } /// @notice Allow a parcel owner to equip a tile /// @dev The _x and _y denote the starting coordinates of the tile and are used to make sure that slot is available on a parcel /// @param _realmId The identifier of the parcel which the tile is being equipped on /// @param _tileId The identifier of the tile being equipped /// @param _x The x(horizontal) coordinate of the tile /// @param _y The y(vertical) coordinate of the tile function equipTile( uint256 _realmId, uint256 _tileId, uint256 _x, uint256 _y, bytes memory _signature ) external onlyParcelOwner(_realmId) gameActive { require( LibSignature.isValid(keccak256(abi.encodePacked(_realmId, _tileId, _x, _y)), _signature, s.backendPubKey), "RealmFacet: Invalid signature" ); LibRealm.placeTile(_realmId, _tileId, _x, _y); TileDiamondInterface(s.tileDiamond).equipTile(msg.sender, _realmId, _tileId); emit EquipTile(_realmId, _tileId, _x, _y); } /// @notice Allow a parcel owner to unequip a tile /// @dev The _x and _y denote the starting coordinates of the tile and are used to make sure that slot is available on a parcel /// @param _realmId The identifier of the parcel which the tile is being unequipped from /// @param _tileId The identifier of the tile being unequipped /// @param _x The x(horizontal) coordinate of the tile /// @param _y The y(vertical) coordinate of the tile function unequipTile( uint256 _realmId, uint256 _tileId, uint256 _x, uint256 _y, bytes memory _signature ) external onlyParcelOwner(_realmId) gameActive { require( LibSignature.isValid(keccak256(abi.encodePacked(_realmId, _tileId, _x, _y)), _signature, s.backendPubKey), "RealmFacet: Invalid signature" ); LibRealm.removeTile(_realmId, _tileId, _x, _y); TileDiamondInterface(s.tileDiamond).unequipTile(msg.sender, _realmId, _tileId); emit UnequipTile(_realmId, _tileId, _x, _y); } function setParcelsAccessRights( uint256[] calldata _realmIds, uint256[] calldata _actionRights, uint256[] calldata _accessRights ) external gameActive { require(_realmIds.length == _accessRights.length && _realmIds.length == _actionRights.length, "RealmFacet: Mismatched arrays"); for (uint256 i; i < _realmIds.length; i++) { require(LibMeta.msgSender() == s.parcels[_realmIds[i]].owner, "RealmFacet: Only Parcel owner can call"); s.accessRights[_realmIds[i]][_actionRights[i]] = _accessRights[i]; } } struct ParcelOutput { string parcelId; string parcelAddress; address owner; uint256 coordinateX; //x position on the map uint256 coordinateY; //y position on the map uint256 size; //0=humble, 1=reasonable, 2=spacious vertical, 3=spacious horizontal, 4=partner uint256 district; uint256[4] boost; uint256 timeRemainingToClaim; } /** @dev Used to resync a parcel on the subgraph if metadata is added later @param _tokenIds The parcels to resync */ function resyncParcel(uint256[] calldata _tokenIds) external onlyOwner { for (uint256 index = 0; index < _tokenIds.length; index++) { emit ResyncParcel(_tokenIds[index]); } } function setGameActive(bool _gameActive) external onlyOwner { s.gameActive = _gameActive; } /// @notice Fetch information about a parcel /// @param _realmId The identifier of the parcel being queried /// @return output_ A struct containing details about the parcel being queried function getParcelInfo(uint256 _realmId) external view returns (ParcelOutput memory output_) { Parcel storage parcel = s.parcels[_realmId]; output_.parcelId = parcel.parcelId; output_.owner = parcel.owner; output_.coordinateX = parcel.coordinateX; output_.coordinateY = parcel.coordinateY; output_.size = parcel.size; output_.parcelAddress = parcel.parcelAddress; output_.district = parcel.district; output_.boost = parcel.alchemicaBoost; output_.timeRemainingToClaim = s.lastClaimedAlchemica[_realmId]; } function checkCoordinates( uint256 _realmId, uint256 _coordinateX, uint256 _coordinateY, uint256 _installationId ) public view { Parcel storage parcel = s.parcels[_realmId]; require(parcel.buildGrid[_coordinateX][_coordinateY] == _installationId, "RealmFacet: wrong coordinates"); } function upgradeInstallation( uint256 _realmId, uint256 _prevInstallationId, uint256 _nextInstallationId, uint256 _coordinateX, uint256 _coordinateY ) external onlyInstallationDiamond { LibRealm.removeInstallation(_realmId, _prevInstallationId, _coordinateX, _coordinateY); LibRealm.placeInstallation(_realmId, _nextInstallationId, _coordinateX, _coordinateY); LibAlchemica.reduceTraits(_realmId, _prevInstallationId, true); LibAlchemica.increaseTraits(_realmId, _prevInstallationId, true); emit InstallationUpgraded(_realmId, _prevInstallationId, _nextInstallationId, _coordinateX, _coordinateY); } function addUpgradeQueueLength(uint256 _realmId) external onlyInstallationDiamond { s.parcels[_realmId].upgradeQueueLength++; } function subUpgradeQueueLength(uint256 _realmId) external onlyInstallationDiamond { s.parcels[_realmId].upgradeQueueLength--; } function getHumbleGrid(uint256 _parcelId, uint256 _gridType) external view returns (uint256[8][8] memory output_) { require(s.parcels[_parcelId].size == 0, "RealmFacet: Not humble"); for (uint256 i; i < 8; i++) { for (uint256 j; j < 8; j++) { if (_gridType == 0) { output_[i][j] = s.parcels[_parcelId].buildGrid[j][i]; } else if (_gridType == 1) { output_[i][j] = s.parcels[_parcelId].tileGrid[j][i]; } } } } function getReasonableGrid(uint256 _parcelId, uint256 _gridType) external view returns (uint256[16][16] memory output_) { require(s.parcels[_parcelId].size == 1, "RealmFacet: Not reasonable"); for (uint256 i; i < 16; i++) { for (uint256 j; j < 16; j++) { if (_gridType == 0) { output_[i][j] = s.parcels[_parcelId].buildGrid[j][i]; } else if (_gridType == 1) { output_[i][j] = s.parcels[_parcelId].tileGrid[j][i]; } } } } function getSpaciousVerticalGrid(uint256 _parcelId, uint256 _gridType) external view returns (uint256[32][64] memory output_) { require(s.parcels[_parcelId].size == 2, "RealmFacet: Not spacious vertical"); for (uint256 i; i < 64; i++) { for (uint256 j; j < 32; j++) { if (_gridType == 0) { output_[i][j] = s.parcels[_parcelId].buildGrid[j][i]; } else if (_gridType == 1) { output_[i][j] = s.parcels[_parcelId].tileGrid[j][i]; } } } } function getSpaciousHorizontalGrid(uint256 _parcelId, uint256 _gridType) external view returns (uint256[64][32] memory output_) { require(s.parcels[_parcelId].size == 3, "RealmFacet: Not spacious horizontal"); for (uint256 i; i < 32; i++) { for (uint256 j; j < 64; j++) { if (_gridType == 0) { output_[i][j] = s.parcels[_parcelId].buildGrid[j][i]; } else if (_gridType == 1) { output_[i][j] = s.parcels[_parcelId].tileGrid[j][i]; } } } } function getPaartnerGrid(uint256 _parcelId, uint256 _gridType) external view returns (uint256[64][64] memory output_) { require(s.parcels[_parcelId].size == 4, "RealmFacet: Not paartner"); for (uint256 i; i < 64; i++) { for (uint256 j; j < 64; j++) { if (_gridType == 0) { output_[i][j] = s.parcels[_parcelId].buildGrid[j][i]; } else if (_gridType == 1) { output_[i][j] = s.parcels[_parcelId].tileGrid[j][i]; } } } } struct ParcelCoordinates { uint256[64][64] coords; } function batchGetGrid(uint256[] calldata _parcelIds, uint256 _gridType) external view returns (ParcelCoordinates[] memory) { ParcelCoordinates[] memory parcels = new ParcelCoordinates[](_parcelIds.length); for (uint256 k; k < _parcelIds.length; k++) { for (uint256 i; i < 64; i++) { for (uint256 j; j < 64; j++) { if (_gridType == 0) { parcels[k].coords[i][j] = s.parcels[_parcelIds[k]].buildGrid[j][i]; } else if (_gridType == 1) { parcels[k].coords[i][j] = s.parcels[_parcelIds[k]].tileGrid[j][i]; } } } } return parcels; } function batchGetDistrictParcels(address _owner, uint256 _district) external view returns (uint256[] memory) { uint256 totalSupply = ERC721Facet(address(this)).totalSupply(); uint256 balance = ERC721Facet(address(this)).balanceOf(_owner); uint256[] memory output_ = new uint256[](balance); uint256 counter; for (uint256 i; i < totalSupply; i++) { if (s.parcels[i].district == _district && s.parcels[i].owner == _owner) { output_[counter] = i; counter++; } } return output_; } function getParcelUpgradeQueueLength(uint256 _parcelId) external view returns (uint256) { return s.parcels[_parcelId].upgradeQueueLength; } function getParcelUpgradeQueueCapacity(uint256 _parcelId) external view returns (uint256) { return s.parcels[_parcelId].upgradeQueueCapacity; } function getParcelsAccessRights(uint256[] calldata _parcelIds, uint256[] calldata _actionRights) external view returns (uint256[] memory output_) { require(_parcelIds.length == _actionRights.length, "RealmFacet: Mismatched arrays"); output_ = new uint256[](_parcelIds.length); for (uint256 i; i < _parcelIds.length; i++) { output_[i] = s.accessRights[_parcelIds[i]][_actionRights[i]]; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import {LibDiamond} from "./LibDiamond.sol"; import {LibMeta} from "./LibMeta.sol"; import "../interfaces/AavegotchiDiamond.sol"; uint256 constant HUMBLE_WIDTH = 8; uint256 constant HUMBLE_HEIGHT = 8; uint256 constant REASONABLE_WIDTH = 16; uint256 constant REASONABLE_HEIGHT = 16; uint256 constant SPACIOUS_WIDTH = 32; uint256 constant SPACIOUS_HEIGHT = 64; uint256 constant PAARTNER_WIDTH = 64; uint256 constant PAARTNER_HEIGHT = 64; uint256 constant FUD = 0; uint256 constant FOMO = 1; uint256 constant ALPHA = 2; uint256 constant KEK = 3; struct Parcel { address owner; string parcelAddress; //looks-like-this string parcelId; //C-4208-3168-R uint256 coordinateX; //x position on the map uint256 coordinateY; //y position on the map uint256 district; uint256 size; //0=humble, 1=reasonable, 2=spacious vertical, 3=spacious horizontal, 4=partner uint256[64][64] buildGrid; //x, then y array of positions - for installations uint256[64][64] tileGrid; //x, then y array of positions - for tiles under the installations (floor) uint256[4] alchemicaBoost; //fud, fomo, alpha, kek uint256[4] alchemicaRemaining; //fud, fomo, alpha, kek uint256 currentRound; //begins at 0 and increments after surveying has begun mapping(uint256 => uint256[]) roundBaseAlchemica; //round alchemica not including boosts mapping(uint256 => uint256[]) roundAlchemica; //round alchemica including boosts // // alchemicaType => array of reservoir id mapping(uint256 => uint256[]) reservoirs; uint256[4] alchemicaHarvestRate; uint256[4] lastUpdateTimestamp; uint256[4] unclaimedAlchemica; uint256 altarId; uint256 upgradeQueueCapacity; uint256 upgradeQueueLength; uint256 lodgeId; bool surveying; } struct RequestConfig { uint64 subId; uint32 callbackGasLimit; uint16 requestConfirmations; uint32 numWords; bytes32 keyHash; } struct AppStorage { uint256[] tokenIds; mapping(uint256 => Parcel) parcels; mapping(address => mapping(uint256 => uint256)) ownerTokenIdIndexes; mapping(address => uint256[]) ownerTokenIds; mapping(address => mapping(address => bool)) operators; mapping(uint256 => address) approved; address aavegotchiDiamond; address[4] alchemicaAddresses; //fud, fomo, alpha, kek address installationsDiamond; uint256 surveyingRound; uint256[4][5] totalAlchemicas; uint256[4] boostMultipliers; uint256[4] greatPortalCapacity; // VRF address vrfCoordinator; address linkAddress; RequestConfig requestConfig; mapping(uint256 => uint256) vrfRequestIdToTokenId; mapping(uint256 => uint256) vrfRequestIdToSurveyingRound; bytes backendPubKey; address gameManager; mapping(uint256 => uint256) lastExitTime; //for aavegotchis exiting alchemica // gotchiId => lastChanneledGotchi mapping(uint256 => uint256) gotchiChannelings; // parcelId => lastChanneledParcel mapping(uint256 => uint256) parcelChannelings; // altarLevel => cooldown hours in seconds mapping(uint256 => uint256) channelingLimits; // parcelId => lastClaimedAlchemica mapping(uint256 => uint256) lastClaimedAlchemica; address gltrAddress; address tileDiamond; bool gameActive; // parcelId => action: 0 Alchemical Channeling, 1 Emptying Reservoirs => permission: 0 Owner only, 1 Owner + Borrowed Gotchis, 2 Any Gotchi mapping(uint256 => mapping(uint256 => uint256)) accessRights; // gotchiId => lastChanneledDay mapping(uint256 => uint256) lastChanneledDay; } library LibAppStorage { function diamondStorage() internal pure returns (AppStorage storage ds) { assembly { ds.slot := 0 } } } contract Modifiers { AppStorage internal s; modifier onlyParcelOwner(uint256 _tokenId) { require(LibMeta.msgSender() == s.parcels[_tokenId].owner, "AppStorage: Only Parcel owner can call"); _; } modifier onlyOwner() { LibDiamond.enforceIsContractOwner(); _; } modifier onlyGotchiOwner(uint256 _gotchiId) { AavegotchiDiamond diamond = AavegotchiDiamond(s.aavegotchiDiamond); require(LibMeta.msgSender() == diamond.ownerOf(_gotchiId), "AppStorage: Only Gotchi Owner can call"); _; } modifier onlyGameManager() { require(msg.sender == s.gameManager, "AlchemicaFacet: Only Game Manager"); _; } modifier onlyInstallationDiamond() { require(LibMeta.msgSender() == s.installationsDiamond, "AppStorage: Only Installation diamond can call"); _; } modifier gameActive() { require(s.gameActive, "AppStorage: game not active"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; library LibDiamond { bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); struct DiamondStorage { // maps function selectors to the facets that execute the functions. // and maps the selectors to their position in the selectorSlots array. // func selector => address facet, selector position mapping(bytes4 => bytes32) facets; // array of slots of function selectors. // each slot holds 8 function selectors. mapping(uint256 => bytes32) selectorSlots; // The number of function selectors in selectorSlots uint16 selectorCount; // Used to query if a contract implements an interface. // Used to implement ERC-165. mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; } function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } } event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; ds.contractOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); } function contractOwner() internal view returns (address contractOwner_) { contractOwner_ = diamondStorage().contractOwner; } function enforceIsContractOwner() internal view { require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner"); } event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); bytes32 constant CLEAR_ADDRESS_MASK = bytes32(uint256(0xffffffffffffffffffffffff)); bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224)); // Internal function version of diamondCut // This code is almost the same as the external diamondCut, // except it is using 'Facet[] memory _diamondCut' instead of // 'Facet[] calldata _diamondCut'. // The code is duplicated to prevent copying calldata to memory which // causes an error for a two dimensional array. function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata ) internal { DiamondStorage storage ds = diamondStorage(); uint256 originalSelectorCount = ds.selectorCount; uint256 selectorCount = originalSelectorCount; bytes32 selectorSlot; // Check if last selector slot is not full if (selectorCount & 7 > 0) { // get last selectorSlot selectorSlot = ds.selectorSlots[selectorCount >> 3]; } // loop through diamond cut for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) { (selectorCount, selectorSlot) = addReplaceRemoveFacetSelectors( selectorCount, selectorSlot, _diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].action, _diamondCut[facetIndex].functionSelectors ); } if (selectorCount != originalSelectorCount) { ds.selectorCount = uint16(selectorCount); } // If last selector slot is not full if (selectorCount & 7 > 0) { ds.selectorSlots[selectorCount >> 3] = selectorSlot; } emit DiamondCut(_diamondCut, _init, _calldata); initializeDiamondCut(_init, _calldata); } function addReplaceRemoveFacetSelectors( uint256 _selectorCount, bytes32 _selectorSlot, address _newFacetAddress, IDiamondCut.FacetCutAction _action, bytes4[] memory _selectors ) internal returns (uint256, bytes32) { DiamondStorage storage ds = diamondStorage(); require(_selectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); if (_action == IDiamondCut.FacetCutAction.Add) { enforceHasContractCode(_newFacetAddress, "LibDiamondCut: Add facet has no code"); for (uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++) { bytes4 selector = _selectors[selectorIndex]; bytes32 oldFacet = ds.facets[selector]; require(address(bytes20(oldFacet)) == address(0), "LibDiamondCut: Can't add function that already exists"); // add facet for selector ds.facets[selector] = bytes20(_newFacetAddress) | bytes32(_selectorCount); uint256 selectorInSlotPosition = (_selectorCount & 7) << 5; // clear selector position in slot and add selector _selectorSlot = (_selectorSlot & ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) | (bytes32(selector) >> selectorInSlotPosition); // if slot is full then write it to storage if (selectorInSlotPosition == 224) { ds.selectorSlots[_selectorCount >> 3] = _selectorSlot; _selectorSlot = 0; } _selectorCount++; } } else if (_action == IDiamondCut.FacetCutAction.Replace) { enforceHasContractCode(_newFacetAddress, "LibDiamondCut: Replace facet has no code"); for (uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++) { bytes4 selector = _selectors[selectorIndex]; bytes32 oldFacet = ds.facets[selector]; address oldFacetAddress = address(bytes20(oldFacet)); // only useful if immutable functions exist require(oldFacetAddress != address(this), "LibDiamondCut: Can't replace immutable function"); require(oldFacetAddress != _newFacetAddress, "LibDiamondCut: Can't replace function with same function"); require(oldFacetAddress != address(0), "LibDiamondCut: Can't replace function that doesn't exist"); // replace old facet address ds.facets[selector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20(_newFacetAddress); } } else if (_action == IDiamondCut.FacetCutAction.Remove) { require(_newFacetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)"); uint256 selectorSlotCount = _selectorCount >> 3; uint256 selectorInSlotIndex = _selectorCount & 7; for (uint256 selectorIndex; selectorIndex < _selectors.length; selectorIndex++) { if (_selectorSlot == 0) { // get last selectorSlot selectorSlotCount--; _selectorSlot = ds.selectorSlots[selectorSlotCount]; selectorInSlotIndex = 7; } else { selectorInSlotIndex--; } bytes4 lastSelector; uint256 oldSelectorsSlotCount; uint256 oldSelectorInSlotPosition; // adding a block here prevents stack too deep error { bytes4 selector = _selectors[selectorIndex]; bytes32 oldFacet = ds.facets[selector]; require(address(bytes20(oldFacet)) != address(0), "LibDiamondCut: Can't remove function that doesn't exist"); // only useful if immutable functions exist require(address(bytes20(oldFacet)) != address(this), "LibDiamondCut: Can't remove immutable function"); // replace selector with last selector in ds.facets // gets the last selector lastSelector = bytes4(_selectorSlot << (selectorInSlotIndex << 5)); if (lastSelector != selector) { // update last selector slot position info ds.facets[lastSelector] = (oldFacet & CLEAR_ADDRESS_MASK) | bytes20(ds.facets[lastSelector]); } delete ds.facets[selector]; uint256 oldSelectorCount = uint16(uint256(oldFacet)); oldSelectorsSlotCount = oldSelectorCount >> 3; oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5; } if (oldSelectorsSlotCount != selectorSlotCount) { bytes32 oldSelectorSlot = ds.selectorSlots[oldSelectorsSlotCount]; // clears the selector we are deleting and puts the last selector in its place. oldSelectorSlot = (oldSelectorSlot & ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)) | (bytes32(lastSelector) >> oldSelectorInSlotPosition); // update storage with the modified slot ds.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot; } else { // clears the selector we are deleting and puts the last selector in its place. _selectorSlot = (_selectorSlot & ~(CLEAR_SELECTOR_MASK >> oldSelectorInSlotPosition)) | (bytes32(lastSelector) >> oldSelectorInSlotPosition); } if (selectorInSlotIndex == 0) { delete ds.selectorSlots[selectorSlotCount]; _selectorSlot = 0; } } _selectorCount = selectorSlotCount * 8 + selectorInSlotIndex; } else { revert("LibDiamondCut: Incorrect FacetCutAction"); } return (_selectorCount, _selectorSlot); } function initializeDiamondCut(address _init, bytes memory _calldata) internal { if (_init == address(0)) { require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty"); } else { require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)"); if (_init != address(this)) { enforceHasContractCode(_init, "LibDiamondCut: _init address has no code"); } (bool success, bytes memory error) = _init.delegatecall(_calldata); if (!success) { if (error.length > 0) { // bubble up the error revert(string(error)); } else { revert("LibDiamondCut: _init function reverted"); } } } } function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } require(contractSize > 0, _errorMessage); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; // From Open Zeppelin contracts: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol /** * @dev String operations. */ library LibStrings { /** * @dev Converts a `uint256` to its ASCII `string` representation. */ function strWithUint(string memory _str, uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol bytes memory buffer; unchecked { if (value == 0) { return string(abi.encodePacked(_str, "0")); } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } buffer = new bytes(digits); uint256 index = digits - 1; temp = value; while (temp != 0) { buffer[index--] = bytes1(uint8(48 + (temp % 10))); temp /= 10; } } return string(abi.encodePacked(_str, buffer)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; library LibMeta { bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(bytes("EIP712Domain(string name,string version,uint256 salt,address verifyingContract)")); function domainSeparator(string memory name, string memory version) internal view returns (bytes32 domainSeparator_) { domainSeparator_ = keccak256( abi.encode(EIP712_DOMAIN_TYPEHASH, keccak256(bytes(name)), keccak256(bytes(version)), getChainID(), address(this)) ); } function getChainID() internal view returns (uint256 id) { assembly { id := chainid() } } function msgSender() internal view returns (address sender_) { if (msg.sender == address(this)) { bytes memory array = msg.data; uint256 index = msg.data.length; assembly { // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those. sender_ := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff) } } else { sender_ = msg.sender; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../interfaces/IERC721TokenReceiver.sol"; import {LibAppStorage, AppStorage} from "./AppStorage.sol"; import "./LibMeta.sol"; library LibERC721 { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of /// any transfer, the approved address for that NFT (if any) is reset to none. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; event MintParcel(address indexed _owner, uint256 indexed _tokenId); function checkOnERC721Received( address _operator, address _from, address _to, uint256 _tokenId, bytes memory _data ) internal { uint256 size; assembly { size := extcodesize(_to) } if (size > 0) { require( ERC721_RECEIVED == IERC721TokenReceiver(_to).onERC721Received(_operator, _from, _tokenId, _data), "LibERC721: Transfer rejected/failed by _to" ); } } // This function is used by transfer functions function transferFrom( address _sender, address _from, address _to, uint256 _tokenId ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); require(_to != address(0), "ER721: Can't transfer to 0 address"); address owner = s.parcels[_tokenId].owner; require(owner != address(0), "ERC721: Invalid tokenId or can't be transferred"); require(_sender == owner || s.operators[owner][_sender] || s.approved[_tokenId] == _sender, "LibERC721: Not owner or approved to transfer"); require(_from == owner, "ERC721: _from is not owner, transfer failed"); s.parcels[_tokenId].owner = _to; //Update indexes and arrays //Get the index of the tokenID to transfer uint256 transferIndex = s.ownerTokenIdIndexes[_from][_tokenId]; uint256 lastIndex = s.ownerTokenIds[_from].length - 1; uint256 lastTokenId = s.ownerTokenIds[_from][lastIndex]; uint256 newIndex = s.ownerTokenIds[_to].length; //Move the last element of the ownerIds array to replace the tokenId to be transferred s.ownerTokenIdIndexes[_from][lastTokenId] = transferIndex; s.ownerTokenIds[_from][transferIndex] = lastTokenId; delete s.ownerTokenIdIndexes[_from][_tokenId]; //pop from array s.ownerTokenIds[_from].pop(); //update index of new token s.ownerTokenIdIndexes[_to][_tokenId] = newIndex; s.ownerTokenIds[_to].push(_tokenId); if (s.approved[_tokenId] != address(0)) { delete s.approved[_tokenId]; emit LibERC721.Approval(owner, address(0), _tokenId); } emit LibERC721.Transfer(_from, _to, _tokenId); } function safeMint(address _to, uint256 _tokenId) internal { AppStorage storage s = LibAppStorage.diamondStorage(); require(s.parcels[_tokenId].owner == address(0), "LibERC721: tokenId already minted"); s.parcels[_tokenId].owner = _to; s.tokenIds.push(_tokenId); s.ownerTokenIdIndexes[_to][_tokenId] = s.ownerTokenIds[_to].length; s.ownerTokenIds[_to].push(_tokenId); emit MintParcel(_to, _tokenId); emit LibERC721.Transfer(address(0), _to, _tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import {InstallationDiamondInterface} from "../interfaces/InstallationDiamondInterface.sol"; import {TileDiamondInterface} from "../interfaces/TileDiamond.sol"; import "./AppStorage.sol"; library LibRealm { event SurveyParcel(uint256 _tokenId, uint256[] _alchemicas); //Place installation function placeInstallation( uint256 _realmId, uint256 _installationId, uint256 _x, uint256 _y ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); uint256[5] memory widths = getWidths(); uint256[5] memory heights = getHeights(); InstallationDiamondInterface installationsDiamond = InstallationDiamondInterface(s.installationsDiamond); InstallationDiamondInterface.InstallationType memory installation = installationsDiamond.getInstallationType(_installationId); Parcel storage parcel = s.parcels[_realmId]; //Check if these slots are available onchain require(_x <= widths[parcel.size] - installation.width, "LibRealm: x exceeding width"); require(_y <= heights[parcel.size] - installation.height, "LibRealm: y exceeding height"); for (uint256 indexW = _x; indexW < _x + installation.width; indexW++) { for (uint256 indexH = _y; indexH < _y + installation.height; indexH++) { require(parcel.buildGrid[indexW][indexH] == 0, "LibRealm: Invalid spot"); parcel.buildGrid[indexW][indexH] = _installationId; } } } function removeInstallation( uint256 _realmId, uint256 _installationId, uint256 _x, uint256 _y ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); InstallationDiamondInterface installationsDiamond = InstallationDiamondInterface(s.installationsDiamond); InstallationDiamondInterface.InstallationType memory installation = installationsDiamond.getInstallationType(_installationId); Parcel storage parcel = s.parcels[_realmId]; require(parcel.buildGrid[_x][_y] == _installationId, "LibRealm: wrong installationId"); for (uint256 indexW = _x; indexW < _x + installation.width; indexW++) { for (uint256 indexH = _y; indexH < _y + installation.height; indexH++) { parcel.buildGrid[indexW][indexH] = 0; } } } function placeTile( uint256 _realmId, uint256 _tileId, uint256 _x, uint256 _y ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); uint256[5] memory widths = getWidths(); uint256[5] memory heights = getHeights(); TileDiamondInterface tilesDiamond = TileDiamondInterface(s.tileDiamond); TileDiamondInterface.TileType memory tile = tilesDiamond.getTileType(_tileId); Parcel storage parcel = s.parcels[_realmId]; //Check if these slots are available onchain require(_x <= widths[parcel.size] - tile.width, "LibRealm: x exceeding width"); require(_y <= heights[parcel.size] - tile.height, "LibRealm: y exceeding height"); for (uint256 indexW = _x; indexW < _x + tile.width; indexW++) { for (uint256 indexH = _y; indexH < _y + tile.height; indexH++) { require(parcel.tileGrid[indexW][indexH] == 0, "LibRealm: Invalid spot"); parcel.tileGrid[indexW][indexH] = _tileId; } } } function removeTile( uint256 _realmId, uint256 _tileId, uint256 _x, uint256 _y ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); TileDiamondInterface tilesDiamond = TileDiamondInterface(s.tileDiamond); TileDiamondInterface.TileType memory tile = tilesDiamond.getTileType(_tileId); Parcel storage parcel = s.parcels[_realmId]; require(parcel.tileGrid[_x][_y] == _tileId, "LibRealm: wrong tileId"); for (uint256 indexW = _x; indexW < _x + tile.width; indexW++) { for (uint256 indexH = _y; indexH < _y + tile.height; indexH++) { parcel.tileGrid[indexW][indexH] = 0; } } } function calculateAmount( uint256 _tokenId, uint256[] memory randomWords, uint256 i ) internal view returns (uint256) { AppStorage storage s = LibAppStorage.diamondStorage(); return (randomWords[i] % s.totalAlchemicas[s.parcels[_tokenId].size][i]); } function updateRemainingAlchemica( uint256 _tokenId, uint256[] memory randomWords, uint256 _round ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); require(s.parcels[_tokenId].currentRound <= s.surveyingRound, "AlchemicaFacet: Round not released"); s.parcels[_tokenId].currentRound++; s.parcels[_tokenId].surveying = false; uint256[] memory alchemicas = new uint256[](4); uint256[] memory roundAmounts = new uint256[](4); for (uint256 i; i < 4; i++) { uint256 baseAmount = calculateAmount(_tokenId, randomWords, i); //100%; //first round is 25%, rounds after are 8.3% uint256 roundAmount = _round == 0 ? baseAmount / 4 : (baseAmount - (baseAmount / 4)) / 9; uint256 boost = s.parcels[_tokenId].alchemicaBoost[i] * s.boostMultipliers[i]; s.parcels[_tokenId].alchemicaRemaining[i] += roundAmount + boost; roundAmounts[i] = roundAmount; alchemicas[i] = roundAmount + boost; } //update round alchemica s.parcels[_tokenId].roundAlchemica[_round] = alchemicas; s.parcels[_tokenId].roundBaseAlchemica[_round] = roundAmounts; emit SurveyParcel(_tokenId, alchemicas); } function getWidths() internal pure returns (uint256[5] memory) { uint256[5] memory widths = [ HUMBLE_WIDTH, //humble REASONABLE_WIDTH, //reasonable SPACIOUS_WIDTH, //spacious vertical SPACIOUS_HEIGHT, //spacious horizontal PAARTNER_WIDTH //partner ]; return widths; } function getHeights() internal pure returns (uint256[5] memory) { uint256[5] memory heights = [ HUMBLE_HEIGHT, //humble REASONABLE_HEIGHT, //reasonable SPACIOUS_HEIGHT, //spacious vertical SPACIOUS_WIDTH, //spacious horizontal PAARTNER_HEIGHT //partner ]; return heights; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import {InstallationDiamondInterface} from "../interfaces/InstallationDiamondInterface.sol"; import {LibAppStorage, AppStorage, Parcel} from "./AppStorage.sol"; library LibAlchemica { function settleUnclaimedAlchemica(uint256 _tokenId, uint256 _alchemicaType) internal { AppStorage storage s = LibAppStorage.diamondStorage(); // uint256 capacity = s.parcels[_tokenId].reservoirCapacity[_alchemicaType]; uint256 capacity = calculateTotalCapacity(_tokenId, _alchemicaType); uint256 alchemicaSinceUpdate = alchemicaSinceLastUpdate(_tokenId, _alchemicaType); if (alchemicaSinceUpdate > 0) { //Cannot settle more than capacity if (s.parcels[_tokenId].unclaimedAlchemica[_alchemicaType] + alchemicaSinceUpdate > capacity) { s.parcels[_tokenId].unclaimedAlchemica[_alchemicaType] = capacity; } else { //Increment alchemica s.parcels[_tokenId].unclaimedAlchemica[_alchemicaType] += alchemicaSinceUpdate; } } s.parcels[_tokenId].lastUpdateTimestamp[_alchemicaType] = block.timestamp; } function alchemicaSinceLastUpdate(uint256 _tokenId, uint256 _alchemicaType) internal view returns (uint256) { AppStorage storage s = LibAppStorage.diamondStorage(); uint256 amount = s.parcels[_tokenId].alchemicaHarvestRate[_alchemicaType] * (block.timestamp - s.parcels[_tokenId].lastUpdateTimestamp[_alchemicaType]); return amount; } function increaseTraits( uint256 _realmId, uint256 _installationId, bool isUpgrade ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); //First save the current harvested amount InstallationDiamondInterface.InstallationType memory installationType = InstallationDiamondInterface(s.installationsDiamond).getInstallationType( _installationId ); uint256 altarPrerequisite = installationType.prerequisites[0]; uint256 lodgePrerequisite = installationType.prerequisites[1]; // check altar requirement uint256 equippedAltarId = s.parcels[_realmId].altarId; uint256 equippedAltarLevel = InstallationDiamondInterface(s.installationsDiamond).getInstallationType(equippedAltarId).level; require(equippedAltarLevel >= altarPrerequisite, "RealmFacet: Altar Tech Tree Reqs not met"); // check lodge requirement if (lodgePrerequisite > 0) { uint256 equippedLodgeId = s.parcels[_realmId].lodgeId; uint256 equippedLodgeLevel = InstallationDiamondInterface(s.installationsDiamond).getInstallationType(equippedLodgeId).level; require(equippedLodgeLevel >= lodgePrerequisite, "RealmFacet: Lodge Tech Tree Reqs not met"); } // check harvester requirement if (installationType.installationType == 1) { require(s.parcels[_realmId].reservoirs[installationType.alchemicaType].length > 0, "RealmFacet: Must equip reservoir of type"); } uint256 alchemicaType = installationType.alchemicaType; //unclaimed alchemica must be settled before mutating harvestRate and capacity settleUnclaimedAlchemica(_realmId, alchemicaType); //handle harvester if (installationType.harvestRate > 0) { s.parcels[_realmId].alchemicaHarvestRate[alchemicaType] += installationType.harvestRate; } //reservoir if (installationType.capacity > 0) { s.parcels[_realmId].reservoirs[alchemicaType].push(_installationId); } //Altar if (installationType.installationType == 0) { require(isUpgrade || s.parcels[_realmId].altarId == 0, "LibAlchemica: Cannot equip two altars"); s.parcels[_realmId].altarId = _installationId; } // upgradeQueueBoost if (installationType.upgradeQueueBoost > 0) { s.parcels[_realmId].upgradeQueueCapacity += installationType.upgradeQueueBoost; } } function reduceTraits( uint256 _realmId, uint256 _installationId, bool isUpgrade ) internal { AppStorage storage s = LibAppStorage.diamondStorage(); InstallationDiamondInterface installationsDiamond = InstallationDiamondInterface(s.installationsDiamond); InstallationDiamondInterface.InstallationType memory installationType = InstallationDiamondInterface(s.installationsDiamond).getInstallationType( _installationId ); InstallationDiamondInterface.InstallationIdIO[] memory installationBalances = installationsDiamond.installationBalancesOfToken( address(this), _realmId ); for (uint256 i; i < installationBalances.length; i++) { InstallationDiamondInterface.InstallationType memory equippedInstallaion = installationsDiamond.getInstallationType(_installationId); // check altar requirement require( InstallationDiamondInterface(s.installationsDiamond).getInstallationType(s.parcels[_realmId].altarId).level >= equippedInstallaion.prerequisites[0], "RealmFacet: Altar Tech Tree Reqs not met" ); // check lodge requirement if (equippedInstallaion.prerequisites[1] > 0) { require( InstallationDiamondInterface(s.installationsDiamond).getInstallationType(s.parcels[_realmId].lodgeId).level >= equippedInstallaion.prerequisites[1], "RealmFacet: Lodge Tech Tree Reqs not met" ); } } uint256 alchemicaType = installationType.alchemicaType; //unclaimed alchemica must be settled before updating harvestRate and capacity settleUnclaimedAlchemica(_realmId, alchemicaType); //Decrement harvest variables if (installationType.harvestRate > 0) { s.parcels[_realmId].alchemicaHarvestRate[alchemicaType] -= installationType.harvestRate; } //Altar if (installationType.installationType == 0 && !isUpgrade) { //@question: do we need any special exceptions for the Altar? Should be handled by tech tree s.parcels[_realmId].altarId = 0; } // Lodge if (installationType.installationType == 3) { s.parcels[_realmId].lodgeId = 0; } //Decrement reservoir variables if (installationType.capacity > 0) { for (uint256 i; i < s.parcels[_realmId].reservoirs[alchemicaType].length; i++) { if (s.parcels[_realmId].reservoirs[alchemicaType][i] == _installationId) { popArray(s.parcels[_realmId].reservoirs[alchemicaType], i); break; } } if (s.parcels[_realmId].unclaimedAlchemica[alchemicaType] > calculateTotalCapacity(_realmId, alchemicaType)) { //step 1 - unequip all harvesters //step 2 - claim alchemica balance //step 3 - unequip reservoir revert("LibAlchemica: Unclaimed alchemica greater than reservoir capacity"); } } // upgradeQueueBoost if (installationType.upgradeQueueBoost > 0) { s.parcels[_realmId].upgradeQueueCapacity -= installationType.upgradeQueueBoost; } } function calculateTotalCapacity(uint256 _tokenId, uint256 _alchemicaType) internal view returns (uint256 capacity_) { AppStorage storage s = LibAppStorage.diamondStorage(); for (uint256 i; i < s.parcels[_tokenId].reservoirs[_alchemicaType].length; i++) { capacity_ += InstallationDiamondInterface(s.installationsDiamond).getReservoirCapacity(s.parcels[_tokenId].reservoirs[_alchemicaType][i]); } } function popArray(uint256[] storage _array, uint256 _index) internal { _array[_index] = _array[_array.length - 1]; _array.pop(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface InstallationDiamondInterface { struct InstallationType { //slot 1 uint8 width; uint8 height; uint16 installationType; //0 = altar, 1 = harvester, 2 = reservoir, 3 = gotchi lodge, 4 = wall, 5 = NFT display, 6 = buildqueue booster uint8 level; //max level 9 uint8 alchemicaType; //0 = none 1 = fud, 2 = fomo, 3 = alpha, 4 = kek uint32 spillRadius; uint16 spillRate; uint8 upgradeQueueBoost; uint32 craftTime; // in blocks uint32 nextLevelId; //the ID of the next level of this installation. Used for upgrades. bool deprecated; //bool //slot 2 uint256[4] alchemicaCost; // [fud, fomo, alpha, kek] //slot 3 uint256 harvestRate; //slot 4 uint256 capacity; //slot 5 uint256[] prerequisites; //IDs of installations that must be present before this installation can be added //slot 6 string name; } struct UpgradeQueue { uint256 parcelId; uint256 coordinateX; uint256 coordinateY; uint256 installationId; uint256 readyBlock; bool claimed; address owner; } struct InstallationIdIO { uint256 installationId; uint256 balance; } struct ReservoirStats { uint256 spillRate; uint256 spillRadius; uint256 capacity; } function craftInstallations(uint256[] calldata _installationTypes) external; function claimInstallations(uint256[] calldata _queueIds) external; function equipInstallation( address _owner, uint256 _realmTokenId, uint256 _installationId ) external; function unequipInstallation(uint256 _realmId, uint256 _installationId) external; function addInstallationTypes(InstallationType[] calldata _installationTypes) external; function getInstallationType(uint256 _itemId) external view returns (InstallationType memory installationType); function getInstallationTypes(uint256[] calldata _itemIds) external view returns (InstallationType[] memory itemTypes_); function getAlchemicaAddresses() external view returns (address[] memory); function balanceOf(address _owner, uint256 _id) external view returns (uint256 bal_); function installationBalancesOfTokenByIds( address _tokenContract, uint256 _tokenId, uint256[] calldata _ids ) external view returns (uint256[] memory); function installationBalancesOfToken(address _tokenContract, uint256 _tokenId) external view returns (InstallationIdIO[] memory bals_); function spilloverRatesOfIds(uint256[] calldata _ids) external view returns (uint256[] memory); function upgradeInstallation(UpgradeQueue calldata _upgradeQueue, bytes memory _signature) external; function finalizeUpgrade() external; function installationsBalances(address _account) external view returns (InstallationIdIO[] memory bals_); function spilloverRateAndRadiusOfId(uint256 _id) external view returns (uint256, uint256); function getAltarLevel(uint256 _altarId) external view returns (uint256 altarLevel_); function getLodgeLevel(uint256 _installationId) external view returns (uint256 lodgeLevel_); function getReservoirCapacity(uint256 _installationId) external view returns (uint256 capacity_); function getReservoirStats(uint256 _installationId) external view returns (ReservoirStats memory reservoirStats_); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library LibSignature { function isValid(bytes32 messageHash, bytes memory signature, bytes memory pubKey) internal pure returns (bool) { bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash); return recoverSigner(ethSignedMessageHash, signature) == address(uint160(uint256(keccak256(pubKey)))); } function getEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash)); } function recoverSigner(bytes32 ethSignedMessageHash, bytes memory signature) internal pure returns (address) { (bytes32 r, bytes32 s, uint8 v) = splitSignature(signature); return ecrecover(ethSignedMessageHash, v, r, s); } function splitSignature(bytes memory sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) { require(sig.length == 65, "Invalid signature length"); assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } // implicitly return (r, s, v) } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.9; import "../../libraries/AppStorage.sol"; import "../../libraries/LibDiamond.sol"; import "../../libraries/LibStrings.sol"; import "../../libraries/LibMeta.sol"; import "../../libraries/LibERC721.sol"; import {IERC721} from "../../interfaces/IERC721.sol"; import {ERC721Marketplace} from "../../interfaces/ERC721Marketplace.sol"; contract ERC721Facet is Modifiers { // bytes4 private constant ERC721_RECEIVED = 0x150b7a02; function tokenIdsOfOwner(address _owner) external view returns (uint256[] memory tokenIds_) { return s.ownerTokenIds[_owner]; } function totalSupply() external view returns (uint256) { return s.tokenIds.length; } /// @notice Enumerate valid NFTs /// @dev Throws if `_index` >= `totalSupply()`. /// @param _index A counter less than `totalSupply()` /// @return tokenId_ The token identifier for the `_index`th NFT, /// (sort order not specified) function tokenByIndex(uint256 _index) external view returns (uint256 tokenId_) { require(_index < s.tokenIds.length, "AavegotchiFacet: _index is greater than total supply."); tokenId_ = s.tokenIds[_index]; } /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this. /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return balance_ The number of NFTs owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256 balance_) { balance_ = s.ownerTokenIds[_owner].length; } /// @notice Find the owner of an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return owner_ The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address owner_) { owner_ = s.parcels[_tokenId].owner; } /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return approved_ The approved address for this NFT, or the zero address if there is none function getApproved(uint256 _tokenId) external view returns (address approved_) { require(s.parcels[_tokenId].owner != address(0), "AavegotchiFacet: tokenId is invalid or is not owned"); approved_ = s.approved[_tokenId]; } /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return approved_ True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) external view returns (bool approved_) { approved_ = s.operators[_owner][_operator]; } /// @notice Transfers the ownership of an NFT from one address to another address /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param _data Additional data with no specified format, sent in call to `_to` function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes calldata _data ) public { address sender = LibMeta.msgSender(); LibERC721.transferFrom(sender, _from, _to, _tokenId); LibERC721.checkOnERC721Received(sender, _from, _to, _tokenId, _data); //Update baazaar listing if (s.aavegotchiDiamond != address(0)) { ERC721Marketplace(s.aavegotchiDiamond).updateERC721Listing(address(this), _tokenId, _from); } } /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom( address _from, address _to, uint256 _tokenId ) external { address sender = LibMeta.msgSender(); LibERC721.transferFrom(sender, _from, _to, _tokenId); LibERC721.checkOnERC721Received(sender, _from, _to, _tokenId, ""); //Update baazaar listing if (s.aavegotchiDiamond != address(0)) { ERC721Marketplace(s.aavegotchiDiamond).updateERC721Listing(address(this), _tokenId, _from); } } /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom( address _from, address _to, uint256 _tokenId ) external { address sender = LibMeta.msgSender(); LibERC721.transferFrom(sender, _from, _to, _tokenId); if (s.aavegotchiDiamond != address(0)) { ERC721Marketplace(s.aavegotchiDiamond).updateERC721Listing(address(this), _tokenId, _from); } } /// @notice Change or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve(address _approved, uint256 _tokenId) external { address owner = s.parcels[_tokenId].owner; address sender = LibMeta.msgSender(); require(owner == sender || s.operators[owner][sender], "ERC721: Not owner or operator of token."); s.approved[_tokenId] = _approved; emit LibERC721.Approval(owner, _approved, _tokenId); } /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @dev Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external { address sender = LibMeta.msgSender(); s.operators[sender][_operator] = _approved; emit LibERC721.ApprovalForAll(sender, _operator, _approved); } function name() external pure returns (string memory) { return "Gotchiverse REALM Parcel"; } /// @notice An abbreviated name for NFTs in this contract function symbol() external pure returns (string memory) { return "REALM"; } /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". function tokenURI(uint256 _tokenId) external pure returns (string memory) { return LibStrings.strWithUint("https://app.aavegotchi.com/metadata/realm/", _tokenId); //Here is your URL! } struct MintParcelInput { uint256 coordinateX; uint256 coordinateY; uint256 parcelId; uint256 size; //0=humble, 1=reasonable, 2=spacious vertical, 3=spacious horizontal, 4=partner uint256 fomoBoost; uint256 fudBoost; uint256 kekBoost; uint256 alphaBoost; } function safeBatchTransfer( address _from, address _to, uint256[] calldata _tokenIds, bytes calldata _data ) external { for (uint256 index = 0; index < _tokenIds.length; index++) { safeTransferFrom(_from, _to, _tokenIds[index], _data); } } function addSupportForERC165() external onlyOwner { LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage(); ds.supportedInterfaces[type(IERC721).interfaceId] = true; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.1; interface AavegotchiDiamond { struct GotchiLending { // storage slot 1 address lender; uint96 initialCost; // GHST in wei, can be zero // storage slot 2 address borrower; uint32 listingId; uint32 erc721TokenId; uint32 whitelistId; // can be zero // storage slot 3 address originalOwner; // if original owner is lender, same as lender uint40 timeCreated; uint40 timeAgreed; bool canceled; bool completed; // storage slot 4 address thirdParty; // can be address(0) uint8[3] revenueSplit; // lender/original owner, borrower, thirdParty uint40 lastClaimed; //timestamp uint32 period; //in seconds // storage slot 5 address[] revenueTokens; } function ownerOf(uint256 _tokenId) external view returns (address owner_); function gotchiEscrow(uint256 _tokenId) external view returns (address); function isAavegotchiLent(uint32 _erc721TokenId) external view returns (bool); function getGotchiLendingFromToken(uint32 _erc721TokenId) external view returns (GotchiLending memory listing_); function addGotchiLending( uint32 _erc721TokenId, uint96 _initialCost, uint32 _period, uint8[3] calldata _revenueSplit, address _originalOwner, address _thirdParty, uint32 _whitelistId, address[] calldata _revenueTokens ) external; function agreeGotchiLending( uint32 _listingId, uint32 _erc721TokenId, uint96 _initialCost, uint32 _period, uint8[3] calldata _revenueSplit ) external; function kinship(uint256 _tokenId) external view returns (uint256 score_); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface IDiamondCut { enum FacetCutAction {Add, Replace, Remove} // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /// @title IERC721TokenReceiver /// @dev See https://eips.ethereum.org/EIPS/eip-721. Note: the ERC-165 identifier for this interface is 0x150b7a02. interface IERC721TokenReceiver { /// @notice Handle the receipt of an NFT /// @dev The ERC721 smart contract calls this function on the recipient /// after a `transfer`. This function MAY throw to revert and reject the /// transfer. Return of other than the magic value MUST result in the /// transaction being reverted. /// Note: the contract address is always the message sender. /// @param _operator The address which called `safeTransferFrom` function /// @param _from The address which previously owned the token /// @param _tokenId The NFT identifier which is being transferred /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns(bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface TileDiamondInterface { struct TileType { uint256 width; uint256 height; bool deprecated; uint16 tileType; uint256[4] alchemicaCost; // [fud, fomo, alpha, kek] uint256 craftTime; // in blocks string name; } struct TileIdIO { uint256 tileId; uint256 balance; } function craftTiles(uint256[] calldata _tileTypes) external; function claimTiles(uint256[] calldata _queueIds) external; function equipTile( address _owner, uint256 _realmTokenId, uint256 _tileId ) external; function unequipTile( address _owner, uint256 _realmId, uint256 _tileId ) external; function addTileTypes(TileType[] calldata _tileTypes) external; function getTileType(uint256 _itemId) external view returns (TileType memory tileType); function getTileTypes(uint256[] calldata _itemIds) external view returns (TileType[] memory itemTypes_); function getAlchemicaAddresses() external view returns (address[] memory); function balanceOf(address _owner, uint256 _id) external view returns (uint256 bal_); function tileBalancesOfTokenByIds( address _tokenContract, uint256 _tokenId, uint256[] calldata _ids ) external view returns (uint256[] memory); function tilesBalances(address _account) external view returns (TileIdIO[] memory bals_); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /// @title ERC-721 Non-Fungible Token Standard /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// Note: the ERC-165 identifier for this interface is 0x80ac58cd. interface IERC721 /* is ERC165 */ { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of /// any transfer, the approved address for that NFT (if any) is reset to none. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256); /// @notice Find the owner of an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address); /// @notice Transfers the ownership of an NFT from one address to another address /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom(address _from, address _to, uint256 _tokenId) external payable; /// @notice Change or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve(address _approved, uint256 _tokenId) external payable; /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @dev Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved(uint256 _tokenId) external view returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ERC721Marketplace { function updateERC721Listing( address _erc721TokenAddress, uint256 _erc721TokenId, address _owner ) external; }
{ "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
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_aavegotchiDiamond","type":"address"}],"name":"AavegotchiDiamondUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_realmId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_installationId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_y","type":"uint256"}],"name":"EquipInstallation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_realmId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tileId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_y","type":"uint256"}],"name":"EquipTile","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_realmId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevInstallationId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_nextInstallationId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_coordinateX","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_coordinateY","type":"uint256"}],"name":"InstallationUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"ResyncParcel","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_realmId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_installationId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_y","type":"uint256"}],"name":"UnequipInstallation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_realmId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tileId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_x","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_y","type":"uint256"}],"name":"UnequipTile","type":"event"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"addUpgradeQueueLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_district","type":"uint256"}],"name":"batchGetDistrictParcels","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_parcelIds","type":"uint256[]"},{"internalType":"uint256","name":"_gridType","type":"uint256"}],"name":"batchGetGrid","outputs":[{"components":[{"internalType":"uint256[64][64]","name":"coords","type":"uint256[64][64]"}],"internalType":"struct RealmFacet.ParcelCoordinates[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"},{"internalType":"uint256","name":"_coordinateX","type":"uint256"},{"internalType":"uint256","name":"_coordinateY","type":"uint256"},{"internalType":"uint256","name":"_installationId","type":"uint256"}],"name":"checkCoordinates","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"},{"internalType":"uint256","name":"_installationId","type":"uint256"},{"internalType":"uint256","name":"_x","type":"uint256"},{"internalType":"uint256","name":"_y","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"equipInstallation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"},{"internalType":"uint256","name":"_tileId","type":"uint256"},{"internalType":"uint256","name":"_x","type":"uint256"},{"internalType":"uint256","name":"_y","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"equipTile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"},{"internalType":"uint256","name":"_gridType","type":"uint256"}],"name":"getHumbleGrid","outputs":[{"internalType":"uint256[8][8]","name":"output_","type":"uint256[8][8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"},{"internalType":"uint256","name":"_gridType","type":"uint256"}],"name":"getPaartnerGrid","outputs":[{"internalType":"uint256[64][64]","name":"output_","type":"uint256[64][64]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"getParcelInfo","outputs":[{"components":[{"internalType":"string","name":"parcelId","type":"string"},{"internalType":"string","name":"parcelAddress","type":"string"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"coordinateX","type":"uint256"},{"internalType":"uint256","name":"coordinateY","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"district","type":"uint256"},{"internalType":"uint256[4]","name":"boost","type":"uint256[4]"},{"internalType":"uint256","name":"timeRemainingToClaim","type":"uint256"}],"internalType":"struct RealmFacet.ParcelOutput","name":"output_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"}],"name":"getParcelUpgradeQueueCapacity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"}],"name":"getParcelUpgradeQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_parcelIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_actionRights","type":"uint256[]"}],"name":"getParcelsAccessRights","outputs":[{"internalType":"uint256[]","name":"output_","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"},{"internalType":"uint256","name":"_gridType","type":"uint256"}],"name":"getReasonableGrid","outputs":[{"internalType":"uint256[16][16]","name":"output_","type":"uint256[16][16]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"},{"internalType":"uint256","name":"_gridType","type":"uint256"}],"name":"getSpaciousHorizontalGrid","outputs":[{"internalType":"uint256[64][32]","name":"output_","type":"uint256[64][32]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_parcelId","type":"uint256"},{"internalType":"uint256","name":"_gridType","type":"uint256"}],"name":"getSpaciousVerticalGrid","outputs":[{"internalType":"uint256[32][64]","name":"output_","type":"uint256[32][64]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"coordinateX","type":"uint256"},{"internalType":"uint256","name":"coordinateY","type":"uint256"},{"internalType":"uint256","name":"district","type":"uint256"},{"internalType":"string","name":"parcelId","type":"string"},{"internalType":"string","name":"parcelAddress","type":"string"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256[4]","name":"boost","type":"uint256[4]"}],"internalType":"struct RealmFacet.MintParcelInput[]","name":"_metadata","type":"tuple[]"}],"name":"mintParcels","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"resyncParcel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_gameActive","type":"bool"}],"name":"setGameActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_realmIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_actionRights","type":"uint256[]"},{"internalType":"uint256[]","name":"_accessRights","type":"uint256[]"}],"name":"setParcelsAccessRights","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"subUpgradeQueueLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"},{"internalType":"uint256","name":"_installationId","type":"uint256"},{"internalType":"uint256","name":"_x","type":"uint256"},{"internalType":"uint256","name":"_y","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"unequipInstallation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"},{"internalType":"uint256","name":"_tileId","type":"uint256"},{"internalType":"uint256","name":"_x","type":"uint256"},{"internalType":"uint256","name":"_y","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"unequipTile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"},{"internalType":"uint256","name":"_prevInstallationId","type":"uint256"},{"internalType":"uint256","name":"_nextInstallationId","type":"uint256"},{"internalType":"uint256","name":"_coordinateX","type":"uint256"},{"internalType":"uint256","name":"_coordinateY","type":"uint256"}],"name":"upgradeInstallation","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506150ee806100206000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c80637690a6b3116100c3578063c96fd9c51161007c578063c96fd9c51461030c578063ccc089741461032c578063d5abeb011461033f578063da80c76e14610352578063dd71950a14610376578063e45c7de21461039657600080fd5b80637690a6b314610273578063ad3d0f6514610293578063adf68808146102b3578063bc6c0d33146102c6578063bd6a3295146102d9578063c3671216146102ec57600080fd5b806351caf05c1161011557806351caf05c146101f45780635505421b1461020757806356ba6c551461021a578063579fa4af1461022d578063594a0a701461024057806375438cd41461026057600080fd5b80631628652a1461015d5780631ef25f94146101725780632d7e13011461019b578063347373c7146101bb578063367e3dac146101ce5780633fa75b65146101e1575b600080fd5b61017061016b366004614093565b6103ba565b005b61018561018036600461410a565b61076d565b6040516101929190614161565b60405180910390f35b6101ae6101a936600461410a565b6108ff565b604051610192919061419a565b6101706101c93660046141fb565b610a94565b6101706101dc366004614278565b610b27565b6101706101ef366004614093565b610ceb565b610170610202366004614093565b611025565b610170610215366004614311565b6111a6565b610170610228366004614402565b611266565b61017061023b366004614584565b611419565b61025361024e36600461459d565b611479565b60405161019291906145c7565b61017061026e366004614584565b611647565b61028661028136600461410a565b61169f565b60405161019291906145ff565b6102a66102a136600461410a565b611821565b6040516101929190614657565b6102536102c136600461468b565b6119b8565b6101706102d43660046146f6565b611ae5565b6101706102e7366004614093565b611b60565b6102ff6102fa36600461410a565b611cd5565b6040516101929190614737565b61031f61031a36600461478f565b611e61565b60405161019291906147da565b61017061033a36600461485e565b612069565b620668e55b604051908152602001610192565b610344610360366004614584565b6000908152600160205260409020612020015490565b610389610384366004614584565b61208f565b60405161019291906148fa565b6103446103a4366004614584565b6000908152600160205260409020612021015490565b60008581526001602052604090205485906001600160a01b03166103dc61224f565b6001600160a01b03161461040b5760405162461bcd60e51b8152600401610402906149a1565b60405180910390fd5b603754600160a01b900460ff166104345760405162461bcd60e51b8152600401610402906149e7565b604080516020810188905290810186905260608101859052608081018490526105059060a0015b60405160208183030381529060405280519060200120836000602f01805461048290614a1e565b80601f01602080910402602001604051908101604052809291908181526020018280546104ae90614a1e565b80156104fb5780601f106104d0576101008083540402835291602001916104fb565b820191906000526020600020905b8154815290600101906020018083116104de57829003601f168201915b50505050506122ac565b6105215760405162461bcd60e51b815260040161040290614a59565b600b5460405163109e13c560e21b8152600481018790526001600160a01b039091169060009082906342784f149060240160006040518083038186803b15801561056a57600080fd5b505afa15801561057e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a69190810190614bca565b90506105b488888888612336565b60005b60048110156106a9576000600782600481106105d5576105d5614d4a565b01546101608401516001600160a01b039091169150600090600290846004811061060157610601614d4a565b60200201516106109190614d76565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb90604401602060405180830381600087803b15801561065b57600080fd5b505af115801561066f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106939190614d98565b50505080806106a190614db5565b9150506105b7565b50600b54604051633240806960e01b8152600481018a9052602481018990526001600160a01b0390911690633240806990604401600060405180830381600087803b1580156106f757600080fd5b505af115801561070b573d6000803e3d6000fd5b5050505061071b888860006124e2565b6040805189815260208101899052908101879052606081018690527feb8dc37534b72de521d16884c32148e05abe550c5627ee4ba527ddfa1a7717ff9060800160405180910390a15050505050505050565b610775613c82565b6000838152600160205260409020600601546004146107d65760405162461bcd60e51b815260206004820152601860248201527f5265616c6d46616365743a204e6f742070616172746e657200000000000000006044820152606401610402565b60005b60408110156108f85760005b60408110156108e557836108605760008581526001602052604090819020600701908290811061081757610817614d4a565b60400201826040811061082c5761082c614d4a565b015483836040811061084057610840614d4a565b6020020151826040811061085657610856614d4a565b60200201526108d3565b83600114156108d3576000858152600160205260409081902061100701908290811061088e5761088e614d4a565b6040020182604081106108a3576108a3614d4a565b01548383604081106108b7576108b7614d4a565b602002015182604081106108cd576108cd614d4a565b60200201525b806108dd81614db5565b9150506107e5565b50806108f081614db5565b9150506107d9565b5092915050565b610907613cb0565b6000838152600160205260409020600601546002146109725760405162461bcd60e51b815260206004820152602160248201527f5265616c6d46616365743a204e6f742073706163696f757320766572746963616044820152601b60fa1b6064820152608401610402565b60005b60408110156108f85760005b6020811015610a8157836109fc576000858152600160205260409081902060070190829081106109b3576109b3614d4a565b6040020182604081106109c8576109c8614d4a565b01548383604081106109dc576109dc614d4a565b602002015182602081106109f2576109f2614d4a565b6020020152610a6f565b8360011415610a6f5760008581526001602052604090819020611007019082908110610a2a57610a2a614d4a565b604002018260408110610a3f57610a3f614d4a565b0154838360408110610a5357610a53614d4a565b60200201518260208110610a6957610a69614d4a565b60200201525b80610a7981614db5565b915050610981565b5080610a8c81614db5565b915050610975565b60008481526001602052604090819020908290600783019086908110610abc57610abc614d4a565b604002018460408110610ad157610ad1614d4a565b015414610b205760405162461bcd60e51b815260206004820152601d60248201527f5265616c6d46616365743a2077726f6e6720636f6f7264696e617465730000006044820152606401610402565b5050505050565b603754600160a01b900460ff16610b505760405162461bcd60e51b8152600401610402906149e7565b8481148015610b5e57508483145b610baa5760405162461bcd60e51b815260206004820152601d60248201527f5265616c6d46616365743a204d69736d617463686564206172726179730000006044820152606401610402565b60005b85811015610ce25760016000888884818110610bcb57610bcb614d4a565b60209081029290920135835250810191909152604001600020546001600160a01b0316610bf661224f565b6001600160a01b031614610c5b5760405162461bcd60e51b815260206004820152602660248201527f5265616c6d46616365743a204f6e6c792050617263656c206f776e65722063616044820152651b8818d85b1b60d21b6064820152608401610402565b828282818110610c6d57610c6d614d4a565b9050602002013560006038016000898985818110610c8d57610c8d614d4a565b9050602002013581526020019081526020016000206000878785818110610cb657610cb6614d4a565b905060200201358152602001908152602001600020819055508080610cda90614db5565b915050610bad565b50505050505050565b60008581526001602052604090205485906001600160a01b0316610d0d61224f565b6001600160a01b031614610d335760405162461bcd60e51b8152600401610402906149a1565b603754600160a01b900460ff16610d5c5760405162461bcd60e51b8152600401610402906149e7565b60408051602081018890529081018690526060810185905260808101849052610d879060a00161045b565b610da35760405162461bcd60e51b815260040161040290614a59565b600b5460405163109e13c560e21b8152600481018790526000916001600160a01b0316906342784f149060240160006040518083038186803b158015610de857600080fd5b505afa158015610dfc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e249190810190614bca565b9050806040015161ffff1660011480610e455750806040015161ffff166002145b15610ebf57600087815260016020819052604090912061200f01541015610ebf5760405162461bcd60e51b815260206004820152602860248201527f5265616c6d46616365743a204d75737420737572766579206265666f726520656044820152677175697070696e6760c01b6064820152608401610402565b806040015161ffff1660031415610f51576000878152600160205260409020612022015415610f3b5760405162461bcd60e51b815260206004820152602260248201527f5265616c6d46616365743a204c6f64676520616c726561647920657175697070604482015261195960f21b6064820152608401610402565b6000878152600160205260409020612022018690555b610f5d87878787612afd565b600b546040516364e5b7a960e01b815233600482015260248101899052604481018890526001600160a01b03909116906364e5b7a990606401600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd487876000612dae565b6040805188815260208101889052908101869052606081018590527f28ee8f870fbf2fc8ef414198cb263e6f548ce9a10088c76c2821b66cf61dddc49060800160405180910390a150505050505050565b60008581526001602052604090205485906001600160a01b031661104761224f565b6001600160a01b03161461106d5760405162461bcd60e51b8152600401610402906149a1565b603754600160a01b900460ff166110965760405162461bcd60e51b8152600401610402906149e7565b604080516020810188905290810186905260608101859052608081018490526110c19060a00161045b565b6110dd5760405162461bcd60e51b815260040161040290614a59565b6110e98686868661322e565b60375460405163e700cdd760e01b815233600482015260248101889052604481018790526001600160a01b039091169063e700cdd790606401600060405180830381600087803b15801561113c57600080fd5b505af1158015611150573d6000803e3d6000fd5b50506040805189815260208101899052908101879052606081018690527ffcb7d72e94eee47cfef784f5d54e1f07cc20dff2f9627de06f1f061428c7c91e925060800190505b60405180910390a1505050505050565b600b546001600160a01b03166111ba61224f565b6001600160a01b0316146111e05760405162461bcd60e51b815260040161040290614dd0565b6111ec85858484612336565b6111f885848484612afd565b611204858560016124e2565b61121085856001612dae565b604080518681526020810186905290810184905260608101839052608081018290527f74b654614ea2444b876a14dec11c709807cda89060906c4b7e443e4f8ff9ed539060a00160405180910390a15050505050565b61126e6134c5565b60005b82811015610b2057600054620668e5116112e75760405162461bcd60e51b815260206004820152603160248201527f5265616c6d46616365743a2043616e6e6f74206d696e74206d6f7265207468616044820152706e203432302c3036392070617263656c7360781b6064820152608401610402565b60008484838181106112fb576112fb614d4a565b905060200201359050600083838151811061131857611318614d4a565b60200260200101519050835186869050146113755760405162461bcd60e51b815260206004820152601a60248201527f496e70757473206d7573742062652073616d65206c656e6774680000000000006044820152606401610402565b6000828152600160209081526040909120825160038201558282015160048201556060830151805191926113b192600285019290910190613cde565b5060a0820151600682015560408201516005820155608082015180516113e1916001840191602090910190613cde565b5060c08201516113f8906120078301906004613d62565b50611403888461354e565b505050808061141190614db5565b915050611271565b600b546001600160a01b031661142d61224f565b6001600160a01b0316146114535760405162461bcd60e51b815260040161040290614dd0565b60008181526001602052604081206120210180549161147183614db5565b919050555050565b60606000306001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b657600080fd5b505afa1580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ee9190614e1e565b6040516370a0823160e01b81526001600160a01b038616600482015290915060009030906370a082319060240160206040518083038186803b15801561153357600080fd5b505afa158015611547573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156b9190614e1e565b90506000816001600160401b0381111561158757611587613f59565b6040519080825280602002602001820160405280156115b0578160200160208202803683370190505b5090506000805b8481101561163b57600081815260016020526040902060050154871480156115f857506000818152600160205260409020546001600160a01b038981169116145b15611629578083838151811061161057611610614d4a565b60209081029190910101528161162581614db5565b9250505b8061163381614db5565b9150506115b7565b50909695505050505050565b600b546001600160a01b031661165b61224f565b6001600160a01b0316146116815760405162461bcd60e51b815260040161040290614dd0565b60008181526001602052604081206120210180549161147183614e37565b6116a7613d8f565b600083815260016020526040902060060154156116ff5760405162461bcd60e51b81526020600482015260166024820152755265616c6d46616365743a204e6f742068756d626c6560501b6044820152606401610402565b60005b60088110156108f85760005b600881101561180e57836117895760008581526001602052604090819020600701908290811061174057611740614d4a565b60400201826040811061175557611755614d4a565b015483836008811061176957611769614d4a565b6020020151826008811061177f5761177f614d4a565b60200201526117fc565b83600114156117fc57600085815260016020526040908190206110070190829081106117b7576117b7614d4a565b6040020182604081106117cc576117cc614d4a565b01548383600881106117e0576117e0614d4a565b602002015182600881106117f6576117f6614d4a565b60200201525b8061180681614db5565b91505061170e565b508061181981614db5565b915050611702565b611829613dbd565b6000838152600160205260409020600601546003146118965760405162461bcd60e51b815260206004820152602360248201527f5265616c6d46616365743a204e6f742073706163696f757320686f72697a6f6e6044820152621d185b60ea1b6064820152608401610402565b60005b60208110156108f85760005b60408110156119a55783611920576000858152600160205260409081902060070190829081106118d7576118d7614d4a565b6040020182604081106118ec576118ec614d4a565b015483836020811061190057611900614d4a565b6020020151826040811061191657611916614d4a565b6020020152611993565b8360011415611993576000858152600160205260409081902061100701908290811061194e5761194e614d4a565b60400201826040811061196357611963614d4a565b015483836020811061197757611977614d4a565b6020020151826040811061198d5761198d614d4a565b60200201525b8061199d81614db5565b9150506118a5565b50806119b081614db5565b915050611899565b6060838214611a095760405162461bcd60e51b815260206004820152601d60248201527f5265616c6d46616365743a204d69736d617463686564206172726179730000006044820152606401610402565b836001600160401b03811115611a2157611a21613f59565b604051908082528060200260200182016040528015611a4a578160200160208202803683370190505b50905060005b84811015611adc5760386000878784818110611a6e57611a6e614d4a565b9050602002013581526020019081526020016000206000858584818110611a9757611a97614d4a565b90506020020135815260200190815260200160002054828281518110611abf57611abf614d4a565b602090810291909101015280611ad481614db5565b915050611a50565b50949350505050565b611aed6134c5565b60005b81811015611b5b577ff20fad4a9aa47ceeb29a7f693b89871de4b3b9ed2fc1fdf327785476f9938c97838383818110611b2b57611b2b614d4a565b90506020020135604051611b4191815260200190565b60405180910390a180611b5381614db5565b915050611af0565b505050565b60008581526001602052604090205485906001600160a01b0316611b8261224f565b6001600160a01b031614611ba85760405162461bcd60e51b8152600401610402906149a1565b603754600160a01b900460ff16611bd15760405162461bcd60e51b8152600401610402906149e7565b60408051602081018890529081018690526060810185905260808101849052611bfc9060a00161045b565b611c185760405162461bcd60e51b815260040161040290614a59565b611c2486868686613699565b6037546040516315b194ef60e21b815233600482015260248101889052604481018790526001600160a01b03909116906356c653bc90606401600060405180830381600087803b158015611c7757600080fd5b505af1158015611c8b573d6000803e3d6000fd5b50506040805189815260208101899052908101879052606081018690527fb1e943c280d055bfe1686ba119599cd2071f18e1f3bce12ad3c3c4f0d5b4541f92506080019050611196565b611cdd613deb565b60008381526001602081905260409091206006015414611d3f5760405162461bcd60e51b815260206004820152601a60248201527f5265616c6d46616365743a204e6f7420726561736f6e61626c650000000000006044820152606401610402565b60005b60108110156108f85760005b6010811015611e4e5783611dc957600085815260016020526040908190206007019082908110611d8057611d80614d4a565b604002018260408110611d9557611d95614d4a565b0154838360108110611da957611da9614d4a565b60200201518260108110611dbf57611dbf614d4a565b6020020152611e3c565b8360011415611e3c5760008581526001602052604090819020611007019082908110611df757611df7614d4a565b604002018260408110611e0c57611e0c614d4a565b0154838360108110611e2057611e20614d4a565b60200201518260108110611e3657611e36614d4a565b60200201525b80611e4681614db5565b915050611d4e565b5080611e5981614db5565b915050611d42565b60606000836001600160401b03811115611e7d57611e7d613f59565b604051908082528060200260200182016040528015611eb657816020015b611ea3613e19565b815260200190600190039081611e9b5790505b50905060005b84811015611adc5760005b60408110156120565760005b60408110156120435785611f865760016000898986818110611ef757611ef7614d4a565b9050602002013581526020019081526020016000206007018160408110611f2057611f20614d4a565b604002018260408110611f3557611f35614d4a565b0154848481518110611f4957611f49614d4a565b6020026020010151600001518360408110611f6657611f66614d4a565b60200201518260408110611f7c57611f7c614d4a565b6020020152612031565b85600114156120315760016000898986818110611fa557611fa5614d4a565b905060200201358152602001908152602001600020611007018160408110611fcf57611fcf614d4a565b604002018260408110611fe457611fe4614d4a565b0154848481518110611ff857611ff8614d4a565b602002602001015160000151836040811061201557612015614d4a565b6020020151826040811061202b5761202b614d4a565b60200201525b8061203b81614db5565b915050611ed3565b508061204e81614db5565b915050611ec7565b508061206181614db5565b915050611ebc565b6120716134c5565b60378054911515600160a01b0260ff60a01b19909216919091179055565b612097613e31565b60008281526001602052604090206002810180546120b490614a1e565b80601f01602080910402602001604051908101604052809291908181526020018280546120e090614a1e565b801561212d5780601f106121025761010080835404028352916020019161212d565b820191906000526020600020905b81548152906001019060200180831161211057829003601f168201915b505050918452505080546001600160a01b031660408301526003810154606083015260048101546080830152600681015460a083015260018101805461217290614a1e565b80601f016020809104026020016040519081016040528092919081815260200182805461219e90614a1e565b80156121eb5780601f106121c0576101008083540402835291602001916121eb565b820191906000526020600020905b8154815290600101906020018083116121ce57829003601f168201915b50505050506020830152600581015460c08301526040805160808101918290529061200783019060049082845b81548152602001906001019080831161221857505050505060e0830152506000918252603560205260409091205461010082015290565b6000333014156122a657600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506122a99050565b50335b90565b600080612306856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b835160208501209091506001600160a01b0316612323828661382f565b6001600160a01b03161495945050505050565b600080600b81015460405163109e13c560e21b8152600481018790529192506001600160a01b03169060009082906342784f149060240160006040518083038186803b15801561238557600080fd5b505afa158015612399573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526123c19190810190614bca565b60008881526001850160205260409081902091925087906007830190889081106123ed576123ed614d4a565b60400201866040811061240257612402614d4a565b0154146124515760405162461bcd60e51b815260206004820152601e60248201527f4c69625265616c6d3a2077726f6e6720696e7374616c6c6174696f6e496400006044820152606401610402565b855b82516124629060ff1688614e4e565b8110156124d757855b602084015161247d9060ff1688614e4e565b8110156124c457600083600701836040811061249b5761249b614d4a565b6040020182604081106124b0576124b0614d4a565b0155806124bc81614db5565b91505061246b565b50806124cf81614db5565b915050612453565b505050505050505050565b600080600b81015460405163109e13c560e21b8152600481018690529192506001600160a01b03169060009082906342784f149060240160006040518083038186803b15801561253157600080fd5b505afa158015612545573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261256d9190810190614bca565b6040516324a7504960e11b8152306004820152602481018890529091506000906001600160a01b0384169063494ea0929060440160006040518083038186803b1580156125b957600080fd5b505afa1580156125cd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125f59190810190614e66565b905060005b81518110156128915760405163109e13c560e21b8152600481018890526000906001600160a01b038616906342784f149060240160006040518083038186803b15801561264657600080fd5b505afa15801561265a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126829190810190614bca565b9050806101c0015160008151811061269c5761269c614d4a565b602090810291909101810151600b88015460008c815260018a0190935260409283902061201f0154925163109e13c560e21b815291926001600160a01b03909116916342784f14916126f49160040190815260200190565b60006040518083038186803b15801561270c57600080fd5b505afa158015612720573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127489190810190614bca565b6060015160ff16101561276d5760405162461bcd60e51b815260040161040290614f1b565b6000816101c0015160018151811061278757612787614d4a565b6020026020010151111561287e57806101c001516001815181106127ad576127ad614d4a565b602090810291909101810151600b88015460008c815260018a019093526040928390206120220154925163109e13c560e21b815291926001600160a01b03909116916342784f14916128059160040190815260200190565b60006040518083038186803b15801561281d57600080fd5b505afa158015612831573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128599190810190614bca565b6060015160ff16101561287e5760405162461bcd60e51b815260040161040290614f63565b508061288981614db5565b9150506125fa565b50608082015160ff166128a488826138ae565b610180830151156128f057610180830151600089815260018701602052604090206120130182600481106128da576128da614d4a565b0160008282546128ea9190614fab565b90915550505b604083015161ffff16158015612904575085155b1561291f576000888152600186016020526040812061201f01555b826040015161ffff1660031415612946576000888152600186016020526040812061202201555b6101a083015115612ab05760005b6000898152600187016020908152604080832085845261201201909152902054811015612a0057600089815260018701602090815260408083208584526120120190915290208054899190839081106129af576129af614d4a565b906000526020600020015414156129ee57600089815260018701602090815260408083208584526120120190915290206129e990826139a7565b612a00565b806129f881614db5565b915050612954565b50612a0b8882613a1c565b6000898152600187016020526040902061201b018260048110612a3057612a30614d4a565b01541115612ab05760405162461bcd60e51b815260206004820152604160248201527f4c6962416c6368656d6963613a20556e636c61696d656420616c6368656d696360448201527f612067726561746572207468616e207265736572766f697220636170616369746064820152607960f81b608482015260a401610402565b60e083015160ff1615612af3578260e0015160ff168560010160008a8152602001908152602001600020612020016000828254612aed9190614fab565b90915550505b5050505050505050565b600080612b08613b31565b90506000612b14613b69565b600b84015460405163109e13c560e21b8152600481018990529192506001600160a01b03169060009082906342784f149060240160006040518083038186803b158015612b6057600080fd5b505afa158015612b74573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b9c9190810190614bca565b60008a8152600187016020526040902081516006820154929350909160ff90911690869060058110612bd057612bd0614d4a565b6020020151612bdf9190614fab565b881115612c2e5760405162461bcd60e51b815260206004820152601b60248201527f4c69625265616c6d3a207820657863656564696e6720776964746800000000006044820152606401610402565b816020015160ff1684826006015460058110612c4c57612c4c614d4a565b6020020151612c5b9190614fab565b871115612caa5760405162461bcd60e51b815260206004820152601c60248201527f4c69625265616c6d3a207920657863656564696e6720686569676874000000006044820152606401610402565b875b8251612cbb9060ff168a614e4e565b811015612da157875b6020840151612cd69060ff168a614e4e565b811015612d8e57826007018260408110612cf257612cf2614d4a565b604002018160408110612d0757612d07614d4a565b015415612d4f5760405162461bcd60e51b8152602060048201526016602482015275131a589499585b1b4e88125b9d985b1a59081cdc1bdd60521b6044820152606401610402565b8a836007018360408110612d6557612d65614d4a565b604002018260408110612d7a57612d7a614d4a565b015580612d8681614db5565b915050612cc4565b5080612d9981614db5565b915050612cac565b5050505050505050505050565b600080600b81015460405163109e13c560e21b8152600481018690529192506000916001600160a01b03909116906342784f149060240160006040518083038186803b158015612dfd57600080fd5b505afa158015612e11573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e399190810190614bca565b90506000816101c00151600081518110612e5557612e55614d4a565b602002602001015190506000826101c00151600181518110612e7957612e79614d4a565b602090810291909101810151600089815260018701909252604080832061201f0154600b880154915163109e13c560e21b81526004810182905292945092916001600160a01b03909116906342784f149060240160006040518083038186803b158015612ee557600080fd5b505afa158015612ef9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612f219190810190614bca565b6060015160ff16905083811015612f4a5760405162461bcd60e51b815260040161040290614f1b565b82156130145760008981526001870160205260408082206120220154600b890154915163109e13c560e21b8152600481018290529092916001600160a01b0316906342784f149060240160006040518083038186803b158015612fac57600080fd5b505afa158015612fc0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fe89190810190614bca565b6060015160ff169050848110156130115760405162461bcd60e51b815260040161040290614f63565b50505b846040015161ffff16600114156130a95760008981526001870160209081526040808320608089015160ff168452612012019091529020546130a95760405162461bcd60e51b815260206004820152602860248201527f5265616c6d46616365743a204d757374206571756970207265736572766f6972604482015267206f66207479706560c01b6064820152608401610402565b608085015160ff166130bb8a826138ae565b610180860151156131075761018086015160008b815260018901602052604090206120130182600481106130f1576130f1614d4a565b0160008282546131019190614e4e565b90915550505b6101a0860151156131425760008a81526001808901602090815260408084208585526120120182528320805492830181558352909120018990555b604086015161ffff166131df57878061316d575060008a8152600188016020526040902061201f0154155b6131c75760405162461bcd60e51b815260206004820152602560248201527f4c6962416c6368656d6963613a2043616e6e6f742065717569702074776f20616044820152646c7461727360d81b6064820152608401610402565b60008a8152600188016020526040902061201f018990555b60e086015160ff1615613222578560e0015160ff168760010160008c815260200190815260200160002061202001600082825461321c9190614e4e565b90915550505b50505050505050505050565b600080613239613b31565b90506000613245613b69565b603784015460405163e042161f60e01b8152600481018990529192506001600160a01b031690600090829063e042161f9060240160006040518083038186803b15801561329157600080fd5b505afa1580156132a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132cd9190810190614fc2565b60008a815260018701602052604090208151600682015492935090918690600581106132fb576132fb614d4a565b602002015161330a9190614fab565b8811156133595760405162461bcd60e51b815260206004820152601b60248201527f4c69625265616c6d3a207820657863656564696e6720776964746800000000006044820152606401610402565b81602001518482600601546005811061337457613374614d4a565b60200201516133839190614fab565b8711156133d25760405162461bcd60e51b815260206004820152601c60248201527f4c69625265616c6d3a207920657863656564696e6720686569676874000000006044820152606401610402565b875b82516133e0908a614e4e565b811015612da157875b60208401516133f8908a614e4e565b8110156134b2578261100701826040811061341557613415614d4a565b60400201816040811061342a5761342a614d4a565b0154156134725760405162461bcd60e51b8152602060048201526016602482015275131a589499585b1b4e88125b9d985b1a59081cdc1bdd60521b6044820152606401610402565b8a8361100701836040811061348957613489614d4a565b60400201826040811061349e5761349e614d4a565b0155806134aa81614db5565b9150506133e9565b50806134bd81614db5565b9150506133d4565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b0316331461354c5760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b6064820152608401610402565b565b6000818152600160205260408120546001600160a01b0316156135bd5760405162461bcd60e51b815260206004820152602160248201527f4c69624552433732313a20746f6b656e496420616c7265616479206d696e74656044820152601960fa1b6064820152608401610402565b600082815260018281016020908152604080842080546001600160a01b0319166001600160a01b03891690811790915585548085018755868652838620018790558085526003860180845282862080546002890186528488208a895286528488208190559185529481018555938552918420909201859055905184927f1661e9eb70c35142fbb4190fa06d962636cf9ccd88dd913f90c08bcbf0d43e9191a360405182906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4505050565b600080603781015460405163e042161f60e01b8152600481018790529192506001600160a01b031690600090829063e042161f9060240160006040518083038186803b1580156136e857600080fd5b505afa1580156136fc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137249190810190614fc2565b60008881526001850160205260409081902091925087906110078301908890811061375157613751614d4a565b60400201866040811061376657613766614d4a565b0154146137ae5760405162461bcd60e51b8152602060048201526016602482015275131a589499585b1b4e881ddc9bdb99c81d1a5b19525960521b6044820152606401610402565b855b82516137bc9088614e4e565b8110156124d757855b60208401516137d49088614e4e565b81101561381c576000836110070183604081106137f3576137f3614d4a565b60400201826040811061380857613808614d4a565b01558061381481614db5565b9150506137c5565b508061382781614db5565b9150506137b0565b60008060008061383e85613ba1565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015613899573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6000806138bb8484613a1c565b905060006138c98585613c15565b9050801561397757600085815260018401602052604090208290829061201b0186600481106138fa576138fa614d4a565b01546139069190614e4e565b111561393a5760008581526001840160205260409020829061201b01856004811061393357613933614d4a565b0155613977565b60008581526001840160205260409020819061201b01856004811061396157613961614d4a565b0160008282546139719190614e4e565b90915550505b60008581526001840160205260409020429061201701856004811061399e5761399e614d4a565b01555050505050565b815482906139b790600190614fab565b815481106139c7576139c7614d4a565b90600052602060002001548282815481106139e4576139e4614d4a565b906000526020600020018190555081805480613a0257613a02615083565b600190038181906000526020600020016000905590555050565b60008060005b6000858152600183016020908152604080832087845261201201909152902054811015613b2957600b8201546000868152600184016020908152604080832088845261201201909152902080546001600160a01b039092169163d3606249919084908110613a9257613a92614d4a565b90600052602060002001546040518263ffffffff1660e01b8152600401613abb91815260200190565b60206040518083038186803b158015613ad357600080fd5b505afa158015613ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0b9190614e1e565b613b159084614e4e565b925080613b2181614db5565b915050613a22565b505092915050565b613b39613e8c565b506040805160a0810182526008815260106020808301919091528183015260608101829052608081019190915290565b613b71613e8c565b506040805160a0810182526008815260106020808301919091528183018390526060820152608081019190915290565b60008060008351604114613bf75760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610402565b50505060208101516040820151606090920151909260009190911a90565b600082815260016020526040812081908190612017018460048110613c3c57613c3c614d4a565b0154613c489042614fab565b60008681526001840160205260409020612013018560048110613c6d57613c6d614d4a565b0154613c799190615099565b95945050505050565b6040518061080001604052806040905b613c9a613eaa565b815260200190600190039081613c925790505090565b6040518061080001604052806040905b613cc8613ec9565b815260200190600190039081613cc05790505090565b828054613cea90614a1e565b90600052602060002090601f016020900481019282613d0c5760008555613d52565b82601f10613d2557805160ff1916838001178555613d52565b82800160010185558215613d52579182015b82811115613d52578251825591602001919060010190613d37565b50613d5e929150613ee8565b5090565b8260048101928215613d525791602002820182811115613d52578251825591602001919060010190613d37565b6040518061010001604052806008905b613da7613efd565b815260200190600190039081613d9f5790505090565b6040518061040001604052806020905b613dd5613eaa565b815260200190600190039081613dcd5790505090565b6040518061020001604052806010905b613e03613f1c565b815260200190600190039081613dfb5790505090565b6040518060200160405280613e2c613c82565b905290565b604051806101200160405280606081526020016060815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001613e7f613f3b565b8152602001600081525090565b6040518060a001604052806005906020820280368337509192915050565b6040518061080001604052806040906020820280368337509192915050565b6040518061040001604052806020906020820280368337509192915050565b5b80821115613d5e5760008155600101613ee9565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715613f9157613f91613f59565b60405290565b60405161020081016001600160401b0381118282101715613f9157613f91613f59565b604080519081016001600160401b0381118282101715613f9157613f91613f59565b604051608081016001600160401b0381118282101715613f9157613f91613f59565b604051601f8201601f191681016001600160401b038111828210171561402657614026613f59565b604052919050565b60006001600160401b0382111561404757614047613f59565b50601f01601f191660200190565b60006140686140638461402e565b613ffe565b905082815283838301111561407c57600080fd5b828260208301376000602084830101529392505050565b600080600080600060a086880312156140ab57600080fd5b8535945060208601359350604086013592506060860135915060808601356001600160401b038111156140dd57600080fd5b8601601f810188136140ee57600080fd5b6140fd88823560208401614055565b9150509295509295909350565b6000806040838503121561411d57600080fd5b50508035926020909101359150565b60008282825b6040811015614151578151835260209283019290910190600101614132565b5050506108008301905092915050565b620200008101818360005b60408110156141915761418083835161412c565b92506020919091019060010161416c565b50505092915050565b62010000810181836000805b60408110156141f157825184835b60208082106141c357506141d7565b8351835292830192909101906001016141b4565b5050506104009390930192602092909201916001016141a6565b5050505092915050565b6000806000806080858703121561421157600080fd5b5050823594602084013594506040840135936060013592509050565b60008083601f84011261423f57600080fd5b5081356001600160401b0381111561425657600080fd5b6020830191508360208260051b850101111561427157600080fd5b9250929050565b6000806000806000806060878903121561429157600080fd5b86356001600160401b03808211156142a857600080fd5b6142b48a838b0161422d565b909850965060208901359150808211156142cd57600080fd5b6142d98a838b0161422d565b909650945060408901359150808211156142f257600080fd5b506142ff89828a0161422d565b979a9699509497509295939492505050565b600080600080600060a0868803121561432957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b80356001600160a01b038116811461436357600080fd5b919050565b60006001600160401b0382111561438157614381613f59565b5060051b60200190565b600082601f83011261439c57600080fd5b6143ab83833560208501614055565b9392505050565b600082601f8301126143c357600080fd5b6143cb613fdc565b8060808401858111156143dd57600080fd5b845b818110156143f75780358452602093840193016143df565b509095945050505050565b6000806000806060858703121561441857600080fd5b6144218561434c565b935060208501356001600160401b038082111561443d57600080fd5b6144498883890161422d565b9095509350604087013591508082111561446257600080fd5b818701915087601f83011261447657600080fd5b6144836140638335614368565b82358082526020808301929160051b8501018a8111156144a257600080fd5b602085015b818110156145725784813511156144bd57600080fd5b80358601610140818e03601f190112156144d657600080fd5b6144de613f6f565b60208201358152604082013560208201526060820135604082015260808201358781111561450b57600080fd5b61451a8f60208386010161438b565b60608301525060a08201358781111561453257600080fd5b6145418f60208386010161438b565b60808301525060c082013560a082015261455e8e60e084016143b2565b60c0820152855250602093840193016144a7565b50508094505050505092959194509250565b60006020828403121561459657600080fd5b5035919050565b600080604083850312156145b057600080fd5b6145b98361434c565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561163b578351835292840192918401916001016145e3565b610800810181836000805b600880821061461957506141f1565b835185845b8381101561463c57825182526020928301929091019060010161461e565b5050506101009490940193506020929092019160010161460a565b620100008101818360005b60208082106146715750614191565b61467c84845161412c565b93509190910190600101614662565b600080600080604085870312156146a157600080fd5b84356001600160401b03808211156146b857600080fd5b6146c48883890161422d565b909650945060208701359150808211156146dd57600080fd5b506146ea8782880161422d565b95989497509550505050565b6000806020838503121561470957600080fd5b82356001600160401b0381111561471f57600080fd5b61472b8582860161422d565b90969095509350505050565b612000810181836000805b601080821061475157506141f1565b835185845b83811015614774578251825260209283019290910190600101614756565b50505061020094909401935060209290920191600101614742565b6000806000604084860312156147a457600080fd5b83356001600160401b038111156147ba57600080fd5b6147c68682870161422d565b909790965060209590950135949350505050565b60208082528251828201819052600091906040908185019086840185805b8381101561483f5782515185835b888110156148275761481982845161412c565b928a01929150600101614806565b505050620200009490940193918601916001016147f8565b509298975050505050505050565b801515811461485b57600080fd5b50565b60006020828403121561487057600080fd5b81356143ab8161484d565b60005b8381101561489657818101518382015260200161487e565b838111156148a5576000848401525b50505050565b600081518084526148c381602086016020860161487b565b601f01601f19169290920160200192915050565b8060005b60048110156148a55781518452602093840193909101906001016148db565b60208152600082516101808060208501526149196101a08501836148ab565b91506020850151601f1985840301604086015261493683826148ab565b925050604085015161495360608601826001600160a01b03169052565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100614990818701836148d7565b959095015193019290925250919050565b60208082526026908201527f41707053746f726167653a204f6e6c792050617263656c206f776e65722063616040820152651b8818d85b1b60d21b606082015260800190565b6020808252601b908201527f41707053746f726167653a2067616d65206e6f74206163746976650000000000604082015260600190565b600181811c90821680614a3257607f821691505b60208210811415614a5357634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601d908201527f5265616c6d46616365743a20496e76616c6964207369676e6174757265000000604082015260600190565b805160ff8116811461436357600080fd5b805161ffff8116811461436357600080fd5b805163ffffffff8116811461436357600080fd5b80516143638161484d565b600082601f830112614ae357600080fd5b614aeb613fdc565b806080840185811115614afd57600080fd5b845b818110156143f7578051845260209384019301614aff565b600082601f830112614b2857600080fd5b81516020614b3861406383614368565b82815260059290921b84018101918181019086841115614b5757600080fd5b8286015b84811015614b725780518352918301918301614b5b565b509695505050505050565b600082601f830112614b8e57600080fd5b8151614b9c6140638261402e565b818152846020838601011115614bb157600080fd5b614bc282602083016020870161487b565b949350505050565b600060208284031215614bdc57600080fd5b81516001600160401b0380821115614bf357600080fd5b908301906102608286031215614c0857600080fd5b614c10613f97565b614c1983614a90565b8152614c2760208401614a90565b6020820152614c3860408401614aa1565b6040820152614c4960608401614a90565b6060820152614c5a60808401614a90565b6080820152614c6b60a08401614ab3565b60a0820152614c7c60c08401614aa1565b60c0820152614c8d60e08401614a90565b60e0820152610100614ca0818501614ab3565b90820152610120614cb2848201614ab3565b90820152610140614cc4848201614ac7565b90820152610160614cd787858301614ad2565b908201526101e0838101516101808301526102008401516101a083015261022084015183811115614d0757600080fd5b614d1388828701614b17565b6101c08401525061024084015183811115614d2d57600080fd5b614d3988828701614b7d565b918301919091525095945050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082614d9357634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215614daa57600080fd5b81516143ab8161484d565b6000600019821415614dc957614dc9614d60565b5060010190565b6020808252602e908201527f41707053746f726167653a204f6e6c7920496e7374616c6c6174696f6e20646960408201526d185b5bdb990818d85b8818d85b1b60921b606082015260800190565b600060208284031215614e3057600080fd5b5051919050565b600081614e4657614e46614d60565b506000190190565b60008219821115614e6157614e61614d60565b500190565b60006020808385031215614e7957600080fd5b82516001600160401b03811115614e8f57600080fd5b8301601f81018513614ea057600080fd5b8051614eae61406382614368565b81815260069190911b82018301908381019087831115614ecd57600080fd5b928401925b82841015614f105760408489031215614eeb5760008081fd5b614ef3613fba565b845181528585015186820152825260409093019290840190614ed2565b979650505050505050565b60208082526028908201527f5265616c6d46616365743a20416c746172205465636820547265652052657173604082015267081b9bdd081b595d60c21b606082015260800190565b60208082526028908201527f5265616c6d46616365743a204c6f646765205465636820547265652052657173604082015267081b9bdd081b595d60c21b606082015260800190565b600082821015614fbd57614fbd614d60565b500390565b600060208284031215614fd457600080fd5b81516001600160401b0380821115614feb57600080fd5b90830190610140828603121561500057600080fd5b615008613f6f565b825181526020830151602082015261502260408401614ac7565b604082015261503360608401614aa1565b60608201526150458660808501614ad2565b608082015261010083015160a08201526101208301518281111561506857600080fd5b61507487828601614b7d565b60c08301525095945050505050565b634e487b7160e01b600052603160045260246000fd5b60008160001904831182151516156150b3576150b3614d60565b50029056fea26469706673582212203e356204c71794312c4bceaf768bd607f53b51e38f1bd09cb48996c468f6babd64736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101585760003560e01c80637690a6b3116100c3578063c96fd9c51161007c578063c96fd9c51461030c578063ccc089741461032c578063d5abeb011461033f578063da80c76e14610352578063dd71950a14610376578063e45c7de21461039657600080fd5b80637690a6b314610273578063ad3d0f6514610293578063adf68808146102b3578063bc6c0d33146102c6578063bd6a3295146102d9578063c3671216146102ec57600080fd5b806351caf05c1161011557806351caf05c146101f45780635505421b1461020757806356ba6c551461021a578063579fa4af1461022d578063594a0a701461024057806375438cd41461026057600080fd5b80631628652a1461015d5780631ef25f94146101725780632d7e13011461019b578063347373c7146101bb578063367e3dac146101ce5780633fa75b65146101e1575b600080fd5b61017061016b366004614093565b6103ba565b005b61018561018036600461410a565b61076d565b6040516101929190614161565b60405180910390f35b6101ae6101a936600461410a565b6108ff565b604051610192919061419a565b6101706101c93660046141fb565b610a94565b6101706101dc366004614278565b610b27565b6101706101ef366004614093565b610ceb565b610170610202366004614093565b611025565b610170610215366004614311565b6111a6565b610170610228366004614402565b611266565b61017061023b366004614584565b611419565b61025361024e36600461459d565b611479565b60405161019291906145c7565b61017061026e366004614584565b611647565b61028661028136600461410a565b61169f565b60405161019291906145ff565b6102a66102a136600461410a565b611821565b6040516101929190614657565b6102536102c136600461468b565b6119b8565b6101706102d43660046146f6565b611ae5565b6101706102e7366004614093565b611b60565b6102ff6102fa36600461410a565b611cd5565b6040516101929190614737565b61031f61031a36600461478f565b611e61565b60405161019291906147da565b61017061033a36600461485e565b612069565b620668e55b604051908152602001610192565b610344610360366004614584565b6000908152600160205260409020612020015490565b610389610384366004614584565b61208f565b60405161019291906148fa565b6103446103a4366004614584565b6000908152600160205260409020612021015490565b60008581526001602052604090205485906001600160a01b03166103dc61224f565b6001600160a01b03161461040b5760405162461bcd60e51b8152600401610402906149a1565b60405180910390fd5b603754600160a01b900460ff166104345760405162461bcd60e51b8152600401610402906149e7565b604080516020810188905290810186905260608101859052608081018490526105059060a0015b60405160208183030381529060405280519060200120836000602f01805461048290614a1e565b80601f01602080910402602001604051908101604052809291908181526020018280546104ae90614a1e565b80156104fb5780601f106104d0576101008083540402835291602001916104fb565b820191906000526020600020905b8154815290600101906020018083116104de57829003601f168201915b50505050506122ac565b6105215760405162461bcd60e51b815260040161040290614a59565b600b5460405163109e13c560e21b8152600481018790526001600160a01b039091169060009082906342784f149060240160006040518083038186803b15801561056a57600080fd5b505afa15801561057e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105a69190810190614bca565b90506105b488888888612336565b60005b60048110156106a9576000600782600481106105d5576105d5614d4a565b01546101608401516001600160a01b039091169150600090600290846004811061060157610601614d4a565b60200201516106109190614d76565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb90604401602060405180830381600087803b15801561065b57600080fd5b505af115801561066f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106939190614d98565b50505080806106a190614db5565b9150506105b7565b50600b54604051633240806960e01b8152600481018a9052602481018990526001600160a01b0390911690633240806990604401600060405180830381600087803b1580156106f757600080fd5b505af115801561070b573d6000803e3d6000fd5b5050505061071b888860006124e2565b6040805189815260208101899052908101879052606081018690527feb8dc37534b72de521d16884c32148e05abe550c5627ee4ba527ddfa1a7717ff9060800160405180910390a15050505050505050565b610775613c82565b6000838152600160205260409020600601546004146107d65760405162461bcd60e51b815260206004820152601860248201527f5265616c6d46616365743a204e6f742070616172746e657200000000000000006044820152606401610402565b60005b60408110156108f85760005b60408110156108e557836108605760008581526001602052604090819020600701908290811061081757610817614d4a565b60400201826040811061082c5761082c614d4a565b015483836040811061084057610840614d4a565b6020020151826040811061085657610856614d4a565b60200201526108d3565b83600114156108d3576000858152600160205260409081902061100701908290811061088e5761088e614d4a565b6040020182604081106108a3576108a3614d4a565b01548383604081106108b7576108b7614d4a565b602002015182604081106108cd576108cd614d4a565b60200201525b806108dd81614db5565b9150506107e5565b50806108f081614db5565b9150506107d9565b5092915050565b610907613cb0565b6000838152600160205260409020600601546002146109725760405162461bcd60e51b815260206004820152602160248201527f5265616c6d46616365743a204e6f742073706163696f757320766572746963616044820152601b60fa1b6064820152608401610402565b60005b60408110156108f85760005b6020811015610a8157836109fc576000858152600160205260409081902060070190829081106109b3576109b3614d4a565b6040020182604081106109c8576109c8614d4a565b01548383604081106109dc576109dc614d4a565b602002015182602081106109f2576109f2614d4a565b6020020152610a6f565b8360011415610a6f5760008581526001602052604090819020611007019082908110610a2a57610a2a614d4a565b604002018260408110610a3f57610a3f614d4a565b0154838360408110610a5357610a53614d4a565b60200201518260208110610a6957610a69614d4a565b60200201525b80610a7981614db5565b915050610981565b5080610a8c81614db5565b915050610975565b60008481526001602052604090819020908290600783019086908110610abc57610abc614d4a565b604002018460408110610ad157610ad1614d4a565b015414610b205760405162461bcd60e51b815260206004820152601d60248201527f5265616c6d46616365743a2077726f6e6720636f6f7264696e617465730000006044820152606401610402565b5050505050565b603754600160a01b900460ff16610b505760405162461bcd60e51b8152600401610402906149e7565b8481148015610b5e57508483145b610baa5760405162461bcd60e51b815260206004820152601d60248201527f5265616c6d46616365743a204d69736d617463686564206172726179730000006044820152606401610402565b60005b85811015610ce25760016000888884818110610bcb57610bcb614d4a565b60209081029290920135835250810191909152604001600020546001600160a01b0316610bf661224f565b6001600160a01b031614610c5b5760405162461bcd60e51b815260206004820152602660248201527f5265616c6d46616365743a204f6e6c792050617263656c206f776e65722063616044820152651b8818d85b1b60d21b6064820152608401610402565b828282818110610c6d57610c6d614d4a565b9050602002013560006038016000898985818110610c8d57610c8d614d4a565b9050602002013581526020019081526020016000206000878785818110610cb657610cb6614d4a565b905060200201358152602001908152602001600020819055508080610cda90614db5565b915050610bad565b50505050505050565b60008581526001602052604090205485906001600160a01b0316610d0d61224f565b6001600160a01b031614610d335760405162461bcd60e51b8152600401610402906149a1565b603754600160a01b900460ff16610d5c5760405162461bcd60e51b8152600401610402906149e7565b60408051602081018890529081018690526060810185905260808101849052610d879060a00161045b565b610da35760405162461bcd60e51b815260040161040290614a59565b600b5460405163109e13c560e21b8152600481018790526000916001600160a01b0316906342784f149060240160006040518083038186803b158015610de857600080fd5b505afa158015610dfc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e249190810190614bca565b9050806040015161ffff1660011480610e455750806040015161ffff166002145b15610ebf57600087815260016020819052604090912061200f01541015610ebf5760405162461bcd60e51b815260206004820152602860248201527f5265616c6d46616365743a204d75737420737572766579206265666f726520656044820152677175697070696e6760c01b6064820152608401610402565b806040015161ffff1660031415610f51576000878152600160205260409020612022015415610f3b5760405162461bcd60e51b815260206004820152602260248201527f5265616c6d46616365743a204c6f64676520616c726561647920657175697070604482015261195960f21b6064820152608401610402565b6000878152600160205260409020612022018690555b610f5d87878787612afd565b600b546040516364e5b7a960e01b815233600482015260248101899052604481018890526001600160a01b03909116906364e5b7a990606401600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050610fd487876000612dae565b6040805188815260208101889052908101869052606081018590527f28ee8f870fbf2fc8ef414198cb263e6f548ce9a10088c76c2821b66cf61dddc49060800160405180910390a150505050505050565b60008581526001602052604090205485906001600160a01b031661104761224f565b6001600160a01b03161461106d5760405162461bcd60e51b8152600401610402906149a1565b603754600160a01b900460ff166110965760405162461bcd60e51b8152600401610402906149e7565b604080516020810188905290810186905260608101859052608081018490526110c19060a00161045b565b6110dd5760405162461bcd60e51b815260040161040290614a59565b6110e98686868661322e565b60375460405163e700cdd760e01b815233600482015260248101889052604481018790526001600160a01b039091169063e700cdd790606401600060405180830381600087803b15801561113c57600080fd5b505af1158015611150573d6000803e3d6000fd5b50506040805189815260208101899052908101879052606081018690527ffcb7d72e94eee47cfef784f5d54e1f07cc20dff2f9627de06f1f061428c7c91e925060800190505b60405180910390a1505050505050565b600b546001600160a01b03166111ba61224f565b6001600160a01b0316146111e05760405162461bcd60e51b815260040161040290614dd0565b6111ec85858484612336565b6111f885848484612afd565b611204858560016124e2565b61121085856001612dae565b604080518681526020810186905290810184905260608101839052608081018290527f74b654614ea2444b876a14dec11c709807cda89060906c4b7e443e4f8ff9ed539060a00160405180910390a15050505050565b61126e6134c5565b60005b82811015610b2057600054620668e5116112e75760405162461bcd60e51b815260206004820152603160248201527f5265616c6d46616365743a2043616e6e6f74206d696e74206d6f7265207468616044820152706e203432302c3036392070617263656c7360781b6064820152608401610402565b60008484838181106112fb576112fb614d4a565b905060200201359050600083838151811061131857611318614d4a565b60200260200101519050835186869050146113755760405162461bcd60e51b815260206004820152601a60248201527f496e70757473206d7573742062652073616d65206c656e6774680000000000006044820152606401610402565b6000828152600160209081526040909120825160038201558282015160048201556060830151805191926113b192600285019290910190613cde565b5060a0820151600682015560408201516005820155608082015180516113e1916001840191602090910190613cde565b5060c08201516113f8906120078301906004613d62565b50611403888461354e565b505050808061141190614db5565b915050611271565b600b546001600160a01b031661142d61224f565b6001600160a01b0316146114535760405162461bcd60e51b815260040161040290614dd0565b60008181526001602052604081206120210180549161147183614db5565b919050555050565b60606000306001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156114b657600080fd5b505afa1580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ee9190614e1e565b6040516370a0823160e01b81526001600160a01b038616600482015290915060009030906370a082319060240160206040518083038186803b15801561153357600080fd5b505afa158015611547573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156b9190614e1e565b90506000816001600160401b0381111561158757611587613f59565b6040519080825280602002602001820160405280156115b0578160200160208202803683370190505b5090506000805b8481101561163b57600081815260016020526040902060050154871480156115f857506000818152600160205260409020546001600160a01b038981169116145b15611629578083838151811061161057611610614d4a565b60209081029190910101528161162581614db5565b9250505b8061163381614db5565b9150506115b7565b50909695505050505050565b600b546001600160a01b031661165b61224f565b6001600160a01b0316146116815760405162461bcd60e51b815260040161040290614dd0565b60008181526001602052604081206120210180549161147183614e37565b6116a7613d8f565b600083815260016020526040902060060154156116ff5760405162461bcd60e51b81526020600482015260166024820152755265616c6d46616365743a204e6f742068756d626c6560501b6044820152606401610402565b60005b60088110156108f85760005b600881101561180e57836117895760008581526001602052604090819020600701908290811061174057611740614d4a565b60400201826040811061175557611755614d4a565b015483836008811061176957611769614d4a565b6020020151826008811061177f5761177f614d4a565b60200201526117fc565b83600114156117fc57600085815260016020526040908190206110070190829081106117b7576117b7614d4a565b6040020182604081106117cc576117cc614d4a565b01548383600881106117e0576117e0614d4a565b602002015182600881106117f6576117f6614d4a565b60200201525b8061180681614db5565b91505061170e565b508061181981614db5565b915050611702565b611829613dbd565b6000838152600160205260409020600601546003146118965760405162461bcd60e51b815260206004820152602360248201527f5265616c6d46616365743a204e6f742073706163696f757320686f72697a6f6e6044820152621d185b60ea1b6064820152608401610402565b60005b60208110156108f85760005b60408110156119a55783611920576000858152600160205260409081902060070190829081106118d7576118d7614d4a565b6040020182604081106118ec576118ec614d4a565b015483836020811061190057611900614d4a565b6020020151826040811061191657611916614d4a565b6020020152611993565b8360011415611993576000858152600160205260409081902061100701908290811061194e5761194e614d4a565b60400201826040811061196357611963614d4a565b015483836020811061197757611977614d4a565b6020020151826040811061198d5761198d614d4a565b60200201525b8061199d81614db5565b9150506118a5565b50806119b081614db5565b915050611899565b6060838214611a095760405162461bcd60e51b815260206004820152601d60248201527f5265616c6d46616365743a204d69736d617463686564206172726179730000006044820152606401610402565b836001600160401b03811115611a2157611a21613f59565b604051908082528060200260200182016040528015611a4a578160200160208202803683370190505b50905060005b84811015611adc5760386000878784818110611a6e57611a6e614d4a565b9050602002013581526020019081526020016000206000858584818110611a9757611a97614d4a565b90506020020135815260200190815260200160002054828281518110611abf57611abf614d4a565b602090810291909101015280611ad481614db5565b915050611a50565b50949350505050565b611aed6134c5565b60005b81811015611b5b577ff20fad4a9aa47ceeb29a7f693b89871de4b3b9ed2fc1fdf327785476f9938c97838383818110611b2b57611b2b614d4a565b90506020020135604051611b4191815260200190565b60405180910390a180611b5381614db5565b915050611af0565b505050565b60008581526001602052604090205485906001600160a01b0316611b8261224f565b6001600160a01b031614611ba85760405162461bcd60e51b8152600401610402906149a1565b603754600160a01b900460ff16611bd15760405162461bcd60e51b8152600401610402906149e7565b60408051602081018890529081018690526060810185905260808101849052611bfc9060a00161045b565b611c185760405162461bcd60e51b815260040161040290614a59565b611c2486868686613699565b6037546040516315b194ef60e21b815233600482015260248101889052604481018790526001600160a01b03909116906356c653bc90606401600060405180830381600087803b158015611c7757600080fd5b505af1158015611c8b573d6000803e3d6000fd5b50506040805189815260208101899052908101879052606081018690527fb1e943c280d055bfe1686ba119599cd2071f18e1f3bce12ad3c3c4f0d5b4541f92506080019050611196565b611cdd613deb565b60008381526001602081905260409091206006015414611d3f5760405162461bcd60e51b815260206004820152601a60248201527f5265616c6d46616365743a204e6f7420726561736f6e61626c650000000000006044820152606401610402565b60005b60108110156108f85760005b6010811015611e4e5783611dc957600085815260016020526040908190206007019082908110611d8057611d80614d4a565b604002018260408110611d9557611d95614d4a565b0154838360108110611da957611da9614d4a565b60200201518260108110611dbf57611dbf614d4a565b6020020152611e3c565b8360011415611e3c5760008581526001602052604090819020611007019082908110611df757611df7614d4a565b604002018260408110611e0c57611e0c614d4a565b0154838360108110611e2057611e20614d4a565b60200201518260108110611e3657611e36614d4a565b60200201525b80611e4681614db5565b915050611d4e565b5080611e5981614db5565b915050611d42565b60606000836001600160401b03811115611e7d57611e7d613f59565b604051908082528060200260200182016040528015611eb657816020015b611ea3613e19565b815260200190600190039081611e9b5790505b50905060005b84811015611adc5760005b60408110156120565760005b60408110156120435785611f865760016000898986818110611ef757611ef7614d4a565b9050602002013581526020019081526020016000206007018160408110611f2057611f20614d4a565b604002018260408110611f3557611f35614d4a565b0154848481518110611f4957611f49614d4a565b6020026020010151600001518360408110611f6657611f66614d4a565b60200201518260408110611f7c57611f7c614d4a565b6020020152612031565b85600114156120315760016000898986818110611fa557611fa5614d4a565b905060200201358152602001908152602001600020611007018160408110611fcf57611fcf614d4a565b604002018260408110611fe457611fe4614d4a565b0154848481518110611ff857611ff8614d4a565b602002602001015160000151836040811061201557612015614d4a565b6020020151826040811061202b5761202b614d4a565b60200201525b8061203b81614db5565b915050611ed3565b508061204e81614db5565b915050611ec7565b508061206181614db5565b915050611ebc565b6120716134c5565b60378054911515600160a01b0260ff60a01b19909216919091179055565b612097613e31565b60008281526001602052604090206002810180546120b490614a1e565b80601f01602080910402602001604051908101604052809291908181526020018280546120e090614a1e565b801561212d5780601f106121025761010080835404028352916020019161212d565b820191906000526020600020905b81548152906001019060200180831161211057829003601f168201915b505050918452505080546001600160a01b031660408301526003810154606083015260048101546080830152600681015460a083015260018101805461217290614a1e565b80601f016020809104026020016040519081016040528092919081815260200182805461219e90614a1e565b80156121eb5780601f106121c0576101008083540402835291602001916121eb565b820191906000526020600020905b8154815290600101906020018083116121ce57829003601f168201915b50505050506020830152600581015460c08301526040805160808101918290529061200783019060049082845b81548152602001906001019080831161221857505050505060e0830152506000918252603560205260409091205461010082015290565b6000333014156122a657600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506122a99050565b50335b90565b600080612306856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b835160208501209091506001600160a01b0316612323828661382f565b6001600160a01b03161495945050505050565b600080600b81015460405163109e13c560e21b8152600481018790529192506001600160a01b03169060009082906342784f149060240160006040518083038186803b15801561238557600080fd5b505afa158015612399573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526123c19190810190614bca565b60008881526001850160205260409081902091925087906007830190889081106123ed576123ed614d4a565b60400201866040811061240257612402614d4a565b0154146124515760405162461bcd60e51b815260206004820152601e60248201527f4c69625265616c6d3a2077726f6e6720696e7374616c6c6174696f6e496400006044820152606401610402565b855b82516124629060ff1688614e4e565b8110156124d757855b602084015161247d9060ff1688614e4e565b8110156124c457600083600701836040811061249b5761249b614d4a565b6040020182604081106124b0576124b0614d4a565b0155806124bc81614db5565b91505061246b565b50806124cf81614db5565b915050612453565b505050505050505050565b600080600b81015460405163109e13c560e21b8152600481018690529192506001600160a01b03169060009082906342784f149060240160006040518083038186803b15801561253157600080fd5b505afa158015612545573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261256d9190810190614bca565b6040516324a7504960e11b8152306004820152602481018890529091506000906001600160a01b0384169063494ea0929060440160006040518083038186803b1580156125b957600080fd5b505afa1580156125cd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125f59190810190614e66565b905060005b81518110156128915760405163109e13c560e21b8152600481018890526000906001600160a01b038616906342784f149060240160006040518083038186803b15801561264657600080fd5b505afa15801561265a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126829190810190614bca565b9050806101c0015160008151811061269c5761269c614d4a565b602090810291909101810151600b88015460008c815260018a0190935260409283902061201f0154925163109e13c560e21b815291926001600160a01b03909116916342784f14916126f49160040190815260200190565b60006040518083038186803b15801561270c57600080fd5b505afa158015612720573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127489190810190614bca565b6060015160ff16101561276d5760405162461bcd60e51b815260040161040290614f1b565b6000816101c0015160018151811061278757612787614d4a565b6020026020010151111561287e57806101c001516001815181106127ad576127ad614d4a565b602090810291909101810151600b88015460008c815260018a019093526040928390206120220154925163109e13c560e21b815291926001600160a01b03909116916342784f14916128059160040190815260200190565b60006040518083038186803b15801561281d57600080fd5b505afa158015612831573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128599190810190614bca565b6060015160ff16101561287e5760405162461bcd60e51b815260040161040290614f63565b508061288981614db5565b9150506125fa565b50608082015160ff166128a488826138ae565b610180830151156128f057610180830151600089815260018701602052604090206120130182600481106128da576128da614d4a565b0160008282546128ea9190614fab565b90915550505b604083015161ffff16158015612904575085155b1561291f576000888152600186016020526040812061201f01555b826040015161ffff1660031415612946576000888152600186016020526040812061202201555b6101a083015115612ab05760005b6000898152600187016020908152604080832085845261201201909152902054811015612a0057600089815260018701602090815260408083208584526120120190915290208054899190839081106129af576129af614d4a565b906000526020600020015414156129ee57600089815260018701602090815260408083208584526120120190915290206129e990826139a7565b612a00565b806129f881614db5565b915050612954565b50612a0b8882613a1c565b6000898152600187016020526040902061201b018260048110612a3057612a30614d4a565b01541115612ab05760405162461bcd60e51b815260206004820152604160248201527f4c6962416c6368656d6963613a20556e636c61696d656420616c6368656d696360448201527f612067726561746572207468616e207265736572766f697220636170616369746064820152607960f81b608482015260a401610402565b60e083015160ff1615612af3578260e0015160ff168560010160008a8152602001908152602001600020612020016000828254612aed9190614fab565b90915550505b5050505050505050565b600080612b08613b31565b90506000612b14613b69565b600b84015460405163109e13c560e21b8152600481018990529192506001600160a01b03169060009082906342784f149060240160006040518083038186803b158015612b6057600080fd5b505afa158015612b74573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b9c9190810190614bca565b60008a8152600187016020526040902081516006820154929350909160ff90911690869060058110612bd057612bd0614d4a565b6020020151612bdf9190614fab565b881115612c2e5760405162461bcd60e51b815260206004820152601b60248201527f4c69625265616c6d3a207820657863656564696e6720776964746800000000006044820152606401610402565b816020015160ff1684826006015460058110612c4c57612c4c614d4a565b6020020151612c5b9190614fab565b871115612caa5760405162461bcd60e51b815260206004820152601c60248201527f4c69625265616c6d3a207920657863656564696e6720686569676874000000006044820152606401610402565b875b8251612cbb9060ff168a614e4e565b811015612da157875b6020840151612cd69060ff168a614e4e565b811015612d8e57826007018260408110612cf257612cf2614d4a565b604002018160408110612d0757612d07614d4a565b015415612d4f5760405162461bcd60e51b8152602060048201526016602482015275131a589499585b1b4e88125b9d985b1a59081cdc1bdd60521b6044820152606401610402565b8a836007018360408110612d6557612d65614d4a565b604002018260408110612d7a57612d7a614d4a565b015580612d8681614db5565b915050612cc4565b5080612d9981614db5565b915050612cac565b5050505050505050505050565b600080600b81015460405163109e13c560e21b8152600481018690529192506000916001600160a01b03909116906342784f149060240160006040518083038186803b158015612dfd57600080fd5b505afa158015612e11573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e399190810190614bca565b90506000816101c00151600081518110612e5557612e55614d4a565b602002602001015190506000826101c00151600181518110612e7957612e79614d4a565b602090810291909101810151600089815260018701909252604080832061201f0154600b880154915163109e13c560e21b81526004810182905292945092916001600160a01b03909116906342784f149060240160006040518083038186803b158015612ee557600080fd5b505afa158015612ef9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612f219190810190614bca565b6060015160ff16905083811015612f4a5760405162461bcd60e51b815260040161040290614f1b565b82156130145760008981526001870160205260408082206120220154600b890154915163109e13c560e21b8152600481018290529092916001600160a01b0316906342784f149060240160006040518083038186803b158015612fac57600080fd5b505afa158015612fc0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fe89190810190614bca565b6060015160ff169050848110156130115760405162461bcd60e51b815260040161040290614f63565b50505b846040015161ffff16600114156130a95760008981526001870160209081526040808320608089015160ff168452612012019091529020546130a95760405162461bcd60e51b815260206004820152602860248201527f5265616c6d46616365743a204d757374206571756970207265736572766f6972604482015267206f66207479706560c01b6064820152608401610402565b608085015160ff166130bb8a826138ae565b610180860151156131075761018086015160008b815260018901602052604090206120130182600481106130f1576130f1614d4a565b0160008282546131019190614e4e565b90915550505b6101a0860151156131425760008a81526001808901602090815260408084208585526120120182528320805492830181558352909120018990555b604086015161ffff166131df57878061316d575060008a8152600188016020526040902061201f0154155b6131c75760405162461bcd60e51b815260206004820152602560248201527f4c6962416c6368656d6963613a2043616e6e6f742065717569702074776f20616044820152646c7461727360d81b6064820152608401610402565b60008a8152600188016020526040902061201f018990555b60e086015160ff1615613222578560e0015160ff168760010160008c815260200190815260200160002061202001600082825461321c9190614e4e565b90915550505b50505050505050505050565b600080613239613b31565b90506000613245613b69565b603784015460405163e042161f60e01b8152600481018990529192506001600160a01b031690600090829063e042161f9060240160006040518083038186803b15801561329157600080fd5b505afa1580156132a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132cd9190810190614fc2565b60008a815260018701602052604090208151600682015492935090918690600581106132fb576132fb614d4a565b602002015161330a9190614fab565b8811156133595760405162461bcd60e51b815260206004820152601b60248201527f4c69625265616c6d3a207820657863656564696e6720776964746800000000006044820152606401610402565b81602001518482600601546005811061337457613374614d4a565b60200201516133839190614fab565b8711156133d25760405162461bcd60e51b815260206004820152601c60248201527f4c69625265616c6d3a207920657863656564696e6720686569676874000000006044820152606401610402565b875b82516133e0908a614e4e565b811015612da157875b60208401516133f8908a614e4e565b8110156134b2578261100701826040811061341557613415614d4a565b60400201816040811061342a5761342a614d4a565b0154156134725760405162461bcd60e51b8152602060048201526016602482015275131a589499585b1b4e88125b9d985b1a59081cdc1bdd60521b6044820152606401610402565b8a8361100701836040811061348957613489614d4a565b60400201826040811061349e5761349e614d4a565b0155806134aa81614db5565b9150506133e9565b50806134bd81614db5565b9150506133d4565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b0316331461354c5760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b6064820152608401610402565b565b6000818152600160205260408120546001600160a01b0316156135bd5760405162461bcd60e51b815260206004820152602160248201527f4c69624552433732313a20746f6b656e496420616c7265616479206d696e74656044820152601960fa1b6064820152608401610402565b600082815260018281016020908152604080842080546001600160a01b0319166001600160a01b03891690811790915585548085018755868652838620018790558085526003860180845282862080546002890186528488208a895286528488208190559185529481018555938552918420909201859055905184927f1661e9eb70c35142fbb4190fa06d962636cf9ccd88dd913f90c08bcbf0d43e9191a360405182906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4505050565b600080603781015460405163e042161f60e01b8152600481018790529192506001600160a01b031690600090829063e042161f9060240160006040518083038186803b1580156136e857600080fd5b505afa1580156136fc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137249190810190614fc2565b60008881526001850160205260409081902091925087906110078301908890811061375157613751614d4a565b60400201866040811061376657613766614d4a565b0154146137ae5760405162461bcd60e51b8152602060048201526016602482015275131a589499585b1b4e881ddc9bdb99c81d1a5b19525960521b6044820152606401610402565b855b82516137bc9088614e4e565b8110156124d757855b60208401516137d49088614e4e565b81101561381c576000836110070183604081106137f3576137f3614d4a565b60400201826040811061380857613808614d4a565b01558061381481614db5565b9150506137c5565b508061382781614db5565b9150506137b0565b60008060008061383e85613ba1565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015613899573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6000806138bb8484613a1c565b905060006138c98585613c15565b9050801561397757600085815260018401602052604090208290829061201b0186600481106138fa576138fa614d4a565b01546139069190614e4e565b111561393a5760008581526001840160205260409020829061201b01856004811061393357613933614d4a565b0155613977565b60008581526001840160205260409020819061201b01856004811061396157613961614d4a565b0160008282546139719190614e4e565b90915550505b60008581526001840160205260409020429061201701856004811061399e5761399e614d4a565b01555050505050565b815482906139b790600190614fab565b815481106139c7576139c7614d4a565b90600052602060002001548282815481106139e4576139e4614d4a565b906000526020600020018190555081805480613a0257613a02615083565b600190038181906000526020600020016000905590555050565b60008060005b6000858152600183016020908152604080832087845261201201909152902054811015613b2957600b8201546000868152600184016020908152604080832088845261201201909152902080546001600160a01b039092169163d3606249919084908110613a9257613a92614d4a565b90600052602060002001546040518263ffffffff1660e01b8152600401613abb91815260200190565b60206040518083038186803b158015613ad357600080fd5b505afa158015613ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0b9190614e1e565b613b159084614e4e565b925080613b2181614db5565b915050613a22565b505092915050565b613b39613e8c565b506040805160a0810182526008815260106020808301919091528183015260608101829052608081019190915290565b613b71613e8c565b506040805160a0810182526008815260106020808301919091528183018390526060820152608081019190915290565b60008060008351604114613bf75760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610402565b50505060208101516040820151606090920151909260009190911a90565b600082815260016020526040812081908190612017018460048110613c3c57613c3c614d4a565b0154613c489042614fab565b60008681526001840160205260409020612013018560048110613c6d57613c6d614d4a565b0154613c799190615099565b95945050505050565b6040518061080001604052806040905b613c9a613eaa565b815260200190600190039081613c925790505090565b6040518061080001604052806040905b613cc8613ec9565b815260200190600190039081613cc05790505090565b828054613cea90614a1e565b90600052602060002090601f016020900481019282613d0c5760008555613d52565b82601f10613d2557805160ff1916838001178555613d52565b82800160010185558215613d52579182015b82811115613d52578251825591602001919060010190613d37565b50613d5e929150613ee8565b5090565b8260048101928215613d525791602002820182811115613d52578251825591602001919060010190613d37565b6040518061010001604052806008905b613da7613efd565b815260200190600190039081613d9f5790505090565b6040518061040001604052806020905b613dd5613eaa565b815260200190600190039081613dcd5790505090565b6040518061020001604052806010905b613e03613f1c565b815260200190600190039081613dfb5790505090565b6040518060200160405280613e2c613c82565b905290565b604051806101200160405280606081526020016060815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001613e7f613f3b565b8152602001600081525090565b6040518060a001604052806005906020820280368337509192915050565b6040518061080001604052806040906020820280368337509192915050565b6040518061040001604052806020906020820280368337509192915050565b5b80821115613d5e5760008155600101613ee9565b6040518061010001604052806008906020820280368337509192915050565b6040518061020001604052806010906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b0381118282101715613f9157613f91613f59565b60405290565b60405161020081016001600160401b0381118282101715613f9157613f91613f59565b604080519081016001600160401b0381118282101715613f9157613f91613f59565b604051608081016001600160401b0381118282101715613f9157613f91613f59565b604051601f8201601f191681016001600160401b038111828210171561402657614026613f59565b604052919050565b60006001600160401b0382111561404757614047613f59565b50601f01601f191660200190565b60006140686140638461402e565b613ffe565b905082815283838301111561407c57600080fd5b828260208301376000602084830101529392505050565b600080600080600060a086880312156140ab57600080fd5b8535945060208601359350604086013592506060860135915060808601356001600160401b038111156140dd57600080fd5b8601601f810188136140ee57600080fd5b6140fd88823560208401614055565b9150509295509295909350565b6000806040838503121561411d57600080fd5b50508035926020909101359150565b60008282825b6040811015614151578151835260209283019290910190600101614132565b5050506108008301905092915050565b620200008101818360005b60408110156141915761418083835161412c565b92506020919091019060010161416c565b50505092915050565b62010000810181836000805b60408110156141f157825184835b60208082106141c357506141d7565b8351835292830192909101906001016141b4565b5050506104009390930192602092909201916001016141a6565b5050505092915050565b6000806000806080858703121561421157600080fd5b5050823594602084013594506040840135936060013592509050565b60008083601f84011261423f57600080fd5b5081356001600160401b0381111561425657600080fd5b6020830191508360208260051b850101111561427157600080fd5b9250929050565b6000806000806000806060878903121561429157600080fd5b86356001600160401b03808211156142a857600080fd5b6142b48a838b0161422d565b909850965060208901359150808211156142cd57600080fd5b6142d98a838b0161422d565b909650945060408901359150808211156142f257600080fd5b506142ff89828a0161422d565b979a9699509497509295939492505050565b600080600080600060a0868803121561432957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b80356001600160a01b038116811461436357600080fd5b919050565b60006001600160401b0382111561438157614381613f59565b5060051b60200190565b600082601f83011261439c57600080fd5b6143ab83833560208501614055565b9392505050565b600082601f8301126143c357600080fd5b6143cb613fdc565b8060808401858111156143dd57600080fd5b845b818110156143f75780358452602093840193016143df565b509095945050505050565b6000806000806060858703121561441857600080fd5b6144218561434c565b935060208501356001600160401b038082111561443d57600080fd5b6144498883890161422d565b9095509350604087013591508082111561446257600080fd5b818701915087601f83011261447657600080fd5b6144836140638335614368565b82358082526020808301929160051b8501018a8111156144a257600080fd5b602085015b818110156145725784813511156144bd57600080fd5b80358601610140818e03601f190112156144d657600080fd5b6144de613f6f565b60208201358152604082013560208201526060820135604082015260808201358781111561450b57600080fd5b61451a8f60208386010161438b565b60608301525060a08201358781111561453257600080fd5b6145418f60208386010161438b565b60808301525060c082013560a082015261455e8e60e084016143b2565b60c0820152855250602093840193016144a7565b50508094505050505092959194509250565b60006020828403121561459657600080fd5b5035919050565b600080604083850312156145b057600080fd5b6145b98361434c565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561163b578351835292840192918401916001016145e3565b610800810181836000805b600880821061461957506141f1565b835185845b8381101561463c57825182526020928301929091019060010161461e565b5050506101009490940193506020929092019160010161460a565b620100008101818360005b60208082106146715750614191565b61467c84845161412c565b93509190910190600101614662565b600080600080604085870312156146a157600080fd5b84356001600160401b03808211156146b857600080fd5b6146c48883890161422d565b909650945060208701359150808211156146dd57600080fd5b506146ea8782880161422d565b95989497509550505050565b6000806020838503121561470957600080fd5b82356001600160401b0381111561471f57600080fd5b61472b8582860161422d565b90969095509350505050565b612000810181836000805b601080821061475157506141f1565b835185845b83811015614774578251825260209283019290910190600101614756565b50505061020094909401935060209290920191600101614742565b6000806000604084860312156147a457600080fd5b83356001600160401b038111156147ba57600080fd5b6147c68682870161422d565b909790965060209590950135949350505050565b60208082528251828201819052600091906040908185019086840185805b8381101561483f5782515185835b888110156148275761481982845161412c565b928a01929150600101614806565b505050620200009490940193918601916001016147f8565b509298975050505050505050565b801515811461485b57600080fd5b50565b60006020828403121561487057600080fd5b81356143ab8161484d565b60005b8381101561489657818101518382015260200161487e565b838111156148a5576000848401525b50505050565b600081518084526148c381602086016020860161487b565b601f01601f19169290920160200192915050565b8060005b60048110156148a55781518452602093840193909101906001016148db565b60208152600082516101808060208501526149196101a08501836148ab565b91506020850151601f1985840301604086015261493683826148ab565b925050604085015161495360608601826001600160a01b03169052565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100614990818701836148d7565b959095015193019290925250919050565b60208082526026908201527f41707053746f726167653a204f6e6c792050617263656c206f776e65722063616040820152651b8818d85b1b60d21b606082015260800190565b6020808252601b908201527f41707053746f726167653a2067616d65206e6f74206163746976650000000000604082015260600190565b600181811c90821680614a3257607f821691505b60208210811415614a5357634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601d908201527f5265616c6d46616365743a20496e76616c6964207369676e6174757265000000604082015260600190565b805160ff8116811461436357600080fd5b805161ffff8116811461436357600080fd5b805163ffffffff8116811461436357600080fd5b80516143638161484d565b600082601f830112614ae357600080fd5b614aeb613fdc565b806080840185811115614afd57600080fd5b845b818110156143f7578051845260209384019301614aff565b600082601f830112614b2857600080fd5b81516020614b3861406383614368565b82815260059290921b84018101918181019086841115614b5757600080fd5b8286015b84811015614b725780518352918301918301614b5b565b509695505050505050565b600082601f830112614b8e57600080fd5b8151614b9c6140638261402e565b818152846020838601011115614bb157600080fd5b614bc282602083016020870161487b565b949350505050565b600060208284031215614bdc57600080fd5b81516001600160401b0380821115614bf357600080fd5b908301906102608286031215614c0857600080fd5b614c10613f97565b614c1983614a90565b8152614c2760208401614a90565b6020820152614c3860408401614aa1565b6040820152614c4960608401614a90565b6060820152614c5a60808401614a90565b6080820152614c6b60a08401614ab3565b60a0820152614c7c60c08401614aa1565b60c0820152614c8d60e08401614a90565b60e0820152610100614ca0818501614ab3565b90820152610120614cb2848201614ab3565b90820152610140614cc4848201614ac7565b90820152610160614cd787858301614ad2565b908201526101e0838101516101808301526102008401516101a083015261022084015183811115614d0757600080fd5b614d1388828701614b17565b6101c08401525061024084015183811115614d2d57600080fd5b614d3988828701614b7d565b918301919091525095945050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082614d9357634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215614daa57600080fd5b81516143ab8161484d565b6000600019821415614dc957614dc9614d60565b5060010190565b6020808252602e908201527f41707053746f726167653a204f6e6c7920496e7374616c6c6174696f6e20646960408201526d185b5bdb990818d85b8818d85b1b60921b606082015260800190565b600060208284031215614e3057600080fd5b5051919050565b600081614e4657614e46614d60565b506000190190565b60008219821115614e6157614e61614d60565b500190565b60006020808385031215614e7957600080fd5b82516001600160401b03811115614e8f57600080fd5b8301601f81018513614ea057600080fd5b8051614eae61406382614368565b81815260069190911b82018301908381019087831115614ecd57600080fd5b928401925b82841015614f105760408489031215614eeb5760008081fd5b614ef3613fba565b845181528585015186820152825260409093019290840190614ed2565b979650505050505050565b60208082526028908201527f5265616c6d46616365743a20416c746172205465636820547265652052657173604082015267081b9bdd081b595d60c21b606082015260800190565b60208082526028908201527f5265616c6d46616365743a204c6f646765205465636820547265652052657173604082015267081b9bdd081b595d60c21b606082015260800190565b600082821015614fbd57614fbd614d60565b500390565b600060208284031215614fd457600080fd5b81516001600160401b0380821115614feb57600080fd5b90830190610140828603121561500057600080fd5b615008613f6f565b825181526020830151602082015261502260408401614ac7565b604082015261503360608401614aa1565b60608201526150458660808501614ad2565b608082015261010083015160a08201526101208301518281111561506857600080fd5b61507487828601614b7d565b60c08301525095945050505050565b634e487b7160e01b600052603160045260246000fd5b60008160001904831182151516156150b3576150b3614d60565b50029056fea26469706673582212203e356204c71794312c4bceaf768bd607f53b51e38f1bd09cb48996c468f6babd64736f6c63430008090033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.