Token Corn
Overview ERC20
Price
$0.00 @ 0.000000 ETH
Fully Diluted Market Cap
Total Supply:
2,307,677.752371 CORN
Holders:
318 addresses
Contract:
Decimals:
18
Official Site:
Balance
47.54025106 CORNValue
$0.00
[ Download CSV Export ]
[ Download CSV Export ]
OVERVIEW
Play-to-Earn with Farmland! A farming game secured by Ethereum running on Arbitrum One.Update? Click here to update the token ICO / general information
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
L2Corn
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 9999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.7.0; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; import "@openzeppelin/contracts/token/ERC777/IERC777Sender.sol"; import "@openzeppelin/contracts/introspection/IERC1820Registry.sol"; import "@openzeppelin/contracts/introspection/ERC165.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/math/Math.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721Holder.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "./interfaces/IFarmlandCollectible.sol"; import "./interfaces/Manageable.sol"; /** * @dev Farmland - CropV2 Smart Contract */ contract L2Corn is Manageable, IERC777Recipient, IERC721Receiver, ERC165, ERC721Holder, ReentrancyGuard { /** * @dev Protect against overflows by using safe math operations (these are .add,.sub functions) */ using SafeMath for uint256; // MODIFIERS /** * @dev To limit one action per block per address when dealing with Land or Harvesting Crops */ modifier preventSameBlock(address farmAddress) { require( ownerOfFarm[farmAddress].blockNumber != block.number && ownerOfFarm[farmAddress].lastHarvestedBlockNumber != block.number, "You can not allocate/release or harvest in the same block" ); _; // Call the actual code } /** * @dev To limit one action per block per address when dealing with Collectibles */ modifier preventSameBlockCollectible(address farmAddress) { (,uint256 lastAddedBlockNumber) = getFarmCollectibleTotals(farmAddress); require( lastAddedBlockNumber != block.number, "You can not equip or release a collectible in the same block" ); _; // Call the actual code } /** * @dev There must be a farm on this LAND to execute this function */ modifier requireFarm(address farmAddress, bool requiredState) { if (requiredState) { require( ownerOfFarm[farmAddress].amount != 0, "You need to allocate land to grow crops on your farm" ); } else { require( ownerOfFarm[farmAddress].amount == 0, "Ensure you release your land first" ); } _; // Call the actual code } /** * @dev Decline some incoming transactions (Only allow crop smart contract to send/receive LAND) */ function tokensReceived( address operator, address from, address to, uint256 amount, bytes calldata, bytes calldata ) external override { require(amount > 0, "You must receive a positive number of tokens"); require(_msgSender() == address(landContract), "You can only build farms on LAND"); require(operator == address(this), "Only CORN contract can send itself LAND tokens"); // Ensure someone doesn't send in some LAND to this contract by mistake (Only the contract itself can send itself LAND) require(to == address(this), "Funds must be coming into a CORN token"); require(from != to, "Why would CORN contract send tokens to itself?"); } // STATE VARIABLES /** * @dev To register the contract with ERC1820 Registry */ IERC1820Registry private constant ERC1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); bytes32 private constant TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); /** * @dev 0.00000001 crops grown per block for each LAND allocated to a farm ... 10^18 / 10^8 = 10^10 */ uint256 private constant HARVEST_PER_BLOCK_DIVISOR = 10**8; /** * @dev To avoid small burn ratios we multiply the ratios by this number. */ uint256 private constant RATIO_MULTIPLIER = 10**10; /** * @dev To get 4 decimals on our multipliers, we multiply all ratios & divide ratios by this number. * @dev This is done because we're using integers without any decimals. */ uint256 private constant PERCENT_MULTIPLIER = 10000; /** * @dev PUBLIC: Create a mapping to the Farm Struct .. by making farms public we can access elements through the contract view (vs having to create methods) */ mapping(address => Farm) public ownerOfFarm; /** * @dev PUBLIC: Create a mapping to the Collectible Struct. */ mapping(address => Collectible[]) public ownerOfCollectibles; // CONSTRUCTOR constructor( address[3] memory farmlandAddresses_, // Load key contract addresses address[] memory farmAddresses_, // Load Addresses that composted Corn on L1 uint256[] memory composted_ // Load Amounts of Corn composted on L1 ) public nonReentrant ERC777 ("Corn", "CORN", new address[](0)) // Define contract details { require(farmlandAddresses_.length == 3, "Invalid number of contract addresses"); require(farmlandAddresses_[0] != address(0), "Invalid Land Contract address"); require(farmlandAddresses_[1] != address(0), "Invalid Gateway Contract address"); require(farmlandAddresses_[2] != address(0), "Invalid L1Corn Contract address"); landContract = IERC777(farmlandAddresses_[0]); // Define the ERC777 Land Contract L2_GATEWAY = farmlandAddresses_[1]; // Set L2 Gateway address l1Address = farmlandAddresses_[2]; // Set the L1 Corn Address uint256 _length = farmAddresses_.length; // Set the amount of addresses to migrate from L1 for(uint i = 0; i < _length; i++){ // Loop through all the addresses ownerOfFarm[farmAddresses_[i]].lastHarvestedBlockNumber = block.number; // Set the last harvest height to the current block ownerOfFarm[farmAddresses_[i]].compostedAmount = composted_[i];} // Set amount composted from L1 _registerInterface(IERC721Receiver.onERC721Received.selector); // Register the ERC721 receiver so we can utilise safeTransferFrom for NFTs ERC1820.setInterfaceImplementer(address(this),TOKENS_RECIPIENT_INTERFACE_HASH,address(this)); // Register the contract with ERC1820 _mint(_msgSender(), 150000 * (10**18), "", ""); // Add premine to provide initial liquidity } // EVENTS event Allocated(address sender, uint256 blockNumber, address farmAddress, uint256 amount, uint256 burnedAmountIncrease); event Released(address sender, uint256 amount, uint256 burnedAmountDecrease); event Composted(address sender, address farmAddress, uint256 amount, uint256 bonus); event Harvested(address sender, uint256 blockNumber, address farmAddress, address targetAddress, uint256 targetBlock, uint256 amount); event CollectibleEquipped(address sender, uint256 blockNumber, uint256 TokenID, CollectibleType collectibleType); event CollectibleReleased(address sender, uint256 blockNumber, uint256 TokenID, CollectibleType collectibleType); // SETTERS /** * @dev PUBLIC: Allocate LAND to farm for growing crops with the specified address as the harvester. */ function allocate(address farmAddress, uint256 amount) external whenNotPaused nonReentrant preventSameBlock(_msgSender()) { Farm storage farm = ownerOfFarm[_msgSender()]; // Shortcut accessor for the farm if ( farm.amount.add(amount) > maxFarmSizeWithoutFarmer && // Check that with the additional Land farm size is within limits getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Farmer)<1 ) { // Check to see if theres a farmer on this farm revert( "You need a farmer to build a farm this size"); } if ( farm.amount.add(amount) > maxFarmSizeWithoutTractor && // Check that with the additional Land farm size is within limits getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Tractor)<1 ) { // Check to see if theres a tractor on this farm revert( "You need a farmer and a tractor to build a farm this size"); } if (farm.amount == 0) { // Check to see if there is LAND in the farm farm.amount = amount; // Stores the amount of LAND farm.blockNumber = block.number; // Block when farm first setup farm.harvesterAddress = farmAddress; // Stores the farmers address globalCompostedAmount = globalCompostedAmount.add(farm.compostedAmount); // retains any composted crops for returning farmers globalTotalFarms = globalTotalFarms.add(1); // Increment the total farms counter } else { if ( getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Farmer)>0 ) { // Ensures that there is a farmer to increase the size of a farm farm.amount = farm.amount.add(amount); // Adds additional LAND } else { revert( "You need a farmer to increase the size of a farm"); } } globalAllocatedAmount = globalAllocatedAmount.add(amount); // Adds the amount of Land to the global variable farm.lastHarvestedBlockNumber = block.number; // Reset the last harvest height to the new LAND allocation height emit Allocated(_msgSender(), block.number, farmAddress, amount, farm.compostedAmount); // Write an event to the chain IERC777(landContract).operatorSend(_msgSender(), address(this), amount, "", "" ); // Send [amount] of LAND token from the address that is calling this function to crop smart contract. [RE-ENTRANCY WARNING] external call, must be at the end } /** * @dev PUBLIC: Releasing a farm returns LAND to the owners */ function release() external nonReentrant preventSameBlock(_msgSender()) requireFarm(_msgSender(), true) // Ensure the address you are releasing has a farm on the LAND { Farm storage farm = ownerOfFarm[_msgSender()]; // Shortcut accessor uint256 amount = farm.amount; // Pull the farm size into a local variable to save gas farm.amount = 0; // Set the farm size to zero globalAllocatedAmount = globalAllocatedAmount.sub(amount); // Reduce the global Land variable globalCompostedAmount = globalCompostedAmount.sub(farm.compostedAmount); // Reduce the global Crop composted globalTotalFarms = globalTotalFarms.sub(1); // Reduce the global number of farms emit Released(_msgSender(), amount, farm.compostedAmount); // Write an event to the chain IERC777(landContract).send(_msgSender(), amount, ""); // Send back the Land to person calling the function. [RE-ENTRANCY WARNING] external call, must be at the end } /** * @dev PUBLIC: Composting a crop fertilizes a farm at specific address */ function compost(address farmAddress, uint256 amount) external whenNotPaused nonReentrant requireFarm(farmAddress, true) // Ensure the address you are composting to has a farm on the LAND { Farm storage farm = ownerOfFarm[farmAddress]; // Shortcut accessor uint256 bonusAmount = getCompostBonus(farmAddress, amount); // Get a composting bonus if you own a farmer or tractor farm.compostedAmount += amount.add(bonusAmount); // Update global Land variable globalCompostedAmount += amount.add(bonusAmount); // Update global composted amount variable emit Composted(_msgSender(), farmAddress, amount, bonusAmount); // Write an event to the chain _burn(_msgSender(), amount, "", ""); // Call the normal ERC-777 burn (this will destroy a crop token). We don't need to check address balance for amount because the internal burn does this check for us. [RE-ENTRANCY WARNING] external call, must be at the end } /** * @dev PUBLIC: Harvests crops from the Farm to a target address UP TO the target block (target address can be used to harvest to an alternative address) */ function harvest( address farmAddress, address targetAddress, uint256 targetBlock ) external whenNotPaused nonReentrant preventSameBlock(farmAddress) requireFarm(farmAddress, true) // Ensure the adress that is being harvested has a farm on the LAND { require(targetBlock <= block.number, "You can only harvest up to current block"); Farm storage farm = ownerOfFarm[farmAddress]; // Shortcut accessor, pay attention to farmAddress here require(farm.lastHarvestedBlockNumber < targetBlock, "You can only harvest ahead of last harvested block"); require(farm.harvesterAddress == _msgSender(), "You must be the owner of the farm to harvest"); uint256 mintAmount = getHarvestAmount(farmAddress, targetBlock); // Get the amount to harvest and store in a local variable saves a little gas farm.lastHarvestedBlockNumber = targetBlock; // Reset the last harvested height emit Harvested(_msgSender(),block.number,farmAddress,targetAddress,targetBlock,mintAmount); // Write an event to the chain _mint(targetAddress, mintAmount, "", ""); // Call the normal ERC-777 mint (this will harvest crop tokens to targetAddress). [RE-ENTRANCY WARNING] external call, must be at the end } /** * @dev PUBLIC: Harvest & Compost in a single call for a farms with a farmer & tractor. */ function directCompost( address farmAddress, uint256 targetBlock ) external whenNotPaused nonReentrant requireFarm(farmAddress, true) // Ensure the adress that is being harvested has a farm on the LAND { require(targetBlock <= block.number, "You can only harvest & compost up to current block"); require(getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Tractor)>0 && getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Farmer)>0, "You need a farmer & a tractor on this farm"); Farm storage farm = ownerOfFarm[farmAddress]; // Shortcut accessor require(farm.lastHarvestedBlockNumber < targetBlock, "You can only harvest and compost ahead of last harvested block"); require(farm.harvesterAddress == _msgSender(), "You must be the owner of the farm to harvest and compost"); uint256 amount = getHarvestAmount(farmAddress, targetBlock); // Pull the harvest amount into a local variable to save gas farm.lastHarvestedBlockNumber = targetBlock; // Reset the last harvested height uint256 bonusAmount = getCompostBonus(farmAddress, amount); // Get a composting bonus if you own a farmer or tractor farm.compostedAmount += amount.add(bonusAmount); // Update global Land variable globalCompostedAmount += amount.add(bonusAmount); // Update global composted amount variable emit Composted(_msgSender(), farmAddress, amount, bonusAmount); // Write an event to the chain } /** * @dev PUBLIC: Add an NFT to the farm */ function equipCollectible(uint256 tokenID, CollectibleType collectibleType) external whenNotPaused nonReentrant preventSameBlockCollectible(_msgSender()) requireFarm(_msgSender(), true) // You can't add a collectible if you don't have a farm { Farm storage farm = ownerOfFarm[_msgSender()]; // Shortcut accessors for farm IFarmlandCollectible farmlandCollectible = IFarmlandCollectible(getNFTAddress(collectibleType)); // Set the collectible contract based on collectible type farm.numberOfCollectibles = farm.numberOfCollectibles.add(1); // Increment number of collectibles owned by that address uint256 _maxBoostLevel; // Initialise the max boost level variable (uint256 _expiry, uint256 _boostTrait,,,,) = farmlandCollectible.collectibleTraits(tokenID); // Retrieve Collectible expiry & boost trait (string memory _uri) = farmlandCollectible.tokenURI(tokenID); // Retrieve Collectible URI if (collectibleType == CollectibleType.Farmer) { // Check for farmer _maxBoostLevel = _boostTrait.mul(100).add(10000); // Farmers stamina gives a boost of between 100% to 200% } else { _maxBoostLevel = _boostTrait.mul(100).div(4).add(5000);} // Tractors power gives a boost of between 75% to 150% ownerOfCollectibles[_msgSender()].push(Collectible(tokenID, collectibleType, _maxBoostLevel, block.number, _expiry, _uri)); // Add details to Collectibles emit CollectibleEquipped(_msgSender(),block.number,tokenID,collectibleType); // Write an event to the chain IERC721(farmlandCollectible).safeTransferFrom(_msgSender(),address(this),tokenID); // Receive the Collectibles from the address that is calling this function to crop smart contract. [RE-ENTRANCY WARNING] external call, must be at the end } /** * @dev PUBLIC: Release an NFT from the farm */ function releaseCollectible(uint256 index) external nonReentrant preventSameBlockCollectible(_msgSender()) { Farm storage farm = ownerOfFarm[_msgSender()]; // Shortcut accessors for farm require(farm.numberOfCollectibles != 0, "You need a collectible on your farm"); Collectible memory collectible = ownerOfCollectibles[_msgSender()][index]; // Shortcut accessors for collectibles CollectibleType collectibleType = collectible.collectibleType; // Pull the collectible type into a local variable to save gas IFarmlandCollectible farmlandCollectible = IFarmlandCollectible(getNFTAddress(collectibleType)); // Set the collectible contract based on collectible type being released uint256 collectibleID = collectible.id; // Store the collectible id before its removed if ( farm.amount > maxFarmSizeWithoutFarmer && // REVERT if the size of the farm is too large to release a farmer getFarmCollectibleTotalOfType(_msgSender(),CollectibleType.Farmer) < 2 && // AND farm has only one farmer left collectibleType == CollectibleType.Farmer) { // AND trying to release a farmer revert( "You need at least one farmer to run a farm this size"); } if ( farm.amount > maxFarmSizeWithoutTractor && // REVERT if the size of the farm is too large to release a tractor getFarmCollectibleTotalOfType(_msgSender(),CollectibleType.Tractor) < 2 && // AND farm has only one tractor left collectibleType == CollectibleType.Tractor) { // AND trying to release a tractor revert( "You need a farmer and a tractor to run a farm this size"); } ownerOfCollectibles[_msgSender()][index] = ownerOfCollectibles[_msgSender()][ownerOfCollectibles[_msgSender()].length.sub(1)]; // In the farms collectible array swap the last item for the item being released ownerOfCollectibles[_msgSender()].pop(); // Delete the final item in the farms collectible array farm.numberOfCollectibles = farm.numberOfCollectibles.sub(1); // Update number of collectibles emit CollectibleReleased(_msgSender(),block.number,collectibleID,collectibleType); // Write an event to the chain IERC721(farmlandCollectible).safeTransferFrom(address(this),_msgSender(),collectibleID); // Return Collectible to the address that is calling this function. [RE-ENTRANCY WARNING] external call, must be at the end } // GETTERS /** * @dev Return the amount available to harvest at a specific block by farm */ function getHarvestAmount(address farmAddress, uint256 targetBlock) private view returns (uint256 availableToHarvest) { Farm memory farm = ownerOfFarm[farmAddress]; // Shortcut accessor for the farm uint256 amount = farm.amount; // Grab the amount of LAND to save gas if (amount == 0) {return 0;} // Ensure this address has a farm on the LAND require(targetBlock <= block.number, "You can only calculate up to current block"); require(farm.lastHarvestedBlockNumber <= targetBlock, "You can only specify blocks at or ahead of last harvested block"); // Owning a farmer increase the length of the growth cycle uint256 _lastBlockInGrowthCycle; // Initialise _lastBlockInGrowthCycle uint256 _blocksMinted; // Initiialise _blocksMinted if ( getFarmCollectibleTotalOfType(farmAddress, CollectibleType.Farmer) < 1 ) { // Check if the farm has a farmer _lastBlockInGrowthCycle = farm.lastHarvestedBlockNumber.add(maxGrowthCycle); // Calculate last block without a farmer _blocksMinted = maxGrowthCycle; // Set the number of blocks that will be harvested if growing cycle completed } else { _lastBlockInGrowthCycle = farm.lastHarvestedBlockNumber.add(maxGrowthCycleWithFarmer); // Calculate last block with a farmer _blocksMinted = maxGrowthCycleWithFarmer; // Set the number of blocks that will be harvested if growing cycle completed .. longer with a farmer } if (targetBlock < _lastBlockInGrowthCycle) { // Check if the growing cycle has completed _blocksMinted = targetBlock.sub(farm.lastHarvestedBlockNumber); // Set the number of blocks that will be harvested if growing cycle not completed } uint256 _availableToHarvestBeforeBoosts = amount.mul(_blocksMinted); // Calculate amount to harvest before boosts availableToHarvest = getTotalBoost(farmAddress).mul(_availableToHarvestBeforeBoosts).div(PERCENT_MULTIPLIER).div(HARVEST_PER_BLOCK_DIVISOR); // Adjust for boosts } /** * @dev Return a farms compost productivity boost for a specific address. This will be returned as PERCENT (10000x) */ function getFarmCompostBoost(address farmAddress) private view returns (uint256 compostBoost) { uint256 myRatio = getAddressRatio(farmAddress); // Sets the LAND/CROP burn ratio for a specific farm uint256 globalRatio = getGlobalRatio(); // Sets the LAND/CROP global compost ratio if (globalRatio == 0 || myRatio == 0) {return PERCENT_MULTIPLIER;} // Avoid division by 0 & ensure 1x boost if nothing is locked compostBoost = Math.min(maxCompostBoost,myRatio.mul(PERCENT_MULTIPLIER).div(globalRatio).add(PERCENT_MULTIPLIER)); // The final multiplier is returned with PERCENT (10000x) multiplication and needs to be divided by 10000 for final number. Min 1x, Max depends on the global maxCompostBoost attribute } /** * @dev Return a farms maturity boost for the farm at the address */ function getFarmMaturityBoost(address farmAddress) private view returns (uint256 maturityBoost) { Farm memory farm = ownerOfFarm[farmAddress]; // Shortcut accessor uint256 _totalMaxBoost; // Initialize local variable for max boost uint256 _targetBlockNumber; // Initialize local variable for target block number if ( farm.amount == 0 ) {return PERCENT_MULTIPLIER;} // Ensure this address has a farm on the LAND if (farm.numberOfCollectibles > 0) { // Ensure there are collectibles and then pull the totals into local variables (_totalMaxBoost, _targetBlockNumber) = getFarmCollectibleTotals(farmAddress); // Sets the collectible boost & the starting block to when the last collectible was added. So adding a collectible restarts the maturity boost counter. } else { _targetBlockNumber = farm.blockNumber; // If there are no collectibles it sets the starting block to when the farm is built } _totalMaxBoost = _totalMaxBoost.add(maxMaturityBoost); // Calculate the combined collectible & maturity boost if ( _totalMaxBoost > maxMaturityCollectibleBoost ) { // Checks the Maturity Collectible boost doesn't exceed the maximum _totalMaxBoost = maxMaturityCollectibleBoost; // if it does set it to the maximum boost } uint256 _boostExtension = _totalMaxBoost.sub(PERCENT_MULTIPLIER); // Calculates the boost extension by removing 10000 from the totalmaxboost; i.e., the extension over and above 1x e.g., the 2x to get to a 3x boost uint256 _blockDiff = block.number.sub(_targetBlockNumber) .mul(_boostExtension).div(endMaturityBoost).add(PERCENT_MULTIPLIER);// Calculate the Min before farm maturity starts to increment, stops maturity boost at max ~ the function returns PERCENT (10000x) the multiplier for 4 decimal accuracy maturityBoost = Math.min(_totalMaxBoost, _blockDiff); // returm the maturity boost .. Min 1x, Max depends on the boostExtension attribute } /** * @dev Return a farms total boost */ function getTotalBoost(address farmAddress) private view returns ( uint256 totalBoost ) { uint256 _maturityBoost = getFarmMaturityBoost(farmAddress); // Get the farms Maturity Boost uint256 _compostBoost = getFarmCompostBoost(farmAddress); // Get the farms Compost Boost totalBoost = _compostBoost.mul(_maturityBoost).div(PERCENT_MULTIPLIER); // Maturity & Collectible boosts are combined & multiplied by the Compost boost to return the total boost. Ensuring that when both collectible and maturity are 10000, that the combined total 10000 and not 20000. } /** * @dev Return the compost bonus */ function getCompostBonus(address farmAddress, uint256 amount) private view returns ( uint256 compostBonus ) { if ( getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Farmer) >0 ){ compostBonus = bonusCompostBoostWithFarmer.mul(amount).div(PERCENT_MULTIPLIER); // If theres a farmer running this farm, add an additional 10% } if ( getFarmCollectibleTotalOfType(farmAddress,CollectibleType.Tractor) >0 ){ compostBonus = bonusCompostBoostWithTractor.mul(amount).div(PERCENT_MULTIPLIER); // If theres a tractor on this farm, add an additional 20% } } /** * @dev PUBLIC: Get NFT contract address based on the collectible type */ function getNFTAddress(CollectibleType collectibleType) internal view returns (address payable collectibleAddress) { if (collectibleType == CollectibleType.Farmer) { collectibleAddress = farmerNFTAddress; // returns the Farmer NFT contract address } else { collectibleAddress = tractorNFTAddress; // returns the Tractor NFT contract address } } /** * @dev PUBLIC: Return the combined totals associated with Collectibles on a farm */ function getFarmCollectibleTotals(address farmAddress) public view returns ( uint256 totalMaxBoost, uint256 lastAddedBlockNumber ) { uint256 _total = ownerOfCollectibles[farmAddress].length; // Store the total number of collectibles on a farm in a local variable bool _expired = false; // Initialize the expired local variable as false uint256 _expiry; // Initialize a local variable to hold the expiry uint256 _addedBlockNumber; // Initialize a local variable to hold the block number each collectible was added for (uint i = 0; i < _total; i++) { // Loop through all the collectibles on this farm _expiry = ownerOfCollectibles[farmAddress][i].expiry; // Store the collectibles expiry in a local variable _addedBlockNumber = ownerOfCollectibles[farmAddress][i].addedBlockNumber; // Store the block the collectibles was added in a local variable if (_expiry == 0 ) { // If expiry is zero _expired = false; // Then this collectible has not expired } else { if ( block.timestamp > _expiry ) { // If the current blocks timestamp is greater than the expiry _expired = true; // Then this collectible has expired } } if ( !_expired ) { // Only count collectibles that have not already expired totalMaxBoost = totalMaxBoost.add(ownerOfCollectibles[farmAddress][i].maxBoostLevel); // Add all the individual collectible boosts to get the total collectible boost if ( lastAddedBlockNumber < _addedBlockNumber) { lastAddedBlockNumber = _addedBlockNumber; // Store the block number of latest collectible added to the farm } } } } /** * @dev PUBLIC: Returns total number of a collectible type found on a farm */ function getFarmCollectibleTotalOfType(address farmAddress, CollectibleType collectibleType) public view returns ( uint256 ownsCollectibleTotal ) { uint256 _total = ownerOfCollectibles[farmAddress].length; // Store the total number of collectibles on a farm in a local variable for (uint i = 0; i < _total; i++) { if ( ownerOfCollectibles[farmAddress][i].collectibleType == collectibleType ) { // Check if collectible type is found on the farm ownsCollectibleTotal = ownsCollectibleTotal.add(1); // If it is then add it to the return variable } } } /** * @dev PUBLIC: Return array of collectibles on a farm */ function getCollectiblesByFarm(address farmAddress) external view returns ( Collectible[] memory farmCollectibles // Define the array of collectibles to be returned. Requires ABIEncoderV2. ) { uint256 _total = ownerOfCollectibles[farmAddress].length; // Store the total number of collectibles on a farm in a local variable Collectible[] memory _collectibles = new Collectible[](_total); // Initialize an array to store all the collectibles on the farm for (uint i = 0; i < _total; i++) { // Loop through the collectibles _collectibles[i].id = ownerOfCollectibles[farmAddress][i].id; // Add the id to the array _collectibles[i].collectibleType = ownerOfCollectibles[farmAddress][i].collectibleType; // Add the colectible type to the array _collectibles[i].maxBoostLevel = ownerOfCollectibles[farmAddress][i].maxBoostLevel; // Add the maxboostlevel to the array _collectibles[i].addedBlockNumber = ownerOfCollectibles[farmAddress][i].addedBlockNumber; // Add the blocknumber the collectible was added to the array _collectibles[i].expiry = ownerOfCollectibles[farmAddress][i].expiry; // Add the expiry to the array _collectibles[i].uri = ownerOfCollectibles[farmAddress][i].uri; // Add the token URI } return _collectibles; // Return the array of collectibles on the farm } /** * @dev Return LAND/CROP burn ratio for a specific farm */ function getAddressRatio(address farmAddress) private view returns (uint256 myRatio) { Farm memory farm = ownerOfFarm[farmAddress]; // Shortcut accessor of the farm uint256 _addressLockedAmount = farm.amount; // Intialize and store the amount of Land on this farm if (_addressLockedAmount == 0) { return 0; } // If you haven't harvested or composted anything then you get the default 1x boost myRatio = farm.compostedAmount.mul(RATIO_MULTIPLIER).div(_addressLockedAmount); // Compost/Maturity ratios for both address & network, multiplying both ratios by the ratio multiplier before dividing for tiny CROP/LAND burn ratios. } /** * @dev Return LAND/CROP compost ratio for global (entire network) */ function getGlobalRatio() private view returns (uint256 globalRatio) { if (globalAllocatedAmount == 0) { return 0; } // If you haven't harvested or composted anything then you get the default 1x multiplier globalRatio = globalCompostedAmount.mul(RATIO_MULTIPLIER).div(globalAllocatedAmount); // Compost/Maturity for both address & network, multiplying both ratios by the ratio multiplier before dividing for tiny CROP/LAND burn ratios. } /** * @dev PUBLIC: Return a collection of data associated with an farm */ function getAddressDetails(address farmAddress) external view returns ( uint256 blockNumber, uint256 cropBalance, uint256 cropAvailableToHarvest, uint256 farmMaturityBoost, uint256 farmCompostBoost, uint256 farmTotalBoost ) { blockNumber = block.number; // return the current block number cropBalance = balanceOf(farmAddress); // return the Crop balance cropAvailableToHarvest = getHarvestAmount(farmAddress, block.number); // return the Crop available to harvest farmMaturityBoost = getFarmMaturityBoost(farmAddress); // return the Maturity boost farmCompostBoost = getFarmCompostBoost(farmAddress); // return the Compost boost farmTotalBoost = getTotalBoost(farmAddress); // return the Total boost } }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2020, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @title Minimum expected interface for L2 token that interacts with the L2 token bridge (this is the interface necessary * for a custom token that interacts with the bridge, see TestArbCustomToken.sol for an example implementation). */ pragma solidity ^0.6.11; interface IArbToken { /** * @notice should increase token supply by amount, and should (probably) only be callable by the L1 bridge. */ function bridgeMint(address account, uint256 amount) external; /** * @notice should decrease token supply by amount, and should (probably) only be callable by the L1 bridge. */ function bridgeBurn(address account, uint256 amount) external; /** * @return address of layer 1 token */ function l1Address() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.7.0; pragma experimental ABIEncoderV2; enum CollectibleType {Farmer, Tractor, Equipment} struct Farm {uint256 amount; uint256 compostedAmount; uint256 blockNumber; uint256 lastHarvestedBlockNumber; address harvesterAddress; uint256 numberOfCollectibles;} struct Collectible {uint256 id; CollectibleType collectibleType; uint256 maxBoostLevel; uint256 addedBlockNumber; uint256 expiry; string uri;} /** * @dev Farmland - Crop V2 Interface */ interface ICropV2 { // SETTERS function allocate(address farmAddress, uint256 amount) external; function release() external; function compost(address farmAddress, uint256 amount) external; function harvest(address farmAddress, address targetAddress, uint256 targetBlock) external; function directCompost(address farmAddress, uint256 targetBlock) external; function equipCollectible(uint256 tokenID, CollectibleType collectibleType) external; function releaseCollectible(uint256 index) external; function isPaused(bool value) external; function setFarmlandVariables(uint256 endMaturityBoost_, uint256 maxGrowthCycle_, uint256 maxGrowthCycleWithFarmer_, uint256 maxCompostBoost_, uint256 maxMaturityBoost_, uint256 maxMaturityCollectibleBoost_,uint256 maxFarmSizeWithoutFarmer_,uint256 maxFarmSizeWithoutTractor_, uint256 bonusCompostBoostWithFarmer_, uint256 bonusCompostBoostWithTractor_) external; function setFarmlandAddresses(address landAddress_, address payable farmerNFTAddress_, address payable tractorNFTAddress_) external; // GETTERS function getHarvestAmount(address farmAddress, uint256 targetBlock) external view returns (uint256 availableToHarvest); function getFarmCompostBoost(address farmAddress) external view returns (uint256 compostBoost); function getFarmMaturityBoost(address farmAddress) external view returns (uint256 maturityBoost); function getTotalBoost(address farmAddress) external view returns (uint256 totalBoost); function getCompostBonus(address farmAddress, uint256 amount) external view returns (uint256 compostBonus); function getNFTAddress(CollectibleType collectibleType) external view returns (address payable collectibleAddress); function getFarmCollectibleTotals(address farmAddress) external view returns (uint256 totalMaxBoost, uint256 lastAddedBlockNumber); function getFarmCollectibleTotalOfType(address farmAddress, CollectibleType collectibleType) external view returns (uint256 ownsCollectibleTotal); function getCollectiblesByFarm(address farmAddress) external view returns (Collectible[] memory farmCollectibles); function getAddressRatio(address farmAddress) external view returns (uint256 myRatio); function getGlobalRatio() external view returns (uint256 globalRatio); function getGlobalAverageRatio() external view returns (uint256 globalAverageRatio); function getAddressDetails(address farmAddress) external view returns (uint256 blockNumber, uint256 cropBalance, uint256 cropAvailableToHarvest, uint256 farmMaturityBoost, uint256 farmCompostBoost, uint256 farmTotalBoost); function getAddressTokenDetails(address farmAddress) external view returns (uint256 blockNumber, bool isOperatorLand, uint256 landBalance, uint256 myRatio, bool isOperatorFarmer, bool isOperatorEquipment, bool isOperatorTractor); function getFarmlandVariables() external view returns (uint256 totalFarms, uint256 totalAllocatedAmount, uint256 totalCompostedAmount,uint256 maximumCompostBoost, uint256 maximumMaturityBoost, uint256 maximumGrowthCycle, uint256 maximumGrowthCycleWithFarmer, uint256 maximumMaturityCollectibleBoost, uint256 endMaturityBoostBlocks, uint256 maximumFarmSizeWithoutFarmer, uint256 maximumFarmSizeWithoutTractor, uint256 bonusCompostBoostWithAFarmer, uint256 bonusCompostBoostWithATractor); function getFarmlandAddresses() external view returns (address, address, address, address, address); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.7.0; import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol"; struct CollectibleTraits {uint256 expiryDate; uint256 trait1; uint256 trait2; uint256 trait3; uint256 trait4; uint256 trait5;} abstract contract IFarmlandCollectible is IERC721Metadata { /** * @dev PUBLIC: Stores the key traits for Farmland Collectibles */ mapping(uint256 => CollectibleTraits) public collectibleTraits; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.7.0; import "@openzeppelin/contracts/token/ERC777/IERC777.sol"; import "@openzeppelin/contracts/token/ERC777/ERC777.sol"; import "@openzeppelin/contracts/utils/Pausable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./IArbToken.sol"; import "./ICropV2.sol"; /** * @dev Farmland - Manageable */ abstract contract Manageable is ERC777, Ownable, Pausable, IArbToken { // STATE VARIABLES /** * @dev Used to define the address of the L2 Custom Gateway */ address public L2_GATEWAY; /** * @dev Defines the L1 Corn contract */ address public override l1Address; /** * @dev This is the LAND contract address */ IERC777 internal landContract; /** * @dev This is the Farmland Farmer NFT contract address */ address payable farmerNFTAddress; /** * @dev This is the Farmland Tractor NFT contract address */ address payable tractorNFTAddress; /** * @dev How many blocks before the maximum 3x farm maturity boost is reached ( Set to 28 days) */ uint256 internal endMaturityBoost = 179200; /** * @dev This is the maximum number of blocks in each growth cycle ( around 7 days) before a harvest is required. After this many blocks crop will stop growing. */ uint256 internal maxGrowthCycle = 44800; /** * @dev If you have a Farmer, this is the maximum number of blocks in each growth cycle ( around 14 days) before a harvest is required. After this many blocks crop will stop growing. */ uint256 internal maxGrowthCycleWithFarmer = 89600; /** * @dev This is the farm's maximum 10x compost productivity boost. It's multiplicative with the maturity boost. */ uint256 internal maxCompostBoost = 100000; /** * @dev This is the farm's maximum 3x maturity productivity boost. */ uint256 internal maxMaturityBoost = 30000; /** * @dev This is the farm's maximum 8x maturity productivity boost. */ uint256 internal maxMaturityCollectibleBoost = 100000; /** * @dev internal: Largest farm you can build without a farmer */ uint256 internal maxFarmSizeWithoutFarmer = 15000 * (10**18); /** * @dev internal: Largest farm you can build without a farmer & a tractor */ uint256 internal maxFarmSizeWithoutTractor = 100000 * (10**18); /** * @dev internal: 10% Compost boost with farmer */ uint256 internal bonusCompostBoostWithFarmer = 1000; /** * @dev internal: 25% Compost boost with tractor */ uint256 internal bonusCompostBoostWithTractor = 2500; /** * @dev internal: Store how much LAND is allocated to growing crops in farms globally */ uint256 internal globalAllocatedAmount; /** * @dev internal: Store how much is crop has been composted globally (only from active farms on LAND addresses) */ uint256 internal globalCompostedAmount; /** * @dev internal: Store how many addresses currently have an active farm */ uint256 internal globalTotalFarms; // MODIFIERS /** * @dev Only the L2 Gateway is allowed to perform this function */ modifier onlyGateway { require(msg.sender == L2_GATEWAY, "ONLY_GATEWAY"); _; } //EVENTS event FarmlandVariablesSet( uint256 endMaturityBoost_, uint256 maxGrowthCycle_, uint256 maxGrowthCycleWithFarmer_, uint256 maxCompostBoost_, uint256 maxMaturityBoost_, uint256 maxMaturityCollectibleBoost_, uint256 maxFarmSizeWithoutFarmer_, uint256 maxFarmSizeWithoutTractor_, uint256 bonusCompostBoostWithFarmer_, uint256 bonusCompostBoostWithTractor_); // SETTERS /** * @notice Mint tokens on L2. Callable path is L1Gateway depositToken (which handles L1 escrow), which triggers L2_GATEWAY, which calls this * @param account recipient of tokens * @param amount amount of tokens minted */ function bridgeMint(address account, uint256 amount) external virtual override onlyGateway { bytes calldata _data; _mint(account, amount, _data, ""); } /** * @notice Burn tokens on L2. * @dev only the token bridge can call this * @param account owner of tokens * @param amount amount of tokens burnt */ function bridgeBurn(address account, uint256 amount) external virtual override onlyGateway { bytes calldata _data; _burn(account, amount, _data, ""); } // Start or pause the contract function isPaused(bool value) public onlyOwner { if ( !value ) { _unpause(); } else { _pause(); } } // Enable changes to key Farmland variables function setFarmlandVariables( uint256 endMaturityBoost_, uint256 maxGrowthCycle_, uint256 maxGrowthCycleWithFarmer_, uint256 maxCompostBoost_, uint256 maxMaturityBoost_, uint256 maxMaturityCollectibleBoost_, uint256 maxFarmSizeWithoutFarmer_, uint256 maxFarmSizeWithoutTractor_, uint256 bonusCompostBoostWithFarmer_, uint256 bonusCompostBoostWithTractor_ ) external onlyOwner { if ( endMaturityBoost_ > 0 && endMaturityBoost_ != endMaturityBoost ) {endMaturityBoost = endMaturityBoost_;} if ( maxGrowthCycle_ > 0 && maxGrowthCycle_ != maxGrowthCycle ) {maxGrowthCycle = maxGrowthCycle_;} if ( maxGrowthCycleWithFarmer_ > 0 && maxGrowthCycleWithFarmer_ != maxGrowthCycleWithFarmer ) {maxGrowthCycleWithFarmer = maxGrowthCycleWithFarmer_;} if ( maxCompostBoost_ > 0 && maxCompostBoost_ != maxCompostBoost ) {maxCompostBoost = maxCompostBoost_;} if ( maxMaturityBoost_ > 0 && maxMaturityBoost_ != maxMaturityBoost ) {maxMaturityBoost = maxMaturityBoost_;} if ( maxMaturityCollectibleBoost_ > 0 && maxMaturityCollectibleBoost_ != maxMaturityCollectibleBoost ) {maxMaturityCollectibleBoost = maxMaturityCollectibleBoost_;} if ( maxFarmSizeWithoutFarmer_ > 0 && maxFarmSizeWithoutFarmer_ != maxFarmSizeWithoutFarmer ) {maxFarmSizeWithoutFarmer = maxFarmSizeWithoutFarmer_;} if ( maxFarmSizeWithoutTractor_ > 0 && maxFarmSizeWithoutTractor_ != maxFarmSizeWithoutTractor ) {maxFarmSizeWithoutTractor = maxFarmSizeWithoutTractor_;} if ( bonusCompostBoostWithFarmer_ > 0 && bonusCompostBoostWithFarmer_ != bonusCompostBoostWithFarmer ) {bonusCompostBoostWithFarmer = bonusCompostBoostWithFarmer_;} if ( bonusCompostBoostWithTractor_ > 0 && bonusCompostBoostWithTractor_ != bonusCompostBoostWithTractor ) {bonusCompostBoostWithTractor = bonusCompostBoostWithTractor_;} emit FarmlandVariablesSet(endMaturityBoost_, maxGrowthCycle_, maxGrowthCycleWithFarmer_, maxCompostBoost_, maxMaturityBoost_, maxMaturityCollectibleBoost_, maxFarmSizeWithoutFarmer_, maxFarmSizeWithoutTractor_, bonusCompostBoostWithFarmer_, bonusCompostBoostWithTractor_); } // Enable changes to key Farmland addresses function setFarmlandAddresses( address landAddress_, address payable farmerNFTAddress_, address payable tractorNFTAddress_ ) external onlyOwner { if ( landAddress_ != address(0) && landAddress_ != address(IERC777(landContract)) ) { landContract = IERC777(landAddress_);} if ( farmerNFTAddress_ != address(0) && farmerNFTAddress_ != farmerNFTAddress ) {farmerNFTAddress = farmerNFTAddress_;} if ( tractorNFTAddress_ != address(0) && tractorNFTAddress_ != tractorNFTAddress ) {tractorNFTAddress = tractorNFTAddress_;} } // GETTERS /** * @dev PUBLIC: Get the key Farmland Variables */ function getFarmlandVariables() external view returns ( uint256 totalFarms, uint256 totalAllocatedAmount, uint256 totalCompostedAmount, uint256 maximumCompostBoost, uint256 maximumMaturityBoost, uint256 maximumGrowthCycle, uint256 maximumGrowthCycleWithFarmer, uint256 maximumMaturityCollectibleBoost, uint256 endMaturityBoostBlocks, uint256 maximumFarmSizeWithoutFarmer, uint256 maximumFarmSizeWithoutTractor, uint256 bonusCompostBoostWithAFarmer, uint256 bonusCompostBoostWithATractor ) { return ( globalTotalFarms, globalAllocatedAmount, globalCompostedAmount, maxCompostBoost, maxMaturityBoost, maxGrowthCycle, maxGrowthCycleWithFarmer, maxMaturityCollectibleBoost, endMaturityBoost, maxFarmSizeWithoutFarmer, maxFarmSizeWithoutTractor, bonusCompostBoostWithFarmer, bonusCompostBoostWithTractor ); } /** * @dev PUBLIC: Get key Farmland addresses */ function getFarmlandAddresses() external view returns ( address, address, address, address, address ) { return ( farmerNFTAddress, tractorNFTAddress, l1Address, L2_GATEWAY, address(IERC777(landContract)) ); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () internal { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the global ERC1820 Registry, as defined in the * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register * implementers for interfaces in this registry, as well as query support. * * Implementers may be shared by multiple accounts, and can also implement more * than a single interface for each account. Contracts can implement interfaces * for themselves, but externally-owned accounts (EOA) must delegate this to a * contract. * * {IERC165} interfaces can also be queried via the registry. * * For an in-depth explanation and source code analysis, see the EIP text. */ interface IERC1820Registry { /** * @dev Sets `newManager` as the manager for `account`. A manager of an * account is able to set interface implementers for it. * * By default, each account is its own manager. Passing a value of `0x0` in * `newManager` will reset the manager to this initial state. * * Emits a {ManagerChanged} event. * * Requirements: * * - the caller must be the current manager for `account`. */ function setManager(address account, address newManager) external; /** * @dev Returns the manager for `account`. * * See {setManager}. */ function getManager(address account) external view returns (address); /** * @dev Sets the `implementer` contract as ``account``'s implementer for * `interfaceHash`. * * `account` being the zero address is an alias for the caller's address. * The zero address can also be used in `implementer` to remove an old one. * * See {interfaceHash} to learn how these are created. * * Emits an {InterfaceImplementerSet} event. * * Requirements: * * - the caller must be the current manager for `account`. * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not * end in 28 zeroes). * - `implementer` must implement {IERC1820Implementer} and return true when * queried for support, unless `implementer` is the caller. See * {IERC1820Implementer-canImplementInterfaceForAddress}. */ function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external; /** * @dev Returns the implementer of `interfaceHash` for `account`. If no such * implementer is registered, returns the zero address. * * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 * zeroes), `account` will be queried for support of it. * * `account` being the zero address is an alias for the caller's address. */ function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); /** * @dev Returns the interface hash for an `interfaceName`, as defined in the * corresponding * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. */ function interfaceHash(string calldata interfaceName) external pure returns (bytes32); /** * @notice Updates the cache with whether the contract implements an ERC165 interface or not. * @param account Address of the contract for which to update the cache. * @param interfaceId ERC165 interface for which to update the cache. */ function updateERC165Cache(address account, bytes4 interfaceId) external; /** * @notice Checks whether a contract implements an ERC165 interface or not. * If the result is not cached a direct lookup on the contract address is performed. * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling * {updateERC165Cache} with the contract address. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); /** * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); event ManagerChanged(address indexed account, address indexed newManager); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, 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.6.0 <0.8.0; import "./IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "../../introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../../utils/Context.sol"; import "./IERC777.sol"; import "./IERC777Recipient.sol"; import "./IERC777Sender.sol"; import "../../token/ERC20/IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; import "../../introspection/IERC1820Registry.sol"; /** * @dev Implementation of the {IERC777} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * Support for ERC20 is included in this contract, as specified by the EIP: both * the ERC777 and ERC20 interfaces can be safely used when interacting with it. * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token * movements. * * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there * are no special restrictions in the amount of tokens that created, moved, or * destroyed. This makes integration with ERC20 applications seamless. */ contract ERC777 is Context, IERC777, IERC20 { using SafeMath for uint256; using Address for address; IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); mapping(address => uint256) private _balances; uint256 private _totalSupply; string private _name; string private _symbol; // We inline the result of the following hashes because Solidity doesn't resolve them at compile time. // See https://github.com/ethereum/solidity/issues/4024. // keccak256("ERC777TokensSender") bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH = 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895; // keccak256("ERC777TokensRecipient") bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH = 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b; // This isn't ever read from - it's only used to respond to the defaultOperators query. address[] private _defaultOperatorsArray; // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators). mapping(address => bool) private _defaultOperators; // For each account, a mapping of its operators and revoked default operators. mapping(address => mapping(address => bool)) private _operators; mapping(address => mapping(address => bool)) private _revokedDefaultOperators; // ERC20-allowances mapping (address => mapping (address => uint256)) private _allowances; /** * @dev `defaultOperators` may be an empty array. */ constructor( string memory name_, string memory symbol_, address[] memory defaultOperators_ ) public { _name = name_; _symbol = symbol_; _defaultOperatorsArray = defaultOperators_; for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) { _defaultOperators[_defaultOperatorsArray[i]] = true; } // register interfaces _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this)); _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this)); } /** * @dev See {IERC777-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC777-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {ERC20-decimals}. * * Always returns 18, as per the * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility). */ function decimals() public pure virtual returns (uint8) { return 18; } /** * @dev See {IERC777-granularity}. * * This implementation always returns `1`. */ function granularity() public view virtual override returns (uint256) { return 1; } /** * @dev See {IERC777-totalSupply}. */ function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) { return _totalSupply; } /** * @dev Returns the amount of tokens owned by an account (`tokenHolder`). */ function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) { return _balances[tokenHolder]; } /** * @dev See {IERC777-send}. * * Also emits a {IERC20-Transfer} event for ERC20 compatibility. */ function send(address recipient, uint256 amount, bytes memory data) public virtual override { _send(_msgSender(), recipient, amount, data, "", true); } /** * @dev See {IERC20-transfer}. * * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient} * interface if it is a contract. * * Also emits a {Sent} event. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { require(recipient != address(0), "ERC777: transfer to the zero address"); address from = _msgSender(); _callTokensToSend(from, from, recipient, amount, "", ""); _move(from, from, recipient, amount, "", ""); _callTokensReceived(from, from, recipient, amount, "", "", false); return true; } /** * @dev See {IERC777-burn}. * * Also emits a {IERC20-Transfer} event for ERC20 compatibility. */ function burn(uint256 amount, bytes memory data) public virtual override { _burn(_msgSender(), amount, data, ""); } /** * @dev See {IERC777-isOperatorFor}. */ function isOperatorFor(address operator, address tokenHolder) public view virtual override returns (bool) { return operator == tokenHolder || (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) || _operators[tokenHolder][operator]; } /** * @dev See {IERC777-authorizeOperator}. */ function authorizeOperator(address operator) public virtual override { require(_msgSender() != operator, "ERC777: authorizing self as operator"); if (_defaultOperators[operator]) { delete _revokedDefaultOperators[_msgSender()][operator]; } else { _operators[_msgSender()][operator] = true; } emit AuthorizedOperator(operator, _msgSender()); } /** * @dev See {IERC777-revokeOperator}. */ function revokeOperator(address operator) public virtual override { require(operator != _msgSender(), "ERC777: revoking self as operator"); if (_defaultOperators[operator]) { _revokedDefaultOperators[_msgSender()][operator] = true; } else { delete _operators[_msgSender()][operator]; } emit RevokedOperator(operator, _msgSender()); } /** * @dev See {IERC777-defaultOperators}. */ function defaultOperators() public view virtual override returns (address[] memory) { return _defaultOperatorsArray; } /** * @dev See {IERC777-operatorSend}. * * Emits {Sent} and {IERC20-Transfer} events. */ function operatorSend( address sender, address recipient, uint256 amount, bytes memory data, bytes memory operatorData ) public virtual override { require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder"); _send(sender, recipient, amount, data, operatorData, true); } /** * @dev See {IERC777-operatorBurn}. * * Emits {Burned} and {IERC20-Transfer} events. */ function operatorBurn(address account, uint256 amount, bytes memory data, bytes memory operatorData) public virtual override { require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder"); _burn(account, amount, data, operatorData); } /** * @dev See {IERC20-allowance}. * * Note that operator and allowance concepts are orthogonal: operators may * not have allowance, and accounts with allowance may not be operators * themselves. */ function allowance(address holder, address spender) public view virtual override returns (uint256) { return _allowances[holder][spender]; } /** * @dev See {IERC20-approve}. * * Note that accounts cannot have allowance issued by their operators. */ function approve(address spender, uint256 value) public virtual override returns (bool) { address holder = _msgSender(); _approve(holder, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Note that operator and allowance concepts are orthogonal: operators cannot * call `transferFrom` (unless they have allowance), and accounts with * allowance cannot call `operatorSend` (unless they are operators). * * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events. */ function transferFrom(address holder, address recipient, uint256 amount) public virtual override returns (bool) { require(recipient != address(0), "ERC777: transfer to the zero address"); require(holder != address(0), "ERC777: transfer from the zero address"); address spender = _msgSender(); _callTokensToSend(spender, holder, recipient, amount, "", ""); _move(spender, holder, recipient, amount, "", ""); _approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance")); _callTokensReceived(spender, holder, recipient, amount, "", "", false); return true; } /** * @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * If a send hook is registered for `account`, the corresponding function * will be called with `operator`, `data` and `operatorData`. * * See {IERC777Sender} and {IERC777Recipient}. * * Emits {Minted} and {IERC20-Transfer} events. * * Requirements * * - `account` cannot be the zero address. * - if `account` is a contract, it must implement the {IERC777Recipient} * interface. */ function _mint( address account, uint256 amount, bytes memory userData, bytes memory operatorData ) internal virtual { require(account != address(0), "ERC777: mint to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), account, amount); // Update state variables _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true); emit Minted(operator, account, amount, userData, operatorData); emit Transfer(address(0), account, amount); } /** * @dev Send tokens * @param from address token holder address * @param to address recipient address * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient */ function _send( address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData, bool requireReceptionAck ) internal virtual { require(from != address(0), "ERC777: send from the zero address"); require(to != address(0), "ERC777: send to the zero address"); address operator = _msgSender(); _callTokensToSend(operator, from, to, amount, userData, operatorData); _move(operator, from, to, amount, userData, operatorData); _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck); } /** * @dev Burn tokens * @param from address token holder address * @param amount uint256 amount of tokens to burn * @param data bytes extra information provided by the token holder * @param operatorData bytes extra information provided by the operator (if any) */ function _burn( address from, uint256 amount, bytes memory data, bytes memory operatorData ) internal virtual { require(from != address(0), "ERC777: burn from the zero address"); address operator = _msgSender(); _callTokensToSend(operator, from, address(0), amount, data, operatorData); _beforeTokenTransfer(operator, from, address(0), amount); // Update state variables _balances[from] = _balances[from].sub(amount, "ERC777: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Burned(operator, from, amount, data, operatorData); emit Transfer(from, address(0), amount); } function _move( address operator, address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData ) private { _beforeTokenTransfer(operator, from, to, amount); _balances[from] = _balances[from].sub(amount, "ERC777: transfer amount exceeds balance"); _balances[to] = _balances[to].add(amount); emit Sent(operator, from, to, amount, userData, operatorData); emit Transfer(from, to, amount); } /** * @dev See {ERC20-_approve}. * * Note that accounts cannot have allowance issued by their operators. */ function _approve(address holder, address spender, uint256 value) internal { require(holder != address(0), "ERC777: approve from the zero address"); require(spender != address(0), "ERC777: approve to the zero address"); _allowances[holder][spender] = value; emit Approval(holder, spender, value); } /** * @dev Call from.tokensToSend() if the interface is registered * @param operator address operator requesting the transfer * @param from address token holder address * @param to address recipient address * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) */ function _callTokensToSend( address operator, address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData ) private { address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH); if (implementer != address(0)) { IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData); } } /** * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but * tokensReceived() was not registered for the recipient * @param operator address operator requesting the transfer * @param from address token holder address * @param to address recipient address * @param amount uint256 amount of tokens to transfer * @param userData bytes extra information provided by the token holder (if any) * @param operatorData bytes extra information provided by the operator (if any) * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient */ function _callTokensReceived( address operator, address from, address to, uint256 amount, bytes memory userData, bytes memory operatorData, bool requireReceptionAck ) private { address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH); if (implementer != address(0)) { IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData); } else if (requireReceptionAck) { require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient"); } } /** * @dev Hook that is called before any token transfer. This includes * calls to {send}, {transfer}, {operatorSend}, minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address operator, address from, address to, uint256 amount) internal virtual { } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777Token standard as defined in the EIP. * * This contract uses the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let * token holders and recipients react to token movements by using setting implementers * for the associated interfaces in said registry. See {IERC1820Registry} and * {ERC1820Implementer}. */ interface IERC777 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() external view returns (string memory); /** * @dev Returns the smallest part of the token that is not divisible. This * means all token operations (creation, movement and destruction) must have * amounts that are a multiple of this number. * * For most token contracts, this value will equal 1. */ function granularity() external view returns (uint256); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by an account (`owner`). */ function balanceOf(address owner) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * If send or receive hooks are registered for the caller and `recipient`, * the corresponding functions will be called with `data` and empty * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - the caller must have at least `amount` tokens. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function send(address recipient, uint256 amount, bytes calldata data) external; /** * @dev Destroys `amount` tokens from the caller's account, reducing the * total supply. * * If a send hook is registered for the caller, the corresponding function * will be called with `data` and empty `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - the caller must have at least `amount` tokens. */ function burn(uint256 amount, bytes calldata data) external; /** * @dev Returns true if an account is an operator of `tokenHolder`. * Operators can send and burn tokens on behalf of their owners. All * accounts are their own operator. * * See {operatorSend} and {operatorBurn}. */ function isOperatorFor(address operator, address tokenHolder) external view returns (bool); /** * @dev Make an account an operator of the caller. * * See {isOperatorFor}. * * Emits an {AuthorizedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function authorizeOperator(address operator) external; /** * @dev Revoke an account's operator status for the caller. * * See {isOperatorFor} and {defaultOperators}. * * Emits a {RevokedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function revokeOperator(address operator) external; /** * @dev Returns the list of default operators. These accounts are operators * for all token holders, even if {authorizeOperator} was never called on * them. * * This list is immutable, but individual holders may revoke these via * {revokeOperator}, in which case {isOperatorFor} will return false. */ function defaultOperators() external view returns (address[] memory); /** * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must * be an operator of `sender`. * * If send or receive hooks are registered for `sender` and `recipient`, * the corresponding functions will be called with `data` and * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - `sender` cannot be the zero address. * - `sender` must have at least `amount` tokens. * - the caller must be an operator for `sender`. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function operatorSend( address sender, address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; /** * @dev Destroys `amount` tokens from `account`, reducing the total supply. * The caller must be an operator of `account`. * * If a send hook is registered for `account`, the corresponding function * will be called with `data` and `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. * - the caller must be an operator for `account`. */ function operatorBurn( address account, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; event Sent( address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData ); event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); event AuthorizedOperator(address indexed operator, address indexed tokenHolder); event RevokedOperator(address indexed operator, address indexed tokenHolder); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. * * Accounts can be notified of {IERC777} tokens being sent to them by having a * contract implement this interface (contract holders can be their own * implementer) and registering it on the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. * * See {IERC1820Registry} and {ERC1820Implementer}. */ interface IERC777Recipient { /** * @dev Called by an {IERC777} token contract whenever tokens are being * moved or created into a registered account (`to`). The type of operation * is conveyed by `from` being the zero address or not. * * This call occurs _after_ the token contract's state is updated, so * {IERC777-balanceOf}, etc., can be used to query the post-operation state. * * This function may revert to prevent the operation from being executed. */ function tokensReceived( address operator, address from, address to, uint256 amount, bytes calldata userData, bytes calldata operatorData ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777TokensSender standard as defined in the EIP. * * {IERC777} Token holders can be notified of operations performed on their * tokens by having a contract implement this interface (contract holders can be * their own implementer) and registering it on the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. * * See {IERC1820Registry} and {ERC1820Implementer}. */ interface IERC777Sender { /** * @dev Called by an {IERC777} token contract whenever a registered holder's * (`from`) tokens are about to be moved or destroyed. The type of operation * is conveyed by `to` being the zero address or not. * * This call occurs _before_ the token contract's state is updated, so * {IERC777-balanceOf}, etc., can be used to query the pre-operation state. * * This function may revert to prevent the operation from being executed. */ function tokensToSend( address operator, address from, address to, uint256 amount, bytes calldata userData, bytes calldata operatorData ) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor () internal { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 9999 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[3]","name":"farmlandAddresses_","type":"address[3]"},{"internalType":"address[]","name":"farmAddresses_","type":"address[]"},{"internalType":"uint256[]","name":"composted_","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"address","name":"farmAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedAmountIncrease","type":"uint256"}],"name":"Allocated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenHolder","type":"address"}],"name":"AuthorizedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"TokenID","type":"uint256"},{"indexed":false,"internalType":"enum CollectibleType","name":"collectibleType","type":"uint8"}],"name":"CollectibleEquipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"TokenID","type":"uint256"},{"indexed":false,"internalType":"enum CollectibleType","name":"collectibleType","type":"uint8"}],"name":"CollectibleReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"farmAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bonus","type":"uint256"}],"name":"Composted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"endMaturityBoost_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxGrowthCycle_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxGrowthCycleWithFarmer_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxCompostBoost_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxMaturityBoost_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxMaturityCollectibleBoost_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxFarmSizeWithoutFarmer_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxFarmSizeWithoutTractor_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bonusCompostBoostWithFarmer_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bonusCompostBoostWithTractor_","type":"uint256"}],"name":"FarmlandVariablesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"address","name":"farmAddress","type":"address"},{"indexed":false,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"targetBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Harvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedAmountDecrease","type":"uint256"}],"name":"Released","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenHolder","type":"address"}],"name":"RevokedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Sent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"L2_GATEWAY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"authorizeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenHolder","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"bridgeBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"bridgeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"compost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"defaultOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"},{"internalType":"uint256","name":"targetBlock","type":"uint256"}],"name":"directCompost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"enum CollectibleType","name":"collectibleType","type":"uint8"}],"name":"equipCollectible","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"}],"name":"getAddressDetails","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"cropBalance","type":"uint256"},{"internalType":"uint256","name":"cropAvailableToHarvest","type":"uint256"},{"internalType":"uint256","name":"farmMaturityBoost","type":"uint256"},{"internalType":"uint256","name":"farmCompostBoost","type":"uint256"},{"internalType":"uint256","name":"farmTotalBoost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"}],"name":"getCollectiblesByFarm","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum CollectibleType","name":"collectibleType","type":"uint8"},{"internalType":"uint256","name":"maxBoostLevel","type":"uint256"},{"internalType":"uint256","name":"addedBlockNumber","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"internalType":"struct Collectible[]","name":"farmCollectibles","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"},{"internalType":"enum CollectibleType","name":"collectibleType","type":"uint8"}],"name":"getFarmCollectibleTotalOfType","outputs":[{"internalType":"uint256","name":"ownsCollectibleTotal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"}],"name":"getFarmCollectibleTotals","outputs":[{"internalType":"uint256","name":"totalMaxBoost","type":"uint256"},{"internalType":"uint256","name":"lastAddedBlockNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFarmlandAddresses","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFarmlandVariables","outputs":[{"internalType":"uint256","name":"totalFarms","type":"uint256"},{"internalType":"uint256","name":"totalAllocatedAmount","type":"uint256"},{"internalType":"uint256","name":"totalCompostedAmount","type":"uint256"},{"internalType":"uint256","name":"maximumCompostBoost","type":"uint256"},{"internalType":"uint256","name":"maximumMaturityBoost","type":"uint256"},{"internalType":"uint256","name":"maximumGrowthCycle","type":"uint256"},{"internalType":"uint256","name":"maximumGrowthCycleWithFarmer","type":"uint256"},{"internalType":"uint256","name":"maximumMaturityCollectibleBoost","type":"uint256"},{"internalType":"uint256","name":"endMaturityBoostBlocks","type":"uint256"},{"internalType":"uint256","name":"maximumFarmSizeWithoutFarmer","type":"uint256"},{"internalType":"uint256","name":"maximumFarmSizeWithoutTractor","type":"uint256"},{"internalType":"uint256","name":"bonusCompostBoostWithAFarmer","type":"uint256"},{"internalType":"uint256","name":"bonusCompostBoostWithATractor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"granularity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"farmAddress","type":"address"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"uint256","name":"targetBlock","type":"uint256"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"tokenHolder","type":"address"}],"name":"isOperatorFor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"isPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"l1Address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"operatorBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"operatorSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownerOfCollectibles","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"enum CollectibleType","name":"collectibleType","type":"uint8"},{"internalType":"uint256","name":"maxBoostLevel","type":"uint256"},{"internalType":"uint256","name":"addedBlockNumber","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ownerOfFarm","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"compostedAmount","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"lastHarvestedBlockNumber","type":"uint256"},{"internalType":"address","name":"harvesterAddress","type":"address"},{"internalType":"uint256","name":"numberOfCollectibles","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"releaseCollectible","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"revokeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"landAddress_","type":"address"},{"internalType":"address payable","name":"farmerNFTAddress_","type":"address"},{"internalType":"address payable","name":"tractorNFTAddress_","type":"address"}],"name":"setFarmlandAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"endMaturityBoost_","type":"uint256"},{"internalType":"uint256","name":"maxGrowthCycle_","type":"uint256"},{"internalType":"uint256","name":"maxGrowthCycleWithFarmer_","type":"uint256"},{"internalType":"uint256","name":"maxCompostBoost_","type":"uint256"},{"internalType":"uint256","name":"maxMaturityBoost_","type":"uint256"},{"internalType":"uint256","name":"maxMaturityCollectibleBoost_","type":"uint256"},{"internalType":"uint256","name":"maxFarmSizeWithoutFarmer_","type":"uint256"},{"internalType":"uint256","name":"maxFarmSizeWithoutTractor_","type":"uint256"},{"internalType":"uint256","name":"bonusCompostBoostWithFarmer_","type":"uint256"},{"internalType":"uint256","name":"bonusCompostBoostWithTractor_","type":"uint256"}],"name":"setFarmlandVariables","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526202bc00600f5561af0060105562015e00601155620186a0601255617530601355620186a060145569032d26d12e980b60000060155569152d02c7e14af68000006016556103e86017556109c46018553480156200006157600080fd5b5060405162006c8138038062006c81833981016040819052620000849162000b78565b6040518060400160405280600481526020016321b7b93760e11b8152506040518060400160405280600481526020016321a7a92760e11b81525060006001600160401b0381118015620000d657600080fd5b5060405190808252806020026020018201604052801562000101578160200160208202803683370190505b5082516200011790600290602086019062000933565b5081516200012d90600390602085019062000933565b50805162000143906004906020840190620009b8565b5060005b600454811015620001a357600160056000600484815481106200016657fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff191691151591909117905560010162000147565b506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d90620002019030907fac7fbab5f54a3ca8194167523c6753bfeb96a445279294b6125b68cce217705490829060040162000d0f565b600060405180830381600087803b1580156200021c57600080fd5b505af115801562000231573d6000803e3d6000fd5b50506040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad2492506329965a1d9150620002929030907faea199e31a596269b42cdafd93407f14436db6e4cad65417994c2eb37381e05a90829060040162000d0f565b600060405180830381600087803b158015620002ad57600080fd5b505af1158015620002c2573d6000803e3d6000fd5b505050505050506000620002db620005c360201b60201c565b600980546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506009805460ff60a01b19169055620003486301ffc9a760e01b620005c7565b6001601d556200035c565b60405180910390fd5b6002601d5582516001600160a01b03166200038b5760405162461bcd60e51b8152600401620003539062000e7f565b60208301516001600160a01b0316620003b85760405162461bcd60e51b8152600401620003539062000eb6565b60408301516001600160a01b0316620003e55760405162461bcd60e51b8152600401620003539062000dd5565b8251600c80546001600160a01b039283166001600160a01b0319918216179091556020850151600a80549184169183169190911790556040850151600b8054919093169116179055815160005b81811015620004df5743601e60008684815181106200044d57fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600301819055508281815181106200048957fe5b6020026020010151601e6000868481518110620004a257fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060010181905550808060010191505062000432565b50620004f2630a85bd0160e11b620005c7565b6040516329965a1d60e01b8152731820a4b7618bde71dce8cdc73aab6c95905fad24906329965a1d906200053e90309060008051602062006c6183398151915290829060040162000d0f565b600060405180830381600087803b1580156200055957600080fd5b505af11580156200056e573d6000803e3d6000fd5b50505050620005b362000586620005c360201b60201c565b604080516020808201835260008083528351918201909352918252691fc3842bd1f071c000009162000619565b50506001601d555062000f919050565b3390565b6001600160e01b03198082161415620005f45760405162461bcd60e51b8152600401620003539062000d32565b6001600160e01b0319166000908152601c60205260409020805460ff19166001179055565b6001600160a01b038416620006425760405162461bcd60e51b8152600401620003539062000da0565b60006200064e620005c3565b90506200065f816000878762000783565b6200067b846001546200078960201b6200308b1790919060201c565b6001556001600160a01b03851660009081526020818152604090912054620006ae9186906200308b62000789821b17901c565b6001600160a01b038616600090815260208190526040812091909155620006dd908290878787876001620007ba565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051620007269392919062000ef4565b60405180910390a3846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8660405162000774919062000eeb565b60405180910390a35050505050565b50505050565b600082820183811015620007b15760405162461bcd60e51b8152600401620003539062000d69565b90505b92915050565b60405163555ddc6560e11b8152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906200080790899060008051602062006c618339815191529060040162000cf6565b60206040518083038186803b1580156200082057600080fd5b505afa15801562000835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200085b919062000b53565b90506001600160a01b03811615620008dd576040516223de2960e01b81526001600160a01b038216906223de2990620008a3908b908b908b908b908b908b9060040162000c98565b600060405180830381600087803b158015620008be57600080fd5b505af1158015620008d3573d6000803e3d6000fd5b5050505062000923565b8115620009235762000903866001600160a01b03166200092d60201b620030b01760201c565b15620009235760405162461bcd60e51b8152600401620003539062000e0c565b5050505050505050565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200097657805160ff1916838001178555620009a6565b82800160010185558215620009a6579182015b82811115620009a657825182559160200191906001019062000989565b50620009b492915062000a1e565b5090565b82805482825590600052602060002090810192821562000a10579160200282015b8281111562000a1057825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620009d9565b50620009b492915062000a35565b5b80821115620009b4576000815560010162000a1f565b5b80821115620009b45780546001600160a01b031916815560010162000a36565b80516001600160a01b0381168114620007b457600080fd5b600082601f83011262000a7f578081fd5b815162000a9662000a908262000f71565b62000f2d565b81815291506020808301908481018184028601820187101562000ab857600080fd5b60005b8481101562000ae35762000ad0888362000a56565b8452928201929082019060010162000abb565b505050505092915050565b600082601f83011262000aff578081fd5b815162000b1062000a908262000f71565b81815291506020808301908481018184028601820187101562000b3257600080fd5b60005b8481101562000ae35781518452928201929082019060010162000b35565b60006020828403121562000b65578081fd5b62000b71838362000a56565b9392505050565b600080600060a0848603121562000b8d578182fd5b84601f85011262000b9c578182fd5b600362000bad62000a908262000f54565b8086606088018981111562000bc0578687fd5b865b8581101562000bed5762000bd78b8462000a56565b8552602094850194929092019160010162000bc2565b50519196509092506001600160401b039150508082111562000c0d578384fd5b62000c1b8783880162000a6e565b9350608086015191508082111562000c31578283fd5b5062000c408682870162000aee565b9150509250925092565b60008151808452815b8181101562000c715760208185018101518683018201520162000c53565b8181111562000c835782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0387811682528681166020830152851660408201526060810184905260c06080820181905260009062000cd59083018562000c4a565b82810360a084015262000ce9818562000c4a565b9998505050505050505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6020808252601c908201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252818101527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252601f908201527f496e76616c6964204c31436f726e20436f6e7472616374206164647265737300604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201526c1ad95b9cd49958da5c1a595b9d609a1b608082015260a00190565b6020808252601d908201527f496e76616c6964204c616e6420436f6e74726163742061646472657373000000604082015260600190565b6020808252818101527f496e76616c6964204761746577617920436f6e74726163742061646472657373604082015260600190565b90815260200190565b60008482526060602083015262000f0f606083018562000c4a565b828103604084015262000f23818562000c4a565b9695505050505050565b6040518181016001600160401b038111828210171562000f4c57600080fd5b604052919050565b60006001600160401b0382111562000f6a578081fd5b5060200290565b60006001600160401b0382111562000f87578081fd5b5060209081020190565b615cc08062000fa16000396000f3fe608060405234801561001057600080fd5b50600436106103145760003560e01c806384546c27116101a7578063c2ceb95f116100ee578063e9c0a26711610097578063fad8b32a11610071578063fad8b32a146106a4578063fc673c4f146106b7578063fe9d9303146106ca57610314565b8063e9c0a2671461066b578063f2fde38b1461067e578063f573e99f1461069157610314565b8063d95b6371116100c8578063d95b63711461062c578063daed5e5b1461063f578063dd62ed3e1461065857610314565b8063c2ceb95f146105ec578063c2eeeebd146105ff578063ccfb92161461060757610314565b80639bd9bbc611610150578063b3b7fdaa1161012a578063b3b7fdaa146105a1578063b78b52df146105c6578063c0181017146105d957610314565b80639bd9bbc614610568578063a68f40511461057b578063a9059cbb1461058e57610314565b80638da5cb5b116101815780638da5cb5b14610545578063959b8c3f1461054d57806395d89b411461056057610314565b806384546c271461051757806386d1a69f1461052a5780638c2a993e1461053257610314565b80633133e3ab1161026b57806362ad1b8311610214578063715018a6116101ee578063715018a6146104db578063735c8c76146104e357806374f4f5471461050457610314565b806362ad1b83146104a057806370a08231146104b357806370db4eb2146104c657610314565b806354a5dc2d1161024557806354a5dc2d1461046f578063556f0dc7146104905780635c975abb1461049857610314565b80633133e3ab14610422578063313ce567146104475780633af3e4511461045c57610314565b80630fbc4b15116102cd57806320f1dbbc116102a757806320f1dbbc146103dc57806323b872dd146103ef578063311406641461040257610314565b80630fbc4b1514610394578063150b7a02146103a757806318160ddd146103c757610314565b806306e48538116102fe57806306e485381461035757806306fdde031461036c578063095ea7b31461038157610314565b806223de291461031957806301ffc9a71461032e575b600080fd5b61032c61032736600461420f565b6106dd565b005b61034161033c366004614537565b6107cc565b60405161034e9190614aa7565b60405180910390f35b61035f610807565b60405161034e9190614998565b61037461086a565b60405161034e9190614adf565b61034161038f366004614424565b6108f4565b61032c6103a23660046146b4565b610918565b6103ba6103b53660046142fd565b610ace565b60405161034e9190614ab2565b6103cf610af7565b60405161034e91906159c7565b61032c6103ea366004614517565b610afd565b6103416103fd3660046142bd565b610b59565b610415610410366004614155565b610c98565b60405161034e91906149e5565b610435610430366004614155565b610fe0565b60405161034e96959493929190615a7e565b61044f611028565b60405161034e9190615b48565b61032c61046a366004614424565b61102d565b610477611221565b60405161034e9d9c9b9a99989796959493929190615aeb565b6103cf611257565b61034161125c565b61032c6104ae366004614367565b61127d565b6103cf6104c1366004614155565b6112c0565b6104ce6112db565b60405161034e9190614765565b61032c6112ea565b6104f66104f1366004614155565b61138b565b60405161034e929190615a3f565b61032c610512366004614424565b6114bd565b6103cf6105253660046143f7565b611536565b61032c6115cf565b61032c610540366004614424565b6117c0565b6104ce611833565b61032c61055b366004614155565b611842565b61037461196f565b61032c61057636600461444f565b6119d0565b61032c6105893660046145ea565b6119fa565b61034161059c366004614424565b611f49565b6105b46105af366004614155565b612003565b60405161034e96959493929190615a4d565b61032c6105d4366004614424565b612044565b61032c6105e7366004614424565b61232d565b61032c6105fa3660046142bd565b612481565b6104ce612683565b61061a610615366004614424565b612692565b60405161034e96959493929190615a05565b61034161063a36600461418d565b612778565b61064761281a565b60405161034e9594939291906148f4565b6103cf61066636600461418d565b612845565b61032c6106793660046141c5565b612870565b61032c61068c366004614155565b6129d2565b61032c61069f366004614647565b612aab565b61032c6106b2366004614155565b612eff565b61032c6106c53660046144a6565b61302c565b61032c6106d8366004614602565b613065565b600085116107065760405162461bcd60e51b81526004016106fd906154ca565b60405180910390fd5b600c546001600160a01b031661071a6130b6565b6001600160a01b0316146107405760405162461bcd60e51b81526004016106fd90615935565b6001600160a01b03881630146107685760405162461bcd60e51b81526004016106fd906155e1565b6001600160a01b03861630146107905760405162461bcd60e51b81526004016106fd90615410565b856001600160a01b0316876001600160a01b031614156107c25760405162461bcd60e51b81526004016106fd9061563e565b5050505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152601c602052604090205460ff165b919050565b6060600480548060200260200160405190810160405280929190818152602001828054801561085f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610841575b505050505090505b90565b60028054604080516020601f600019610100600187161502019094168590049384018190048102820181019092528281526060939092909183018282801561085f5780601f106108c85761010080835404028352916020019161085f565b820191906000526020600020905b8154815290600101906020018083116108d657509395945050505050565b6000806108ff6130b6565b905061090c8185856130ba565b60019150505b92915050565b6109206130b6565b6001600160a01b0316610931611833565b6001600160a01b0316146109575760405162461bcd60e51b81526004016106fd90615358565b60008a1180156109695750600f548a14155b1561097457600f8a90555b60008911801561098657506010548914155b156109915760108990555b6000881180156109a357506011548814155b156109ae5760118890555b6000871180156109c057506012548714155b156109cb5760128790555b6000861180156109dd57506013548614155b156109e85760138690555b6000851180156109fa57506014548514155b15610a055760148590555b600084118015610a1757506015548414155b15610a225760158490555b600083118015610a3457506016548314155b15610a3f5760168390555b600082118015610a5157506017548214155b15610a5c5760178290555b600081118015610a6e57506018548114155b15610a795760188190555b7ff50e3d54552661ab9fcd2009f7358e5404ec49741cc8182e75e2df2ac316ba488a8a8a8a8a8a8a8a8a8a604051610aba9a99989796959493929190615aa6565b60405180910390a150505050505050505050565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b60015490565b610b056130b6565b6001600160a01b0316610b16611833565b6001600160a01b031614610b3c5760405162461bcd60e51b81526004016106fd90615358565b80610b4e57610b4961316e565b610b56565b610b566131fa565b50565b60006001600160a01b038316610b815760405162461bcd60e51b81526004016106fd9061546d565b6001600160a01b038416610ba75760405162461bcd60e51b81526004016106fd906157b2565b6000610bb16130b6565b9050610bdf818686866040518060200160405280600081525060405180602001604052806000815250613287565b610c0b8186868660405180602001604052806000815250604051806020016040528060008152506133e8565b610c5f8582610c5a86604051806060016040528060298152602001615c3f602991396001600160a01b03808c166000908152600860209081526040808320938b16835292905220549190613514565b6130ba565b610c8d8186868660405180602001604052806000815250604051806020016040528060008152506000613540565b506001949350505050565b6001600160a01b0381166000908152601f6020526040902054606090818167ffffffffffffffff81118015610ccc57600080fd5b50604051908082528060200260200182016040528015610d0657816020015b610cf3613ef9565b815260200190600190039081610ceb5790505b50905060005b82811015610fd8576001600160a01b0385166000908152601f60205260409020805482908110610d3857fe5b906000526020600020906006020160000154828281518110610d5657fe5b602090810291909101810151919091526001600160a01b0386166000908152601f90915260409020805482908110610d8a57fe5b906000526020600020906006020160010160009054906101000a900460ff16828281518110610db557fe5b6020026020010151602001906002811115610dcc57fe5b90816002811115610dd957fe5b9052506001600160a01b0385166000908152601f60205260409020805482908110610e0057fe5b906000526020600020906006020160020154828281518110610e1e57fe5b60200260200101516040018181525050601f6000866001600160a01b03166001600160a01b031681526020019081526020016000208181548110610e5e57fe5b906000526020600020906006020160030154828281518110610e7c57fe5b60200260200101516060018181525050601f6000866001600160a01b03166001600160a01b031681526020019081526020016000208181548110610ebc57fe5b906000526020600020906006020160040154828281518110610eda57fe5b60200260200101516080018181525050601f6000866001600160a01b03166001600160a01b031681526020019081526020016000208181548110610f1a57fe5b6000918252602091829020600560069092020101805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015610fb05780601f10610f8557610100808354040283529160200191610fb0565b820191906000526020600020905b815481529060010190602001808311610f9357829003601f168201915b5050505050828281518110610fc157fe5b602090810291909101015160a00152600101610d0c565b509392505050565b43600080808080610ff0876112c0565b9450610ffc87436136cf565b935061100787613835565b925061101287613946565b915061101d876139a4565b905091939550919395565b601290565b61103561125c565b156110525760405162461bcd60e51b81526004016106fd906150be565b6002601d5414156110755760405162461bcd60e51b81526004016106fd9061580f565b6002601d558160016001600160a01b0382166000908152601e60205260409020546110b25760405162461bcd60e51b81526004016106fd9061587b565b438311156110d25760405162461bcd60e51b81526004016106fd90614f70565b60006110df856001611536565b1180156110f6575060006110f4856000611536565b115b6111125760405162461bcd60e51b81526004016106fd9061520c565b6001600160a01b0384166000908152601e602052604090206003810154841161114d5760405162461bcd60e51b81526004016106fd90615527565b6111556130b6565b60048201546001600160a01b039081169116146111845760405162461bcd60e51b81526004016106fd90614af2565b600061119086866136cf565b60038301869055905060006111a587836139cf565b90506111b1828261308b565b60018401805490910190556111c6828261308b565b601a805490910190557f1bb11a48efce84136dfd03628800501f9fa4d84e04f56c3ab6369b9c71b629226111f86130b6565b88848460405161120b94939291906147de565b60405180910390a150506001601d555050505050565b601b54601954601a54601254601354601054601154601454600f54601554601654601754601854909192939495969798999a9b9c565b600190565b60095474010000000000000000000000000000000000000000900460ff1690565b61128e6112886130b6565b86612778565b6112aa5760405162461bcd60e51b81526004016106fd9061569b565b6112b985858585856001613a2f565b5050505050565b6001600160a01b031660009081526020819052604090205490565b600a546001600160a01b031681565b6112f26130b6565b6001600160a01b0316611303611833565b6001600160a01b0316146113295760405162461bcd60e51b81526004016106fd90615358565b6009546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600980547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6001600160a01b0381166000908152601f60205260408120548190818080805b848110156114b3576001600160a01b0388166000908152601f602052604090208054829081106113d757fe5b9060005260206000209060060201600401549250601f6000896001600160a01b03166001600160a01b03168152602001908152602001600020818154811061141b57fe5b90600052602060002090600602016003015491508260001415611441576000935061144e565b8242111561144e57600193505b836114ab576001600160a01b0388166000908152601f60205260409020805461149d91908390811061147c57fe5b9060005260206000209060060201600201548861308b90919063ffffffff16565b9650818610156114ab578195505b6001016113ab565b5050505050915091565b600a546001600160a01b031633146114e75760405162461bcd60e51b81526004016106fd90614c40565b6040805160208101918290526000808252369290916115309186918691869086908190838280828437600092018290525060408051602081019091529081529250613ab2915050565b50505050565b6001600160a01b0382166000908152601f6020526040812054815b818110156115c75783600281111561156557fe5b6001600160a01b0386166000908152601f6020526040902080548390811061158957fe5b600091825260209091206001600690920201015460ff1660028111156115ab57fe5b14156115bf576115bc83600161308b565b92505b600101611551565b505092915050565b6002601d5414156115f25760405162461bcd60e51b81526004016106fd9061580f565b6002601d556115ff6130b6565b6001600160a01b0381166000908152601e6020526040902060020154431480159061164557506001600160a01b0381166000908152601e60205260409020600301544314155b6116615760405162461bcd60e51b81526004016106fd90614d8e565b6116696130b6565b60016001600160a01b0382166000908152601e60205260409020546116a05760405162461bcd60e51b81526004016106fd9061587b565b6000601e60006116ae6130b6565b6001600160a01b031681526020810191909152604001600090812080549181556019549092506116de9082613c0b565b6019556001820154601a546116f291613c0b565b601a55601b54611703906001613c0b565b601b557f82e416ba72d10e709b5de7ac16f5f49ff1d94f22d55bf582d353d3c313a1e8dd61172f6130b6565b60018401546040516117439291859161489d565b60405180910390a1600c546001600160a01b0316639bd9bbc66117646130b6565b836040518363ffffffff1660e01b8152600401611782929190614875565b600060405180830381600087803b15801561179c57600080fd5b505af11580156117b0573d6000803e3d6000fd5b50506001601d5550505050505050565b600a546001600160a01b031633146117ea5760405162461bcd60e51b81526004016106fd90614c40565b6040805160208101918290526000808252369290916115309186918691869086908190838280828437600092018290525060408051602081019091529081529250613c33915050565b6009546001600160a01b031690565b806001600160a01b03166118546130b6565b6001600160a01b0316141561187b5760405162461bcd60e51b81526004016106fd90614e7f565b6001600160a01b03811660009081526005602052604090205460ff16156118de57600760006118a86130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff19169055611925565b6001600660006118ec6130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b61192d6130b6565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561085f5780601f106108c85761010080835404028352916020019161085f565b6119f56119db6130b6565b848484604051806020016040528060008152506001613a2f565b505050565b6002601d541415611a1d5760405162461bcd60e51b81526004016106fd9061580f565b6002601d55611a2a6130b6565b6000611a358261138b565b91505043811415611a585760405162461bcd60e51b81526004016106fd90614cd4565b6000601e6000611a666130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000209050806005015460001415611aad5760405162461bcd60e51b81526004016106fd906151af565b611ab5613ef9565b601f6000611ac16130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110611aec57fe5b90600052602060002090600602016040518060c0016040529081600082015481526020016001820160009054906101000a900460ff166002811115611b2d57fe5b6002811115611b3857fe5b8152602001600282015481526020016003820154815260200160048201548152602001600582018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611bf35780601f10611bc857610100808354040283529160200191611bf3565b820191906000526020600020905b815481529060010190602001808311611bd657829003601f168201915b5050509190925250505060208101519091506000611c1082613d65565b835160155486549293509091118015611c3a57506002611c38611c316130b6565b6000611536565b105b8015611c5157506000836002811115611c4f57fe5b145b15611c6e5760405162461bcd60e51b81526004016106fd90614c77565b6016548554118015611c9157506002611c8f611c886130b6565b6001611536565b105b8015611ca857506001836002811115611ca657fe5b145b15611cc55760405162461bcd60e51b81526004016106fd90614edc565b601f6000611cd16130b6565b6001600160a01b03166001600160a01b03168152602001908152602001600020611d226001601f6000611d026130b6565b6001600160a01b0316815260208101919091526040016000205490613c0b565b81548110611d2c57fe5b9060005260206000209060060201601f6000611d466130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000208981548110611d7157fe5b600091825260209091208254600690920201908155600180830154818301805460ff90921692909160ff191690836002811115611daa57fe5b021790555060028201548160020155600382015481600301556004820154816004015560058201816005019080546001816001161561010002031660029004611df4929190613f30565b50905050601f6000611e046130b6565b6001600160a01b03166001600160a01b03168152602001908152602001600020805480611e2d57fe5b60008281526020812060066000199093019283020181815560018101805460ff1916905560028101829055600381018290556004810182905590611e746005830182613fb5565b505090556005850154611e88906001613c0b565b60058601557f87aef2e82b62c3909dc67b9b479f5738d0de8fe16d58078401cf360e64563390611eb66130b6565b438386604051611ec994939291906148be565b60405180910390a1816001600160a01b03166342842e0e30611ee96130b6565b846040518463ffffffff1660e01b8152600401611f0893929190614779565b600060405180830381600087803b158015611f2257600080fd5b505af1158015611f36573d6000803e3d6000fd5b50506001601d5550505050505050505050565b60006001600160a01b038316611f715760405162461bcd60e51b81526004016106fd9061546d565b6000611f7b6130b6565b9050611fa9818286866040518060200160405280600081525060405180602001604052806000815250613287565b611fd58182868660405180602001604052806000815250604051806020016040528060008152506133e8565b61090c8182868660405180602001604052806000815250604051806020016040528060008152506000613540565b601e6020526000908152604090208054600182015460028301546003840154600485015460059095015493949293919290916001600160a01b039091169086565b61204c61125c565b156120695760405162461bcd60e51b81526004016106fd906150be565b6002601d54141561208c5760405162461bcd60e51b81526004016106fd9061580f565b6002601d556120996130b6565b6001600160a01b0381166000908152601e602052604090206002015443148015906120df57506001600160a01b0381166000908152601e60205260409020600301544314155b6120fb5760405162461bcd60e51b81526004016106fd90614d8e565b6000601e60006121096130b6565b6001600160a01b031681526020810191909152604001600020601554815491925090612135908561308b565b11801561214c5750600161214a856000611536565b105b156121695760405162461bcd60e51b81526004016106fd90615004565b6016548154612178908561308b565b11801561218f5750600161218d856001611536565b105b156121ac5760405162461bcd60e51b81526004016106fd90615755565b805461221a578281554360028201556004810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386161790556001810154601a546122019161308b565b601a55601b5461221290600161308b565b601b55612258565b6000612227856000611536565b1115612240578054612239908461308b565b8155612258565b60405162461bcd60e51b81526004016106fd906156f8565b601954612265908461308b565b6019554360038201557f39d12b1a9bde2a7e34304e5a951514ac2a0679475d0a8b35bedf400ebe8b506d6122976130b6565b60018301546040516122af9291439189918991614841565b60405180910390a1600c546001600160a01b03166362ad1b836122d06130b6565b30866040518463ffffffff1660e01b81526004016122f09392919061479d565b600060405180830381600087803b15801561230a57600080fd5b505af115801561231e573d6000803e3d6000fd5b50506001601d55505050505050565b61233561125c565b156123525760405162461bcd60e51b81526004016106fd906150be565b6002601d5414156123755760405162461bcd60e51b81526004016106fd9061580f565b6002601d558160016001600160a01b0382166000908152601e60205260409020546123b25760405162461bcd60e51b81526004016106fd9061587b565b6001600160a01b0384166000908152601e60205260408120906123d586866139cf565b90506123e1858261308b565b60018301805490910190556123f6858261308b565b601a805490910190557f1bb11a48efce84136dfd03628800501f9fa4d84e04f56c3ab6369b9c71b629226124286130b6565b87878460405161243b94939291906147de565b60405180910390a161247461244e6130b6565b866040518060200160405280600081525060405180602001604052806000815250613ab2565b50506001601d5550505050565b61248961125c565b156124a65760405162461bcd60e51b81526004016106fd906150be565b6002601d5414156124c95760405162461bcd60e51b81526004016106fd9061580f565b6002601d8190556001600160a01b0384166000908152601e6020526040902001548390431480159061251657506001600160a01b0381166000908152601e60205260409020600301544314155b6125325760405162461bcd60e51b81526004016106fd90614d8e565b8360016001600160a01b0382166000908152601e602052604090205461256a5760405162461bcd60e51b81526004016106fd9061587b565b4384111561258a5760405162461bcd60e51b81526004016106fd90615584565b6001600160a01b0386166000908152601e60205260409020600381015485116125c55760405162461bcd60e51b81526004016106fd90615152565b6125cd6130b6565b60048201546001600160a01b039081169116146125fc5760405162461bcd60e51b81526004016106fd9061529e565b600061260888876136cf565b6003830187905590507fb757d83b4531499e2d84501fbd6edd8467f4aa78b20051773e245c703fb891db61263a6130b6565b438a8a8a8660405161265196959493929190614807565b60405180910390a161231e87826040518060200160405280600081525060405180602001604052806000815250613c33565b600b546001600160a01b031681565b601f60205281600052604060002081815481106126ab57fe5b6000918252602091829020600691909102018054600180830154600280850154600386015460048701546005880180546040805161010099831615999099026000190190911695909504601f81018b90048b0288018b01909552848752969a5060ff9094169850909690959294929392919083018282801561276e5780601f106127435761010080835404028352916020019161276e565b820191906000526020600020905b81548152906001019060200180831161275157829003601f168201915b5050505050905086565b6000816001600160a01b0316836001600160a01b031614806127e357506001600160a01b03831660009081526005602052604090205460ff1680156127e357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b8061281357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b600d54600e54600b54600a54600c546001600160a01b03948516959385169492831693918316921690565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b6128786130b6565b6001600160a01b0316612889611833565b6001600160a01b0316146128af5760405162461bcd60e51b81526004016106fd90615358565b6001600160a01b038316158015906128d55750600c546001600160a01b03848116911614155b1561290e57600c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385161790555b6001600160a01b038216158015906129345750600d546001600160a01b03838116911614155b1561296d57600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384161790555b6001600160a01b038116158015906129935750600e546001600160a01b03828116911614155b156119f557600e80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055505050565b6129da6130b6565b6001600160a01b03166129eb611833565b6001600160a01b031614612a115760405162461bcd60e51b81526004016106fd90615358565b6001600160a01b038116612a375760405162461bcd60e51b81526004016106fd90614d31565b6009546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600980547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b612ab361125c565b15612ad05760405162461bcd60e51b81526004016106fd906150be565b6002601d541415612af35760405162461bcd60e51b81526004016106fd9061580f565b6002601d55612b006130b6565b6000612b0b8261138b565b91505043811415612b2e5760405162461bcd60e51b81526004016106fd90614cd4565b612b366130b6565b60016001600160a01b0382166000908152601e6020526040902054612b6d5760405162461bcd60e51b81526004016106fd9061587b565b6000601e6000612b7b6130b6565b6001600160a01b03166001600160a01b0316815260200190815260200160002090506000612ba887613d65565b6005830154909150612bbb90600161308b565b60058301556040517f939f1eb6000000000000000000000000000000000000000000000000000000008152600090819081906001600160a01b0385169063939f1eb690612c0c908e906004016159c7565b60c06040518083038186803b158015612c2457600080fd5b505afa158015612c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5c919061466b565b50505050915091506060846001600160a01b031663c87b56dd8d6040518263ffffffff1660e01b8152600401612c9291906159c7565b60006040518083038186803b158015612caa57600080fd5b505afa158015612cbe573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612d049190810190614577565b905060008b6002811115612d1457fe5b1415612d3857612d31612710612d2b846064613d9d565b9061308b565b9350612d57565b612d54611388612d2b6004612d4e866064613d9d565b90613dd7565b93505b601f6000612d636130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000206040518060c001604052808e81526020018d6002811115612da057fe5b815260208082018890524360408301526060820187905260809091018490528254600181810185556000948552938290208351600690920201908155908201518184018054939492939192909160ff191690836002811115612dfe57fe5b021790555060408201516002820155606082015160038201556080820151600482015560a08201518051612e3c916005840191602090910190613ff9565b5050507f36d977532e3d06244e7254e8b5afc1f6ce2555c1200b4d483ba135c239d1148d612e686130b6565b438e8e604051612e7b94939291906148be565b60405180910390a1846001600160a01b03166342842e0e612e9a6130b6565b308f6040518463ffffffff1660e01b8152600401612eba93929190614779565b600060405180830381600087803b158015612ed457600080fd5b505af1158015612ee8573d6000803e3d6000fd5b50506001601d555050505050505050505050505050565b612f076130b6565b6001600160a01b0316816001600160a01b03161415612f385760405162461bcd60e51b81526004016106fd90615061565b6001600160a01b03811660009081526005602052604090205460ff1615612fa457600160076000612f676130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055612fe2565b60066000612fb06130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b612fea6130b6565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b61303d6130376130b6565b85612778565b6130595760405162461bcd60e51b81526004016106fd9061569b565b61153084848484613ab2565b6130876130706130b6565b838360405180602001604052806000815250613ab2565b5050565b6000828201838110156128135760405162461bcd60e51b81526004016106fd90614deb565b3b151590565b3390565b6001600160a01b0383166130e05760405162461bcd60e51b81526004016106fd90614b86565b6001600160a01b0382166131065760405162461bcd60e51b81526004016106fd906158d8565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906131619085906159c7565b60405180910390a3505050565b61317661125c565b6131925760405162461bcd60e51b81526004016106fd90614b4f565b600980547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6131e36130b6565b6040516131f09190614765565b60405180910390a1565b61320261125c565b1561321f5760405162461bcd60e51b81526004016106fd906150be565b600980547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586131e36130b6565b6040517faabbb8ca000000000000000000000000000000000000000000000000000000008152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906132fc9089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe8959060040161497f565b60206040518083038186803b15801561331457600080fd5b505afa158015613328573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061334c9190614171565b90506001600160a01b038116156133df576040517f75ab97820000000000000000000000000000000000000000000000000000000081526001600160a01b038216906375ab9782906133ac908a908a908a908a908a908a90600401614926565b600060405180830381600087803b1580156133c657600080fd5b505af11580156133da573d6000803e3d6000fd5b505050505b50505050505050565b6133f486868686611530565b61343183604051806060016040528060278152602001615c18602791396001600160a01b0388166000908152602081905260409020549190613514565b6001600160a01b038087166000908152602081905260408082209390935590861681522054613460908461308b565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987906134b9908890889088906159d0565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161350491906159c7565b60405180910390a3505050505050565b600081848411156135385760405162461bcd60e51b81526004016106fd9190614adf565b505050900390565b6040517faabbb8ca000000000000000000000000000000000000000000000000000000008152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906135b59089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b9060040161497f565b60206040518083038186803b1580156135cd57600080fd5b505afa1580156135e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136059190614171565b90506001600160a01b0381161561369a576040517e23de290000000000000000000000000000000000000000000000000000000081526001600160a01b038216906223de2990613663908b908b908b908b908b908b90600401614926565b600060405180830381600087803b15801561367d57600080fd5b505af1158015613691573d6000803e3d6000fd5b505050506107c2565b81156107c2576136b2866001600160a01b03166130b0565b156107c25760405162461bcd60e51b81526004016106fd9061538d565b60006136d9614067565b506001600160a01b038084166000908152601e6020908152604091829020825160c0810184528154808252600183015493820193909352600282015493810193909352600381015460608401526004810154909316608083015260059092015460a0820152908061374f57600092505050610912565b4384111561376f5760405162461bcd60e51b81526004016106fd9061596a565b83826060015111156137935760405162461bcd60e51b81526004016106fd906150f5565b60008060016137a3886000611536565b10156137c65760105460608501516137ba9161308b565b915060105490506137df565b60115460608501516137d79161308b565b915060115490505b818610156137fa5760608401516137f7908790613c0b565b90505b60006138068483613d9d565b90506138296305f5e100612d4e612710612d4e856138238e6139a4565b90613d9d565b98975050505050505050565b600061383f614067565b506001600160a01b038083166000908152601e60209081526040808320815160c0810183528154808252600183015494820194909452600282015492810192909252600381015460608301526004810154909416608082015260059093015460a084015281906138b6576127109350505050610802565b60a0830151156138d3576138c98561138b565b90925090506138da565b5060408201515b6013546138e890839061308b565b91506014548211156138fa5760145491505b600061390883612710613c0b565b9050600061392f612710612d2b600f54612d4e866138238943613c0b90919063ffffffff16565b905061393b8482613e09565b979650505050505050565b60008061395283613e1f565b9050600061395e613ebf565b905080158061396b575081155b1561397c5761271092505050610802565b60125461399c90613997612710612d2b85612d4e8884613d9d565b613e09565b949350505050565b6000806139b083613835565b905060006139bd84613946565b905061399c612710612d4e8385613d9d565b6000806139dd846000611536565b1115613a01576139fe612710612d4e84601754613d9d90919063ffffffff16565b90505b6000613a0e846001611536565b111561091257612813612710612d4e84601854613d9d90919063ffffffff16565b6001600160a01b038616613a555760405162461bcd60e51b81526004016106fd90614be3565b6001600160a01b038516613a7b5760405162461bcd60e51b81526004016106fd90615846565b6000613a856130b6565b9050613a95818888888888613287565b613aa38188888888886133e8565b6133df81888888888888613540565b6001600160a01b038416613ad85760405162461bcd60e51b81526004016106fd90614e22565b6000613ae26130b6565b9050613af381866000878787613287565b613b008186600087611530565b613b3d84604051806060016040528060238152602001615c68602391396001600160a01b0388166000908152602081905260409020549190613514565b6001600160a01b038616600090815260208190526040902055600154613b639085613c0b565b600181905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051613bb0939291906159d0565b60405180910390a360006001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051613bfc91906159c7565b60405180910390a35050505050565b600082821115613c2d5760405162461bcd60e51b81526004016106fd90614f39565b50900390565b6001600160a01b038416613c595760405162461bcd60e51b81526004016106fd90615269565b6000613c636130b6565b9050613c728160008787611530565b600154613c7f908561308b565b6001556001600160a01b038516600090815260208190526040902054613ca5908561308b565b6001600160a01b038616600090815260208190526040812091909155613cd2908290878787876001613540565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051613d19939291906159d0565b60405180910390a3846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051613bfc91906159c7565b600080826002811115613d7457fe5b1415613d8c5750600d546001600160a01b0316610802565b5050600e546001600160a01b031690565b600082613dac57506000610912565b82820282848281613db957fe5b04146128135760405162461bcd60e51b81526004016106fd906152fb565b6000808211613df85760405162461bcd60e51b81526004016106fd90614fcd565b818381613e0157fe5b049392505050565b6000818310613e185781612813565b5090919050565b6000613e29614067565b506001600160a01b038083166000908152601e6020908152604091829020825160c0810184528154808252600183015493820193909352600282015493810193909352600381015460608401526004810154909316608083015260059092015460a08201529080613e9f57600092505050610802565b61399c81612d4e6402540be4008560200151613d9d90919063ffffffff16565b600060195460001415613ed457506000610867565b613ef4601954612d4e6402540be400601a54613d9d90919063ffffffff16565b905090565b6040805160c08101909152600080825260208201908152602001600081526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613f695780548555613fa5565b82800160010185558215613fa557600052602060002091601f016020900482015b82811115613fa5578254825591600101919060010190613f8a565b50613fb19291506140a6565b5090565b50805460018160011615610100020316600290046000825580601f10613fdb5750610b56565b601f016020900490600052602060002090810190610b5691906140a6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061403a57805160ff1916838001178555613fa5565b82800160010185558215613fa5579182015b82811115613fa557825182559160200191906001019061404c565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b5b80821115613fb157600081556001016140a7565b60008083601f8401126140cc578182fd5b50813567ffffffffffffffff8111156140e3578182fd5b6020830191508360208285010111156140fb57600080fd5b9250929050565b600082601f830112614112578081fd5b813561412561412082615b7d565b615b56565b915080825283602082850101111561413c57600080fd5b8060208401602084013760009082016020015292915050565b600060208284031215614166578081fd5b813561281381615bf5565b600060208284031215614182578081fd5b815161281381615bf5565b6000806040838503121561419f578081fd5b82356141aa81615bf5565b915060208301356141ba81615bf5565b809150509250929050565b6000806000606084860312156141d9578081fd5b83356141e481615bf5565b925060208401356141f481615bf5565b9150604084013561420481615bf5565b809150509250925092565b60008060008060008060008060c0898b03121561422a578384fd5b883561423581615bf5565b9750602089013561424581615bf5565b9650604089013561425581615bf5565b955060608901359450608089013567ffffffffffffffff80821115614278578586fd5b6142848c838d016140bb565b909650945060a08b013591508082111561429c578384fd5b506142a98b828c016140bb565b999c989b5096995094979396929594505050565b6000806000606084860312156142d1578283fd5b83356142dc81615bf5565b925060208401356142ec81615bf5565b929592945050506040919091013590565b60008060008060808587031215614312578384fd5b843561431d81615bf5565b9350602085013561432d81615bf5565b925060408501359150606085013567ffffffffffffffff81111561434f578182fd5b61435b87828801614102565b91505092959194509250565b600080600080600060a0868803121561437e578081fd5b853561438981615bf5565b9450602086013561439981615bf5565b935060408601359250606086013567ffffffffffffffff808211156143bc578283fd5b6143c889838a01614102565b935060808801359150808211156143dd578283fd5b506143ea88828901614102565b9150509295509295909350565b60008060408385031215614409578182fd5b823561441481615bf5565b915060208301356141ba81615c0a565b60008060408385031215614436578081fd5b823561444181615bf5565b946020939093013593505050565b600080600060608486031215614463578081fd5b833561446e81615bf5565b925060208401359150604084013567ffffffffffffffff811115614490578182fd5b61449c86828701614102565b9150509250925092565b600080600080608085870312156144bb578182fd5b84356144c681615bf5565b935060208501359250604085013567ffffffffffffffff808211156144e9578384fd5b6144f588838901614102565b9350606087013591508082111561450a578283fd5b5061435b87828801614102565b600060208284031215614528578081fd5b81358015158114612813578182fd5b600060208284031215614548578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114612813578182fd5b600060208284031215614588578081fd5b815167ffffffffffffffff81111561459e578182fd5b8201601f810184136145ae578182fd5b80516145bc61412082615b7d565b8181528560208385010111156145d0578384fd5b6145e1826020830160208601615bbf565b95945050505050565b6000602082840312156145fb578081fd5b5035919050565b60008060408385031215614614578182fd5b82359150602083013567ffffffffffffffff811115614631578182fd5b61463d85828601614102565b9150509250929050565b60008060408385031215614659578182fd5b8235915060208301356141ba81615c0a565b60008060008060008060c08789031215614683578384fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6000806000806000806000806000806101408b8d0312156146d3578384fd5b505088359a60208a01359a5060408a013599606081013599506080810135985060a0810135975060c0810135965060e081013595506101008101359450610120013592509050565b60008151808452614733816020860160208601615bbf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039384168152919092166020820152604081019190915260a060608201819052600090820181905260c06080830181905282015260e00190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b0396871681526020810195909552928516604085015293166060830152608082019290925260a081019190915260c00190565b6001600160a01b03958616815260208101949094529190931660408301526060820192909252608081019190915260a00190565b6001600160a01b03929092168252602082015260606040820181905260009082015260800190565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b03851681526020810184905260408101839052608081016148e583615beb565b82606083015295945050505050565b6001600160a01b0395861681529385166020850152918416604084015283166060830152909116608082015260a00190565b60006001600160a01b038089168352808816602084015280871660408401525084606083015260c0608083015261496060c083018561471b565b82810360a0840152614972818561471b565b9998505050505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156149d95783516001600160a01b0316835292840192918401916001016149b4565b50909695505050505050565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614a99577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160c08151855288820151614a4d81615beb565b858a01528188015188860152606080830151908601526080808301519086015260a091820151918501819052614a858186018361471b565b968901969450505090860190600101614a09565b509098975050505050505050565b901515815260200190565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b600060208252612813602083018461471b565b60208082526038908201527f596f75206d75737420626520746865206f776e6572206f66207468652066617260408201527f6d20746f206861727665737420616e6420636f6d706f73740000000000000000606082015260800190565b60208082526014908201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604082015260600190565b60208082526025908201527f4552433737373a20617070726f76652066726f6d20746865207a65726f20616460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f4552433737373a2073656e642066726f6d20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252600c908201527f4f4e4c595f474154455741590000000000000000000000000000000000000000604082015260600190565b60208082526034908201527f596f75206e656564206174206c65617374206f6e65206661726d657220746f2060408201527f72756e2061206661726d20746869732073697a65000000000000000000000000606082015260800190565b6020808252603c908201527f596f752063616e206e6f74206571756970206f722072656c656173652061206360408201527f6f6c6c65637469626c6520696e207468652073616d6520626c6f636b00000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b60208082526039908201527f596f752063616e206e6f7420616c6c6f636174652f72656c65617365206f722060408201527f6861727665737420696e207468652073616d6520626c6f636b00000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f4552433737373a206275726e2066726f6d20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201527f61746f7200000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526037908201527f596f75206e6565642061206661726d657220616e6420612074726163746f722060408201527f746f2072756e2061206661726d20746869732073697a65000000000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526032908201527f596f752063616e206f6e6c792068617276657374202620636f6d706f7374207560408201527f7020746f2063757272656e7420626c6f636b0000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602b908201527f596f75206e6565642061206661726d657220746f206275696c6420612066617260408201527f6d20746869732073697a65000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f60408201527f7200000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526010908201527f5061757361626c653a2070617573656400000000000000000000000000000000604082015260600190565b6020808252603f908201527f596f752063616e206f6e6c79207370656369667920626c6f636b73206174206f60408201527f72206168656164206f66206c6173742068617276657374656420626c6f636b00606082015260800190565b60208082526032908201527f596f752063616e206f6e6c792068617276657374206168656164206f66206c6160408201527f73742068617276657374656420626c6f636b0000000000000000000000000000606082015260800190565b60208082526023908201527f596f75206e656564206120636f6c6c65637469626c65206f6e20796f7572206660408201527f61726d0000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f596f75206e6565642061206661726d6572202620612074726163746f72206f6e60408201527f2074686973206661726d00000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f596f75206d75737420626520746865206f776e6572206f66207468652066617260408201527f6d20746f20686172766573740000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201527f6b656e73526563697069656e7400000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f46756e6473206d75737420626520636f6d696e6720696e746f206120434f524e60408201527f20746f6b656e0000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4552433737373a207472616e7366657220746f20746865207a65726f2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f596f75206d7573742072656365697665206120706f736974697665206e756d6260408201527f6572206f6620746f6b656e730000000000000000000000000000000000000000606082015260800190565b6020808252603e908201527f596f752063616e206f6e6c79206861727665737420616e6420636f6d706f737460408201527f206168656164206f66206c6173742068617276657374656420626c6f636b0000606082015260800190565b60208082526028908201527f596f752063616e206f6e6c79206861727665737420757020746f20637572726560408201527f6e7420626c6f636b000000000000000000000000000000000000000000000000606082015260800190565b6020808252602e908201527f4f6e6c7920434f524e20636f6e74726163742063616e2073656e64206974736560408201527f6c66204c414e4420746f6b656e73000000000000000000000000000000000000606082015260800190565b6020808252602e908201527f57687920776f756c6420434f524e20636f6e74726163742073656e6420746f6b60408201527f656e7320746f20697473656c663f000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f60408201527f7220666f7220686f6c6465720000000000000000000000000000000000000000606082015260800190565b60208082526030908201527f596f75206e6565642061206661726d657220746f20696e63726561736520746860408201527f652073697a65206f662061206661726d00000000000000000000000000000000606082015260800190565b60208082526039908201527f596f75206e6565642061206661726d657220616e6420612074726163746f722060408201527f746f206275696c642061206661726d20746869732073697a6500000000000000606082015260800190565b60208082526026908201527f4552433737373a207472616e736665722066726f6d20746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252818101527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604082015260600190565b60208082526034908201527f596f75206e65656420746f20616c6c6f63617465206c616e6420746f2067726f60408201527f772063726f7073206f6e20796f7572206661726d000000000000000000000000606082015260800190565b60208082526023908201527f4552433737373a20617070726f766520746f20746865207a65726f206164647260408201527f6573730000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f596f752063616e206f6e6c79206275696c64206661726d73206f6e204c414e44604082015260600190565b6020808252602a908201527f596f752063616e206f6e6c792063616c63756c61746520757020746f2063757260408201527f72656e7420626c6f636b00000000000000000000000000000000000000000000606082015260800190565b90815260200190565b6000848252606060208301526159e9606083018561471b565b82810360408401526159fb818561471b565b9695505050505050565b6000878252615a1387615beb565b86602083015285604083015284606083015283608083015260c060a083015261382960c083018461471b565b918252602082015260400190565b9586526020860194909452604085019290925260608401526001600160a01b0316608083015260a082015260c00190565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b998a5260208a019890985260408901969096526060880194909452608087019290925260a086015260c085015260e08401526101008301526101208201526101400190565b9c8d5260208d019b909b5260408c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701526101008601526101208501526101408401526101608301526101808201526101a00190565b60ff91909116815260200190565b60405181810167ffffffffffffffff81118282101715615b7557600080fd5b604052919050565b600067ffffffffffffffff821115615b93578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015615bda578181015183820152602001615bc2565b838111156115305750506000910152565b60038110610b5657fe5b6001600160a01b0381168114610b5657600080fd5b60038110610b5657600080fdfe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220701470c719115ffe67df2ca8cb47a18c42ff499a261d34af4e4f8a81ed76d15564736f6c634300060c0033b281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b0000000000000000000000003cd1833ce959e087d0ef0cb45ed06bffe60f23ba000000000000000000000000096760f208390250649e3e8763348e783aef55620000000000000000000000003cd1833ce959e087d0ef0cb45ed06bffe60f23ba00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000ed2c2cdec695be3a4dc421c1a8a6756dc5a927b60000000000000000000000008cd0a9e2073a47ca93e2af65a3a2b82a5008feca000000000000000000000000ec6547058594ba4842a5f4e5a6221b32e72b3be90000000000000000000000008855e1458d167af9499c83ce75474d8129f8e1b20000000000000000000000009da7453486d1dffdcdab93d733c9f06d428ff4c300000000000000000000000087ca488d23a4d0b261a7220e533beb0a84bffa4800000000000000000000000030a3509fbd34d30c8581069f8cdd6d9db65eda530000000000000000000000002316b36d718353dd2334965337a8fcb21f6c4be500000000000000000000000068dcd0743ea5dea3f03c6e49bbfb1eb72ab050a3000000000000000000000000576ac8189481f675a179ea96eaa8d8d03c490de30000000000000000000000009f7610115501abd147d1d82ce92cea2a716690ed00000000000000000000000012d964f702db7b301765c0066a04ec4fbdb59e3a000000000000000000000000ef9eff0479d57032cda12e0d6bbedb55b9b8c9e700000000000000000000000094446fc7b099ac0f2177ae40eb1eb4d11bae6536000000000000000000000000584313319d0bfead2a9d98a7154f5dcb5a62887f00000000000000000000000015d9b63779a1ad283f4b8f2391d7182d3fe9620700000000000000000000000054f54ac68d92aaef256550957b4d8f9d5fd5960400000000000000000000000098dcb5545e9c9d4c16e5c1831fd22d4276a2acf9000000000000000000000000805b3967aab7fead5b4a58faa391e8d420ef9d2c0000000000000000000000003ac1183d993177f33c5c2bbc7b0322f1e6bb8dd3000000000000000000000000b3cd06b4044778c38ba3e7ee67cda505e2e1a64700000000000000000000000081aa6141923ea42fcaa763d9857418224d9b025a000000000000000000000000bdef62bc8ec76737ea43ee03ab80928449f003030000000000000000000000000d97b6ddcb5bae41a89c1705f08930c9d629180f0000000000000000000000006c78f46f32c35c1e86b4b303d1bc2c1ad570e9fc0000000000000000000000007a25af1bfe363cce64ba7b52b5170bbb5926d48800000000000000000000000024e219ebf46093dc5c5a748cb20b8c83e86bf09d0000000000000000000000008c46c00fc633e1e73254bec5a7364235976adbf5000000000000000000000000910b48c25afc5b2a998458b62d467d482eca74af00000000000000000000000022322380ba90c486320cec43620d9dc540004586000000000000000000000000d78b76a77efa46282cbdd3c2a2960aadc44c594e000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000008ce2a1eb5a27cd5f41d0000000000000000000000000000000000000000000000da1db16da2e0698d220000000000000000000000000000000000000000000000271ab12d5416d5360000000000000000000000000000000000000000000000001f8fe5aebf3140e2f800000000000000000000000000000000000000000000001c6257dea1782048a200000000000000000000000000000000000000000000001babfdc24af844e600000000000000000000000000000000000000000000000018cc8f83ef1089652900000000000000000000000000000000000000000000000fc9246d2d76503d060000000000000000000000000000000000000000000000081984cfefe7ff0080000000000000000000000000000000000000000000000003beb0d02af39304c60000000000000000000000000000000000000000000000017284bd386b12230f00000000000000000000000000000000000000000000000165abd032196b4d0000000000000000000000000000000000000000000000000114a15c7386f31d00000000000000000000000000000000000000000000000000fe1af1e4cbab2000000000000000000000000000000000000000000000000000eca5f675e57f8fc0000000000000000000000000000000000000000000000000d060b78ff931ec6e000000000000000000000000000000000000000000000000af6b961824ec63c6000000000000000000000000000000000000000000000000a2f81b96e3944a0400000000000000000000000000000000000000000000000079709348d3541d030000000000000000000000000000000000000000000000006fe915466cc000000000000000000000000000000000000000000000000000006d71df31362a91000000000000000000000000000000000000000000000000006d3dab8eb5eea8c90000000000000000000000000000000000000000000000006adbe534228200000000000000000000000000000000000000000000000000006124fee993bc00000000000000000000000000000000000000000000000000005ffa1b1f86c7e00000000000000000000000000000000000000000000000000058eb71c84f26c0000000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000001f49ae4337780be00000000000000000000000000000000000000000000000001ee28c35a4823b80000000000000000000000000000000000000000000000000194393fcdb4b500000000000000000000000000000000000000000000000000009d3c07f34695e00
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103145760003560e01c806384546c27116101a7578063c2ceb95f116100ee578063e9c0a26711610097578063fad8b32a11610071578063fad8b32a146106a4578063fc673c4f146106b7578063fe9d9303146106ca57610314565b8063e9c0a2671461066b578063f2fde38b1461067e578063f573e99f1461069157610314565b8063d95b6371116100c8578063d95b63711461062c578063daed5e5b1461063f578063dd62ed3e1461065857610314565b8063c2ceb95f146105ec578063c2eeeebd146105ff578063ccfb92161461060757610314565b80639bd9bbc611610150578063b3b7fdaa1161012a578063b3b7fdaa146105a1578063b78b52df146105c6578063c0181017146105d957610314565b80639bd9bbc614610568578063a68f40511461057b578063a9059cbb1461058e57610314565b80638da5cb5b116101815780638da5cb5b14610545578063959b8c3f1461054d57806395d89b411461056057610314565b806384546c271461051757806386d1a69f1461052a5780638c2a993e1461053257610314565b80633133e3ab1161026b57806362ad1b8311610214578063715018a6116101ee578063715018a6146104db578063735c8c76146104e357806374f4f5471461050457610314565b806362ad1b83146104a057806370a08231146104b357806370db4eb2146104c657610314565b806354a5dc2d1161024557806354a5dc2d1461046f578063556f0dc7146104905780635c975abb1461049857610314565b80633133e3ab14610422578063313ce567146104475780633af3e4511461045c57610314565b80630fbc4b15116102cd57806320f1dbbc116102a757806320f1dbbc146103dc57806323b872dd146103ef578063311406641461040257610314565b80630fbc4b1514610394578063150b7a02146103a757806318160ddd146103c757610314565b806306e48538116102fe57806306e485381461035757806306fdde031461036c578063095ea7b31461038157610314565b806223de291461031957806301ffc9a71461032e575b600080fd5b61032c61032736600461420f565b6106dd565b005b61034161033c366004614537565b6107cc565b60405161034e9190614aa7565b60405180910390f35b61035f610807565b60405161034e9190614998565b61037461086a565b60405161034e9190614adf565b61034161038f366004614424565b6108f4565b61032c6103a23660046146b4565b610918565b6103ba6103b53660046142fd565b610ace565b60405161034e9190614ab2565b6103cf610af7565b60405161034e91906159c7565b61032c6103ea366004614517565b610afd565b6103416103fd3660046142bd565b610b59565b610415610410366004614155565b610c98565b60405161034e91906149e5565b610435610430366004614155565b610fe0565b60405161034e96959493929190615a7e565b61044f611028565b60405161034e9190615b48565b61032c61046a366004614424565b61102d565b610477611221565b60405161034e9d9c9b9a99989796959493929190615aeb565b6103cf611257565b61034161125c565b61032c6104ae366004614367565b61127d565b6103cf6104c1366004614155565b6112c0565b6104ce6112db565b60405161034e9190614765565b61032c6112ea565b6104f66104f1366004614155565b61138b565b60405161034e929190615a3f565b61032c610512366004614424565b6114bd565b6103cf6105253660046143f7565b611536565b61032c6115cf565b61032c610540366004614424565b6117c0565b6104ce611833565b61032c61055b366004614155565b611842565b61037461196f565b61032c61057636600461444f565b6119d0565b61032c6105893660046145ea565b6119fa565b61034161059c366004614424565b611f49565b6105b46105af366004614155565b612003565b60405161034e96959493929190615a4d565b61032c6105d4366004614424565b612044565b61032c6105e7366004614424565b61232d565b61032c6105fa3660046142bd565b612481565b6104ce612683565b61061a610615366004614424565b612692565b60405161034e96959493929190615a05565b61034161063a36600461418d565b612778565b61064761281a565b60405161034e9594939291906148f4565b6103cf61066636600461418d565b612845565b61032c6106793660046141c5565b612870565b61032c61068c366004614155565b6129d2565b61032c61069f366004614647565b612aab565b61032c6106b2366004614155565b612eff565b61032c6106c53660046144a6565b61302c565b61032c6106d8366004614602565b613065565b600085116107065760405162461bcd60e51b81526004016106fd906154ca565b60405180910390fd5b600c546001600160a01b031661071a6130b6565b6001600160a01b0316146107405760405162461bcd60e51b81526004016106fd90615935565b6001600160a01b03881630146107685760405162461bcd60e51b81526004016106fd906155e1565b6001600160a01b03861630146107905760405162461bcd60e51b81526004016106fd90615410565b856001600160a01b0316876001600160a01b031614156107c25760405162461bcd60e51b81526004016106fd9061563e565b5050505050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152601c602052604090205460ff165b919050565b6060600480548060200260200160405190810160405280929190818152602001828054801561085f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610841575b505050505090505b90565b60028054604080516020601f600019610100600187161502019094168590049384018190048102820181019092528281526060939092909183018282801561085f5780601f106108c85761010080835404028352916020019161085f565b820191906000526020600020905b8154815290600101906020018083116108d657509395945050505050565b6000806108ff6130b6565b905061090c8185856130ba565b60019150505b92915050565b6109206130b6565b6001600160a01b0316610931611833565b6001600160a01b0316146109575760405162461bcd60e51b81526004016106fd90615358565b60008a1180156109695750600f548a14155b1561097457600f8a90555b60008911801561098657506010548914155b156109915760108990555b6000881180156109a357506011548814155b156109ae5760118890555b6000871180156109c057506012548714155b156109cb5760128790555b6000861180156109dd57506013548614155b156109e85760138690555b6000851180156109fa57506014548514155b15610a055760148590555b600084118015610a1757506015548414155b15610a225760158490555b600083118015610a3457506016548314155b15610a3f5760168390555b600082118015610a5157506017548214155b15610a5c5760178290555b600081118015610a6e57506018548114155b15610a795760188190555b7ff50e3d54552661ab9fcd2009f7358e5404ec49741cc8182e75e2df2ac316ba488a8a8a8a8a8a8a8a8a8a604051610aba9a99989796959493929190615aa6565b60405180910390a150505050505050505050565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b60015490565b610b056130b6565b6001600160a01b0316610b16611833565b6001600160a01b031614610b3c5760405162461bcd60e51b81526004016106fd90615358565b80610b4e57610b4961316e565b610b56565b610b566131fa565b50565b60006001600160a01b038316610b815760405162461bcd60e51b81526004016106fd9061546d565b6001600160a01b038416610ba75760405162461bcd60e51b81526004016106fd906157b2565b6000610bb16130b6565b9050610bdf818686866040518060200160405280600081525060405180602001604052806000815250613287565b610c0b8186868660405180602001604052806000815250604051806020016040528060008152506133e8565b610c5f8582610c5a86604051806060016040528060298152602001615c3f602991396001600160a01b03808c166000908152600860209081526040808320938b16835292905220549190613514565b6130ba565b610c8d8186868660405180602001604052806000815250604051806020016040528060008152506000613540565b506001949350505050565b6001600160a01b0381166000908152601f6020526040902054606090818167ffffffffffffffff81118015610ccc57600080fd5b50604051908082528060200260200182016040528015610d0657816020015b610cf3613ef9565b815260200190600190039081610ceb5790505b50905060005b82811015610fd8576001600160a01b0385166000908152601f60205260409020805482908110610d3857fe5b906000526020600020906006020160000154828281518110610d5657fe5b602090810291909101810151919091526001600160a01b0386166000908152601f90915260409020805482908110610d8a57fe5b906000526020600020906006020160010160009054906101000a900460ff16828281518110610db557fe5b6020026020010151602001906002811115610dcc57fe5b90816002811115610dd957fe5b9052506001600160a01b0385166000908152601f60205260409020805482908110610e0057fe5b906000526020600020906006020160020154828281518110610e1e57fe5b60200260200101516040018181525050601f6000866001600160a01b03166001600160a01b031681526020019081526020016000208181548110610e5e57fe5b906000526020600020906006020160030154828281518110610e7c57fe5b60200260200101516060018181525050601f6000866001600160a01b03166001600160a01b031681526020019081526020016000208181548110610ebc57fe5b906000526020600020906006020160040154828281518110610eda57fe5b60200260200101516080018181525050601f6000866001600160a01b03166001600160a01b031681526020019081526020016000208181548110610f1a57fe5b6000918252602091829020600560069092020101805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015610fb05780601f10610f8557610100808354040283529160200191610fb0565b820191906000526020600020905b815481529060010190602001808311610f9357829003601f168201915b5050505050828281518110610fc157fe5b602090810291909101015160a00152600101610d0c565b509392505050565b43600080808080610ff0876112c0565b9450610ffc87436136cf565b935061100787613835565b925061101287613946565b915061101d876139a4565b905091939550919395565b601290565b61103561125c565b156110525760405162461bcd60e51b81526004016106fd906150be565b6002601d5414156110755760405162461bcd60e51b81526004016106fd9061580f565b6002601d558160016001600160a01b0382166000908152601e60205260409020546110b25760405162461bcd60e51b81526004016106fd9061587b565b438311156110d25760405162461bcd60e51b81526004016106fd90614f70565b60006110df856001611536565b1180156110f6575060006110f4856000611536565b115b6111125760405162461bcd60e51b81526004016106fd9061520c565b6001600160a01b0384166000908152601e602052604090206003810154841161114d5760405162461bcd60e51b81526004016106fd90615527565b6111556130b6565b60048201546001600160a01b039081169116146111845760405162461bcd60e51b81526004016106fd90614af2565b600061119086866136cf565b60038301869055905060006111a587836139cf565b90506111b1828261308b565b60018401805490910190556111c6828261308b565b601a805490910190557f1bb11a48efce84136dfd03628800501f9fa4d84e04f56c3ab6369b9c71b629226111f86130b6565b88848460405161120b94939291906147de565b60405180910390a150506001601d555050505050565b601b54601954601a54601254601354601054601154601454600f54601554601654601754601854909192939495969798999a9b9c565b600190565b60095474010000000000000000000000000000000000000000900460ff1690565b61128e6112886130b6565b86612778565b6112aa5760405162461bcd60e51b81526004016106fd9061569b565b6112b985858585856001613a2f565b5050505050565b6001600160a01b031660009081526020819052604090205490565b600a546001600160a01b031681565b6112f26130b6565b6001600160a01b0316611303611833565b6001600160a01b0316146113295760405162461bcd60e51b81526004016106fd90615358565b6009546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600980547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6001600160a01b0381166000908152601f60205260408120548190818080805b848110156114b3576001600160a01b0388166000908152601f602052604090208054829081106113d757fe5b9060005260206000209060060201600401549250601f6000896001600160a01b03166001600160a01b03168152602001908152602001600020818154811061141b57fe5b90600052602060002090600602016003015491508260001415611441576000935061144e565b8242111561144e57600193505b836114ab576001600160a01b0388166000908152601f60205260409020805461149d91908390811061147c57fe5b9060005260206000209060060201600201548861308b90919063ffffffff16565b9650818610156114ab578195505b6001016113ab565b5050505050915091565b600a546001600160a01b031633146114e75760405162461bcd60e51b81526004016106fd90614c40565b6040805160208101918290526000808252369290916115309186918691869086908190838280828437600092018290525060408051602081019091529081529250613ab2915050565b50505050565b6001600160a01b0382166000908152601f6020526040812054815b818110156115c75783600281111561156557fe5b6001600160a01b0386166000908152601f6020526040902080548390811061158957fe5b600091825260209091206001600690920201015460ff1660028111156115ab57fe5b14156115bf576115bc83600161308b565b92505b600101611551565b505092915050565b6002601d5414156115f25760405162461bcd60e51b81526004016106fd9061580f565b6002601d556115ff6130b6565b6001600160a01b0381166000908152601e6020526040902060020154431480159061164557506001600160a01b0381166000908152601e60205260409020600301544314155b6116615760405162461bcd60e51b81526004016106fd90614d8e565b6116696130b6565b60016001600160a01b0382166000908152601e60205260409020546116a05760405162461bcd60e51b81526004016106fd9061587b565b6000601e60006116ae6130b6565b6001600160a01b031681526020810191909152604001600090812080549181556019549092506116de9082613c0b565b6019556001820154601a546116f291613c0b565b601a55601b54611703906001613c0b565b601b557f82e416ba72d10e709b5de7ac16f5f49ff1d94f22d55bf582d353d3c313a1e8dd61172f6130b6565b60018401546040516117439291859161489d565b60405180910390a1600c546001600160a01b0316639bd9bbc66117646130b6565b836040518363ffffffff1660e01b8152600401611782929190614875565b600060405180830381600087803b15801561179c57600080fd5b505af11580156117b0573d6000803e3d6000fd5b50506001601d5550505050505050565b600a546001600160a01b031633146117ea5760405162461bcd60e51b81526004016106fd90614c40565b6040805160208101918290526000808252369290916115309186918691869086908190838280828437600092018290525060408051602081019091529081529250613c33915050565b6009546001600160a01b031690565b806001600160a01b03166118546130b6565b6001600160a01b0316141561187b5760405162461bcd60e51b81526004016106fd90614e7f565b6001600160a01b03811660009081526005602052604090205460ff16156118de57600760006118a86130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff19169055611925565b6001600660006118ec6130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b61192d6130b6565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561085f5780601f106108c85761010080835404028352916020019161085f565b6119f56119db6130b6565b848484604051806020016040528060008152506001613a2f565b505050565b6002601d541415611a1d5760405162461bcd60e51b81526004016106fd9061580f565b6002601d55611a2a6130b6565b6000611a358261138b565b91505043811415611a585760405162461bcd60e51b81526004016106fd90614cd4565b6000601e6000611a666130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000209050806005015460001415611aad5760405162461bcd60e51b81526004016106fd906151af565b611ab5613ef9565b601f6000611ac16130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110611aec57fe5b90600052602060002090600602016040518060c0016040529081600082015481526020016001820160009054906101000a900460ff166002811115611b2d57fe5b6002811115611b3857fe5b8152602001600282015481526020016003820154815260200160048201548152602001600582018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611bf35780601f10611bc857610100808354040283529160200191611bf3565b820191906000526020600020905b815481529060010190602001808311611bd657829003601f168201915b5050509190925250505060208101519091506000611c1082613d65565b835160155486549293509091118015611c3a57506002611c38611c316130b6565b6000611536565b105b8015611c5157506000836002811115611c4f57fe5b145b15611c6e5760405162461bcd60e51b81526004016106fd90614c77565b6016548554118015611c9157506002611c8f611c886130b6565b6001611536565b105b8015611ca857506001836002811115611ca657fe5b145b15611cc55760405162461bcd60e51b81526004016106fd90614edc565b601f6000611cd16130b6565b6001600160a01b03166001600160a01b03168152602001908152602001600020611d226001601f6000611d026130b6565b6001600160a01b0316815260208101919091526040016000205490613c0b565b81548110611d2c57fe5b9060005260206000209060060201601f6000611d466130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000208981548110611d7157fe5b600091825260209091208254600690920201908155600180830154818301805460ff90921692909160ff191690836002811115611daa57fe5b021790555060028201548160020155600382015481600301556004820154816004015560058201816005019080546001816001161561010002031660029004611df4929190613f30565b50905050601f6000611e046130b6565b6001600160a01b03166001600160a01b03168152602001908152602001600020805480611e2d57fe5b60008281526020812060066000199093019283020181815560018101805460ff1916905560028101829055600381018290556004810182905590611e746005830182613fb5565b505090556005850154611e88906001613c0b565b60058601557f87aef2e82b62c3909dc67b9b479f5738d0de8fe16d58078401cf360e64563390611eb66130b6565b438386604051611ec994939291906148be565b60405180910390a1816001600160a01b03166342842e0e30611ee96130b6565b846040518463ffffffff1660e01b8152600401611f0893929190614779565b600060405180830381600087803b158015611f2257600080fd5b505af1158015611f36573d6000803e3d6000fd5b50506001601d5550505050505050505050565b60006001600160a01b038316611f715760405162461bcd60e51b81526004016106fd9061546d565b6000611f7b6130b6565b9050611fa9818286866040518060200160405280600081525060405180602001604052806000815250613287565b611fd58182868660405180602001604052806000815250604051806020016040528060008152506133e8565b61090c8182868660405180602001604052806000815250604051806020016040528060008152506000613540565b601e6020526000908152604090208054600182015460028301546003840154600485015460059095015493949293919290916001600160a01b039091169086565b61204c61125c565b156120695760405162461bcd60e51b81526004016106fd906150be565b6002601d54141561208c5760405162461bcd60e51b81526004016106fd9061580f565b6002601d556120996130b6565b6001600160a01b0381166000908152601e602052604090206002015443148015906120df57506001600160a01b0381166000908152601e60205260409020600301544314155b6120fb5760405162461bcd60e51b81526004016106fd90614d8e565b6000601e60006121096130b6565b6001600160a01b031681526020810191909152604001600020601554815491925090612135908561308b565b11801561214c5750600161214a856000611536565b105b156121695760405162461bcd60e51b81526004016106fd90615004565b6016548154612178908561308b565b11801561218f5750600161218d856001611536565b105b156121ac5760405162461bcd60e51b81526004016106fd90615755565b805461221a578281554360028201556004810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386161790556001810154601a546122019161308b565b601a55601b5461221290600161308b565b601b55612258565b6000612227856000611536565b1115612240578054612239908461308b565b8155612258565b60405162461bcd60e51b81526004016106fd906156f8565b601954612265908461308b565b6019554360038201557f39d12b1a9bde2a7e34304e5a951514ac2a0679475d0a8b35bedf400ebe8b506d6122976130b6565b60018301546040516122af9291439189918991614841565b60405180910390a1600c546001600160a01b03166362ad1b836122d06130b6565b30866040518463ffffffff1660e01b81526004016122f09392919061479d565b600060405180830381600087803b15801561230a57600080fd5b505af115801561231e573d6000803e3d6000fd5b50506001601d55505050505050565b61233561125c565b156123525760405162461bcd60e51b81526004016106fd906150be565b6002601d5414156123755760405162461bcd60e51b81526004016106fd9061580f565b6002601d558160016001600160a01b0382166000908152601e60205260409020546123b25760405162461bcd60e51b81526004016106fd9061587b565b6001600160a01b0384166000908152601e60205260408120906123d586866139cf565b90506123e1858261308b565b60018301805490910190556123f6858261308b565b601a805490910190557f1bb11a48efce84136dfd03628800501f9fa4d84e04f56c3ab6369b9c71b629226124286130b6565b87878460405161243b94939291906147de565b60405180910390a161247461244e6130b6565b866040518060200160405280600081525060405180602001604052806000815250613ab2565b50506001601d5550505050565b61248961125c565b156124a65760405162461bcd60e51b81526004016106fd906150be565b6002601d5414156124c95760405162461bcd60e51b81526004016106fd9061580f565b6002601d8190556001600160a01b0384166000908152601e6020526040902001548390431480159061251657506001600160a01b0381166000908152601e60205260409020600301544314155b6125325760405162461bcd60e51b81526004016106fd90614d8e565b8360016001600160a01b0382166000908152601e602052604090205461256a5760405162461bcd60e51b81526004016106fd9061587b565b4384111561258a5760405162461bcd60e51b81526004016106fd90615584565b6001600160a01b0386166000908152601e60205260409020600381015485116125c55760405162461bcd60e51b81526004016106fd90615152565b6125cd6130b6565b60048201546001600160a01b039081169116146125fc5760405162461bcd60e51b81526004016106fd9061529e565b600061260888876136cf565b6003830187905590507fb757d83b4531499e2d84501fbd6edd8467f4aa78b20051773e245c703fb891db61263a6130b6565b438a8a8a8660405161265196959493929190614807565b60405180910390a161231e87826040518060200160405280600081525060405180602001604052806000815250613c33565b600b546001600160a01b031681565b601f60205281600052604060002081815481106126ab57fe5b6000918252602091829020600691909102018054600180830154600280850154600386015460048701546005880180546040805161010099831615999099026000190190911695909504601f81018b90048b0288018b01909552848752969a5060ff9094169850909690959294929392919083018282801561276e5780601f106127435761010080835404028352916020019161276e565b820191906000526020600020905b81548152906001019060200180831161275157829003601f168201915b5050505050905086565b6000816001600160a01b0316836001600160a01b031614806127e357506001600160a01b03831660009081526005602052604090205460ff1680156127e357506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b8061281357506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b600d54600e54600b54600a54600c546001600160a01b03948516959385169492831693918316921690565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b6128786130b6565b6001600160a01b0316612889611833565b6001600160a01b0316146128af5760405162461bcd60e51b81526004016106fd90615358565b6001600160a01b038316158015906128d55750600c546001600160a01b03848116911614155b1561290e57600c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385161790555b6001600160a01b038216158015906129345750600d546001600160a01b03838116911614155b1561296d57600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0384161790555b6001600160a01b038116158015906129935750600e546001600160a01b03828116911614155b156119f557600e80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055505050565b6129da6130b6565b6001600160a01b03166129eb611833565b6001600160a01b031614612a115760405162461bcd60e51b81526004016106fd90615358565b6001600160a01b038116612a375760405162461bcd60e51b81526004016106fd90614d31565b6009546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600980547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b612ab361125c565b15612ad05760405162461bcd60e51b81526004016106fd906150be565b6002601d541415612af35760405162461bcd60e51b81526004016106fd9061580f565b6002601d55612b006130b6565b6000612b0b8261138b565b91505043811415612b2e5760405162461bcd60e51b81526004016106fd90614cd4565b612b366130b6565b60016001600160a01b0382166000908152601e6020526040902054612b6d5760405162461bcd60e51b81526004016106fd9061587b565b6000601e6000612b7b6130b6565b6001600160a01b03166001600160a01b0316815260200190815260200160002090506000612ba887613d65565b6005830154909150612bbb90600161308b565b60058301556040517f939f1eb6000000000000000000000000000000000000000000000000000000008152600090819081906001600160a01b0385169063939f1eb690612c0c908e906004016159c7565b60c06040518083038186803b158015612c2457600080fd5b505afa158015612c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5c919061466b565b50505050915091506060846001600160a01b031663c87b56dd8d6040518263ffffffff1660e01b8152600401612c9291906159c7565b60006040518083038186803b158015612caa57600080fd5b505afa158015612cbe573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612d049190810190614577565b905060008b6002811115612d1457fe5b1415612d3857612d31612710612d2b846064613d9d565b9061308b565b9350612d57565b612d54611388612d2b6004612d4e866064613d9d565b90613dd7565b93505b601f6000612d636130b6565b6001600160a01b03166001600160a01b031681526020019081526020016000206040518060c001604052808e81526020018d6002811115612da057fe5b815260208082018890524360408301526060820187905260809091018490528254600181810185556000948552938290208351600690920201908155908201518184018054939492939192909160ff191690836002811115612dfe57fe5b021790555060408201516002820155606082015160038201556080820151600482015560a08201518051612e3c916005840191602090910190613ff9565b5050507f36d977532e3d06244e7254e8b5afc1f6ce2555c1200b4d483ba135c239d1148d612e686130b6565b438e8e604051612e7b94939291906148be565b60405180910390a1846001600160a01b03166342842e0e612e9a6130b6565b308f6040518463ffffffff1660e01b8152600401612eba93929190614779565b600060405180830381600087803b158015612ed457600080fd5b505af1158015612ee8573d6000803e3d6000fd5b50506001601d555050505050505050505050505050565b612f076130b6565b6001600160a01b0316816001600160a01b03161415612f385760405162461bcd60e51b81526004016106fd90615061565b6001600160a01b03811660009081526005602052604090205460ff1615612fa457600160076000612f676130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055612fe2565b60066000612fb06130b6565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b612fea6130b6565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b61303d6130376130b6565b85612778565b6130595760405162461bcd60e51b81526004016106fd9061569b565b61153084848484613ab2565b6130876130706130b6565b838360405180602001604052806000815250613ab2565b5050565b6000828201838110156128135760405162461bcd60e51b81526004016106fd90614deb565b3b151590565b3390565b6001600160a01b0383166130e05760405162461bcd60e51b81526004016106fd90614b86565b6001600160a01b0382166131065760405162461bcd60e51b81526004016106fd906158d8565b6001600160a01b0380841660008181526008602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906131619085906159c7565b60405180910390a3505050565b61317661125c565b6131925760405162461bcd60e51b81526004016106fd90614b4f565b600980547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6131e36130b6565b6040516131f09190614765565b60405180910390a1565b61320261125c565b1561321f5760405162461bcd60e51b81526004016106fd906150be565b600980547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586131e36130b6565b6040517faabbb8ca000000000000000000000000000000000000000000000000000000008152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906132fc9089907f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe8959060040161497f565b60206040518083038186803b15801561331457600080fd5b505afa158015613328573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061334c9190614171565b90506001600160a01b038116156133df576040517f75ab97820000000000000000000000000000000000000000000000000000000081526001600160a01b038216906375ab9782906133ac908a908a908a908a908a908a90600401614926565b600060405180830381600087803b1580156133c657600080fd5b505af11580156133da573d6000803e3d6000fd5b505050505b50505050505050565b6133f486868686611530565b61343183604051806060016040528060278152602001615c18602791396001600160a01b0388166000908152602081905260409020549190613514565b6001600160a01b038087166000908152602081905260408082209390935590861681522054613460908461308b565b6001600160a01b0380861660008181526020819052604090819020939093559151878216918916907f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987906134b9908890889088906159d0565b60405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161350491906159c7565b60405180910390a3505050505050565b600081848411156135385760405162461bcd60e51b81526004016106fd9190614adf565b505050900390565b6040517faabbb8ca000000000000000000000000000000000000000000000000000000008152600090731820a4b7618bde71dce8cdc73aab6c95905fad249063aabbb8ca906135b59089907fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b9060040161497f565b60206040518083038186803b1580156135cd57600080fd5b505afa1580156135e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136059190614171565b90506001600160a01b0381161561369a576040517e23de290000000000000000000000000000000000000000000000000000000081526001600160a01b038216906223de2990613663908b908b908b908b908b908b90600401614926565b600060405180830381600087803b15801561367d57600080fd5b505af1158015613691573d6000803e3d6000fd5b505050506107c2565b81156107c2576136b2866001600160a01b03166130b0565b156107c25760405162461bcd60e51b81526004016106fd9061538d565b60006136d9614067565b506001600160a01b038084166000908152601e6020908152604091829020825160c0810184528154808252600183015493820193909352600282015493810193909352600381015460608401526004810154909316608083015260059092015460a0820152908061374f57600092505050610912565b4384111561376f5760405162461bcd60e51b81526004016106fd9061596a565b83826060015111156137935760405162461bcd60e51b81526004016106fd906150f5565b60008060016137a3886000611536565b10156137c65760105460608501516137ba9161308b565b915060105490506137df565b60115460608501516137d79161308b565b915060115490505b818610156137fa5760608401516137f7908790613c0b565b90505b60006138068483613d9d565b90506138296305f5e100612d4e612710612d4e856138238e6139a4565b90613d9d565b98975050505050505050565b600061383f614067565b506001600160a01b038083166000908152601e60209081526040808320815160c0810183528154808252600183015494820194909452600282015492810192909252600381015460608301526004810154909416608082015260059093015460a084015281906138b6576127109350505050610802565b60a0830151156138d3576138c98561138b565b90925090506138da565b5060408201515b6013546138e890839061308b565b91506014548211156138fa5760145491505b600061390883612710613c0b565b9050600061392f612710612d2b600f54612d4e866138238943613c0b90919063ffffffff16565b905061393b8482613e09565b979650505050505050565b60008061395283613e1f565b9050600061395e613ebf565b905080158061396b575081155b1561397c5761271092505050610802565b60125461399c90613997612710612d2b85612d4e8884613d9d565b613e09565b949350505050565b6000806139b083613835565b905060006139bd84613946565b905061399c612710612d4e8385613d9d565b6000806139dd846000611536565b1115613a01576139fe612710612d4e84601754613d9d90919063ffffffff16565b90505b6000613a0e846001611536565b111561091257612813612710612d4e84601854613d9d90919063ffffffff16565b6001600160a01b038616613a555760405162461bcd60e51b81526004016106fd90614be3565b6001600160a01b038516613a7b5760405162461bcd60e51b81526004016106fd90615846565b6000613a856130b6565b9050613a95818888888888613287565b613aa38188888888886133e8565b6133df81888888888888613540565b6001600160a01b038416613ad85760405162461bcd60e51b81526004016106fd90614e22565b6000613ae26130b6565b9050613af381866000878787613287565b613b008186600087611530565b613b3d84604051806060016040528060238152602001615c68602391396001600160a01b0388166000908152602081905260409020549190613514565b6001600160a01b038616600090815260208190526040902055600154613b639085613c0b565b600181905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051613bb0939291906159d0565b60405180910390a360006001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051613bfc91906159c7565b60405180910390a35050505050565b600082821115613c2d5760405162461bcd60e51b81526004016106fd90614f39565b50900390565b6001600160a01b038416613c595760405162461bcd60e51b81526004016106fd90615269565b6000613c636130b6565b9050613c728160008787611530565b600154613c7f908561308b565b6001556001600160a01b038516600090815260208190526040902054613ca5908561308b565b6001600160a01b038616600090815260208190526040812091909155613cd2908290878787876001613540565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051613d19939291906159d0565b60405180910390a3846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051613bfc91906159c7565b600080826002811115613d7457fe5b1415613d8c5750600d546001600160a01b0316610802565b5050600e546001600160a01b031690565b600082613dac57506000610912565b82820282848281613db957fe5b04146128135760405162461bcd60e51b81526004016106fd906152fb565b6000808211613df85760405162461bcd60e51b81526004016106fd90614fcd565b818381613e0157fe5b049392505050565b6000818310613e185781612813565b5090919050565b6000613e29614067565b506001600160a01b038083166000908152601e6020908152604091829020825160c0810184528154808252600183015493820193909352600282015493810193909352600381015460608401526004810154909316608083015260059092015460a08201529080613e9f57600092505050610802565b61399c81612d4e6402540be4008560200151613d9d90919063ffffffff16565b600060195460001415613ed457506000610867565b613ef4601954612d4e6402540be400601a54613d9d90919063ffffffff16565b905090565b6040805160c08101909152600080825260208201908152602001600081526020016000815260200160008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613f695780548555613fa5565b82800160010185558215613fa557600052602060002091601f016020900482015b82811115613fa5578254825591600101919060010190613f8a565b50613fb19291506140a6565b5090565b50805460018160011615610100020316600290046000825580601f10613fdb5750610b56565b601f016020900490600052602060002090810190610b5691906140a6565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061403a57805160ff1916838001178555613fa5565b82800160010185558215613fa5579182015b82811115613fa557825182559160200191906001019061404c565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b5b80821115613fb157600081556001016140a7565b60008083601f8401126140cc578182fd5b50813567ffffffffffffffff8111156140e3578182fd5b6020830191508360208285010111156140fb57600080fd5b9250929050565b600082601f830112614112578081fd5b813561412561412082615b7d565b615b56565b915080825283602082850101111561413c57600080fd5b8060208401602084013760009082016020015292915050565b600060208284031215614166578081fd5b813561281381615bf5565b600060208284031215614182578081fd5b815161281381615bf5565b6000806040838503121561419f578081fd5b82356141aa81615bf5565b915060208301356141ba81615bf5565b809150509250929050565b6000806000606084860312156141d9578081fd5b83356141e481615bf5565b925060208401356141f481615bf5565b9150604084013561420481615bf5565b809150509250925092565b60008060008060008060008060c0898b03121561422a578384fd5b883561423581615bf5565b9750602089013561424581615bf5565b9650604089013561425581615bf5565b955060608901359450608089013567ffffffffffffffff80821115614278578586fd5b6142848c838d016140bb565b909650945060a08b013591508082111561429c578384fd5b506142a98b828c016140bb565b999c989b5096995094979396929594505050565b6000806000606084860312156142d1578283fd5b83356142dc81615bf5565b925060208401356142ec81615bf5565b929592945050506040919091013590565b60008060008060808587031215614312578384fd5b843561431d81615bf5565b9350602085013561432d81615bf5565b925060408501359150606085013567ffffffffffffffff81111561434f578182fd5b61435b87828801614102565b91505092959194509250565b600080600080600060a0868803121561437e578081fd5b853561438981615bf5565b9450602086013561439981615bf5565b935060408601359250606086013567ffffffffffffffff808211156143bc578283fd5b6143c889838a01614102565b935060808801359150808211156143dd578283fd5b506143ea88828901614102565b9150509295509295909350565b60008060408385031215614409578182fd5b823561441481615bf5565b915060208301356141ba81615c0a565b60008060408385031215614436578081fd5b823561444181615bf5565b946020939093013593505050565b600080600060608486031215614463578081fd5b833561446e81615bf5565b925060208401359150604084013567ffffffffffffffff811115614490578182fd5b61449c86828701614102565b9150509250925092565b600080600080608085870312156144bb578182fd5b84356144c681615bf5565b935060208501359250604085013567ffffffffffffffff808211156144e9578384fd5b6144f588838901614102565b9350606087013591508082111561450a578283fd5b5061435b87828801614102565b600060208284031215614528578081fd5b81358015158114612813578182fd5b600060208284031215614548578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114612813578182fd5b600060208284031215614588578081fd5b815167ffffffffffffffff81111561459e578182fd5b8201601f810184136145ae578182fd5b80516145bc61412082615b7d565b8181528560208385010111156145d0578384fd5b6145e1826020830160208601615bbf565b95945050505050565b6000602082840312156145fb578081fd5b5035919050565b60008060408385031215614614578182fd5b82359150602083013567ffffffffffffffff811115614631578182fd5b61463d85828601614102565b9150509250929050565b60008060408385031215614659578182fd5b8235915060208301356141ba81615c0a565b60008060008060008060c08789031215614683578384fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6000806000806000806000806000806101408b8d0312156146d3578384fd5b505088359a60208a01359a5060408a013599606081013599506080810135985060a0810135975060c0810135965060e081013595506101008101359450610120013592509050565b60008151808452614733816020860160208601615bbf565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b039384168152919092166020820152604081019190915260a060608201819052600090820181905260c06080830181905282015260e00190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b0396871681526020810195909552928516604085015293166060830152608082019290925260a081019190915260c00190565b6001600160a01b03958616815260208101949094529190931660408301526060820192909252608081019190915260a00190565b6001600160a01b03929092168252602082015260606040820181905260009082015260800190565b6001600160a01b039390931683526020830191909152604082015260600190565b6001600160a01b03851681526020810184905260408101839052608081016148e583615beb565b82606083015295945050505050565b6001600160a01b0395861681529385166020850152918416604084015283166060830152909116608082015260a00190565b60006001600160a01b038089168352808816602084015280871660408401525084606083015260c0608083015261496060c083018561471b565b82810360a0840152614972818561471b565b9998505050505050505050565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156149d95783516001600160a01b0316835292840192918401916001016149b4565b50909695505050505050565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614a99577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0898403018552815160c08151855288820151614a4d81615beb565b858a01528188015188860152606080830151908601526080808301519086015260a091820151918501819052614a858186018361471b565b968901969450505090860190600101614a09565b509098975050505050505050565b901515815260200190565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b600060208252612813602083018461471b565b60208082526038908201527f596f75206d75737420626520746865206f776e6572206f66207468652066617260408201527f6d20746f206861727665737420616e6420636f6d706f73740000000000000000606082015260800190565b60208082526014908201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604082015260600190565b60208082526025908201527f4552433737373a20617070726f76652066726f6d20746865207a65726f20616460408201527f6472657373000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f4552433737373a2073656e642066726f6d20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252600c908201527f4f4e4c595f474154455741590000000000000000000000000000000000000000604082015260600190565b60208082526034908201527f596f75206e656564206174206c65617374206f6e65206661726d657220746f2060408201527f72756e2061206661726d20746869732073697a65000000000000000000000000606082015260800190565b6020808252603c908201527f596f752063616e206e6f74206571756970206f722072656c656173652061206360408201527f6f6c6c65637469626c6520696e207468652073616d6520626c6f636b00000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b60208082526039908201527f596f752063616e206e6f7420616c6c6f636174652f72656c65617365206f722060408201527f6861727665737420696e207468652073616d6520626c6f636b00000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526022908201527f4552433737373a206275726e2066726f6d20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4552433737373a20617574686f72697a696e672073656c66206173206f70657260408201527f61746f7200000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526037908201527f596f75206e6565642061206661726d657220616e6420612074726163746f722060408201527f746f2072756e2061206661726d20746869732073697a65000000000000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526032908201527f596f752063616e206f6e6c792068617276657374202620636f6d706f7374207560408201527f7020746f2063757272656e7420626c6f636b0000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602b908201527f596f75206e6565642061206661726d657220746f206275696c6420612066617260408201527f6d20746869732073697a65000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f4552433737373a207265766f6b696e672073656c66206173206f70657261746f60408201527f7200000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526010908201527f5061757361626c653a2070617573656400000000000000000000000000000000604082015260600190565b6020808252603f908201527f596f752063616e206f6e6c79207370656369667920626c6f636b73206174206f60408201527f72206168656164206f66206c6173742068617276657374656420626c6f636b00606082015260800190565b60208082526032908201527f596f752063616e206f6e6c792068617276657374206168656164206f66206c6160408201527f73742068617276657374656420626c6f636b0000000000000000000000000000606082015260800190565b60208082526023908201527f596f75206e656564206120636f6c6c65637469626c65206f6e20796f7572206660408201527f61726d0000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f596f75206e6565642061206661726d6572202620612074726163746f72206f6e60408201527f2074686973206661726d00000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f596f75206d75737420626520746865206f776e6572206f66207468652066617260408201527f6d20746f20686172766573740000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252604d908201527f4552433737373a20746f6b656e20726563697069656e7420636f6e747261637460408201527f20686173206e6f20696d706c656d656e74657220666f7220455243373737546f60608201527f6b656e73526563697069656e7400000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f46756e6473206d75737420626520636f6d696e6720696e746f206120434f524e60408201527f20746f6b656e0000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4552433737373a207472616e7366657220746f20746865207a65726f2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f596f75206d7573742072656365697665206120706f736974697665206e756d6260408201527f6572206f6620746f6b656e730000000000000000000000000000000000000000606082015260800190565b6020808252603e908201527f596f752063616e206f6e6c79206861727665737420616e6420636f6d706f737460408201527f206168656164206f66206c6173742068617276657374656420626c6f636b0000606082015260800190565b60208082526028908201527f596f752063616e206f6e6c79206861727665737420757020746f20637572726560408201527f6e7420626c6f636b000000000000000000000000000000000000000000000000606082015260800190565b6020808252602e908201527f4f6e6c7920434f524e20636f6e74726163742063616e2073656e64206974736560408201527f6c66204c414e4420746f6b656e73000000000000000000000000000000000000606082015260800190565b6020808252602e908201527f57687920776f756c6420434f524e20636f6e74726163742073656e6420746f6b60408201527f656e7320746f20697473656c663f000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f60408201527f7220666f7220686f6c6465720000000000000000000000000000000000000000606082015260800190565b60208082526030908201527f596f75206e6565642061206661726d657220746f20696e63726561736520746860408201527f652073697a65206f662061206661726d00000000000000000000000000000000606082015260800190565b60208082526039908201527f596f75206e6565642061206661726d657220616e6420612074726163746f722060408201527f746f206275696c642061206661726d20746869732073697a6500000000000000606082015260800190565b60208082526026908201527f4552433737373a207472616e736665722066726f6d20746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252818101527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604082015260600190565b60208082526034908201527f596f75206e65656420746f20616c6c6f63617465206c616e6420746f2067726f60408201527f772063726f7073206f6e20796f7572206661726d000000000000000000000000606082015260800190565b60208082526023908201527f4552433737373a20617070726f766520746f20746865207a65726f206164647260408201527f6573730000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f596f752063616e206f6e6c79206275696c64206661726d73206f6e204c414e44604082015260600190565b6020808252602a908201527f596f752063616e206f6e6c792063616c63756c61746520757020746f2063757260408201527f72656e7420626c6f636b00000000000000000000000000000000000000000000606082015260800190565b90815260200190565b6000848252606060208301526159e9606083018561471b565b82810360408401526159fb818561471b565b9695505050505050565b6000878252615a1387615beb565b86602083015285604083015284606083015283608083015260c060a083015261382960c083018461471b565b918252602082015260400190565b9586526020860194909452604085019290925260608401526001600160a01b0316608083015260a082015260c00190565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b998a5260208a019890985260408901969096526060880194909452608087019290925260a086015260c085015260e08401526101008301526101208201526101400190565b9c8d5260208d019b909b5260408c019990995260608b019790975260808a019590955260a089019390935260c088019190915260e08701526101008601526101208501526101408401526101608301526101808201526101a00190565b60ff91909116815260200190565b60405181810167ffffffffffffffff81118282101715615b7557600080fd5b604052919050565b600067ffffffffffffffff821115615b93578081fd5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015615bda578181015183820152602001615bc2565b838111156115305750506000910152565b60038110610b5657fe5b6001600160a01b0381168114610b5657600080fd5b60038110610b5657600080fdfe4552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e63654552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a206275726e20616d6f756e7420657863656564732062616c616e6365a2646970667358221220701470c719115ffe67df2ca8cb47a18c42ff499a261d34af4e4f8a81ed76d15564736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003cd1833ce959e087d0ef0cb45ed06bffe60f23ba000000000000000000000000096760f208390250649e3e8763348e783aef55620000000000000000000000003cd1833ce959e087d0ef0cb45ed06bffe60f23ba00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000001f000000000000000000000000ed2c2cdec695be3a4dc421c1a8a6756dc5a927b60000000000000000000000008cd0a9e2073a47ca93e2af65a3a2b82a5008feca000000000000000000000000ec6547058594ba4842a5f4e5a6221b32e72b3be90000000000000000000000008855e1458d167af9499c83ce75474d8129f8e1b20000000000000000000000009da7453486d1dffdcdab93d733c9f06d428ff4c300000000000000000000000087ca488d23a4d0b261a7220e533beb0a84bffa4800000000000000000000000030a3509fbd34d30c8581069f8cdd6d9db65eda530000000000000000000000002316b36d718353dd2334965337a8fcb21f6c4be500000000000000000000000068dcd0743ea5dea3f03c6e49bbfb1eb72ab050a3000000000000000000000000576ac8189481f675a179ea96eaa8d8d03c490de30000000000000000000000009f7610115501abd147d1d82ce92cea2a716690ed00000000000000000000000012d964f702db7b301765c0066a04ec4fbdb59e3a000000000000000000000000ef9eff0479d57032cda12e0d6bbedb55b9b8c9e700000000000000000000000094446fc7b099ac0f2177ae40eb1eb4d11bae6536000000000000000000000000584313319d0bfead2a9d98a7154f5dcb5a62887f00000000000000000000000015d9b63779a1ad283f4b8f2391d7182d3fe9620700000000000000000000000054f54ac68d92aaef256550957b4d8f9d5fd5960400000000000000000000000098dcb5545e9c9d4c16e5c1831fd22d4276a2acf9000000000000000000000000805b3967aab7fead5b4a58faa391e8d420ef9d2c0000000000000000000000003ac1183d993177f33c5c2bbc7b0322f1e6bb8dd3000000000000000000000000b3cd06b4044778c38ba3e7ee67cda505e2e1a64700000000000000000000000081aa6141923ea42fcaa763d9857418224d9b025a000000000000000000000000bdef62bc8ec76737ea43ee03ab80928449f003030000000000000000000000000d97b6ddcb5bae41a89c1705f08930c9d629180f0000000000000000000000006c78f46f32c35c1e86b4b303d1bc2c1ad570e9fc0000000000000000000000007a25af1bfe363cce64ba7b52b5170bbb5926d48800000000000000000000000024e219ebf46093dc5c5a748cb20b8c83e86bf09d0000000000000000000000008c46c00fc633e1e73254bec5a7364235976adbf5000000000000000000000000910b48c25afc5b2a998458b62d467d482eca74af00000000000000000000000022322380ba90c486320cec43620d9dc540004586000000000000000000000000d78b76a77efa46282cbdd3c2a2960aadc44c594e000000000000000000000000000000000000000000000000000000000000001f0000000000000000000000000000000000000000000008ce2a1eb5a27cd5f41d0000000000000000000000000000000000000000000000da1db16da2e0698d220000000000000000000000000000000000000000000000271ab12d5416d5360000000000000000000000000000000000000000000000001f8fe5aebf3140e2f800000000000000000000000000000000000000000000001c6257dea1782048a200000000000000000000000000000000000000000000001babfdc24af844e600000000000000000000000000000000000000000000000018cc8f83ef1089652900000000000000000000000000000000000000000000000fc9246d2d76503d060000000000000000000000000000000000000000000000081984cfefe7ff0080000000000000000000000000000000000000000000000003beb0d02af39304c60000000000000000000000000000000000000000000000017284bd386b12230f00000000000000000000000000000000000000000000000165abd032196b4d0000000000000000000000000000000000000000000000000114a15c7386f31d00000000000000000000000000000000000000000000000000fe1af1e4cbab2000000000000000000000000000000000000000000000000000eca5f675e57f8fc0000000000000000000000000000000000000000000000000d060b78ff931ec6e000000000000000000000000000000000000000000000000af6b961824ec63c6000000000000000000000000000000000000000000000000a2f81b96e3944a0400000000000000000000000000000000000000000000000079709348d3541d030000000000000000000000000000000000000000000000006fe915466cc000000000000000000000000000000000000000000000000000006d71df31362a91000000000000000000000000000000000000000000000000006d3dab8eb5eea8c90000000000000000000000000000000000000000000000006adbe534228200000000000000000000000000000000000000000000000000006124fee993bc00000000000000000000000000000000000000000000000000005ffa1b1f86c7e00000000000000000000000000000000000000000000000000058eb71c84f26c0000000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000001f49ae4337780be00000000000000000000000000000000000000000000000001ee28c35a4823b80000000000000000000000000000000000000000000000000194393fcdb4b500000000000000000000000000000000000000000000000000009d3c07f34695e00
-----Decoded View---------------
Arg [0] : farmlandAddresses_ (address[3]): 0x3CD1833Ce959E087D0eF0Cb45ed06BffE60F23Ba,0x096760F208390250649E3e8763348E783AEF5562,0x3CD1833Ce959E087D0eF0Cb45ed06BffE60F23Ba
Arg [1] : farmAddresses_ (address[]): 0xeD2C2CdEc695be3A4Dc421c1A8a6756dc5A927b6,0x8CD0a9e2073A47CA93E2AF65a3A2b82A5008feca,0xEc6547058594BA4842A5f4E5A6221B32E72B3BE9,0x8855E1458d167aF9499C83cE75474d8129F8E1b2,0x9DA7453486d1dFFDcDAB93d733c9f06d428ff4C3,0x87Ca488D23a4d0B261A7220e533bEb0A84bFfA48,0x30a3509FbD34d30C8581069F8Cdd6D9Db65EDa53,0x2316B36d718353dd2334965337A8fcb21f6c4Be5,0x68Dcd0743eA5dea3F03C6E49BbFB1eB72AB050A3,0x576ac8189481f675a179ea96eAa8d8D03c490dE3,0x9F7610115501abD147d1d82Ce92cea2A716690ED,0x12d964f702DB7b301765c0066a04eC4FBdb59e3a,0xEF9EFf0479d57032cda12e0d6bBEDb55B9b8c9E7,0x94446Fc7B099aC0f2177ae40eB1EB4D11BaE6536,0x584313319d0bFeAd2a9d98a7154f5dCb5a62887F,0x15D9b63779a1Ad283F4B8f2391d7182d3fe96207,0x54f54aC68d92aaeF256550957b4D8f9D5fD59604,0x98dcb5545E9c9d4C16e5C1831fd22D4276a2aCF9,0x805B3967AAb7FEaD5b4A58faa391E8d420EF9D2c,0x3AC1183D993177F33c5c2BBC7b0322F1e6bB8dD3,0xB3cd06b4044778c38Ba3e7ee67CDA505E2e1A647,0x81aA6141923Ea42fCAa763d9857418224d9b025a,0xbDef62bC8Ec76737eA43ee03aB80928449f00303,0x0d97B6DdcB5baE41A89c1705F08930C9D629180f,0x6c78F46f32C35c1E86B4b303D1BC2c1aD570e9fC,0x7A25Af1BFE363ccE64ba7b52B5170BbB5926D488,0x24E219EBf46093dC5c5A748Cb20B8c83e86bf09d,0x8c46C00FC633e1e73254bEC5A7364235976aDbF5,0x910B48C25aFC5b2a998458B62d467D482ECA74AF,0x22322380bA90C486320CeC43620d9Dc540004586,0xd78b76a77eFA46282cbDd3c2A2960AADC44c594e
Arg [2] : composted_ (uint256[]): 41581996205049707361309,4023529819912977091874,721346387229720000000,582217952138274857720,523595211387644692642,510455365367000000000,457462002937234023721,291194990648454298886,149412775766846800000,69080943567129740486,26698672540971311887,25772922206151200000,19933315076973600000,18310213200000000000,17052306550330200000,15015202986642238574,12640361809588282310,11743166363245758980,8750656016973307139,8064000000000000000,7886329824957600000,7871636353139517641,7700000000000000000,7000000000000000000,6915870000000000000,6407340000000000000,5000000000000000000,2254524692192300000,2225495327895600000,1820461388608000000,708121219000000000
-----Encoded View---------------
69 Constructor Arguments found :
Arg [0] : 0000000000000000000000003cd1833ce959e087d0ef0cb45ed06bffe60f23ba
Arg [1] : 000000000000000000000000096760f208390250649e3e8763348e783aef5562
Arg [2] : 0000000000000000000000003cd1833ce959e087d0ef0cb45ed06bffe60f23ba
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [4] : 00000000000000000000000000000000000000000000000000000000000004a0
Arg [5] : 000000000000000000000000000000000000000000000000000000000000001f
Arg [6] : 000000000000000000000000ed2c2cdec695be3a4dc421c1a8a6756dc5a927b6
Arg [7] : 0000000000000000000000008cd0a9e2073a47ca93e2af65a3a2b82a5008feca
Arg [8] : 000000000000000000000000ec6547058594ba4842a5f4e5a6221b32e72b3be9
Arg [9] : 0000000000000000000000008855e1458d167af9499c83ce75474d8129f8e1b2
Arg [10] : 0000000000000000000000009da7453486d1dffdcdab93d733c9f06d428ff4c3
Arg [11] : 00000000000000000000000087ca488d23a4d0b261a7220e533beb0a84bffa48
Arg [12] : 00000000000000000000000030a3509fbd34d30c8581069f8cdd6d9db65eda53
Arg [13] : 0000000000000000000000002316b36d718353dd2334965337a8fcb21f6c4be5
Arg [14] : 00000000000000000000000068dcd0743ea5dea3f03c6e49bbfb1eb72ab050a3
Arg [15] : 000000000000000000000000576ac8189481f675a179ea96eaa8d8d03c490de3
Arg [16] : 0000000000000000000000009f7610115501abd147d1d82ce92cea2a716690ed
Arg [17] : 00000000000000000000000012d964f702db7b301765c0066a04ec4fbdb59e3a
Arg [18] : 000000000000000000000000ef9eff0479d57032cda12e0d6bbedb55b9b8c9e7
Arg [19] : 00000000000000000000000094446fc7b099ac0f2177ae40eb1eb4d11bae6536
Arg [20] : 000000000000000000000000584313319d0bfead2a9d98a7154f5dcb5a62887f
Arg [21] : 00000000000000000000000015d9b63779a1ad283f4b8f2391d7182d3fe96207
Arg [22] : 00000000000000000000000054f54ac68d92aaef256550957b4d8f9d5fd59604
Arg [23] : 00000000000000000000000098dcb5545e9c9d4c16e5c1831fd22d4276a2acf9
Arg [24] : 000000000000000000000000805b3967aab7fead5b4a58faa391e8d420ef9d2c
Arg [25] : 0000000000000000000000003ac1183d993177f33c5c2bbc7b0322f1e6bb8dd3
Arg [26] : 000000000000000000000000b3cd06b4044778c38ba3e7ee67cda505e2e1a647
Arg [27] : 00000000000000000000000081aa6141923ea42fcaa763d9857418224d9b025a
Arg [28] : 000000000000000000000000bdef62bc8ec76737ea43ee03ab80928449f00303
Arg [29] : 0000000000000000000000000d97b6ddcb5bae41a89c1705f08930c9d629180f
Arg [30] : 0000000000000000000000006c78f46f32c35c1e86b4b303d1bc2c1ad570e9fc
Arg [31] : 0000000000000000000000007a25af1bfe363cce64ba7b52b5170bbb5926d488
Arg [32] : 00000000000000000000000024e219ebf46093dc5c5a748cb20b8c83e86bf09d
Arg [33] : 0000000000000000000000008c46c00fc633e1e73254bec5a7364235976adbf5
Arg [34] : 000000000000000000000000910b48c25afc5b2a998458b62d467d482eca74af
Arg [35] : 00000000000000000000000022322380ba90c486320cec43620d9dc540004586
Arg [36] : 000000000000000000000000d78b76a77efa46282cbdd3c2a2960aadc44c594e
Arg [37] : 000000000000000000000000000000000000000000000000000000000000001f
Arg [38] : 0000000000000000000000000000000000000000000008ce2a1eb5a27cd5f41d
Arg [39] : 0000000000000000000000000000000000000000000000da1db16da2e0698d22
Arg [40] : 0000000000000000000000000000000000000000000000271ab12d5416d53600
Arg [41] : 00000000000000000000000000000000000000000000001f8fe5aebf3140e2f8
Arg [42] : 00000000000000000000000000000000000000000000001c6257dea1782048a2
Arg [43] : 00000000000000000000000000000000000000000000001babfdc24af844e600
Arg [44] : 000000000000000000000000000000000000000000000018cc8f83ef10896529
Arg [45] : 00000000000000000000000000000000000000000000000fc9246d2d76503d06
Arg [46] : 0000000000000000000000000000000000000000000000081984cfefe7ff0080
Arg [47] : 000000000000000000000000000000000000000000000003beb0d02af39304c6
Arg [48] : 0000000000000000000000000000000000000000000000017284bd386b12230f
Arg [49] : 00000000000000000000000000000000000000000000000165abd032196b4d00
Arg [50] : 00000000000000000000000000000000000000000000000114a15c7386f31d00
Arg [51] : 000000000000000000000000000000000000000000000000fe1af1e4cbab2000
Arg [52] : 000000000000000000000000000000000000000000000000eca5f675e57f8fc0
Arg [53] : 000000000000000000000000000000000000000000000000d060b78ff931ec6e
Arg [54] : 000000000000000000000000000000000000000000000000af6b961824ec63c6
Arg [55] : 000000000000000000000000000000000000000000000000a2f81b96e3944a04
Arg [56] : 00000000000000000000000000000000000000000000000079709348d3541d03
Arg [57] : 0000000000000000000000000000000000000000000000006fe915466cc00000
Arg [58] : 0000000000000000000000000000000000000000000000006d71df31362a9100
Arg [59] : 0000000000000000000000000000000000000000000000006d3dab8eb5eea8c9
Arg [60] : 0000000000000000000000000000000000000000000000006adbe53422820000
Arg [61] : 0000000000000000000000000000000000000000000000006124fee993bc0000
Arg [62] : 0000000000000000000000000000000000000000000000005ffa1b1f86c7e000
Arg [63] : 00000000000000000000000000000000000000000000000058eb71c84f26c000
Arg [64] : 0000000000000000000000000000000000000000000000004563918244f40000
Arg [65] : 0000000000000000000000000000000000000000000000001f49ae4337780be0
Arg [66] : 0000000000000000000000000000000000000000000000001ee28c35a4823b80
Arg [67] : 000000000000000000000000000000000000000000000000194393fcdb4b5000
Arg [68] : 00000000000000000000000000000000000000000000000009d3c07f34695e00