ETH Price: $3,028.93 (+4.34%)

Contract

0x5778846313A5a051884Db163004ef0B286765fe7
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw Eth148015782022-05-18 23:06:29905 days ago1652915189IN
0x57788463...286765fe7
0 ETH0.001425444.70866293
Claim Tree147981382022-05-18 9:47:35905 days ago1652867255IN
0x57788463...286765fe7
0.005 ETH0.0018775116.1779111
Claim Tree147979212022-05-18 8:57:23905 days ago1652864243IN
0x57788463...286765fe7
0.005 ETH0.0026083919.79402343
Claim Tree147979082022-05-18 8:54:56905 days ago1652864096IN
0x57788463...286765fe7
0.005 ETH0.0024904318.75989365
Claim Tree147978472022-05-18 8:39:52906 days ago1652863192IN
0x57788463...286765fe7
0.001 ETH0.0030371923.04414683
Claim Tree147977832022-05-18 8:22:40906 days ago1652862160IN
0x57788463...286765fe7
0.001 ETH0.0020693116.71820004
Claim Tree147977822022-05-18 8:22:26906 days ago1652862146IN
0x57788463...286765fe7
0.001 ETH0.0021728416.35872042
Claim Tree147974922022-05-18 7:22:34906 days ago1652858554IN
0x57788463...286765fe7
0.001 ETH0.0027428420.81082184
Claim Tree147973842022-05-18 6:55:55906 days ago1652856955IN
0x57788463...286765fe7
0.001 ETH0.0034670526.30560289
Claim Tree147973672022-05-18 6:51:18906 days ago1652856678IN
0x57788463...286765fe7
0.005 ETH0.0021921316.50664608
Claim Tree147973542022-05-18 6:48:46906 days ago1652856526IN
0x57788463...286765fe7
0.005 ETH0.0027886420.99046529
Claim Tree147973312022-05-18 6:41:55906 days ago1652856115IN
0x57788463...286765fe7
0.005 ETH0.0020456715.39225858
Claim Tree147971612022-05-18 6:03:12906 days ago1652853792IN
0x57788463...286765fe7
0.005 ETH0.0024319118.4477974
Claim Tree147968512022-05-18 4:52:33906 days ago1652849553IN
0x57788463...286765fe7
0.005 ETH0.0027305720.55338559
Claim Tree147967932022-05-18 4:40:33906 days ago1652848833IN
0x57788463...286765fe7
0.005 ETH0.002468418.5799564
Claim Tree147965232022-05-18 3:38:48906 days ago1652845128IN
0x57788463...286765fe7
0.001 ETH0.0030796123.17677486
Claim Tree147964052022-05-18 3:10:51906 days ago1652843451IN
0x57788463...286765fe7
0.005 ETH0.0029877822.48092214
Claim Tree147962792022-05-18 2:39:09906 days ago1652841549IN
0x57788463...286765fe7
0.001 ETH0.0031469523.87693369
Claim Tree147960012022-05-18 1:42:01906 days ago1652838121IN
0x57788463...286765fe7
0.005 ETH0.0029122121.9288122
Claim Tree147958712022-05-18 1:09:08906 days ago1652836148IN
0x57788463...286765fe7
0.005 ETH0.0016886512.70589976
Claim Tree147957562022-05-18 0:47:47906 days ago1652834867IN
0x57788463...286765fe7
0.005 ETH0.0033827625.47202323
Claim Tree147957312022-05-18 0:41:25906 days ago1652834485IN
0x57788463...286765fe7
0.001 ETH0.0005923524.35579527
Claim Tree147957312022-05-18 0:41:25906 days ago1652834485IN
0x57788463...286765fe7
0.001 ETH0.0032112824.35579527
Claim Tree147954962022-05-17 23:47:40906 days ago1652831260IN
0x57788463...286765fe7
0.005 ETH0.0028716721.60733029
Claim Tree147954962022-05-17 23:47:40906 days ago1652831260IN
0x57788463...286765fe7
0.005 ETH0.0028716721.60733029
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
148015782022-05-18 23:06:29905 days ago1652915189
0x57788463...286765fe7
0.41 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TheForest

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 10 : TheForest.sol
// SPDX-License-Identifier: MIT
// Omnus Contracts (contracts/ether-tree/TheForest.sol)
// https://omnuslab.com/ethertree
// https://ethertree.org

// EtherTree 100 total supply ERC721

/**
*
* @dev EtherTree
*
* Distribution contract for the ether tree project. This token implements a few innovations:
* - Pre minted token supply. The total supply was minted on contract creation (which saves gas). 
* - All metadata is revealed, opensea site is up etc. so people know exactly what they are buying in to.
* - Which creates the issue of random assignment, which is solved by RandomlyAlloacted and IceRing, in their first mainnet incarnation.
*   For more details see  https://omnuslab.com/RandomlyAllocated and https://omnuslab.com/IceRing
*/

pragma solidity ^0.8.13;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@omnus/contracts/token/RandomlyAllocated/RandomlyAllocatedEtherTree.sol"; 

/**
*
* @dev Contract implements RandomlyAllocated and IceRing (which is in RandomlyAllocated)
*
*/
contract TheForest is Ownable, RandomlyAllocated, IERC721Receiver {

  IERC721 public immutable etherTree; 
  IERC721 public immutable wassiesByWassies;
  address payable public immutable etherTreesury; 
  address public immutable ice; 
  address public immutable oat; 

  uint256 public constant PRICE        =  5000000000000000; // 0.005 eth
  uint256 public constant WASSIE_PRICE =  1000000000000000; // 0.001 eth

  mapping(address => bool) private youveGotOneAlready;

  constructor(address etherTree_, address wassiesByWassies_, address payable etherTreesury_, address ice_, address oat_) 
    RandomlyAllocated(100, oat_, ice_, 0, 0, 0) {
    
    etherTree = IERC721(etherTree_);
    wassiesByWassies = IERC721(wassiesByWassies_);
    etherTreesury = etherTreesury_;
    ice = ice_;
    oat = oat_;
  }

  /**
  *
  * @dev Events
  *
  */
  event EthWithdrawal(uint256 indexed withdrawal);

  /**
  *
  * @dev Do not accept random calls:
  *
  */
  
  receive() external payable {
    revert();
  }

  fallback() external payable {
    revert();
  }

  /** 
  *
  * @dev owner can withdraw eth to treasury:
  *
  */ 
  function withdrawEth(uint256 _amount) external onlyOwner returns (bool) {
    (bool success, ) = etherTreesury.call{value: _amount}("");
    require(success, "Transfer failed.");
    emit EthWithdrawal(_amount);
    return true;
  }

  /**
  *
  * @dev claimTree
  *
  */
  function claimTree(bool wassie) payable external {

    uint256 requiredPrice;
    if (wassie) {
      requiredPrice = WASSIE_PRICE;
    }
    else {
      requiredPrice = PRICE;
    }

    bool isEligible;
    string memory reason;

    (isEligible, reason) = canClaimATree(wassie, msg.value, requiredPrice);

    require(isEligible, reason);

    // Send them their randomly selected tree!
    etherTree.safeTransferFrom(address(this), msg.sender, _getItem(0));

    youveGotOneAlready[msg.sender] = true;

  }

  /**
  *
  * @dev canClaimATree - check is the caller address is eligible
  *
  */
  function canClaimATree(bool wassie, uint256 payment, uint256 price) public view returns(bool isEligible, string memory message) {

    // 1) See if they have already claimed one - it's one per address:
    if (youveGotOneAlready[msg.sender]) {
      return(false, "Hey, one each please!");
    }

    // 2) Check passed payment:
    if (payment != price) {
      return(false, "Incorrect ETH amount passed.");
    }

    // 3) If claiming to be a wassie, check for a wassie:
    if (wassie && wassiesByWassies.balanceOf(msg.sender) < 1) {
      return(false, "Must have a wassie for this price. Pay normie price, or checkout yellowbird.ethertree.org");
    }

    // 3) If claiming to not be a wassie, check for a wassie:
    if (!wassie && wassiesByWassies.balanceOf(msg.sender) > 0) {
      return(false, "You have a wassie! Press the other button it's cheaper!");
    }

    // 4) We got here? Good to go:
    return(true, "");

  }

  /**
  *
  * @dev onERC721Received: Always returns `IERC721Receiver.onERC721Received.selector`. We need this to custody NFTs on the contract:
  *
  */
  function onERC721Received(
    address,
    address,
    uint256,
    bytes memory
  ) external virtual override returns (bytes4) {
    return this.onERC721Received.selector;
  }

}

File 2 of 10 : RandomlyAllocatedEtherTree.sol
// SPDX-License-Identifier: MIT
// Omnus Contracts (contracts/token/RandomlyAllocated/RandomlyAllocated.sol)
// https://omnuslab.com/randomallocation

// RandomlyAllocated (Allocate the items in a fixed length collection, calling IceRing to randomly assign each ID.

pragma solidity ^0.8.13;

/**
*
* @dev RandomlyAllocated
*
* This contract extension allows the selection of items from a finite collection, each selection using the IceRing
* entropy source and removing the assigned item from selection. Intended for use with random token mints etc.
*
*/

import "@openzeppelin/contracts/utils/Context.sol";  
import "@omnus/contracts/entropy/IceRing.sol";

/**
*
* @dev Contract module which allows children to randomly allocated items from a decaying array.
* You must pass in:
* 1) The length of the collection you wish to select from (e.g. 1,000)
* 2) The IceRing contract address for this chain.
* 3) The ERC20Payable contract acting as relay.
* 
* The contract will pass back the item from the array that has been selected and remove that item from the array,
* hence you have a decaying list of items to select from.
*
*/

abstract contract RandomlyAllocated is Context, IceRing {

  // The parent array holds an index addressing each of the underlying 32 entry uint8 children arrays. The number of each
  // entry in the parentArray denotes how many times 32 we elevate the number in the child array when it is selected, with 
  // each child array running from 0 to 32 (one slot). For example, if we have parentArray 4 then every number in childArray
  // 4 is elevated by 4*32, position 0 in childArray 4 therefore representing number 128 (4 * 32 + 0)
  uint16[] public parentArray; 
  // Mapping of parentArray to childArray:
  mapping (uint16 => uint8[]) childArray;

  uint256 public continueLoadFromArray;
  
  uint256 public immutable entropyMode;
  
  // In theory this approach could handle a collection of 2,097,120 items. But as that would required 65,535 parentArray entries
  // we would need to load these items in batches. Set a notional parent array max size of 1,600 items, which gives a collection
  // max size of 51,200 (1,600 * 32):
  uint256 private constant COLLECTION_LIMIT = 51200; 
  // Each child array holds 32 items (1 slot wide):
  uint256 private constant CHILD_ARRAY_WIDTH = 32;
  // Max number of child arrays that can be loaded in one block
  uint16 private constant LOAD_LIMIT = 125;
  // Save a small amount of gas by holding these values as constants:
  uint256 private constant EXPONENT_18 = 10 ** 18;
  uint256 private constant EXPONENT_36 = 10 ** 36;

  /**
  *
  * @dev must be passed supply details, ERC20 payable contract and ice contract addresses, as well as entropy mode and fee (if any)
  *
  */
  constructor(uint16 supply_, address ERC20SpendableContract_, address iceContract_, uint256 entropyMode_, uint256 ethFee_, uint256 oatFee_)
    IceRing(ERC20SpendableContract_, iceContract_, ethFee_, oatFee_) {
    
    require(supply_ < (COLLECTION_LIMIT + 1),"Max supply of 51,200");

    entropyMode = entropyMode_;

    uint256 numberOfParentEntries = supply_ / CHILD_ARRAY_WIDTH;

    uint256 finalChildWidth = supply_ % CHILD_ARRAY_WIDTH;

    // If the supply didn't divide perfectly by the child width we have a remainder child at the end. We will load this now
    // so that all subsequent child loads can safely assume a full width load:
    if (finalChildWidth != 0) {

      // Set the final child array now:
      // Exclude 98 (yellow bird) as that is available for free at yellowbird.ethertree.org:
      childArray[uint16(numberOfParentEntries)] = [0,1,3];

      // Add one to the numberOfParentEntries to include the finalChild (as this will have been truncated off the calc above):
      numberOfParentEntries += 1;

    }

    // Now load the parent array:
    for(uint256 i = 0; i < numberOfParentEntries;) {
      parentArray.push(uint16(i));
      unchecked{ i++; }
    }

    // Load complete, all set up and ready to go.
  }

  /**
  *
  * @dev View total remaining items left in the array
  *
  */
  function remainingParentItems() external view returns(uint256) {
    return(parentArray.length);
  }

  /**
  *
  * @dev View parent array
  *
  */
  function parentItemsArray() external view returns(uint16[] memory) {
    return(parentArray);
  }

  /**
  *
  * @dev View items array
  *
  */
  function childItemsArray(uint16 index_) external view returns(uint8[] memory) {
    return(childArray[index_]);
  }

  /**
  *
  * @dev View total remaining IDs
  *
  */
  function countOfRemainingIds() external view returns(uint256 totalRemainingIds) {
        
    for (uint16 i = 0; i < parentArray.length; i++) {
      // A child array with a length of 0 means that this entry in the parent array has yet to 
      // have the child array created. If the child array was fully depleted to 0 Ids the parent
      // array will have been deleted. Therefore a parent array with no corresponding child array
      // needs to increase the total count by the full 32 items that will be loaded into the child
      // array when it is instantiate.
      if (childArray[i].length == 0) {
        totalRemainingIds += 32;
      }
      else {
        totalRemainingIds += uint256(childArray[i].length);
      }
    }
          
    return(totalRemainingIds);
  }

  /**
  *
  * @dev Allocate item from array:
  *
  */
  function _getItem(uint256 accessMode_) internal returns(uint256 allocatedItem_) { //mode: 0 = light, 1 = standard, 2 = heavy
    
    require(parentArray.length != 0, "ID allocation exhausted");

    // Retrieve a uint256 of entropy from IceRing. We will use separate parts of this entropy uint for number in range
    // calcs for array selection:
    uint256 entropy = _getEntropy(accessMode_);

    // First select the entry from the parent array, using the left most 18 entropy digits:
    uint16 parentIndex = uint16(((entropy % EXPONENT_18) * parentArray.length) / EXPONENT_18);

    uint16 parent = parentArray[parentIndex];

    // Check if we need to load the child (we will the first time it is accessed):
    if (childArray[parent].length == 0) {
      // Exclude blueberrybird5:
      if (parent == 0) {
        childArray[parent] = [0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];  
      }
      else {
        childArray[parent] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
      }  
    }

    // Select the item from the child array, using the a different 18 entropy digits, and add on the elevation factor from the parent:
    uint256 childIndex = (((entropy % EXPONENT_36) / EXPONENT_18) * childArray[parent].length) / EXPONENT_18;
    
    allocatedItem_ = uint256(childArray[parent][childIndex]) + (parent * CHILD_ARRAY_WIDTH);

    // Pop this item from the child array. First set the last item index:
    uint256 lastChildIndex = childArray[parent].length - 1;

    // When the item to remove from the array is the last item, the swap operation is unnecessary
    if (childIndex != lastChildIndex) {
      childArray[parent][childIndex] = childArray[parent][lastChildIndex];
    }

    // Remove the last position of the array:
    childArray[parent].pop();

    // Check if the childArray is no more:
    if (childArray[parent].length == 0) {
      // Remove the parent as the child allocation is exhausted. First set the last index:
      uint256 lastParentIndex = parentArray.length - 1;

      // When the item to remove from the array is the last item, the swap operation is unnecessary
      if (parentIndex != lastParentIndex) {
        parentArray[parentIndex] = parentArray[lastParentIndex];
      }

      parentArray.pop();

    }

    return(allocatedItem_);
  }

  /**
  *
  * @dev Retrieve Entropy
  *
  */
  function _getEntropy(uint256 accessMode_) internal returns(uint256 entropy_) { 
    
    // Access mode of 0 is direct access, ETH payment may be required:
    if (accessMode_ == 0) { 
      if (entropyMode == 0) entropy_ = (_getEntropyETH(ENTROPY_LIGHT));
      else if (entropyMode == 1) entropy_ = (_getEntropyETH(ENTROPY_STANDARD));
      else if (entropyMode == 2) entropy_ = (_getEntropyETH(ENTROPY_HEAVY));
      else revert("Unrecognised entropy mode");
    }
    // Access mode of 0 is token relayed access, OAT payment may be required:
    else {
      if (entropyMode == 0) entropy_ = (_getEntropyOAT(ENTROPY_LIGHT));
      else if (entropyMode == 1) entropy_ = (_getEntropyOAT(ENTROPY_STANDARD));
      else if (entropyMode == 2) entropy_ = (_getEntropyOAT(ENTROPY_HEAVY));
      else revert("Unrecognised entropy mode");
    }

    return(entropy_);

  }

  /**
  *
  * @dev _loadChildren: Optional function that can be used to pre-load child arrays. This can be used to shift gas costs out of
  * execution by pre-loading some or all of the child arrays.
  *
  */
  function _loadChildren() internal {

    require(continueLoadFromArray < parentArray.length, "Load Children: load already complete");
        
    // Determine how many arrays we will be checking and loading on this call:
    uint256 loadUntil;

    // Example: Parent array length is 300 (index 0 to 299). On the first call to this function
    // the storage var continueLoadFromArray will be 0. Therefore the statement below will be
    // if (300 - 0) > 125, which it is. We therefore set loadUntil to 0 + 125 (the load limit)
    // which is 125.
    // On the second call to this function continueLoadFromArray will be 125 (we set it to the loadUntil
    // value at the end of this function). (300 - 125) is 175, so still greater than the load limit of 125.
    // We therefore set loadUntil to 125 + 125 = 250.
    // On the third call to this function continueLoadFromArray will be 250. (300 - 250) = 50, which is less 
    // that our load limit. We therefore set loadUntil to the length of the parent array, which is 300. Note
    // that when processing the parent array items we terminate the look when i < loadUntil, meaning that in 
    // are example we will load index 0 all the way to 299, which is as it should be.
    if ((parentArray.length - continueLoadFromArray) > LOAD_LIMIT) {
      loadUntil = continueLoadFromArray + LOAD_LIMIT;
    }
    else {
      loadUntil = parentArray.length;
    }

    for(uint256 i = continueLoadFromArray; i < loadUntil;) {
      if (childArray[uint16(i)].length == 0) {
        childArray[uint16(i)] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
      }
      unchecked{ i++; }
    }

    continueLoadFromArray = loadUntil;

  }

}

File 3 of 10 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^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 `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 4 of 10 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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;
}

File 5 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^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() {
        _transferOwnership(_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 {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 6 of 10 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^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);
}

File 7 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^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 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) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 8 of 10 : IceRing.sol
// SPDX-License-Identifier: MIT
// Omnus Contracts (contracts/entropy/IceRing.sol)
// https://omnuslab.com/icering

// ICERiNG (In Chain Entropy - Randomised Number Generator)

pragma solidity ^0.8.13;

/**
* @dev ICE - In-Chain Entropy
*
* This protocol generates in-chain entropy (OK, ON-chain not in-chain, but that didn't make a cool acronym...).
* Solidity and blockchains are deterministic, so standard warnings apply, this produces pseudorandomness. For very strict levels of 
* randomness the answer remains to go off-chain, but that carries a cost and also introduces an off-chain dependency that could fail or,
* worse, some day be tampered with or become vulnerable. 
* 
* The core premise of this protocol is that we aren't chasing true random (does that even exist? Philosophers?). What we are chasing 
* is a source or sources of entropy that are unpredictable in that they can't practically be controlled or predicted by a single entity.
*
* A key source of entropy in this protocol is contract balances, namely the balances of contracts that change with every block. Think large 
* value wallets, like exchange wallets. We store a list of these contract addresses and every request combine the eth value of these addresses
* with the current block time and a modulo and hash it. 
* 
* Block.timestamp has been used as entropy before, but it has a significant drawback in that it can be controlled by miners. If the incentive is
* high enough a miner could look to control the outcome by controlling the timestamp. 
* 
* When we add into this a variable contract balance we require a single entity be able to control both the block.timestamp and, for example, the 
* eth balance of a binance hot wallet. In the same block. To make it even harder, we loop through our available entropy sources, so the one that
* a transaction uses depends on where in the order we are, which depends on any other txns using this protocol before it. So to be sure of the 
* outcome an entity needs to control the block.timestamp, either control other txns using this in the block or make sure it's the first txn in 
* the block, control the balance of another parties wallet than changes with every block, then be able to hash those known variables to see if the
* outcome is a positive one for them. Whether any entity could achieve that is debatable, but you would imagine that if it is possible it 
* would come at significant cost.
*
* The protocol can be used in two ways: to return a full uin256 of entropy or a number within a given range. Each of these can be called in light,
* standard or heavy mode:
*   Light    - uses the balance of the last contract loaded into the entropy list for every generation. This reduces storage reads
*              at the disadvantage of reducing the variability of the seed.
*   Standard - increments through our list of sources using a different one as the seed each time, returning to the first item at the end of the 
*              loop and so on.
*   Heavy    - creates a hash of hashes using ALL of the entropy seed sources. In principle this would require a single entity to control both
*              the block timestamp and the precise balances of a range of addresses within that block. 
*
*                                                             D I S C L A I M E R
*                                                             ===================    
*                   Use at your own risk, obvs. I've tried hard to make this good quality entropy, but whether random exists is
*                   a question for philosophers not solidity devs. If there is a lot at stake on whatever it is you are doing 
*                   please DYOR on what option is best for you. There are no guarantees the entropy seeds here will be maintained
*                   (I mean, no one might ever use this). No liability is accepted etc.
*/

import "@openzeppelin/contracts/utils/Context.sol";  
import "@omnus/contracts/token/ERC20Spendable/IERC20Spendable.sol";
import "@omnus/contracts/entropy/IIce.sol"; 

/**
*
* @dev - library contract for Ice access
*
*/
abstract contract IceRing is Context {

  uint256 constant NUMBER_IN_RANGE_LIGHT = 0;
  uint256 constant NUMBER_IN_RANGE_STANDARD = 1;
  uint256 constant NUMBER_IN_RANGE_HEAVY = 2;
  uint256 constant ENTROPY_LIGHT = 3;
  uint256 constant ENTROPY_STANDARD = 4;
  uint256 constant ENTROPY_HEAVY = 5;
  
  uint256 public ethFee;
  uint256 public oatFee;

  IERC20Spendable public immutable ERC20SpendableContract; 
  address public immutable IceAddress; 
  IIce public immutable IceContract;

  event ETHFeeUpdated(uint256 oldFee, uint256 newFee);
  event OATFeeUpdated(uint256 oldFee, uint256 newFee);

  /**
  *
  * @dev - Constructor - both the ICE contract and the ERC20Spendable contract need to be provided:
  *
  */
  constructor(address _ERC20SpendableContract, address _IceAddress, uint256 _ethFee, uint256 _oatFee) {
    ERC20SpendableContract = IERC20Spendable(_ERC20SpendableContract); 
    IceAddress = _IceAddress;
    IceContract = IIce(IceAddress);
    ethFee = _ethFee;
    oatFee = _oatFee;
  }


  /**
  *
  * @dev Update fee. Implement an external call that calls this in child contract, likely ownerOnly.
  *
  */
  function _updateETHFee(uint256 _ethFee) internal {
    uint256 oldETHFee = ethFee;
    ethFee = _ethFee;
    emit ETHFeeUpdated(oldETHFee, _ethFee);
  }

  /**
  *
  * @dev Update fee. Implement an external call that calls this in child contract, likely ownerOnly.
  *
  */
  function _updateOATFee(uint256 _oatFee) internal {
    uint256 oldOATFee = oatFee;
    oatFee = _oatFee;
    emit OATFeeUpdated(oldOATFee, oatFee);
  }

  /**
  *
  * @dev Get entropy, access direct:
  *
  */
  function _getEntropyETH(uint256 _mode) internal returns(uint256 ice_) {

    (bool success, uint256 result) = IceContract.iceRingEntropy{value: ethFee}(_mode);
    
    require(success, "Ice call failed"); 

    return(result);
  }

  /**
  *
  * @dev Get number in range, access direct:
  *
  */
  function _getNumberInRangeETH(uint256 _mode, uint256 _upperBound) internal returns(uint256 ice_) {

    (bool success, uint256 result) = IceContract.iceRingNumberInRange{value: ethFee}(_mode, _upperBound);
    
    require(success, "Ice call failed"); 

    return(result);
  }

  /**
  *
  * @dev Get entropy, access through the ERC20 payable relay:
  *
  */
  function _getEntropyOAT(uint256 _mode) internal returns(uint256 ice_) {

    uint256[] memory arguments = new uint256[](1);
    arguments[0] = _mode;

    ice_ = ERC20SpendableContract.spendToken(IceAddress, oatFee, arguments)[0]; 

    return(ice_);
  }
  
  /**
  *
  * @dev Get number in range, access through the ERC20 payable relay:
  *
  */
  function _getNumberInRangeOAT(uint256 _mode, uint256 _upperBound) internal returns(uint256 ice_) {

    uint256[] memory arguments = new uint256[](2);
    arguments[0] = _mode;
    arguments[1] = _upperBound;

    ice_ = ERC20SpendableContract.spendToken(IceAddress, oatFee, arguments)[0]; 

    return(ice_);
  }

}

File 9 of 10 : IIce.sol
// SPDX-License-Identifier: MIT
// Omnus Contracts (contracts/entropy/IIce.sol)
// https://omnuslab.com/icering

// IIce (In Chain Entropy - Interface)

pragma solidity ^0.8.13;

/**
* @dev ICE - In-Chain Entropy
*
* This protocol generates in-chain entropy (OK, ON-chain not in-chain, but that didn't make a cool acronym...).
* Solidity and blockchains are deterministic, so standard warnings apply, this produces pseudorandomness. For very strict levels of 
* randomness the answer remains to go off-chain, but that carries a cost and also introduces an off-chain dependency that could fail or,
* worse, some day be tampered with or become vulnerable. 
* 
* The core premise of this protocol is that we aren't chasing true random (does that even exist? Philosophers?). What we are chasing 
* is a source or sources of entropy that are unpredictable in that they can't practically be controlled or predicted by a single entity.
*
* A key source of entropy in this protocol is contract balances, namely the balances of contracts that change with every block. Think large 
* value wallets, like exchange wallets. We store a list of these contract addresses and every request combine the eth value of these addresses
* with the current block time and a modulo and hash it. 
* 
* Block.timestamp has been used as entropy before, but it has a significant drawback in that it can be controlled by miners. If the incentive is
* high enough a miner could look to control the outcome by controlling the timestamp. 
* 
* When we add into this a variable contract balance we require a single entity be able to control both the block.timestamp and, for example, the 
* eth balance of a binance hot wallet. In the same block. To make it even harder, we loop through our available entropy sources, so the one that
* a transaction uses depends on where in the order we are, which depends on any other txns using this protocol before it. So to be sure of the 
* outcome an entity needs to control the block.timestamp, either control other txns using this in the block or make sure it's the first txn in 
* the block, control the balance of another parties wallet than changes with every block, then be able to hash those known variables to see if the
* outcome is a positive one for them. Whether any entity could achieve that is debatable, but you would imagine that if it is possible it 
* would come at significant cost.
*
* The protocol can be used in two ways: to return a full uin256 of entropy or a number within a given range. Each of these can be called in light,
* standard or heavy mode:
*   Light    - uses the balance of the last contract loaded into the entropy list for every generation. This reduces storage reads
*              at the disadvantage of reducing the variability of the seed.
*   Standard - increments through our list of sources using a different one as the seed each time, returning to the first item at the end of the 
*              loop and so on.
*   Heavy    - creates a hash of hashes using ALL of the entropy seed sources. In principle this would require a single entity to control both
*              the block timestamp and the precise balances of a range of addresses within that block. 
*
*                                                             D I S C L A I M E R
*                                                             ===================    
*                   Use at your own risk, obvs. I've tried hard to make this good quality entropy, but whether random exists is
*                   a question for philosophers not solidity devs. If there is a lot at stake on whatever it is you are doing 
*                   please DYOR on what option is best for you. No liability is accepted etc.
*/

/**
*
* @dev Implementation of the Ice interface.
*
*/

interface IIce {
  event EntropyAdded (address _entropyAddress);
  event EntropyUpdated (uint256 _index, address _newAddress, address _oldAddress); 
  event EntropyCleared (); 
  event EntropyServed(address seedAddress, uint256 seedValue, uint256 timeStamp, uint256 modulo, uint256 entropy);
  event BaseFeeUpdated(uint256 oldFee, uint256 newFee);
  event ETHExponentUpdated(uint256 oldETHExponent, uint256 newETHExponent);
  event OATExponentUpdated(uint256 oldOATExponent, uint256 newOATExponent);
  event TreasurySet(address treasury);
  event TokenWithdrawal(uint256 indexed withdrawal, address indexed tokenAddress);
  event EthWithdrawal(uint256 indexed withdrawal);

  function iceRingEntropy(uint256 _mode) external payable returns(bool, uint256 entropy_);
  function iceRingNumberInRange(uint256 _mode, uint256 _upperBound) external payable returns(bool, uint256 numberInRange_);
  function viewEntropyAddress(uint256 _index) external view returns (address entropyAddress);
  function addEntropy(address _entropyAddress) external;
  function updateEntropy(uint256 _index, address _newAddress) external;
  function deleteAllEntropy() external;
  function updateBaseFee(uint256 _newBasefee) external;
  function updateOATFeeExponent(uint256 _newOatExponent) external;
  function updateETHFeeExponent(uint256 _newEthExponent) external;
  function getConfig() external view returns(uint256 seedIndex_, uint256 counter_, uint256 modulo_, address seedAddress_, uint256 baseFee_, uint256 ethExponent_, uint256 oatExponent_);
  function getEthFee() external view returns (uint256 ethFee);
  function getOatFee() external view returns (uint256 oatFee); 
  function validateProof(uint256 _seedValue, uint256 _modulo, uint256 _timeStamp, uint256 _entropy) external pure returns(bool valid);
}

File 10 of 10 : IERC20Spendable.sol
// SPDX-License-Identifier: MIT
// Omnus Contracts (contracts/token/ERC20Spendable/ISpendableERC20.sol)
// https://omnuslab.com/spendable

// IERC20Spendable - Interface definition for contracts to implement spendable ERC20 functionality

pragma solidity ^0.8.13;

/**
*
* @dev ERC20Spendable - library contract for an ERC20 extension to allow ERC20s to 
* operate as 'spendable' items, i.e. a token that can trigger an action on another contract
* at the same time as being transfered. Similar to ERC677 and the hooks in ERC777, but with more
* of an empasis on interoperability (returned values) than ERC677 and specifically scoped interaction
* rather than the general hooks of ERC777. 
*
* Interface Definition IERC20Spendable
*
*/

interface IERC20Spendable{

  /**
  *
  * @dev New function, spendToken, that allows the transfer of the owners token to the receiver, a call on the receiver, and 
  * the return of information from the receiver back up the call stack:
  *
  */
  function spendToken(address receiver, uint256 _tokenPaid, uint256[] memory _arguments) external returns(uint256[] memory);

}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"etherTree_","type":"address"},{"internalType":"address","name":"wassiesByWassies_","type":"address"},{"internalType":"address payable","name":"etherTreesury_","type":"address"},{"internalType":"address","name":"ice_","type":"address"},{"internalType":"address","name":"oat_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"ETHFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"withdrawal","type":"uint256"}],"name":"EthWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"OATFeeUpdated","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ERC20SpendableContract","outputs":[{"internalType":"contract IERC20Spendable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IceAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IceContract","outputs":[{"internalType":"contract IIce","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WASSIE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"wassie","type":"bool"},{"internalType":"uint256","name":"payment","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"canClaimATree","outputs":[{"internalType":"bool","name":"isEligible","type":"bool"},{"internalType":"string","name":"message","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"index_","type":"uint16"}],"name":"childItemsArray","outputs":[{"internalType":"uint8[]","name":"","type":"uint8[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"wassie","type":"bool"}],"name":"claimTree","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"continueLoadFromArray","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"countOfRemainingIds","outputs":[{"internalType":"uint256","name":"totalRemainingIds","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"entropyMode","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"etherTree","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"etherTreesury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ice","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oat","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oatFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"parentArray","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"parentItemsArray","outputs":[{"internalType":"uint16[]","name":"","type":"uint16[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingParentItems","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wassiesByWassies","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawEth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101a06040523480156200001257600080fd5b50604051620022133803806200221383398101604081905262000035916200032c565b6064818360008080848482806200004c33620001ff565b6001600160a01b039384166080529190921660a081905260c05260019182556002556200007d9061c80090620003ac565b8661ffff1610620000d45760405162461bcd60e51b815260206004820152601460248201527f4d617820737570706c79206f662035312c323030000000000000000000000000604482015260640160405180910390fd5b60e08390526000620000ec602061ffff8916620003e9565b9050600062000101602061ffff8a1662000400565b905080156200015a576040805160608101825260008082526001602080840191909152600383850181905261ffff87168352600490915292902062000149929091906200024f565b5062000157600183620003ac565b91505b60005b82811015620001c65760038054600180820183556000929092527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b60108204018054600f9092166002026101000a61ffff8181021990931692851602919091179055016200015d565b5050506001600160a01b039a8b166101005250505050948616610120525091841661014052831661016052909116610180525062000417565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090601f01602090048101928215620002ea5791602002820160005b83821115620002b957835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000279565b8015620002e85782816101000a81549060ff0219169055600101602081600001049283019260010302620002b9565b505b50620002f8929150620002fc565b5090565b5b80821115620002f85760008155600101620002fd565b6001600160a01b03811681146200032957600080fd5b50565b600080600080600060a086880312156200034557600080fd5b8551620003528162000313565b6020870151909550620003658162000313565b6040870151909450620003788162000313565b60608701519093506200038b8162000313565b60808701519092506200039e8162000313565b809150509295509295909350565b60008219821115620003ce57634e487b7160e01b600052601160045260246000fd5b500190565b634e487b7160e01b600052601260045260246000fd5b600082620003fb57620003fb620003d3565b500490565b600082620004125762000412620003d3565b500690565b60805160a05160c05160e0516101005161012051610140516101605161018051611d30620004e36000396000610353015260006102d50152600081816102120152610aa201526000818161059f015281816106ec01526107ab01526000818161051e01526108fd01526000818161031f015281816112f60152818161132e01528181611360015281816113da0152818161140c015261143e0152600081816104ba015261147501526000818161038701526115db01526000818161045501526115ae0152611d306000f3fe6080604052600436106101855760003560e01c8063715018a6116100d1578063bc26c5c21161008a578063dd61db7811610064578063dd61db781461050c578063ec0f351d14610540578063f2fde38b1461056d578063f7044c7b1461058d57600080fd5b8063bc26c5c21461048d578063be37fbf2146104a8578063c311d049146104dc57600080fd5b8063715018a6146103d357806381016ac8146103e85780638d859f3e1461040a5780638da5cb5b146104255780639a34f65714610443578063ac5515761461047757600080fd5b80634c2a860d1161013e57806353959ad01161011857806353959ad01461034157806357bf223b1461037557806367eadae3146103a95780636eba9308146103be57600080fd5b80634c2a860d146102c35780634cf1115d146102f75780634ec27e0e1461030d57600080fd5b806313ffeeda14610194578063150b7a02146101bc5780631e23108d14610200578063233bd0c41461024c5780633251175b1461027a57806336654cc71461029057600080fd5b3661018f57600080fd5b600080fd5b3480156101a057600080fd5b506101a96105c1565b6040519081526020015b60405180910390f35b3480156101c857600080fd5b506101e76101d736600461177e565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016101b3565b34801561020c57600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101b3565b34801561025857600080fd5b5061026c61026736600461184c565b610636565b6040516101b39291906118ce565b34801561028657600080fd5b506101a960025481565b34801561029c57600080fd5b506102b06102ab3660046118f1565b610866565b60405161ffff90911681526020016101b3565b3480156102cf57600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b34801561030357600080fd5b506101a960015481565b34801561031957600080fd5b506101a97f000000000000000000000000000000000000000000000000000000000000000081565b34801561034d57600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b34801561038157600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b6103bc6103b736600461190a565b61089e565b005b3480156103ca57600080fd5b506003546101a9565b3480156103df57600080fd5b506103bc6109bd565b3480156103f457600080fd5b506103fd6109f3565b6040516101b39190611927565b34801561041657600080fd5b506101a96611c37937e0800081565b34801561043157600080fd5b506000546001600160a01b0316610234565b34801561044f57600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b34801561048357600080fd5b506101a960055481565b34801561049957600080fd5b506101a966038d7ea4c6800081565b3480156104b457600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e857600080fd5b506104fc6104f73660046118f1565b610a73565b60405190151581526020016101b3565b34801561051857600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b34801561054c57600080fd5b5061056061055b36600461196f565b610b8a565b6040516101b39190611993565b34801561057957600080fd5b506103bc6105883660046119ce565b610c0f565b34801561059957600080fd5b506102347f000000000000000000000000000000000000000000000000000000000000000081565b6000805b60035461ffff821610156106325761ffff811660009081526004602052604081205490036105ff576105f86020836119ff565b9150610620565b61ffff811660009081526004602052604090205461061d90836119ff565b91505b8061062a81611a17565b9150506105c5565b5090565b3360009081526006602052604081205460609060ff16156106875750506040805180820190915260158152744865792c206f6e65206561636820706c656173652160581b602082015260009061085e565b8284146106cc57505060408051808201909152601c81527f496e636f72726563742045544820616d6f756e74207061737365642e00000000602082015260009061085e565b84801561076157506040516370a0823160e01b81523360048201526001907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f9190611a38565b105b1561078a576000604051806080016040528060598152602001611ca2605991399150915061085e565b8415801561082057506040516370a0823160e01b81523360048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156107fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081e9190611a38565b115b15610849576000604051806060016040528060378152602001611c6b603791399150915061085e565b50506040805160208101909152600081526001905b935093915050565b6003818154811061087657600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b600081156108b4575066038d7ea4c680006108be565b506611c37937e080005b600060606108cd843485610636565b909250905080826108fa5760405162461bcd60e51b81526004016108f19190611a51565b60405180910390fd5b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166342842e0e30336109366000610caa565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561098557600080fd5b505af1158015610999573d6000803e3d6000fd5b5050336000908152600660205260409020805460ff19166001179055505050505050565b6000546001600160a01b031633146109e75760405162461bcd60e51b81526004016108f190611a64565b6109f1600061129a565b565b60606003805480602002602001604051908101604052809291908181526020018280548015610a6957602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610a305790505b5050505050905090565b600080546001600160a01b03163314610a9e5760405162461bcd60e51b81526004016108f190611a64565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168360405160006040518083038185875af1925050503d8060008114610b0b576040519150601f19603f3d011682016040523d82523d6000602084013e610b10565b606091505b5050905080610b545760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016108f1565b60405183907fa4e4b7031216965b449ed4f72176cb8d9fefc3ef42984463c7f4682481996dbf90600090a260019150505b919050565b61ffff8116600090815260046020908152604091829020805483518184028101840190945280845260609392830182828015610c0357602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411610bd45790505b50505050509050919050565b6000546001600160a01b03163314610c395760405162461bcd60e51b81526004016108f190611a64565b6001600160a01b038116610c9e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108f1565b610ca78161129a565b50565b6003546000908103610cfe5760405162461bcd60e51b815260206004820152601760248201527f494420616c6c6f636174696f6e2065786861757374656400000000000000000060448201526064016108f1565b6000610d09836112ea565b600354909150600090670de0b6b3a764000090610d268285611aaf565b610d309190611ac3565b610d3a9190611ae2565b9050600060038261ffff1681548110610d5557610d55611af6565b60009182526020808320601083040154600f9092166002026101000a90910461ffff16808352600490915260408220549092509003610fd8578061ffff16600003610eb857604080516103e0810182526000808252600160208084019190915260028385015260036060840152600460808401819052600660a0850152600760c0850152600860e08501526009610100850152600a610120850152600b610140850152600c610160850152600d610180850152600e6101a0850152600f6101c085015260106101e08501526011610200850152601261022085015260136102408501526014610260850152601561028085015260166102a085015260176102c085015260186102e08501526019610300850152601a610320850152601b610340850152601c610360850152601d610380850152601e6103a0850152601f6103c0850181905261ffff871684529152929020610eb29290919061166e565b50610fd8565b60408051610400810182526000808252600160208084019190915260028385015260036060840152600460808401819052600560a0850152600660c0850152600760e085015260086101008501526009610120850152600a610140850152600b610160850152600c610180850152600d6101a0850152600e6101c0850152600f6101e08501526010610200850152601161022085015260126102408501526013610260850152601461028085015260156102a085015260166102c085015260176102e085015260186103008501526019610320850152601a610340850152601b610360850152601c610380850152601d6103a0850152601e6103c0850152601f6103e085015261ffff861683528152929020610fd69290919061166e565b505b61ffff8116600090815260046020526040812054670de0b6b3a764000090816110106ec097ce7bc90715b34b9f100000000088611aaf565b61101a9190611ae2565b6110249190611ac3565b61102e9190611ae2565b905061103f602061ffff8416611ac3565b61ffff8316600090815260046020526040902080548390811061106457611064611af6565b90600052602060002090602091828204019190069054906101000a900460ff1660ff1661109191906119ff565b61ffff8316600090815260046020526040812054919650906110b590600190611b0c565b90508082146111515761ffff831660009081526004602052604090208054829081106110e3576110e3611af6565b60009182526020808320818304015461ffff87168452600490915260409092208054601f9092166101000a90920460ff1691908490811061112657611126611af6565b90600052602060002090602091828204019190066101000a81548160ff021916908360ff1602179055505b61ffff8316600090815260046020526040902080548061117357611173611b23565b60008281526020808220600019909301818104909301805460ff601f86166101000a02191690559190925561ffff851682526004905260408120549003611290576003546000906111c690600190611b0c565b9050808561ffff161461125157600381815481106111e6576111e6611af6565b90600052602060002090601091828204019190066002029054906101000a900461ffff1660038661ffff168154811061122157611221611af6565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055505b600380548061126257611262611b23565b600082815260209020601060001990920191820401805461ffff6002600f8516026101000a02191690559055505b5050505050919050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816000036113d8577f000000000000000000000000000000000000000000000000000000000000000060000361132c57611326600361146e565b92915050565b7f000000000000000000000000000000000000000000000000000000000000000060010361135e57611326600461146e565b7f000000000000000000000000000000000000000000000000000000000000000060020361139057611326600561146e565b60405162461bcd60e51b815260206004820152601960248201527f556e7265636f676e6973656420656e74726f7079206d6f64650000000000000060448201526064016108f1565b7f000000000000000000000000000000000000000000000000000000000000000060000361140a576113266003611550565b7f000000000000000000000000000000000000000000000000000000000000000060010361143c576113266004611550565b7f0000000000000000000000000000000000000000000000000000000000000000600203611390576113266005611550565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632636b0df600154866040518363ffffffff1660e01b81526004016114c491815260200190565b604080518083038185885af11580156114e1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906115069190611b39565b91509150816115495760405162461bcd60e51b815260206004820152600f60248201526e1258d94818d85b1b0819985a5b1959608a1b60448201526064016108f1565b9392505050565b60408051600180825281830190925260009182919060208083019080368337019050509050828160008151811061158957611589611af6565b60209081029190910101526002546040516326dcbb5b60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691634db976b691611605917f0000000000000000000000000000000000000000000000000000000000000000918690600401611b67565b6000604051808303816000875af1158015611624573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261164c9190810190611bc4565b60008151811061165e5761165e611af6565b6020026020010151915050919050565b82805482825590600052602060002090601f016020900481019282156117045791602002820160005b838211156116d557835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302611697565b80156117025782816101000a81549060ff02191690556001016020816000010492830192600103026116d5565b505b506106329291505b80821115610632576000815560010161170c565b80356001600160a01b0381168114610b8557600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561177657611776611737565b604052919050565b6000806000806080858703121561179457600080fd5b61179d85611720565b935060206117ac818701611720565b935060408601359250606086013567ffffffffffffffff808211156117d057600080fd5b818801915088601f8301126117e457600080fd5b8135818111156117f6576117f6611737565b611808601f8201601f1916850161174d565b9150808252898482850101111561181e57600080fd5b808484018584013760008482840101525080935050505092959194509250565b8015158114610ca757600080fd5b60008060006060848603121561186157600080fd5b833561186c8161183e565b95602085013595506040909401359392505050565b6000815180845260005b818110156118a75760208185018101518683018201520161188b565b818111156118b9576000602083870101525b50601f01601f19169290920160200192915050565b82151581526040602082015260006118e96040830184611881565b949350505050565b60006020828403121561190357600080fd5b5035919050565b60006020828403121561191c57600080fd5b81356115498161183e565b6020808252825182820181905260009190848201906040850190845b8181101561196357835161ffff1683529284019291840191600101611943565b50909695505050505050565b60006020828403121561198157600080fd5b813561ffff8116811461154957600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561196357835160ff16835292840192918401916001016119af565b6000602082840312156119e057600080fd5b61154982611720565b634e487b7160e01b600052601160045260246000fd5b60008219821115611a1257611a126119e9565b500190565b600061ffff808316818103611a2e57611a2e6119e9565b6001019392505050565b600060208284031215611a4a57600080fd5b5051919050565b6020815260006115496020830184611881565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601260045260246000fd5b600082611abe57611abe611a99565b500690565b6000816000190483118215151615611add57611add6119e9565b500290565b600082611af157611af1611a99565b500490565b634e487b7160e01b600052603260045260246000fd5b600082821015611b1e57611b1e6119e9565b500390565b634e487b7160e01b600052603160045260246000fd5b60008060408385031215611b4c57600080fd5b8251611b578161183e565b6020939093015192949293505050565b6001600160a01b038416815260208082018490526060604083018190528351908301819052600091848101916080850190845b81811015611bb657845183529383019391830191600101611b9a565b509098975050505050505050565b60006020808385031215611bd757600080fd5b825167ffffffffffffffff80821115611bef57600080fd5b818501915085601f830112611c0357600080fd5b815181811115611c1557611c15611737565b8060051b9150611c2684830161174d565b8181529183018401918481019088841115611c4057600080fd5b938501935b83851015611c5e57845182529385019390850190611c45565b9897505050505050505056fe596f7520686176652061207761737369652120507265737320746865206f7468657220627574746f6e20697427732063686561706572214d757374206861766520612077617373696520666f7220746869732070726963652e20506179206e6f726d69652070726963652c206f7220636865636b6f75742079656c6c6f77626972642e6574686572747265652e6f7267a2646970667358221220a1cf8f31527655850f872d0eb3217fb6e6d5edd66b56c4f97f488dda3f8edfc264736f6c634300080d0033000000000000000000000000e77c4e5e17ea350993cac2eb48bb50dbcccc956b0000000000000000000000001d20a51f088492a0f1c57f047a9e30c9ab5c07ea00000000000000000000000028b918b11d28ac3f28c363cede2cc816dca11b8a0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e57000000000000000000000000400a524420c464b9a8eba65614f297b5478ad6f3

Deployed Bytecode

0x6080604052600436106101855760003560e01c8063715018a6116100d1578063bc26c5c21161008a578063dd61db7811610064578063dd61db781461050c578063ec0f351d14610540578063f2fde38b1461056d578063f7044c7b1461058d57600080fd5b8063bc26c5c21461048d578063be37fbf2146104a8578063c311d049146104dc57600080fd5b8063715018a6146103d357806381016ac8146103e85780638d859f3e1461040a5780638da5cb5b146104255780639a34f65714610443578063ac5515761461047757600080fd5b80634c2a860d1161013e57806353959ad01161011857806353959ad01461034157806357bf223b1461037557806367eadae3146103a95780636eba9308146103be57600080fd5b80634c2a860d146102c35780634cf1115d146102f75780634ec27e0e1461030d57600080fd5b806313ffeeda14610194578063150b7a02146101bc5780631e23108d14610200578063233bd0c41461024c5780633251175b1461027a57806336654cc71461029057600080fd5b3661018f57600080fd5b600080fd5b3480156101a057600080fd5b506101a96105c1565b6040519081526020015b60405180910390f35b3480156101c857600080fd5b506101e76101d736600461177e565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016101b3565b34801561020c57600080fd5b506102347f00000000000000000000000028b918b11d28ac3f28c363cede2cc816dca11b8a81565b6040516001600160a01b0390911681526020016101b3565b34801561025857600080fd5b5061026c61026736600461184c565b610636565b6040516101b39291906118ce565b34801561028657600080fd5b506101a960025481565b34801561029c57600080fd5b506102b06102ab3660046118f1565b610866565b60405161ffff90911681526020016101b3565b3480156102cf57600080fd5b506102347f0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e5781565b34801561030357600080fd5b506101a960015481565b34801561031957600080fd5b506101a97f000000000000000000000000000000000000000000000000000000000000000081565b34801561034d57600080fd5b506102347f000000000000000000000000400a524420c464b9a8eba65614f297b5478ad6f381565b34801561038157600080fd5b506102347f0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e5781565b6103bc6103b736600461190a565b61089e565b005b3480156103ca57600080fd5b506003546101a9565b3480156103df57600080fd5b506103bc6109bd565b3480156103f457600080fd5b506103fd6109f3565b6040516101b39190611927565b34801561041657600080fd5b506101a96611c37937e0800081565b34801561043157600080fd5b506000546001600160a01b0316610234565b34801561044f57600080fd5b506102347f000000000000000000000000400a524420c464b9a8eba65614f297b5478ad6f381565b34801561048357600080fd5b506101a960055481565b34801561049957600080fd5b506101a966038d7ea4c6800081565b3480156104b457600080fd5b506102347f0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e5781565b3480156104e857600080fd5b506104fc6104f73660046118f1565b610a73565b60405190151581526020016101b3565b34801561051857600080fd5b506102347f000000000000000000000000e77c4e5e17ea350993cac2eb48bb50dbcccc956b81565b34801561054c57600080fd5b5061056061055b36600461196f565b610b8a565b6040516101b39190611993565b34801561057957600080fd5b506103bc6105883660046119ce565b610c0f565b34801561059957600080fd5b506102347f0000000000000000000000001d20a51f088492a0f1c57f047a9e30c9ab5c07ea81565b6000805b60035461ffff821610156106325761ffff811660009081526004602052604081205490036105ff576105f86020836119ff565b9150610620565b61ffff811660009081526004602052604090205461061d90836119ff565b91505b8061062a81611a17565b9150506105c5565b5090565b3360009081526006602052604081205460609060ff16156106875750506040805180820190915260158152744865792c206f6e65206561636820706c656173652160581b602082015260009061085e565b8284146106cc57505060408051808201909152601c81527f496e636f72726563742045544820616d6f756e74207061737365642e00000000602082015260009061085e565b84801561076157506040516370a0823160e01b81523360048201526001907f0000000000000000000000001d20a51f088492a0f1c57f047a9e30c9ab5c07ea6001600160a01b0316906370a0823190602401602060405180830381865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f9190611a38565b105b1561078a576000604051806080016040528060598152602001611ca2605991399150915061085e565b8415801561082057506040516370a0823160e01b81523360048201526000907f0000000000000000000000001d20a51f088492a0f1c57f047a9e30c9ab5c07ea6001600160a01b0316906370a0823190602401602060405180830381865afa1580156107fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081e9190611a38565b115b15610849576000604051806060016040528060378152602001611c6b603791399150915061085e565b50506040805160208101909152600081526001905b935093915050565b6003818154811061087657600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b600081156108b4575066038d7ea4c680006108be565b506611c37937e080005b600060606108cd843485610636565b909250905080826108fa5760405162461bcd60e51b81526004016108f19190611a51565b60405180910390fd5b507f000000000000000000000000e77c4e5e17ea350993cac2eb48bb50dbcccc956b6001600160a01b03166342842e0e30336109366000610caa565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561098557600080fd5b505af1158015610999573d6000803e3d6000fd5b5050336000908152600660205260409020805460ff19166001179055505050505050565b6000546001600160a01b031633146109e75760405162461bcd60e51b81526004016108f190611a64565b6109f1600061129a565b565b60606003805480602002602001604051908101604052809291908181526020018280548015610a6957602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610a305790505b5050505050905090565b600080546001600160a01b03163314610a9e5760405162461bcd60e51b81526004016108f190611a64565b60007f00000000000000000000000028b918b11d28ac3f28c363cede2cc816dca11b8a6001600160a01b03168360405160006040518083038185875af1925050503d8060008114610b0b576040519150601f19603f3d011682016040523d82523d6000602084013e610b10565b606091505b5050905080610b545760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016108f1565b60405183907fa4e4b7031216965b449ed4f72176cb8d9fefc3ef42984463c7f4682481996dbf90600090a260019150505b919050565b61ffff8116600090815260046020908152604091829020805483518184028101840190945280845260609392830182828015610c0357602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411610bd45790505b50505050509050919050565b6000546001600160a01b03163314610c395760405162461bcd60e51b81526004016108f190611a64565b6001600160a01b038116610c9e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108f1565b610ca78161129a565b50565b6003546000908103610cfe5760405162461bcd60e51b815260206004820152601760248201527f494420616c6c6f636174696f6e2065786861757374656400000000000000000060448201526064016108f1565b6000610d09836112ea565b600354909150600090670de0b6b3a764000090610d268285611aaf565b610d309190611ac3565b610d3a9190611ae2565b9050600060038261ffff1681548110610d5557610d55611af6565b60009182526020808320601083040154600f9092166002026101000a90910461ffff16808352600490915260408220549092509003610fd8578061ffff16600003610eb857604080516103e0810182526000808252600160208084019190915260028385015260036060840152600460808401819052600660a0850152600760c0850152600860e08501526009610100850152600a610120850152600b610140850152600c610160850152600d610180850152600e6101a0850152600f6101c085015260106101e08501526011610200850152601261022085015260136102408501526014610260850152601561028085015260166102a085015260176102c085015260186102e08501526019610300850152601a610320850152601b610340850152601c610360850152601d610380850152601e6103a0850152601f6103c0850181905261ffff871684529152929020610eb29290919061166e565b50610fd8565b60408051610400810182526000808252600160208084019190915260028385015260036060840152600460808401819052600560a0850152600660c0850152600760e085015260086101008501526009610120850152600a610140850152600b610160850152600c610180850152600d6101a0850152600e6101c0850152600f6101e08501526010610200850152601161022085015260126102408501526013610260850152601461028085015260156102a085015260166102c085015260176102e085015260186103008501526019610320850152601a610340850152601b610360850152601c610380850152601d6103a0850152601e6103c0850152601f6103e085015261ffff861683528152929020610fd69290919061166e565b505b61ffff8116600090815260046020526040812054670de0b6b3a764000090816110106ec097ce7bc90715b34b9f100000000088611aaf565b61101a9190611ae2565b6110249190611ac3565b61102e9190611ae2565b905061103f602061ffff8416611ac3565b61ffff8316600090815260046020526040902080548390811061106457611064611af6565b90600052602060002090602091828204019190069054906101000a900460ff1660ff1661109191906119ff565b61ffff8316600090815260046020526040812054919650906110b590600190611b0c565b90508082146111515761ffff831660009081526004602052604090208054829081106110e3576110e3611af6565b60009182526020808320818304015461ffff87168452600490915260409092208054601f9092166101000a90920460ff1691908490811061112657611126611af6565b90600052602060002090602091828204019190066101000a81548160ff021916908360ff1602179055505b61ffff8316600090815260046020526040902080548061117357611173611b23565b60008281526020808220600019909301818104909301805460ff601f86166101000a02191690559190925561ffff851682526004905260408120549003611290576003546000906111c690600190611b0c565b9050808561ffff161461125157600381815481106111e6576111e6611af6565b90600052602060002090601091828204019190066002029054906101000a900461ffff1660038661ffff168154811061122157611221611af6565b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055505b600380548061126257611262611b23565b600082815260209020601060001990920191820401805461ffff6002600f8516026101000a02191690559055505b5050505050919050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816000036113d8577f000000000000000000000000000000000000000000000000000000000000000060000361132c57611326600361146e565b92915050565b7f000000000000000000000000000000000000000000000000000000000000000060010361135e57611326600461146e565b7f000000000000000000000000000000000000000000000000000000000000000060020361139057611326600561146e565b60405162461bcd60e51b815260206004820152601960248201527f556e7265636f676e6973656420656e74726f7079206d6f64650000000000000060448201526064016108f1565b7f000000000000000000000000000000000000000000000000000000000000000060000361140a576113266003611550565b7f000000000000000000000000000000000000000000000000000000000000000060010361143c576113266004611550565b7f0000000000000000000000000000000000000000000000000000000000000000600203611390576113266005611550565b60008060007f0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e576001600160a01b0316632636b0df600154866040518363ffffffff1660e01b81526004016114c491815260200190565b604080518083038185885af11580156114e1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906115069190611b39565b91509150816115495760405162461bcd60e51b815260206004820152600f60248201526e1258d94818d85b1b0819985a5b1959608a1b60448201526064016108f1565b9392505050565b60408051600180825281830190925260009182919060208083019080368337019050509050828160008151811061158957611589611af6565b60209081029190910101526002546040516326dcbb5b60e11b81526001600160a01b037f000000000000000000000000400a524420c464b9a8eba65614f297b5478ad6f31691634db976b691611605917f0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e57918690600401611b67565b6000604051808303816000875af1158015611624573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261164c9190810190611bc4565b60008151811061165e5761165e611af6565b6020026020010151915050919050565b82805482825590600052602060002090601f016020900481019282156117045791602002820160005b838211156116d557835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302611697565b80156117025782816101000a81549060ff02191690556001016020816000010492830192600103026116d5565b505b506106329291505b80821115610632576000815560010161170c565b80356001600160a01b0381168114610b8557600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561177657611776611737565b604052919050565b6000806000806080858703121561179457600080fd5b61179d85611720565b935060206117ac818701611720565b935060408601359250606086013567ffffffffffffffff808211156117d057600080fd5b818801915088601f8301126117e457600080fd5b8135818111156117f6576117f6611737565b611808601f8201601f1916850161174d565b9150808252898482850101111561181e57600080fd5b808484018584013760008482840101525080935050505092959194509250565b8015158114610ca757600080fd5b60008060006060848603121561186157600080fd5b833561186c8161183e565b95602085013595506040909401359392505050565b6000815180845260005b818110156118a75760208185018101518683018201520161188b565b818111156118b9576000602083870101525b50601f01601f19169290920160200192915050565b82151581526040602082015260006118e96040830184611881565b949350505050565b60006020828403121561190357600080fd5b5035919050565b60006020828403121561191c57600080fd5b81356115498161183e565b6020808252825182820181905260009190848201906040850190845b8181101561196357835161ffff1683529284019291840191600101611943565b50909695505050505050565b60006020828403121561198157600080fd5b813561ffff8116811461154957600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561196357835160ff16835292840192918401916001016119af565b6000602082840312156119e057600080fd5b61154982611720565b634e487b7160e01b600052601160045260246000fd5b60008219821115611a1257611a126119e9565b500190565b600061ffff808316818103611a2e57611a2e6119e9565b6001019392505050565b600060208284031215611a4a57600080fd5b5051919050565b6020815260006115496020830184611881565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601260045260246000fd5b600082611abe57611abe611a99565b500690565b6000816000190483118215151615611add57611add6119e9565b500290565b600082611af157611af1611a99565b500490565b634e487b7160e01b600052603260045260246000fd5b600082821015611b1e57611b1e6119e9565b500390565b634e487b7160e01b600052603160045260246000fd5b60008060408385031215611b4c57600080fd5b8251611b578161183e565b6020939093015192949293505050565b6001600160a01b038416815260208082018490526060604083018190528351908301819052600091848101916080850190845b81811015611bb657845183529383019391830191600101611b9a565b509098975050505050505050565b60006020808385031215611bd757600080fd5b825167ffffffffffffffff80821115611bef57600080fd5b818501915085601f830112611c0357600080fd5b815181811115611c1557611c15611737565b8060051b9150611c2684830161174d565b8181529183018401918481019088841115611c4057600080fd5b938501935b83851015611c5e57845182529385019390850190611c45565b9897505050505050505056fe596f7520686176652061207761737369652120507265737320746865206f7468657220627574746f6e20697427732063686561706572214d757374206861766520612077617373696520666f7220746869732070726963652e20506179206e6f726d69652070726963652c206f7220636865636b6f75742079656c6c6f77626972642e6574686572747265652e6f7267a2646970667358221220a1cf8f31527655850f872d0eb3217fb6e6d5edd66b56c4f97f488dda3f8edfc264736f6c634300080d0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000e77c4e5e17ea350993cac2eb48bb50dbcccc956b0000000000000000000000001d20a51f088492a0f1c57f047a9e30c9ab5c07ea00000000000000000000000028b918b11d28ac3f28c363cede2cc816dca11b8a0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e57000000000000000000000000400a524420c464b9a8eba65614f297b5478ad6f3

-----Decoded View---------------
Arg [0] : etherTree_ (address): 0xe77c4E5e17Ea350993CAC2EB48BB50DbCcCc956B
Arg [1] : wassiesByWassies_ (address): 0x1D20A51F088492A0f1C57f047A9e30c9aB5C07Ea
Arg [2] : etherTreesury_ (address): 0x28B918B11D28ac3F28C363cEDE2cC816DCA11b8a
Arg [3] : ice_ (address): 0x7257B57cc14A749B75e1F073c15132F7Ac893E57
Arg [4] : oat_ (address): 0x400A524420c464b9A8EBa65614F297B5478aD6F3

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000e77c4e5e17ea350993cac2eb48bb50dbcccc956b
Arg [1] : 0000000000000000000000001d20a51f088492a0f1c57f047a9e30c9ab5c07ea
Arg [2] : 00000000000000000000000028b918b11d28ac3f28c363cede2cc816dca11b8a
Arg [3] : 0000000000000000000000007257b57cc14a749b75e1f073c15132f7ac893e57
Arg [4] : 000000000000000000000000400a524420c464b9a8eba65614f297b5478ad6f3


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.