ETH Price: $3,074.09 (-0.95%)

Contract

0xC1F04af99fc53DD3b74615AB47D8825EB98B7943
 
Transaction Hash
Method
Block
From
To
Harvest Rewards ...205464342024-08-17 6:03:5993 days ago1723874639IN
0xC1F04af9...EB98B7943
0 ETH0.001023610.97781583
Increase Referra...197186992024-04-23 14:30:47208 days ago1713882647IN
0xC1F04af9...EB98B7943
0 ETH0.0018992426.86112825
Increase Referra...186337562023-11-23 10:12:47361 days ago1700734367IN
0xC1F04af9...EB98B7943
0 ETH0.0018521428.37928952
Increase Referra...185203372023-11-07 13:20:23377 days ago1699363223IN
0xC1F04af9...EB98B7943
0 ETH0.0029232725.07874983
Harvest Rewards ...176174572023-07-04 2:00:23503 days ago1688436023IN
0xC1F04af9...EB98B7943
0 ETH0.0477251525.43762203
Harvest Rewards ...176173952023-07-04 1:47:47503 days ago1688435267IN
0xC1F04af9...EB98B7943
0 ETH0.0256621414.06284404
Harvest Rewards ...175736462023-06-27 22:26:47509 days ago1687904807IN
0xC1F04af9...EB98B7943
0 ETH0.0272076613.06613939
Harvest Rewards ...175095572023-06-18 22:13:35518 days ago1687126415IN
0xC1F04af9...EB98B7943
0 ETH0.0288055613.76978777
Harvest Rewards ...174686442023-06-13 4:16:11524 days ago1686629771IN
0xC1F04af9...EB98B7943
0 ETH0.0285163315.03834794
Harvest Rewards ...174685552023-06-13 3:57:59524 days ago1686628679IN
0xC1F04af9...EB98B7943
0 ETH0.0289264315.40855448
Harvest Rewards ...169719862023-04-04 0:19:11594 days ago1680567551IN
0xC1F04af9...EB98B7943
0 ETH0.0645499224.86087594
Increase Referra...168262882023-03-14 12:48:47615 days ago1678798127IN
0xC1F04af9...EB98B7943
0 ETH0.0064854563.00964084
Increase Referra...168262112023-03-14 12:33:23615 days ago1678797203IN
0xC1F04af9...EB98B7943
0 ETH0.0035565950.30122583
Harvest Rewards ...168168762023-03-13 5:05:59616 days ago1678683959IN
0xC1F04af9...EB98B7943
0 ETH0.0256226416.10679691
Harvest Rewards ...168168732023-03-13 5:05:23616 days ago1678683923IN
0xC1F04af9...EB98B7943
0 ETH0.0271105616.76605539
Harvest Rewards ...168090842023-03-12 2:48:47617 days ago1678589327IN
0xC1F04af9...EB98B7943
0 ETH0.0210618618.78508011
Harvest Rewards ...168085092023-03-12 0:51:47617 days ago1678582307IN
0xC1F04af9...EB98B7943
0 ETH0.0453068722.71533916
Harvest Rewards ...167835982023-03-08 12:40:47621 days ago1678279247IN
0xC1F04af9...EB98B7943
0 ETH0.0397631325.80883698
Harvest Rewards ...167825362023-03-08 9:05:35621 days ago1678266335IN
0xC1F04af9...EB98B7943
0 ETH0.0510161320.08178049
Harvest Rewards ...167597562023-03-05 4:13:23624 days ago1677989603IN
0xC1F04af9...EB98B7943
0 ETH0.0107829821.56596131
Configure Metast...167401972023-03-02 10:09:47627 days ago1677751787IN
0xC1F04af9...EB98B7943
0 ETH0.0006866620.26342569
Configure Metast...167401902023-03-02 10:08:23627 days ago1677751703IN
0xC1F04af9...EB98B7943
0 ETH0.0006634321.54985189
Increase Referra...167267512023-02-28 12:47:23629 days ago1677588443IN
0xC1F04af9...EB98B7943
0 ETH0.0025396121.5780801
Increase Referra...166214482023-02-13 17:52:59643 days ago1676310779IN
0xC1F04af9...EB98B7943
0 ETH0.0032277532.42806588
Increase Referra...165897622023-02-09 7:39:11648 days ago1675928351IN
0xC1F04af9...EB98B7943
0 ETH0.0022081821.87380282
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ReferralFarmsV1

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license
File 1 of 7 : ReferralFarmsV1.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.14;

//
//                                 (((((((((((()                                 
//                              (((((((((((((((((((                              
//                            ((((((           ((((((                            
//                           (((((               (((((                           
//                         (((((/                 ((((((                         
//                        (((((                     (((((                        
//                      ((((((                       ((((()                      
//                     (((((                           (((((                     
//                   ((((((                             (((((                    
//                  (((((                                                        
//                ((((((                        (((((((((((((((                  
//               (((((                       (((((((((((((((((((((               
//             ((((((                      ((((((             (((((.             
//            (((((                      ((((((.               ((((((            
//          ((((((                     ((((((((                  (((((           
//         (((((                      (((((((((                   ((((((         
//        (((((                     ((((((.(((((                    (((((        
//       (((((                     ((((((   (((((                    (((((       
//      (((((                    ((((((      ((((((                   (((((      
//      ((((.                  ((((((          (((((                  (((((      
//      (((((                .((((((            ((((((                (((((      
//       ((((()            (((((((                (((((             ((((((       
//        .(((((((      (((((((.                   ((((((((     ((((((((         
//           ((((((((((((((((                         ((((((((((((((((           
//                .((((.                                    (((()         
//                                  
//                               attrace.com
//

// import "hardhat/console.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "../chainAddress/ChainAddress.sol";
import "../interfaces/IERC20.sol";
import "../confirmations/types.sol";
// import "../oracles/OracleEffectsV1.sol";
// import "../support/DevRescuableOnTestnets.sol";

// Attrace Referral Farms V1
//
// A farm can be thought of as a "farm deposit". A single owner can have multiple deposits for different reward tokens and different farms.
// Token farms aggregated are a virtual/logical concept: UI's can render and groups these together as "Farms per token" and can group further "Aggregated farming value per token" and so on.
//
// This contract manages these deposits by sponsor (sponsor=msg.sender).
contract ReferralFarmsV1 is Ownable {

  // Pointer to oracles confirmations contract
  ConfirmationsResolver confirmationsAddr;

  // The farm reward token deposits remaining
  // farmHash => deposit remaining
  // Where farmHash = hash(encode(chainId,sponsor,rewardTokenDefn,referredTokenDefn))
  mapping(bytes32 => uint256) private farmDeposits;

  // Mapping which tracks which effects have been executed at the account token level (and thus are burned).
  // account => token => offset
  mapping(address => mapping(address => uint256)) private accountTokenConfirmationOffsets;

  // Mapping which tracks which effects have been executed at the farm level (and thus are burned).
  // Tracks sponsor withdraw offsets.
  // farmHash => offset
  mapping(bytes32 => uint256) private farmConfirmationOffsets;

  // Max-reward value per farm/confirmation, used by claim flows to act as a fail-safe to ensure the rewards don't overflow in the unlikely event of a bug/attack.
  mapping(bytes32 => uint256) private farmConfirmationRewardMax;

  // Tracks the remaining rewards that can be transferred per confirmation
  // farmHash -> confirmation number -> { initialized, valueRemaining }
  mapping(bytes32 => mapping(uint256 => FarmConfirmationRewardRemaining)) private farmConfirmationRewardRemaining;

  // Emitted whenever a farm is increased (which guarantees creation). Occurs multiple times per farm.
  event FarmExists(address indexed sponsor, bytes24 indexed rewardTokenDefn, bytes24 indexed referredTokenDefn, bytes32 farmHash);

  // Emitted whenever a farm is increased
  event FarmDepositIncreased(bytes32 indexed farmHash, uint128 delta);

  // Emitted when a sponsor _requests_ to withdraw their funds.
  // UI's can use the value here to indicate the change to the farm.
  // Promoters can be notified to stop promoting this farm.
  event FarmDepositDecreaseRequested(bytes32 indexed farmHash, uint128 value, uint128 confirmation);

  // Emitted whenever a farm deposit decrease is claimed
  event FarmDepositDecreaseClaimed(bytes32 indexed farmHash, uint128 delta);

  // Dynamic field to control farm behavior. 
  event FarmMetastate(bytes32 indexed farmHash, bytes32 indexed key, bytes value);

  // Emitted when rewards have been harvested by an account
  event RewardsHarvested(address indexed caller, bytes24 indexed rewardTokenDefn, bytes32 indexed farmHash, uint128 value, bytes32 leafHash);

  bytes32 constant CONFIRMATION_REWARD = "confirmationReward";

  function configure(address confirmationsAddr_) external onlyOwner {
    confirmationsAddr = ConfirmationsResolver(confirmationsAddr_);
  }

  function getFarmDepositRemaining(bytes32 farmHash) external view returns (uint256) {
    return farmDeposits[farmHash];
  }

  // Returns the confirmation offset per account per reward token
  function getAccountTokenConfirmationOffset(address account, address token) external view returns (uint256) {
    return accountTokenConfirmationOffsets[account][token];
  }

  // Getter to step through the history of farm confirmation rewards over time
  function getFarmConfirmationRewardMax(bytes32 farmHash) external view returns (uint256) {
    return farmConfirmationRewardMax[farmHash];
  }

  // Increase referral farm using ERC20 reward token (also creates any non-existing farm)
  function increaseReferralFarm(bytes24 rewardTokenDefn, bytes24 referredTokenDefn, uint128 rewardDeposit, KeyVal[] calldata metastate) external {
    require(
      rewardDeposit > 0 && rewardTokenDefn != ChainAddressExt.getNativeTokenChainAddress(), 
      "400: invalid"
    );

    // First transfer the reward token deposit to this
    IERC20(ChainAddressExt.toAddress(rewardTokenDefn)).transferFrom(msg.sender, address(this), uint256(rewardDeposit));

    // Increase the farm (this doubles as security)
    bytes32 farmHash = toFarmHash(msg.sender, rewardTokenDefn, referredTokenDefn);
    farmDeposits[farmHash] += rewardDeposit;
    
    // Inform listeners about this new farm and allow discovering the farmHash (since we don't store it)
    emit FarmExists(msg.sender, rewardTokenDefn, referredTokenDefn, farmHash);

    // Emit creation and increase of deposit
    emit FarmDepositIncreased(farmHash, rewardDeposit);

    // Handle metastate
    handleMetastateChange(farmHash, metastate);
  }

  // Configure additional metastate for a farm
  function configureMetastate(bytes24 rewardTokenDefn, bytes24 referredTokenDefn, KeyVal[] calldata metastate) external {
    // FarmHash calculation doubles as security
    bytes32 farmHash = toFarmHash(msg.sender, rewardTokenDefn, referredTokenDefn);
    handleMetastateChange(farmHash, metastate);
  }

  function handleMetastateChange(bytes32 farmHash, KeyVal[] calldata metastate) private {
    for(uint256 i = 0; i < metastate.length; i++) {
      // Manage the confirmation reward rate changes
      if(metastate[i].key == CONFIRMATION_REWARD) {
        processConfirmationRewardChangeRequest(farmHash, metastate[i].value);
      }

      emit FarmMetastate(farmHash, metastate[i].key, metastate[i].value);
    }

    // Checks if the confirmationReward has at least one value or throws error that it's required
    require(farmConfirmationRewardMax[farmHash] > 0, "400: confirmationReward");
  }

  // It should be impossible to change history.
  function processConfirmationRewardChangeRequest(bytes32 farmHash, bytes calldata value) private {
    (uint128 reward, ) = abi.decode(value, (uint128, uint128));
    if(reward > farmConfirmationRewardMax[farmHash]) {
      farmConfirmationRewardMax[farmHash] = reward;
    }
  }

  // -- HARVEST REWARDS

  // Validates against double spend
  function validateEntitlementsSetOffsetOrRevert(address rewardToken, TokenEntitlement[] calldata entitlements) private {
    require(entitlements.length > 0, "400: entitlements");
    uint128 min = entitlements[0].confirmation;
    uint128 max;
    
    // Search min/max from list
    for(uint256 i = 0; i < entitlements.length; i++) {
      if(entitlements[i].confirmation < min) {
        min = entitlements[i].confirmation;
      }
      if(entitlements[i].confirmation > max) {
        max = entitlements[i].confirmation;
      }
    }
    
    // Validate against double spend
    require(accountTokenConfirmationOffsets[msg.sender][rewardToken] < min, "401: double spend");

    // Store the new offset to protect against double spend
    accountTokenConfirmationOffsets[msg.sender][rewardToken] = max;
  }

  // Check the requested amount against the limits and update confirmation remaining value to protect against re-entrancy
  function adjustFarmConfirmationRewardRemainingOrRevert(bytes32 farmHash, uint128 confirmation, uint128 value) private {
    // Find reward remaining or initialize the first time it's used
    uint128 rewardRemaining;
    if(farmConfirmationRewardRemaining[farmHash][confirmation].initialized == false) {
      // First initializes the farmConfirmationRewardRemaining...valueRemaining
      rewardRemaining = uint128(farmConfirmationRewardMax[farmHash]); 
    } else {
      rewardRemaining = farmConfirmationRewardRemaining[farmHash][confirmation].valueRemaining;
    }

    // Adjust reward
    rewardRemaining -= value; // Underflow will throw here on insufficient confirmation balance.
    farmConfirmationRewardRemaining[farmHash][confirmation] = FarmConfirmationRewardRemaining(true, rewardRemaining);

    // Ensure sufficient deposit is left for this farm
    farmDeposits[farmHash] -= value; // Underflow will throw here on insufficient balance.
  }

  // Collect rewards entitled by the oracles.
  // Function has been tested to support 2000 requests, each carrying 20 proofs.
  function harvestRewardsNoGapcheck(HarvestTokenRequest[] calldata reqs, bytes32[][][] calldata proofs) external {
    require(reqs.length > 0 && proofs.length == reqs.length, "400: request");

    // Execute requests by reward token
    for(uint256 i = 0; i < reqs.length; i++) {
      HarvestTokenRequest calldata req = reqs[i];
      require(uint32(block.chainid) == ChainAddressExt.toChainId(req.rewardTokenDefn), "400: chain");
      address rewardTokenAddr = ChainAddressExt.toAddress(req.rewardTokenDefn);

      // Validate nonces and protects against re-entrancy.
      validateEntitlementsSetOffsetOrRevert(rewardTokenAddr, reqs[i].entitlements);

      // Check entitlements and sum reward value
      uint128 rewardValueSum = 0;
      for(uint256 j = 0; j < req.entitlements.length; j++) {
        TokenEntitlement calldata entitlement = req.entitlements[j];

        // Check if its a valid call
        bytes32 leafHash = makeLeafHash(req.rewardTokenDefn, entitlement);
        bytes32 computedHash = MerkleProof.processProof(proofs[i][j], leafHash);
        // bytes32 computedHash = OracleEffectsV1.computeRoot(leafHash, proofs[i][j]);
        (uint128 confirmation, ) = confirmationsAddr.getConfirmation(computedHash);
        require(confirmation > 0, "401: not finalized proof");  

        adjustFarmConfirmationRewardRemainingOrRevert(entitlement.farmHash, entitlement.confirmation, entitlement.value);

        emit RewardsHarvested(msg.sender, req.rewardTokenDefn, entitlement.farmHash, entitlement.value, leafHash);

        rewardValueSum += entitlement.value;
      }

      // Transfer the value using ERC20 implementation
      if(rewardValueSum > 0) {
        IERC20(rewardTokenAddr).transfer(msg.sender, rewardValueSum);
      }
    }
  }

  // -- Sponsor withdrawals

  // Called by a sponsor to request extracting (unused) funds.
  // This will be picked up by the oracle, who will reduce the deposit in it's state and provide a valid claim for extracting the value.
  function requestDecreaseReferralFarm(bytes24 rewardTokenDefn, bytes24 referredTokenDefn, uint128 value) external {
    // Farm hash doubles as security
    bytes32 farmHash = toFarmHash(msg.sender, rewardTokenDefn, referredTokenDefn);
    require(farmDeposits[farmHash] > 0, "400: deposit");

    // For good ux, replace value here with max if it overflows the deposit
    if(value > farmDeposits[farmHash]) {
      value = uint128(farmDeposits[farmHash]);
    }
    
    // Emit event for oracle trie calculation
    (uint128 headConfirmation, ) = confirmationsAddr.getConfirmation(confirmationsAddr.getHead());
    emit FarmDepositDecreaseRequested(farmHash, value, headConfirmation);
  }

  // Can be called by the sponsor after the confirmation has included the decrease request.
  // Sponsor then collects a proof which allows to extract the value.
  function claimReferralFarmDecrease(bytes24 rewardTokenDefn, bytes24 referredTokenDefn, uint128 confirmation, uint128 value, bytes32[] calldata proof) external {
    // Farm hash doubles as security
    bytes32 farmHash = toFarmHash(msg.sender, rewardTokenDefn, referredTokenDefn);

    // Check if this request is already burned (protect against double-spend and re-entrancy)
    require(confirmation > farmConfirmationOffsets[farmHash], "400: invalid or burned");

    // Burn the request
    farmConfirmationOffsets[farmHash] = confirmation;

    // Calculate leaf hash
    bytes32 leafHash = makeDecreaseLeafHash(farmHash, confirmation, value);
    
    // Check that the proof is valid (the oracle keeps a state of decrease requests, requests are bound to their request confirmation)
    // bytes32 computedHash = OracleEffectsV1.computeRoot(leafHash, proof);
    bytes32 computedHash = MerkleProof.processProof(proof, leafHash);
    (uint128 searchConfirmation, ) = confirmationsAddr.getConfirmation(computedHash);
    require(searchConfirmation > 0, "401: not finalized proof");

    // Failsafe against any bugs
    if(farmDeposits[farmHash] < value) {
      value = uint128(farmDeposits[farmHash]);
    }

    // Avoid re-entrancy on value before transfer
    farmDeposits[farmHash] -= value;

    // Transfer the value
    address rewardTokenAddr = ChainAddressExt.toAddress(rewardTokenDefn);
    IERC20(rewardTokenAddr).transfer(msg.sender, value);

    // Emit event of decrease in farm value
    emit FarmDepositDecreaseClaimed(farmHash, value);
  }

  function makeLeafHash(bytes24 rewardTokenDefn, TokenEntitlement calldata entitlement) private view returns (bytes32) {
    return keccak256(abi.encode(
      ChainAddressExt.toChainAddress(block.chainid, address(confirmationsAddr)), 
      ChainAddressExt.toChainAddress(block.chainid, address(this)),
      msg.sender, 
      rewardTokenDefn,
      entitlement
    ));
  }

  function makeDecreaseLeafHash(bytes32 farmHash, uint128 confirmation, uint128 value) private view returns (bytes32) {
    return keccak256(abi.encode(
      ChainAddressExt.toChainAddress(block.chainid, address(confirmationsAddr)), 
      ChainAddressExt.toChainAddress(block.chainid, address(this)),
      farmHash,
      confirmation,
      value
    ));
  }

  // -- don't accept raw ether
  receive() external payable {
    revert('unsupported');
  }

  // -- reject any other function
  fallback() external payable {
    revert('unsupported');
  }
}

struct KeyVal {
  bytes32 key;
  bytes value;
}

struct FarmConfirmationRewardRemaining {
  bool initialized;
  uint128 valueRemaining;
}

// Entitlements for a reward token
struct HarvestTokenRequest {
  // The reward token
  bytes24 rewardTokenDefn;

  // Entitlements for this token which can be verified against the confirmation hashes
  TokenEntitlement[] entitlements;
}

// An entitlement to token value, which can be harvested, if confirmed by the oracles
struct TokenEntitlement {
  // The farm deposit
  bytes32 farmHash;

  // Reward token value which can be harvested
  uint128 value;

  // The confirmation number during which this entitlement was generated
  uint128 confirmation;
}

// Farm Hash - represents a single sponsor owned farm.
function toFarmHash(address sponsor, bytes24 rewardTokenDefn, bytes24 referredTokenDefn) view returns (bytes32 farmHash) {
  return keccak256(abi.encode(block.chainid, sponsor, rewardTokenDefn, referredTokenDefn));
}

File 2 of 7 : ChainAddress.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.14;

// import "hardhat/console.sol";

// Core new data type: *`chaddress`*, an address with chain information encoded into it.
// bytes24 with 4 chainId bytes followed by 20 address bytes.
//
// example for 0xAA97FED7413A944118Db403Ce65116DCc4D381E2 addr on chainId 1:
// hex-encoded: 0x00000001aa97fed7413a944118db403ce65116dcc4d381e2
// eg:           [ChainId.Address.................................]
// hex-parts:   0x[00000001][aa97fed7413a944118db403ce65116dcc4d381e2]

// Hardhat-upgrades doesn't support user defined types..
// type ChainAddress is bytes24;

// Helper tooling for ChainAddress
library ChainAddressExt {

  function toChainId(bytes24 chAddr) internal pure returns (uint32 chainId) {
    return uint32(bytes4(chAddr)); // Slices off the first 4 bytes
  }

  function toAddress(bytes24 chAddr) internal pure returns (address addr) {
    return address(bytes20(bytes24(uint192(chAddr) << 32)));
  }

  function toChainAddress(uint256 chainId, address addr) internal pure returns (bytes24) {
    uint192 a = uint192(chainId);
    a = a << 160;
    a = a | uint160(addr);
    return bytes24(a);
  }

  // For the native token we set twice the chainId (which is easily checked, identifies different chains and distinguishes from real addresses)
  function getNativeTokenChainAddress() internal view returns (bytes24) {
    // [NNNN AAAAAAAAAAAAAAAAAAAA]
    // [0001 00000000000000000001] for eth-mainnet chainId: 1
    uint192 rewardToken = uint192(block.chainid);
    rewardToken = rewardToken << 160;
    rewardToken = rewardToken | uint160(block.chainid);
    return bytes24(rewardToken);
  }
}

File 3 of 7 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.14;

/**
 * @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);
}

File 4 of 7 : types.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.14;

interface ConfirmationsResolver {
  function getHead() external view returns(bytes32);
  function getConfirmation(bytes32 confirmationHash) external view returns (uint128 number, uint64 timestamp);
}

File 5 of 7 : 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 7 : 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 7 of 7 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"farmHash","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"delta","type":"uint128"}],"name":"FarmDepositDecreaseClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"farmHash","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"value","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"confirmation","type":"uint128"}],"name":"FarmDepositDecreaseRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"farmHash","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"delta","type":"uint128"}],"name":"FarmDepositIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"indexed":true,"internalType":"bytes24","name":"referredTokenDefn","type":"bytes24"},{"indexed":false,"internalType":"bytes32","name":"farmHash","type":"bytes32"}],"name":"FarmExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"farmHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"value","type":"bytes"}],"name":"FarmMetastate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"indexed":true,"internalType":"bytes32","name":"farmHash","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"value","type":"uint128"},{"indexed":false,"internalType":"bytes32","name":"leafHash","type":"bytes32"}],"name":"RewardsHarvested","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"internalType":"bytes24","name":"referredTokenDefn","type":"bytes24"},{"internalType":"uint128","name":"confirmation","type":"uint128"},{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"claimReferralFarmDecrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"confirmationsAddr_","type":"address"}],"name":"configure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"internalType":"bytes24","name":"referredTokenDefn","type":"bytes24"},{"components":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct KeyVal[]","name":"metastate","type":"tuple[]"}],"name":"configureMetastate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getAccountTokenConfirmationOffset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"farmHash","type":"bytes32"}],"name":"getFarmConfirmationRewardMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"farmHash","type":"bytes32"}],"name":"getFarmDepositRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"components":[{"internalType":"bytes32","name":"farmHash","type":"bytes32"},{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"uint128","name":"confirmation","type":"uint128"}],"internalType":"struct TokenEntitlement[]","name":"entitlements","type":"tuple[]"}],"internalType":"struct HarvestTokenRequest[]","name":"reqs","type":"tuple[]"},{"internalType":"bytes32[][][]","name":"proofs","type":"bytes32[][][]"}],"name":"harvestRewardsNoGapcheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"internalType":"bytes24","name":"referredTokenDefn","type":"bytes24"},{"internalType":"uint128","name":"rewardDeposit","type":"uint128"},{"components":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct KeyVal[]","name":"metastate","type":"tuple[]"}],"name":"increaseReferralFarm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes24","name":"rewardTokenDefn","type":"bytes24"},{"internalType":"bytes24","name":"referredTokenDefn","type":"bytes24"},{"internalType":"uint128","name":"value","type":"uint128"}],"name":"requestDecreaseReferralFarm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611d018061007e6000396000f3fe6080604052600436106100ab5760003560e01c80638da5cb5b116100645780638da5cb5b14610211578063ab77722a14610239578063b489580414610266578063ee250db114610293578063f2fde38b146102b3578063f36683f9146102d3576100eb565b80630efe42f714610121578063617700d11461014357806368ddd2d514610163578063715018a61461018357806375cb26721461019857806380fb7c00146101b8576100eb565b366100eb5760405162461bcd60e51b815260206004820152600b60248201526a1d5b9cdd5c1c1bdc9d195960aa1b60448201526064015b60405180910390fd5b60405162461bcd60e51b815260206004820152600b60248201526a1d5b9cdd5c1c1bdc9d195960aa1b60448201526064016100e2565b34801561012d57600080fd5b5061014161013c36600461167f565b6102f3565b005b34801561014f57600080fd5b5061014161015e36600461171e565b610745565b34801561016f57600080fd5b5061014161017e366004611765565b6108f4565b34801561018f57600080fd5b50610141610add565b3480156101a457600080fd5b506101416101b33660046117f4565b610b13565b3480156101c457600080fd5b506101fe6101d3366004611816565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6040519081526020015b60405180910390f35b34801561021d57600080fd5b506000546040516001600160a01b039091168152602001610208565b34801561024557600080fd5b506101fe610254366004611849565b60009081526002602052604090205490565b34801561027257600080fd5b506101fe610281366004611849565b60009081526005602052604090205490565b34801561029f57600080fd5b506101416102ae366004611862565b610b5f565b3480156102bf57600080fd5b506101416102ce3660046117f4565b610e34565b3480156102df57600080fd5b506101416102ee3660046118ec565b610ecf565b821580159061030157508083145b61033c5760405162461bcd60e51b815260206004820152600c60248201526b0d0c0c0e881c995c5d595cdd60a21b60448201526064016100e2565b60005b8381101561073e573685858381811061035a5761035a611941565b905060200281019061036c9190611957565b905061038461037e6020830183611977565b60e01c90565b63ffffffff164663ffffffff16146103cb5760405162461bcd60e51b815260206004820152600a6024820152691a18181d1031b430b4b760b11b60448201526064016100e2565b60006103ec6103dd6020840184611977565b60401c6001600160a01b031690565b90506104298188888681811061040457610404611941565b90506020028101906104169190611957565b610424906020810190611992565b610ee9565b6000805b61043a6020850185611992565b905081101561069d57366104516020860186611992565b8381811061046157610461611941565b6060029190910191506000905061048461047e6020880188611977565b83611101565b9050600061050a8a8a8a81811061049d5761049d611941565b90506020028101906104af91906119db565b868181106104bf576104bf611941565b90506020028101906104d191906119db565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525086925061115a915050565b60015460405163175a021f60e21b8152600481018390529192506000916001600160a01b0390911690635d68087c906024016040805180830381865afa158015610558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057c9190611a25565b5090506000816001600160801b0316116105d35760405162461bcd60e51b81526020600482015260186024820152771a18189d103737ba103334b730b634bd32b210383937b7b360411b60448201526064016100e2565b6105fd84356105e86060870160408801611a6c565b6105f86040880160208901611a6c565b611206565b833561060c60208a018a611977565b67ffffffffffffffff1916337fe54a9dd2276641948cf7ebe9936fba7758c340a2de1ffabba6bbd8d0bb86029e6106496040890160208a01611a6c565b604080516001600160801b039092168252602082018990520160405180910390a461067a6040850160208601611a6c565b6106849087611a9f565b955050505050808061069590611aca565b91505061042d565b506001600160801b038116156107285760405163a9059cbb60e01b81523360048201526001600160801b03821660248201526001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610702573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107269190611ae3565b505b505050808061073690611aca565b91505061033f565b5050505050565b6000610752338585611324565b60008181526002602052604090205490915061079f5760405162461bcd60e51b815260206004820152600c60248201526b0d0c0c0e8819195c1bdcda5d60a21b60448201526064016100e2565b6000818152600260205260409020546001600160801b03831611156107d05760008181526002602052604090205491505b6001546040805163dc281aff60e01b815290516000926001600160a01b031691635d68087c91839163dc281aff9160048083019260209291908290030181865afa158015610822573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108469190611b05565b6040518263ffffffff1660e01b815260040161086491815260200190565b6040805180830381865afa158015610880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a49190611a25565b50604080516001600160801b0380871682528316602082015291925083917fca5f2e28300a7455e8eb9bbce87f2b391ea690d75170cff5e8a34ccb2f51bce3910160405180910390a25050505050565b6000836001600160801b031611801561093a57504660a081901b6001600160a01b0319166001600160a01b03919091161760401b67ffffffffffffffff19868116911614155b6109755760405162461bcd60e51b815260206004820152600c60248201526b0d0c0c0e881a5b9d985b1a5960a21b60448201526064016100e2565b604085901c6001600160a01b03166040516323b872dd60e01b81523360048201523060248201526001600160801b03851660448201526001600160a01b0391909116906323b872dd906064016020604051808303816000875af11580156109e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a049190611ae3565b506000610a12338787611324565b9050836001600160801b0316600260008381526020019081526020016000206000828254610a409190611b1e565b909155505060405181815267ffffffffffffffff19868116919088169033907f46401a1ea83c45ef34b64281c8161df97eaf1b1b25ed2a5866c7dc6a1503150f9060200160405180910390a46040516001600160801b038516815281907faec8623c192e1b4252b6bec8033c0e1a3c473b882a43041578660d768b9d8d8b9060200160405180910390a2610ad581848461137e565b505050505050565b6000546001600160a01b03163314610b075760405162461bcd60e51b81526004016100e290611b36565b610b116000611506565b565b6000546001600160a01b03163314610b3d5760405162461bcd60e51b81526004016100e290611b36565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b6c338888611324565b6000818152600460205260409020549091506001600160801b03861611610bce5760405162461bcd60e51b81526020600482015260166024820152750d0c0c0e881a5b9d985b1a59081bdc88189d5c9b995960521b60448201526064016100e2565b60008181526004602052604081206001600160801b0387169055610bf3828787611556565b90506000610c3585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525086925061115a915050565b60015460405163175a021f60e21b8152600481018390529192506000916001600160a01b0390911690635d68087c906024016040805180830381865afa158015610c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca79190611a25565b5090506000816001600160801b031611610cfe5760405162461bcd60e51b81526020600482015260186024820152771a18189d103737ba103334b730b634bd32b210383937b7b360411b60448201526064016100e2565b6000848152600260205260409020546001600160801b0388161115610d2f5760008481526002602052604090205496505b600084815260026020526040812080546001600160801b038a169290610d56908490611b6b565b909155506000905060408b901c6001600160a01b031660405163a9059cbb60e01b81523360048201526001600160801b038a1660248201529091506001600160a01b0382169063a9059cbb906044016020604051808303816000875af1158015610dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de89190611ae3565b506040516001600160801b038916815285907fb7413b5fb0f1cfb1bb023023ca81aa091943e1b70b9049c85c2121617cc40bdf9060200160405180910390a25050505050505050505050565b6000546001600160a01b03163314610e5e5760405162461bcd60e51b81526004016100e290611b36565b6001600160a01b038116610ec35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016100e2565b610ecc81611506565b50565b6000610edc338686611324565b905061073e81848461137e565b80610f2a5760405162461bcd60e51b81526020600482015260116024820152703430303a20656e7469746c656d656e747360781b60448201526064016100e2565b600082826000818110610f3f57610f3f611941565b9050606002016040016020810190610f579190611a6c565b90506000805b8381101561105757826001600160801b0316858583818110610f8157610f81611941565b9050606002016040016020810190610f999190611a6c565b6001600160801b03161015610fd557848482818110610fba57610fba611941565b9050606002016040016020810190610fd29190611a6c565b92505b816001600160801b0316858583818110610ff157610ff1611941565b90506060020160400160208101906110099190611a6c565b6001600160801b031611156110455784848281811061102a5761102a611941565b90506060020160400160208101906110429190611a6c565b91505b8061104f81611aca565b915050610f5d565b503360009081526003602090815260408083206001600160a01b03891684529091529020546001600160801b038316116110c75760405162461bcd60e51b81526020600482015260116024820152700d0c0c4e88191bdd589b19481cdc195b99607a1b60448201526064016100e2565b3360009081526003602090815260408083206001600160a01b03989098168352969052949094206001600160801b03909416909355505050565b60015460009061111b9046906001600160a01b03166115be565b61112546306115be565b33858560405160200161113c959493929190611b82565b60405160208183030381529060405280519060200120905092915050565b600081815b84518110156111fe57600085828151811061117c5761117c611941565b602002602001015190508083116111be5760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506111eb565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b50806111f681611aca565b91505061115f565b509392505050565b60008381526006602090815260408083206001600160801b038616845290915281205460ff16151581036112495750600083815260056020526040902054611275565b5060008381526006602090815260408083206001600160801b0380871685529252909120546101009004165b61127f8282611bff565b604080518082018252600181526001600160801b03838116602080840191825260008a8152600682528581208a85168252825285812094518554935170ffffffffffffffffffffffffffffffffff1990941690151570ffffffffffffffffffffffffffffffff0019161761010093851693909302929092179093558881526002909252918120805493945091851692611319908490611b6b565b909155505050505050565b604080514660208201526001600160a01b0385169181019190915267ffffffffffffffff1980841660608301528216608082015260009060a0015b6040516020818303038152906040528051906020012090509392505050565b60005b818110156114a5577118dbdb999a5c9b585d1a5bdb94995dd85c9960721b8383838181106113b1576113b1611941565b90506020028101906113c39190611957565b350361140457611404848484848181106113df576113df611941565b90506020028101906113f19190611957565b6113ff906020810190611c27565b6115e1565b82828281811061141657611416611941565b90506020028101906114289190611957565b35847f108f6f39d8fdfa7287fbdc4c6537b4a8d6591ce9c0f729c777b83a0b32682e0285858581811061145d5761145d611941565b905060200281019061146f9190611957565b61147d906020810190611c27565b60405161148b929190611c6e565b60405180910390a38061149d81611aca565b915050611381565b506000838152600560205260409020546115015760405162461bcd60e51b815260206004820152601760248201527f3430303a20636f6e6669726d6174696f6e52657761726400000000000000000060448201526064016100e2565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001546000906115709046906001600160a01b03166115be565b61157a46306115be565b6040805167ffffffffffffffff1993841660208201529290911690820152606081018590526001600160801b038085166080830152831660a082015260c00161135f565b6001600160a01b0381166001600160a01b031960a084901b161760401b92915050565b60006115ef82840184611c9d565b506000858152600560205260409020549091506001600160801b038216111561162d5760008481526005602052604090206001600160801b03821690555b50505050565b60008083601f84011261164557600080fd5b50813567ffffffffffffffff81111561165d57600080fd5b6020830191508360208260051b850101111561167857600080fd5b9250929050565b6000806000806040858703121561169557600080fd5b843567ffffffffffffffff808211156116ad57600080fd5b6116b988838901611633565b909650945060208701359150808211156116d257600080fd5b506116df87828801611633565b95989497509550505050565b803567ffffffffffffffff198116811461170457600080fd5b919050565b6001600160801b0381168114610ecc57600080fd5b60008060006060848603121561173357600080fd5b61173c846116eb565b925061174a602085016116eb565b9150604084013561175a81611709565b809150509250925092565b60008060008060006080868803121561177d57600080fd5b611786866116eb565b9450611794602087016116eb565b935060408601356117a481611709565b9250606086013567ffffffffffffffff8111156117c057600080fd5b6117cc88828901611633565b969995985093965092949392505050565b80356001600160a01b038116811461170457600080fd5b60006020828403121561180657600080fd5b61180f826117dd565b9392505050565b6000806040838503121561182957600080fd5b611832836117dd565b9150611840602084016117dd565b90509250929050565b60006020828403121561185b57600080fd5b5035919050565b60008060008060008060a0878903121561187b57600080fd5b611884876116eb565b9550611892602088016116eb565b945060408701356118a281611709565b935060608701356118b281611709565b9250608087013567ffffffffffffffff8111156118ce57600080fd5b6118da89828a01611633565b979a9699509497509295939492505050565b6000806000806060858703121561190257600080fd5b61190b856116eb565b9350611919602086016116eb565b9250604085013567ffffffffffffffff81111561193557600080fd5b6116df87828801611633565b634e487b7160e01b600052603260045260246000fd5b60008235603e1983360301811261196d57600080fd5b9190910192915050565b60006020828403121561198957600080fd5b61180f826116eb565b6000808335601e198436030181126119a957600080fd5b83018035915067ffffffffffffffff8211156119c457600080fd5b602001915060608102360382131561167857600080fd5b6000808335601e198436030181126119f257600080fd5b83018035915067ffffffffffffffff821115611a0d57600080fd5b6020019150600581901b360382131561167857600080fd5b60008060408385031215611a3857600080fd5b8251611a4381611709565b602084015190925067ffffffffffffffff81168114611a6157600080fd5b809150509250929050565b600060208284031215611a7e57600080fd5b813561180f81611709565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b03808316818516808303821115611ac157611ac1611a89565b01949350505050565b600060018201611adc57611adc611a89565b5060010190565b600060208284031215611af557600080fd5b8151801515811461180f57600080fd5b600060208284031215611b1757600080fd5b5051919050565b60008219821115611b3157611b31611a89565b500190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082821015611b7d57611b7d611a89565b500390565b67ffffffffffffffff1986811682528581166020808401919091526001600160a01b038616604084015290841660608301528235608083015260e0820190830135611bcc81611709565b6001600160801b0390811660a0840152604084013590611beb82611709565b80821660c085015250509695505050505050565b60006001600160801b0383811690831681811015611c1f57611c1f611a89565b039392505050565b6000808335601e19843603018112611c3e57600080fd5b83018035915067ffffffffffffffff821115611c5957600080fd5b60200191503681900382131561167857600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60008060408385031215611cb057600080fd5b8235611cbb81611709565b91506020830135611a618161170956fea2646970667358221220d6531a7f72db2cc88dc8560ff0545760277e5b1445616005a61dd6ed0664cea464736f6c634300080e0033

Deployed Bytecode

0x6080604052600436106100ab5760003560e01c80638da5cb5b116100645780638da5cb5b14610211578063ab77722a14610239578063b489580414610266578063ee250db114610293578063f2fde38b146102b3578063f36683f9146102d3576100eb565b80630efe42f714610121578063617700d11461014357806368ddd2d514610163578063715018a61461018357806375cb26721461019857806380fb7c00146101b8576100eb565b366100eb5760405162461bcd60e51b815260206004820152600b60248201526a1d5b9cdd5c1c1bdc9d195960aa1b60448201526064015b60405180910390fd5b60405162461bcd60e51b815260206004820152600b60248201526a1d5b9cdd5c1c1bdc9d195960aa1b60448201526064016100e2565b34801561012d57600080fd5b5061014161013c36600461167f565b6102f3565b005b34801561014f57600080fd5b5061014161015e36600461171e565b610745565b34801561016f57600080fd5b5061014161017e366004611765565b6108f4565b34801561018f57600080fd5b50610141610add565b3480156101a457600080fd5b506101416101b33660046117f4565b610b13565b3480156101c457600080fd5b506101fe6101d3366004611816565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6040519081526020015b60405180910390f35b34801561021d57600080fd5b506000546040516001600160a01b039091168152602001610208565b34801561024557600080fd5b506101fe610254366004611849565b60009081526002602052604090205490565b34801561027257600080fd5b506101fe610281366004611849565b60009081526005602052604090205490565b34801561029f57600080fd5b506101416102ae366004611862565b610b5f565b3480156102bf57600080fd5b506101416102ce3660046117f4565b610e34565b3480156102df57600080fd5b506101416102ee3660046118ec565b610ecf565b821580159061030157508083145b61033c5760405162461bcd60e51b815260206004820152600c60248201526b0d0c0c0e881c995c5d595cdd60a21b60448201526064016100e2565b60005b8381101561073e573685858381811061035a5761035a611941565b905060200281019061036c9190611957565b905061038461037e6020830183611977565b60e01c90565b63ffffffff164663ffffffff16146103cb5760405162461bcd60e51b815260206004820152600a6024820152691a18181d1031b430b4b760b11b60448201526064016100e2565b60006103ec6103dd6020840184611977565b60401c6001600160a01b031690565b90506104298188888681811061040457610404611941565b90506020028101906104169190611957565b610424906020810190611992565b610ee9565b6000805b61043a6020850185611992565b905081101561069d57366104516020860186611992565b8381811061046157610461611941565b6060029190910191506000905061048461047e6020880188611977565b83611101565b9050600061050a8a8a8a81811061049d5761049d611941565b90506020028101906104af91906119db565b868181106104bf576104bf611941565b90506020028101906104d191906119db565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525086925061115a915050565b60015460405163175a021f60e21b8152600481018390529192506000916001600160a01b0390911690635d68087c906024016040805180830381865afa158015610558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057c9190611a25565b5090506000816001600160801b0316116105d35760405162461bcd60e51b81526020600482015260186024820152771a18189d103737ba103334b730b634bd32b210383937b7b360411b60448201526064016100e2565b6105fd84356105e86060870160408801611a6c565b6105f86040880160208901611a6c565b611206565b833561060c60208a018a611977565b67ffffffffffffffff1916337fe54a9dd2276641948cf7ebe9936fba7758c340a2de1ffabba6bbd8d0bb86029e6106496040890160208a01611a6c565b604080516001600160801b039092168252602082018990520160405180910390a461067a6040850160208601611a6c565b6106849087611a9f565b955050505050808061069590611aca565b91505061042d565b506001600160801b038116156107285760405163a9059cbb60e01b81523360048201526001600160801b03821660248201526001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610702573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107269190611ae3565b505b505050808061073690611aca565b91505061033f565b5050505050565b6000610752338585611324565b60008181526002602052604090205490915061079f5760405162461bcd60e51b815260206004820152600c60248201526b0d0c0c0e8819195c1bdcda5d60a21b60448201526064016100e2565b6000818152600260205260409020546001600160801b03831611156107d05760008181526002602052604090205491505b6001546040805163dc281aff60e01b815290516000926001600160a01b031691635d68087c91839163dc281aff9160048083019260209291908290030181865afa158015610822573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108469190611b05565b6040518263ffffffff1660e01b815260040161086491815260200190565b6040805180830381865afa158015610880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a49190611a25565b50604080516001600160801b0380871682528316602082015291925083917fca5f2e28300a7455e8eb9bbce87f2b391ea690d75170cff5e8a34ccb2f51bce3910160405180910390a25050505050565b6000836001600160801b031611801561093a57504660a081901b6001600160a01b0319166001600160a01b03919091161760401b67ffffffffffffffff19868116911614155b6109755760405162461bcd60e51b815260206004820152600c60248201526b0d0c0c0e881a5b9d985b1a5960a21b60448201526064016100e2565b604085901c6001600160a01b03166040516323b872dd60e01b81523360048201523060248201526001600160801b03851660448201526001600160a01b0391909116906323b872dd906064016020604051808303816000875af11580156109e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a049190611ae3565b506000610a12338787611324565b9050836001600160801b0316600260008381526020019081526020016000206000828254610a409190611b1e565b909155505060405181815267ffffffffffffffff19868116919088169033907f46401a1ea83c45ef34b64281c8161df97eaf1b1b25ed2a5866c7dc6a1503150f9060200160405180910390a46040516001600160801b038516815281907faec8623c192e1b4252b6bec8033c0e1a3c473b882a43041578660d768b9d8d8b9060200160405180910390a2610ad581848461137e565b505050505050565b6000546001600160a01b03163314610b075760405162461bcd60e51b81526004016100e290611b36565b610b116000611506565b565b6000546001600160a01b03163314610b3d5760405162461bcd60e51b81526004016100e290611b36565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b6c338888611324565b6000818152600460205260409020549091506001600160801b03861611610bce5760405162461bcd60e51b81526020600482015260166024820152750d0c0c0e881a5b9d985b1a59081bdc88189d5c9b995960521b60448201526064016100e2565b60008181526004602052604081206001600160801b0387169055610bf3828787611556565b90506000610c3585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525086925061115a915050565b60015460405163175a021f60e21b8152600481018390529192506000916001600160a01b0390911690635d68087c906024016040805180830381865afa158015610c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca79190611a25565b5090506000816001600160801b031611610cfe5760405162461bcd60e51b81526020600482015260186024820152771a18189d103737ba103334b730b634bd32b210383937b7b360411b60448201526064016100e2565b6000848152600260205260409020546001600160801b0388161115610d2f5760008481526002602052604090205496505b600084815260026020526040812080546001600160801b038a169290610d56908490611b6b565b909155506000905060408b901c6001600160a01b031660405163a9059cbb60e01b81523360048201526001600160801b038a1660248201529091506001600160a01b0382169063a9059cbb906044016020604051808303816000875af1158015610dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de89190611ae3565b506040516001600160801b038916815285907fb7413b5fb0f1cfb1bb023023ca81aa091943e1b70b9049c85c2121617cc40bdf9060200160405180910390a25050505050505050505050565b6000546001600160a01b03163314610e5e5760405162461bcd60e51b81526004016100e290611b36565b6001600160a01b038116610ec35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016100e2565b610ecc81611506565b50565b6000610edc338686611324565b905061073e81848461137e565b80610f2a5760405162461bcd60e51b81526020600482015260116024820152703430303a20656e7469746c656d656e747360781b60448201526064016100e2565b600082826000818110610f3f57610f3f611941565b9050606002016040016020810190610f579190611a6c565b90506000805b8381101561105757826001600160801b0316858583818110610f8157610f81611941565b9050606002016040016020810190610f999190611a6c565b6001600160801b03161015610fd557848482818110610fba57610fba611941565b9050606002016040016020810190610fd29190611a6c565b92505b816001600160801b0316858583818110610ff157610ff1611941565b90506060020160400160208101906110099190611a6c565b6001600160801b031611156110455784848281811061102a5761102a611941565b90506060020160400160208101906110429190611a6c565b91505b8061104f81611aca565b915050610f5d565b503360009081526003602090815260408083206001600160a01b03891684529091529020546001600160801b038316116110c75760405162461bcd60e51b81526020600482015260116024820152700d0c0c4e88191bdd589b19481cdc195b99607a1b60448201526064016100e2565b3360009081526003602090815260408083206001600160a01b03989098168352969052949094206001600160801b03909416909355505050565b60015460009061111b9046906001600160a01b03166115be565b61112546306115be565b33858560405160200161113c959493929190611b82565b60405160208183030381529060405280519060200120905092915050565b600081815b84518110156111fe57600085828151811061117c5761117c611941565b602002602001015190508083116111be5760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506111eb565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b50806111f681611aca565b91505061115f565b509392505050565b60008381526006602090815260408083206001600160801b038616845290915281205460ff16151581036112495750600083815260056020526040902054611275565b5060008381526006602090815260408083206001600160801b0380871685529252909120546101009004165b61127f8282611bff565b604080518082018252600181526001600160801b03838116602080840191825260008a8152600682528581208a85168252825285812094518554935170ffffffffffffffffffffffffffffffffff1990941690151570ffffffffffffffffffffffffffffffff0019161761010093851693909302929092179093558881526002909252918120805493945091851692611319908490611b6b565b909155505050505050565b604080514660208201526001600160a01b0385169181019190915267ffffffffffffffff1980841660608301528216608082015260009060a0015b6040516020818303038152906040528051906020012090509392505050565b60005b818110156114a5577118dbdb999a5c9b585d1a5bdb94995dd85c9960721b8383838181106113b1576113b1611941565b90506020028101906113c39190611957565b350361140457611404848484848181106113df576113df611941565b90506020028101906113f19190611957565b6113ff906020810190611c27565b6115e1565b82828281811061141657611416611941565b90506020028101906114289190611957565b35847f108f6f39d8fdfa7287fbdc4c6537b4a8d6591ce9c0f729c777b83a0b32682e0285858581811061145d5761145d611941565b905060200281019061146f9190611957565b61147d906020810190611c27565b60405161148b929190611c6e565b60405180910390a38061149d81611aca565b915050611381565b506000838152600560205260409020546115015760405162461bcd60e51b815260206004820152601760248201527f3430303a20636f6e6669726d6174696f6e52657761726400000000000000000060448201526064016100e2565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001546000906115709046906001600160a01b03166115be565b61157a46306115be565b6040805167ffffffffffffffff1993841660208201529290911690820152606081018590526001600160801b038085166080830152831660a082015260c00161135f565b6001600160a01b0381166001600160a01b031960a084901b161760401b92915050565b60006115ef82840184611c9d565b506000858152600560205260409020549091506001600160801b038216111561162d5760008481526005602052604090206001600160801b03821690555b50505050565b60008083601f84011261164557600080fd5b50813567ffffffffffffffff81111561165d57600080fd5b6020830191508360208260051b850101111561167857600080fd5b9250929050565b6000806000806040858703121561169557600080fd5b843567ffffffffffffffff808211156116ad57600080fd5b6116b988838901611633565b909650945060208701359150808211156116d257600080fd5b506116df87828801611633565b95989497509550505050565b803567ffffffffffffffff198116811461170457600080fd5b919050565b6001600160801b0381168114610ecc57600080fd5b60008060006060848603121561173357600080fd5b61173c846116eb565b925061174a602085016116eb565b9150604084013561175a81611709565b809150509250925092565b60008060008060006080868803121561177d57600080fd5b611786866116eb565b9450611794602087016116eb565b935060408601356117a481611709565b9250606086013567ffffffffffffffff8111156117c057600080fd5b6117cc88828901611633565b969995985093965092949392505050565b80356001600160a01b038116811461170457600080fd5b60006020828403121561180657600080fd5b61180f826117dd565b9392505050565b6000806040838503121561182957600080fd5b611832836117dd565b9150611840602084016117dd565b90509250929050565b60006020828403121561185b57600080fd5b5035919050565b60008060008060008060a0878903121561187b57600080fd5b611884876116eb565b9550611892602088016116eb565b945060408701356118a281611709565b935060608701356118b281611709565b9250608087013567ffffffffffffffff8111156118ce57600080fd5b6118da89828a01611633565b979a9699509497509295939492505050565b6000806000806060858703121561190257600080fd5b61190b856116eb565b9350611919602086016116eb565b9250604085013567ffffffffffffffff81111561193557600080fd5b6116df87828801611633565b634e487b7160e01b600052603260045260246000fd5b60008235603e1983360301811261196d57600080fd5b9190910192915050565b60006020828403121561198957600080fd5b61180f826116eb565b6000808335601e198436030181126119a957600080fd5b83018035915067ffffffffffffffff8211156119c457600080fd5b602001915060608102360382131561167857600080fd5b6000808335601e198436030181126119f257600080fd5b83018035915067ffffffffffffffff821115611a0d57600080fd5b6020019150600581901b360382131561167857600080fd5b60008060408385031215611a3857600080fd5b8251611a4381611709565b602084015190925067ffffffffffffffff81168114611a6157600080fd5b809150509250929050565b600060208284031215611a7e57600080fd5b813561180f81611709565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b03808316818516808303821115611ac157611ac1611a89565b01949350505050565b600060018201611adc57611adc611a89565b5060010190565b600060208284031215611af557600080fd5b8151801515811461180f57600080fd5b600060208284031215611b1757600080fd5b5051919050565b60008219821115611b3157611b31611a89565b500190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082821015611b7d57611b7d611a89565b500390565b67ffffffffffffffff1986811682528581166020808401919091526001600160a01b038616604084015290841660608301528235608083015260e0820190830135611bcc81611709565b6001600160801b0390811660a0840152604084013590611beb82611709565b80821660c085015250509695505050505050565b60006001600160801b0383811690831681811015611c1f57611c1f611a89565b039392505050565b6000808335601e19843603018112611c3e57600080fd5b83018035915067ffffffffffffffff821115611c5957600080fd5b60200191503681900382131561167857600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b60008060408385031215611cb057600080fd5b8235611cbb81611709565b91506020830135611a618161170956fea2646970667358221220d6531a7f72db2cc88dc8560ff0545760277e5b1445616005a61dd6ed0664cea464736f6c634300080e0033

Deployed Bytecode Sourcemap

2999:13031:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15904:21;;-1:-1:-1;;;15904:21:2;;216:2:7;15904:21:2;;;198::7;255:2;235:18;;;228:30;-1:-1:-1;;;274:18:7;;;267:41;325:18;;15904:21:2;;;;;;;;2999:13031;16002:21;;-1:-1:-1;;;16002:21:2;;216:2:7;16002:21:2;;;198::7;255:2;235:18;;;228:30;-1:-1:-1;;;274:18:7;;;267:41;325:18;;16002:21:2;14:335:7;10679:1766:2;;;;;;;;;;-1:-1:-1;10679:1766:2;;;;;:::i;:::-;;:::i;:::-;;12678:690;;;;;;;;;;-1:-1:-1;12678:690:2;;;;;:::i;:::-;;:::i;6303:1003::-;;;;;;;;;;-1:-1:-1;6303:1003:2;;;;;:::i;:::-;;:::i;1668:101:4:-;;;;;;;;;;;;;:::i;5478:138:2:-;;;;;;;;;;-1:-1:-1;5478:138:2;;;;;:::i;:::-;;:::i;5813:172::-;;;;;;;;;;-1:-1:-1;5813:172:2;;;;;:::i;:::-;-1:-1:-1;;;;;5933:40:2;;;5911:7;5933:40;;;:31;:40;;;;;;;;:47;;;;;;;;;;;;;5813:172;;;;3974:25:7;;;3962:2;3947:18;5813:172:2;;;;;;;;1036:85:4;;;;;;;;;;-1:-1:-1;1082:7:4;1108:6;1036:85;;-1:-1:-1;;;;;1108:6:4;;;4156:51:7;;4144:2;4129:18;1036:85:4;4010:203:7;5620:123:2;;;;;;;;;;-1:-1:-1;5620:123:2;;;;;:::i;:::-;5694:7;5716:22;;;:12;:22;;;;;;;5620:123;6068:141;;;;;;;;;;-1:-1:-1;6068:141:2;;;;;:::i;:::-;6147:7;6169:35;;;:25;:35;;;;;;;6068:141;13534:1561;;;;;;;;;;-1:-1:-1;13534:1561:2;;;;;:::i;:::-;;:::i;1918:198:4:-;;;;;;;;;;-1:-1:-1;1918:198:4;;;;;:::i;:::-;;:::i;7357:302:2:-;;;;;;;;;;-1:-1:-1;7357:302:2;;;;;:::i;:::-;;:::i;10679:1766::-;10804:15;;;;;:47;;-1:-1:-1;10823:28:2;;;10804:47;10796:72;;;;-1:-1:-1;;;10796:72:2;;6145:2:7;10796:72:2;;;6127:21:7;6184:2;6164:18;;;6157:30;-1:-1:-1;;;6203:18:7;;;6196:42;6255:18;;10796:72:2;5943:336:7;10796:72:2;10919:9;10915:1526;10934:15;;;10915:1526;;;10964:32;10999:4;;11004:1;10999:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;10964:42;-1:-1:-1;11047:46:2;11073:19;;;;10964:42;11073:19;:::i;:::-;778:22:0;;;691:146;11047:46:2;11022:71;;11029:13;11022:71;;;11014:94;;;;-1:-1:-1;;;11014:94:2;;7150:2:7;11014:94:2;;;7132:21:7;7189:2;7169:18;;;7162:30;-1:-1:-1;;;7208:18:7;;;7201:40;7258:18;;11014:94:2;6948:334:7;11014:94:2;11116:23;11142:46;11168:19;;;;:3;:19;:::i;:::-;950:15:0;;-1:-1:-1;;;;;926:48:0;;841:138;11142:46:2;11116:72;;11256:76;11294:15;11311:4;;11316:1;11311:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:20;;;;;;;:::i;:::-;11256:37;:76::i;:::-;11390:22;11428:9;11424:846;11447:16;;;;:3;:16;:::i;:::-;:23;;11443:1;:27;11424:846;;;11487:37;11527:16;;;;:3;:16;:::i;:::-;11544:1;11527:19;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;11594:16:2;;-1:-1:-1;11613:46:2;11626:19;;;;:3;:19;:::i;:::-;11647:11;11613:12;:46::i;:::-;11594:65;;11669:20;11692:48;11717:6;;11724:1;11717:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;11727:1;11717:12;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;11692:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11731:8:2;;-1:-1:-1;11692:24:2;;-1:-1:-1;;11692:48:2:i;:::-;11864:17;;:47;;-1:-1:-1;;;11864:47:2;;;;;3974:25:7;;;11669:71:2;;-1:-1:-1;11838:20:2;;-1:-1:-1;;;;;11864:17:2;;;;:33;;3947:18:7;;11864:47:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11837:74;;;11944:1;11929:12;-1:-1:-1;;;;;11929:16:2;;11921:53;;;;-1:-1:-1;;;11921:53:2;;9816:2:7;11921:53:2;;;9798:21:7;9855:2;9835:18;;;9828:30;-1:-1:-1;;;9874:18:7;;;9867:54;9938:18;;11921:53:2;9614:348:7;11921:53:2;11987:112;12033:20;;12055:24;;;;;;;;:::i;:::-;12081:17;;;;;;;;:::i;:::-;11987:45;:112::i;:::-;12165:20;;12144:19;;;;:3;:19;:::i;:::-;-1:-1:-1;;12115:100:2;12132:10;12115:100;12187:17;;;;;;;;:::i;:::-;12115:100;;;-1:-1:-1;;;;;10411:47:7;;;10393:66;;10490:2;10475:18;;10468:34;;;10366:18;12115:100:2;;;;;;;12244:17;;;;;;;;:::i;:::-;12226:35;;;;:::i;:::-;;;11477:793;;;;11472:3;;;;;:::i;:::-;;;;11424:846;;;-1:-1:-1;;;;;;12336:18:2;;;12333:102;;12366:60;;-1:-1:-1;;;12366:60:2;;12399:10;12366:60;;;11217:51:7;-1:-1:-1;;;;;11304:47:7;;11284:18;;;11277:75;-1:-1:-1;;;;;12366:32:2;;;;;11190:18:7;;12366:60:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;12333:102;10956:1485;;;10951:3;;;;;:::i;:::-;;;;10915:1526;;;;10679:1766;;;;:::o;12678:690::-;12834:16;12853:58;12864:10;12876:15;12893:17;12853:10;:58::i;:::-;12950:1;12925:22;;;:12;:22;;;;;;12834:77;;-1:-1:-1;12917:51:2;;;;-1:-1:-1;;;12917:51:2;;11847:2:7;12917:51:2;;;11829:21:7;11886:2;11866:18;;;11859:30;-1:-1:-1;;;11905:18:7;;;11898:42;11957:18;;12917:51:2;11645:336:7;12917:51:2;13062:22;;;;:12;:22;;;;;;-1:-1:-1;;;;;13054:30:2;;;13051:89;;;13110:22;;;;:12;:22;;;;;;;-1:-1:-1;13051:89:2;13227:17;;13261:27;;;-1:-1:-1;;;13261:27:2;;;;13197:24;;-1:-1:-1;;;;;13227:17:2;;:33;;:17;;13261:25;;:27;;;;;;;;;;;;;;13227:17;13261:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13227:62;;;;;;;;;;;;;3974:25:7;;3962:2;3947:18;;3828:177;13227:62:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;13300:63:2;;;-1:-1:-1;;;;;12420:15:7;;;12402:34;;12472:15;;12467:2;12452:18;;12445:43;13196:93:2;;-1:-1:-1;13329:8:2;;13300:63;;12322:18:7;13300:63:2;;;;;;;12791:577;;12678:690;;;:::o;6303:1003::-;6483:1;6467:13;-1:-1:-1;;;;;6467:17:2;;:84;;;;-1:-1:-1;1528:13:0;1577:3;1562:18;;;-1:-1:-1;;;;;;1562:18:0;-1:-1:-1;;;;;1600:36:0;;;;;1649:20;;-1:-1:-1;;6488:63:2;;;;;;;6467:84;6452:128;;;;-1:-1:-1;;;6452:128:2;;12701:2:7;6452:128:2;;;12683:21:7;12740:2;12720:18;;;12713:30;-1:-1:-1;;;12759:18:7;;;12752:42;12811:18;;6452:128:2;12499:336:7;6452:128:2;950:15:0;;;;-1:-1:-1;;;;;926:48:0;6642:114:2;;-1:-1:-1;;;6642:114:2;;6706:10;6642:114;;;13080:34:7;6726:4:2;13130:18:7;;;13123:43;-1:-1:-1;;;;;6733:22:2;;13182:18:7;;;13175:34;-1:-1:-1;;;;;6642:63:2;;;;;;;13015:18:7;;6642:114:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;6815:16;6834:58;6845:10;6857:15;6874:17;6834:10;:58::i;:::-;6815:77;;6924:13;-1:-1:-1;;;;;6898:39:2;:12;:22;6911:8;6898:22;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;;7058:68:2;;3974:25:7;;;-1:-1:-1;;7058:68:2;;;;;;;;7069:10;;7058:68;;3962:2:7;3947:18;7058:68:2;;;;;;;7183:45;;-1:-1:-1;;;;;13517:47:7;;13499:66;;7204:8:2;;7183:45;;13487:2:7;13472:18;7183:45:2;;;;;;;7259:42;7281:8;7291:9;;7259:21;:42::i;:::-;6446:860;6303:1003;;;;;:::o;1668:101:4:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:4;719:10:5;1248:23:4;1240:68;;;;-1:-1:-1;;;1240:68:4;;;;;;;:::i;:::-;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;5478:138:2:-;1082:7:4;1108:6;-1:-1:-1;;;;;1108:6:4;719:10:5;1248:23:4;1240:68;;;;-1:-1:-1;;;1240:68:4;;;;;;;:::i;:::-;5550:17:2::1;:61:::0;;-1:-1:-1;;;;;;5550:61:2::1;-1:-1:-1::0;;;;;5550:61:2;;;::::1;::::0;;;::::1;::::0;;5478:138::o;13534:1561::-;13736:16;13755:58;13766:10;13778:15;13795:17;13755:10;:58::i;:::-;13937:33;;;;:23;:33;;;;;;13736:77;;-1:-1:-1;;;;;;13922:48:2;;;13914:83;;;;-1:-1:-1;;;13914:83:2;;14139:2:7;13914:83:2;;;14121:21:7;14178:2;14158:18;;;14151:30;-1:-1:-1;;;14197:18:7;;;14190:52;14259:18;;13914:83:2;13937:346:7;13914:83:2;14028:33;;;;:23;:33;;;;;-1:-1:-1;;;;;14028:48:2;;;;14129:51;14052:8;14064:12;14174:5;14129:20;:51::i;:::-;14110:70;;14402:20;14425:41;14450:5;;14425:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14457:8:2;;-1:-1:-1;14425:24:2;;-1:-1:-1;;14425:41:2:i;:::-;14505:17;;:47;;-1:-1:-1;;;14505:47:2;;;;;3974:25:7;;;14402:64:2;;-1:-1:-1;14473:26:2;;-1:-1:-1;;;;;14505:17:2;;;;:33;;3947:18:7;;14505:47:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14472:80;;;14587:1;14566:18;-1:-1:-1;;;;;14566:22:2;;14558:59;;;;-1:-1:-1;;;14558:59:2;;9816:2:7;14558:59:2;;;9798:21:7;9855:2;9835:18;;;9828:30;-1:-1:-1;;;9874:18:7;;;9867:54;9938:18;;14558:59:2;9614:348:7;14558:59:2;14660:22;;;;:12;:22;;;;;;-1:-1:-1;;;;;14660:30:2;;-1:-1:-1;14657:89:2;;;14716:22;;;;:12;:22;;;;;;;-1:-1:-1;14657:89:2;14802:22;;;;:12;:22;;;;;:31;;-1:-1:-1;;;;;14802:31:2;;;:22;:31;;;;;:::i;:::-;;;;-1:-1:-1;14866:23:2;;-1:-1:-1;950:15:0;;;;-1:-1:-1;;;;;926:48:0;14940:51:2;;-1:-1:-1;;;14940:51:2;;14973:10;14940:51;;;11217::7;-1:-1:-1;;;;;11304:47:7;;11284:18;;;11277:75;14866:68:2;;-1:-1:-1;;;;;;14940:32:2;;;;;11190:18:7;;14940:51:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;15047:43:2;;-1:-1:-1;;;;;13517:47:7;;13499:66;;15074:8:2;;15047:43;;13487:2:7;13472:18;15047:43:2;;;;;;;13693:1402;;;;;13534:1561;;;;;;:::o;1918:198:4:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:4;719:10:5;1248:23:4;1240:68;;;;-1:-1:-1;;;1240:68:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;2006:22:4;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:4;;14620:2:7;1998:73:4::1;::::0;::::1;14602:21:7::0;14659:2;14639:18;;;14632:30;14698:34;14678:18;;;14671:62;-1:-1:-1;;;14749:18:7;;;14742:36;14795:19;;1998:73:4::1;14418:402:7::0;1998:73:4::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;7357:302:2:-;7529:16;7548:58;7559:10;7571:15;7588:17;7548:10;:58::i;:::-;7529:77;;7612:42;7634:8;7644:9;;7612:21;:42::i;8653:812::-;8785:23;8777:53;;;;-1:-1:-1;;;8777:53:2;;15027:2:7;8777:53:2;;;15009:21:7;15066:2;15046:18;;;15039:30;-1:-1:-1;;;15085:18:7;;;15078:47;15142:18;;8777:53:2;14825:341:7;8777:53:2;8836:11;8850:12;;8863:1;8850:15;;;;;;;:::i;:::-;;;;;;:28;;;;;;;;;;:::i;:::-;8836:42;-1:-1:-1;8884:11:2;;8938:254;8957:23;;;8938:254;;;9029:3;-1:-1:-1;;;;;8998:34:2;:12;;9011:1;8998:15;;;;;;;:::i;:::-;;;;;;:28;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;8998:34:2;;8995:92;;;9050:12;;9063:1;9050:15;;;;;;;:::i;:::-;;;;;;:28;;;;;;;;;;:::i;:::-;9044:34;;8995:92;9128:3;-1:-1:-1;;;;;9097:34:2;:12;;9110:1;9097:15;;;;;;;:::i;:::-;;;;;;:28;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;9097:34:2;;9094:92;;;9149:12;;9162:1;9149:15;;;;;;;:::i;:::-;;;;;;:28;;;;;;;;;;:::i;:::-;9143:34;;9094:92;8982:3;;;;:::i;:::-;;;;8938:254;;;-1:-1:-1;9279:10:2;9247:43;;;;:31;:43;;;;;;;;-1:-1:-1;;;;;9247:56:2;;;;;;;;;;-1:-1:-1;;;;;9247:62:2;;-1:-1:-1;9239:92:2;;;;-1:-1:-1;;;9239:92:2;;15373:2:7;9239:92:2;;;15355:21:7;15412:2;15392:18;;;15385:30;-1:-1:-1;;;15431:18:7;;;15424:47;15488:18;;9239:92:2;15171:341:7;9239:92:2;9430:10;9398:43;;;;:31;:43;;;;;;;;-1:-1:-1;;;;;9398:56:2;;;;;;;;;;;;;-1:-1:-1;;;;;9398:62:2;;;;;;-1:-1:-1;;;8653:812:2:o;15099:373::-;15311:17;;15207:7;;15257:73;;15288:13;;-1:-1:-1;;;;;15311:17:2;15257:30;:73::i;:::-;15339:60;15370:13;15393:4;15339:30;:60::i;:::-;15407:10;15426:15;15449:11;15239:227;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;15229:238;;;;;;15222:245;;15099:373;;;;:::o;1383:688:6:-;1466:7;1508:4;1466:7;1522:514;1546:5;:12;1542:1;:16;1522:514;;;1579:20;1602:5;1608:1;1602:8;;;;;;;;:::i;:::-;;;;;;;1579:31;;1644:12;1628;:28;1624:402;;1779:44;;;;;;16666:19:7;;;16701:12;;;16694:28;;;16738:12;;1779:44:6;;;;;;;;;;;;1769:55;;;;;;1754:70;;1624:402;;;1966:44;;;;;;16666:19:7;;;16701:12;;;16694:28;;;16738:12;;1966:44:6;;;;;;;;;;;;1956:55;;;;;;1941:70;;1624:402;-1:-1:-1;1560:3:6;;;;:::i;:::-;;;;1522:514;;;-1:-1:-1;2052:12:6;1383:688;-1:-1:-1;;;1383:688:6:o;9591:957:2:-;9783:23;9815:41;;;:31;:41;;;;;;;;-1:-1:-1;;;;;9815:55:2;;;;;;;;;:67;;;:76;;;;9812:348;;-1:-1:-1;10007:35:2;;;;:25;:35;;;;;;9812:348;;;-1:-1:-1;10083:41:2;;;;:31;:41;;;;;;;;-1:-1:-1;;;;;10083:55:2;;;;;;;;;;:70;;;;;9812:348;10187:24;10206:5;10187:24;;:::i;:::-;10342:54;;;;;;;;10374:4;10342:54;;-1:-1:-1;;;;;10342:54:2;;;;;;;;;;-1:-1:-1;10284:41:2;;;:31;:41;;;;;:55;;;;;;;;;;:112;;;;;;-1:-1:-1;;10284:112:2;;;;;;-1:-1:-1;;10284:112:2;;;;;;;;;;;;;;;;;10458:22;;;:12;:22;;;;;;:31;;10342:54;;-1:-1:-1;10458:31:2;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;9591:957:2:o;16785:216::-;16927:70;;;16938:13;16927:70;;;17243:25:7;-1:-1:-1;;;;;17304:32:7;;17284:18;;;17277:60;;;;-1:-1:-1;;17415:15:7;;;17395:18;;;17388:43;17467:15;;17447:18;;;17440:43;16888:16:2;;17215:19:7;;16927:70:2;;;;;;;;;;;;;16917:81;;;;;;16910:88;;16785:216;;;;;:::o;7663:595::-;7759:9;7755:319;7774:20;;;7755:319;;;-1:-1:-1;;;7865:9:2;;7875:1;7865:12;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:16;:39;7862:131;;7916:68;7955:8;7965:9;;7975:1;7965:12;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:18;;;;;;;:::i;:::-;7916:38;:68::i;:::-;8030:9;;8040:1;8030:12;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:16;8020:8;8006:61;8048:9;;8058:1;8048:12;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:18;;;;;;;:::i;:::-;8006:61;;;;;;;:::i;:::-;;;;;;;;7796:3;;;;:::i;:::-;;;;7755:319;;;-1:-1:-1;8224:1:2;8186:35;;;:25;:35;;;;;;8178:75;;;;-1:-1:-1;;;8178:75:2;;18943:2:7;8178:75:2;;;18925:21:7;18982:2;18962:18;;;18955:30;19021:25;19001:18;;;18994:53;19064:18;;8178:75:2;18741:347:7;8178:75:2;7663:595;;;:::o;2270:187:4:-;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:4;;;-1:-1:-1;;;;;;2378:17:4;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2333:124;2270:187;:::o;15476:360:2:-;15687:17;;15583:7;;15633:73;;15664:13;;-1:-1:-1;;;;;15687:17:2;15633:30;:73::i;:::-;15715:60;15746:13;15769:4;15715:30;:60::i;:::-;15615:215;;;-1:-1:-1;;19412:15:7;;;15615:215:2;;;19394:34:7;19464:15;;;;19444:18;;;19437:43;19496:18;;;19489:34;;;-1:-1:-1;;;;;19612:15:7;;;19592:18;;;19585:43;19665:15;;19644:19;;;19637:44;19324:19;;15615:215:2;19093:594:7;983:194:0;-1:-1:-1;;;;;1132:17:0;;-1:-1:-1;;;;;;1119:3:0;1114:8;;;;1132:17;1162:10;;983:194;;;;:::o;8310:278:2:-;8413:14;8433:37;;;;8444:5;8433:37;:::i;:::-;-1:-1:-1;8488:35:2;;;;:25;:35;;;;;;8412:58;;-1:-1:-1;;;;;;8479:44:2;;;8476:108;;;8533:35;;;;:25;:35;;;;;-1:-1:-1;;;;;8533:44:2;;;;8476:108;8406:182;8310:278;;;:::o;354:395:7:-;445:8;455:6;509:3;502:4;494:6;490:17;486:27;476:55;;527:1;524;517:12;476:55;-1:-1:-1;550:20:7;;593:18;582:30;;579:50;;;625:1;622;615:12;579:50;662:4;654:6;650:17;638:29;;722:3;715:4;705:6;702:1;698:14;690:6;686:27;682:38;679:47;676:67;;;739:1;736;729:12;676:67;354:395;;;;;:::o;754:922::-;969:6;977;985;993;1046:2;1034:9;1025:7;1021:23;1017:32;1014:52;;;1062:1;1059;1052:12;1014:52;1102:9;1089:23;1131:18;1172:2;1164:6;1161:14;1158:34;;;1188:1;1185;1178:12;1158:34;1227:98;1317:7;1308:6;1297:9;1293:22;1227:98;:::i;:::-;1344:8;;-1:-1:-1;1201:124:7;-1:-1:-1;1432:2:7;1417:18;;1404:32;;-1:-1:-1;1448:16:7;;;1445:36;;;1477:1;1474;1467:12;1445:36;;1516:100;1608:7;1597:8;1586:9;1582:24;1516:100;:::i;:::-;754:922;;;;-1:-1:-1;1635:8:7;-1:-1:-1;;;;754:922:7:o;1681:177::-;1749:20;;-1:-1:-1;;1798:35:7;;1788:46;;1778:74;;1848:1;1845;1838:12;1778:74;1681:177;;;:::o;1863:146::-;-1:-1:-1;;;;;1942:5:7;1938:46;1931:5;1928:57;1918:85;;1999:1;1996;1989:12;2014:395;2091:6;2099;2107;2160:2;2148:9;2139:7;2135:23;2131:32;2128:52;;;2176:1;2173;2166:12;2128:52;2199:29;2218:9;2199:29;:::i;:::-;2189:39;;2247:38;2281:2;2270:9;2266:18;2247:38;:::i;:::-;2237:48;;2335:2;2324:9;2320:18;2307:32;2348:31;2373:5;2348:31;:::i;:::-;2398:5;2388:15;;;2014:395;;;;;:::o;2414:775::-;2553:6;2561;2569;2577;2585;2638:3;2626:9;2617:7;2613:23;2609:33;2606:53;;;2655:1;2652;2645:12;2606:53;2678:29;2697:9;2678:29;:::i;:::-;2668:39;;2726:38;2760:2;2749:9;2745:18;2726:38;:::i;:::-;2716:48;;2814:2;2803:9;2799:18;2786:32;2827:31;2852:5;2827:31;:::i;:::-;2877:5;-1:-1:-1;2933:2:7;2918:18;;2905:32;2960:18;2949:30;;2946:50;;;2992:1;2989;2982:12;2946:50;3031:98;3121:7;3112:6;3101:9;3097:22;3031:98;:::i;:::-;2414:775;;;;-1:-1:-1;2414:775:7;;-1:-1:-1;3148:8:7;;3005:124;2414:775;-1:-1:-1;;;2414:775:7:o;3194:173::-;3262:20;;-1:-1:-1;;;;;3311:31:7;;3301:42;;3291:70;;3357:1;3354;3347:12;3372:186;3431:6;3484:2;3472:9;3463:7;3459:23;3455:32;3452:52;;;3500:1;3497;3490:12;3452:52;3523:29;3542:9;3523:29;:::i;:::-;3513:39;3372:186;-1:-1:-1;;;3372:186:7:o;3563:260::-;3631:6;3639;3692:2;3680:9;3671:7;3667:23;3663:32;3660:52;;;3708:1;3705;3698:12;3660:52;3731:29;3750:9;3731:29;:::i;:::-;3721:39;;3779:38;3813:2;3802:9;3798:18;3779:38;:::i;:::-;3769:48;;3563:260;;;;;:::o;4218:180::-;4277:6;4330:2;4318:9;4309:7;4305:23;4301:32;4298:52;;;4346:1;4343;4336:12;4298:52;-1:-1:-1;4369:23:7;;4218:180;-1:-1:-1;4218:180:7:o;4403:891::-;4525:6;4533;4541;4549;4557;4565;4618:3;4606:9;4597:7;4593:23;4589:33;4586:53;;;4635:1;4632;4625:12;4586:53;4658:29;4677:9;4658:29;:::i;:::-;4648:39;;4706:38;4740:2;4729:9;4725:18;4706:38;:::i;:::-;4696:48;;4794:2;4783:9;4779:18;4766:32;4807:31;4832:5;4807:31;:::i;:::-;4857:5;-1:-1:-1;4914:2:7;4899:18;;4886:32;4927:33;4886:32;4927:33;:::i;:::-;4979:7;-1:-1:-1;5037:3:7;5022:19;;5009:33;5065:18;5054:30;;5051:50;;;5097:1;5094;5087:12;5051:50;5136:98;5226:7;5217:6;5206:9;5202:22;5136:98;:::i;:::-;4403:891;;;;-1:-1:-1;4403:891:7;;-1:-1:-1;4403:891:7;;5253:8;;4403:891;-1:-1:-1;;;4403:891:7:o;5299:639::-;5429:6;5437;5445;5453;5506:2;5494:9;5485:7;5481:23;5477:32;5474:52;;;5522:1;5519;5512:12;5474:52;5545:29;5564:9;5545:29;:::i;:::-;5535:39;;5593:38;5627:2;5616:9;5612:18;5593:38;:::i;:::-;5583:48;;5682:2;5671:9;5667:18;5654:32;5709:18;5701:6;5698:30;5695:50;;;5741:1;5738;5731:12;5695:50;5780:98;5870:7;5861:6;5850:9;5846:22;5780:98;:::i;6284:127::-;6345:10;6340:3;6336:20;6333:1;6326:31;6376:4;6373:1;6366:15;6400:4;6397:1;6390:15;6416:336;6521:4;6579:11;6566:25;6673:2;6669:7;6658:8;6642:14;6638:29;6634:43;6614:18;6610:68;6600:96;;6692:1;6689;6682:12;6600:96;6713:33;;;;;6416:336;-1:-1:-1;;6416:336:7:o;6757:186::-;6816:6;6869:2;6857:9;6848:7;6844:23;6840:32;6837:52;;;6885:1;6882;6875:12;6837:52;6908:29;6927:9;6908:29;:::i;7287:584::-;7416:4;7422:6;7482:11;7469:25;7576:2;7572:7;7561:8;7545:14;7541:29;7537:43;7517:18;7513:68;7503:96;;7595:1;7592;7585:12;7503:96;7622:33;;7674:20;;;-1:-1:-1;7717:18:7;7706:30;;7703:50;;;7749:1;7746;7739:12;7703:50;7782:4;7770:17;;-1:-1:-1;7841:4:7;7829:17;;7813:14;7809:38;7799:49;;7796:69;;;7861:1;7858;7851:12;7876:572;7996:4;8002:6;8062:11;8049:25;8156:2;8152:7;8141:8;8125:14;8121:29;8117:43;8097:18;8093:68;8083:96;;8175:1;8172;8165:12;8083:96;8202:33;;8254:20;;;-1:-1:-1;8297:18:7;8286:30;;8283:50;;;8329:1;8326;8319:12;8283:50;8362:4;8350:17;;-1:-1:-1;8413:1:7;8409:14;;;8393;8389:35;8379:46;;8376:66;;;8438:1;8435;8428:12;9185:424;9263:6;9271;9324:2;9312:9;9303:7;9299:23;9295:32;9292:52;;;9340:1;9337;9330:12;9292:52;9372:9;9366:16;9391:31;9416:5;9391:31;:::i;:::-;9491:2;9476:18;;9470:25;9441:5;;-1:-1:-1;9539:18:7;9526:32;;9514:45;;9504:73;;9573:1;9570;9563:12;9504:73;9596:7;9586:17;;;9185:424;;;;;:::o;9967:247::-;10026:6;10079:2;10067:9;10058:7;10054:23;10050:32;10047:52;;;10095:1;10092;10085:12;10047:52;10134:9;10121:23;10153:31;10178:5;10153:31;:::i;10513:127::-;10574:10;10569:3;10565:20;10562:1;10555:31;10605:4;10602:1;10595:15;10629:4;10626:1;10619:15;10645:253;10685:3;-1:-1:-1;;;;;10774:2:7;10771:1;10767:10;10804:2;10801:1;10797:10;10835:3;10831:2;10827:12;10822:3;10819:21;10816:47;;;10843:18;;:::i;:::-;10879:13;;10645:253;-1:-1:-1;;;;10645:253:7:o;10903:135::-;10942:3;10963:17;;;10960:43;;10983:18;;:::i;:::-;-1:-1:-1;11030:1:7;11019:13;;10903:135::o;11363:277::-;11430:6;11483:2;11471:9;11462:7;11458:23;11454:32;11451:52;;;11499:1;11496;11489:12;11451:52;11531:9;11525:16;11584:5;11577:13;11570:21;11563:5;11560:32;11550:60;;11606:1;11603;11596:12;11986:184;12056:6;12109:2;12097:9;12088:7;12084:23;12080:32;12077:52;;;12125:1;12122;12115:12;12077:52;-1:-1:-1;12148:16:7;;11986:184;-1:-1:-1;11986:184:7:o;13220:128::-;13260:3;13291:1;13287:6;13284:1;13281:13;13278:39;;;13297:18;;:::i;:::-;-1:-1:-1;13333:9:7;;13220:128::o;13576:356::-;13778:2;13760:21;;;13797:18;;;13790:30;13856:34;13851:2;13836:18;;13829:62;13923:2;13908:18;;13576:356::o;14288:125::-;14328:4;14356:1;14353;14350:8;14347:34;;;14361:18;;:::i;:::-;-1:-1:-1;14398:9:7;;14288:125::o;15517:987::-;-1:-1:-1;;15906:15:7;;;15888:34;;15958:15;;;15953:2;15938:18;;;15931:43;;;;-1:-1:-1;;;;;16010:32:7;;16005:2;15990:18;;15983:60;16079:15;;;16074:2;16059:18;;16052:43;16132:20;;16126:3;16111:19;;16104:49;15833:3;15818:19;;;16188:15;;16175:29;16213:31;16175:29;16213:31;:::i;:::-;-1:-1:-1;;;;;16334:14:7;;;16328:3;16313:19;;16306:43;16398:2;16386:15;;16373:29;;16411:33;16373:29;16411:33;:::i;:::-;16494:2;16485:7;16481:16;16475:3;16464:9;16460:19;16453:45;;;15517:987;;;;;;;;:::o;16761:246::-;16801:4;-1:-1:-1;;;;;16914:10:7;;;;16884;;16936:12;;;16933:38;;;16951:18;;:::i;:::-;16988:13;;16761:246;-1:-1:-1;;;16761:246:7:o;17822:521::-;17899:4;17905:6;17965:11;17952:25;18059:2;18055:7;18044:8;18028:14;18024:29;18020:43;18000:18;17996:68;17986:96;;18078:1;18075;18068:12;17986:96;18105:33;;18157:20;;;-1:-1:-1;18200:18:7;18189:30;;18186:50;;;18232:1;18229;18222:12;18186:50;18265:4;18253:17;;-1:-1:-1;18296:14:7;18292:27;;;18282:38;;18279:58;;;18333:1;18330;18323:12;18348:388;18505:2;18494:9;18487:21;18544:6;18539:2;18528:9;18524:18;18517:34;18601:6;18593;18588:2;18577:9;18573:18;18560:48;18657:1;18628:22;;;18652:2;18624:31;;;18617:42;;;;18720:2;18699:15;;;-1:-1:-1;;18695:29:7;18680:45;18676:54;;18348:388;-1:-1:-1;18348:388:7:o;19692:::-;19760:6;19768;19821:2;19809:9;19800:7;19796:23;19792:32;19789:52;;;19837:1;19834;19827:12;19789:52;19876:9;19863:23;19895:31;19920:5;19895:31;:::i;:::-;19945:5;-1:-1:-1;20002:2:7;19987:18;;19974:32;20015:33;19974:32;20015:33;:::i

Swarm Source

ipfs://d6531a7f72db2cc88dc8560ff0545760277e5b1445616005a61dd6ed0664cea4

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  ]

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.