false
false
0

Contract Address Details

0x26d460c3Cf931Fb2014FA436a49e3Af08619810e

Token
Reward Flare (rFLR)
Creator
0x4598a6–d10d29 at 0x94327a–98f59a
Balance
484,418,288.315582075736494205 FLR
Tokens
Fetching tokens...
Transactions
6,425 Transactions
Transfers
0 Transfers
Gas Used
2,207,801,476
Last Balance Update
31506744
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
RNat




Optimization enabled
true
Compiler version
v0.8.20+commit.a1b79de6




Optimization runs
200
EVM Version
london




Verified at
2024-07-02T10:54:04.449173Z

Constructor Arguments

0x00000000000000000000000010000000000000000000000000000000000000070000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d290000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d290000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000120000000000000000000000004a0565f8960feb35dc0e0c2ce0fe1ffbea12fca3000000000000000000000000000000000000000000000000000000006661a4c0000000000000000000000000000000000000000000000000000000000000000c52657761726420466c6172650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000472464c5200000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x1000000000000000000000000000000000000007
Arg [1] (address) : 0x4598a6c05910ab914f0cbaaca1911cd337d10d29
Arg [2] (address) : 0x4598a6c05910ab914f0cbaaca1911cd337d10d29
Arg [3] (string) : Reward Flare
Arg [4] (string) : rFLR
Arg [5] (uint8) : 18
Arg [6] (address) : 0x4a0565f8960feb35dc0e0c2ce0fe1ffbea12fca3
Arg [7] (uint256) : 1717675200

              

contracts/rNat/implementation/RNat.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "./CloneFactory.sol";
import "../interface/IIRNat.sol";
import "../interface/IIRNatAccount.sol";
import "../../governance/implementation/Governed.sol";
import "../../incentivePool/implementation/IncentivePoolReceiver.sol";
import "../../protocol/interface/IIClaimSetupManager.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";


/**
 * RNat is a non-transferable linearly vested token (12 months). This contract is used for managing all processes
 * related to the RNat token - assigning, distributing, claiming and withdrawing.
 */
contract RNat is IIRNat, Governed, IncentivePoolReceiver, CloneFactory, ReentrancyGuard {

    /// Struct used to store the project data.
    struct Project {
        string name;
        address distributor;
        bool currentMonthDistributionEnabled;
        bool distributionDisabled;
        bool claimingDisabled;
        uint128 totalAssignedRewards;
        uint128 totalDistributedRewards;
        uint128 totalClaimedRewards;
        uint128 totalUnassignedUnclaimedRewards;
        mapping(uint256 month => MonthlyRewards) monthlyRewards;
        uint256[] monthsWithRewards; // sorted list of months with rewards
        // equal to project.monthsWithRewards.length when all rewards are claimed and the last month is in the past
        mapping(address owner => uint256 index) lastClaimingMonthIndex;
    }

    /// Struct used to store the monthly rewards data.
    struct MonthlyRewards {
        uint128 assignedRewards;
        uint128 distributedRewards; // distributedRewards <= assignedRewards
        uint128 claimedRewards; // claimedRewards <= distributedRewards
        uint128 unassignedUnclaimedRewards; // unassignedUnclaimedRewards <= distributedRewards - claimedRewards
        mapping(address owner => Rewards) rewards;
    }

    /// Struct used to store the rewards data for the owner.
    struct Rewards {
        uint128 assignedRewards;
        uint128 claimedRewards;
    }

    /// The duration of a month in seconds.
    uint256 public constant MONTH = 30 days;
    /// The timestamp of the first month start.
    uint256 public immutable firstMonthStartTs;

    /// @inheritdoc IERC20Metadata
    string public name;
    /// @inheritdoc IERC20Metadata
    string public symbol;
    /// @inheritdoc IERC20Metadata
    uint8 public immutable decimals;

    /// Total assignable rewards received from the funding address or the incentive pool.
    uint128 internal totalAssignableRewards;
    /// Already assigned rewards.
    uint128 internal totalAssignedRewards;
    /// Total claimed rewards.
    uint128 internal totalClaimedRewards;
    /// Total withdrawn rewards.
    uint128 internal totalWithdrawnRewards;
    /// Total withdrawn assignable rewards (needed for the circulating supply calculation).
    uint128 internal totalWithdrawnAssignableRewards;

    /// Indicates if the incentive pool is enabled.
    bool public incentivePoolEnabled;

    /// The `ClaimSetupManager` contract.
    IIClaimSetupManager public claimSetupManager;
    /// The `WNat` contract.
    IWNat public wNat;

    /// The address of the library contract (RNatAccount).
    address public libraryAddress;
    /// The manager address.
    address public manager;
    /// The funding address.
    address public fundingAddress;

    Project[] internal projects;

    mapping(address owner => IIRNatAccount) private ownerToRNatAccount;
    mapping(IIRNatAccount => address owner) private rNatAccountToOwner;

    modifier onlyManager() {
        _checkOnlyManager();
        _;
    }

    /**
     * Constructor.
     * @param _governanceSettings The address of the GovernanceSettings contract.
     * @param _initialGovernance The initial governance address.
     * @param _addressUpdater The address of the AddressUpdater contract.
     * @param _manager The manager address.
     * @param _firstMonthStartTs The timestamp of the first month start.
     */
    constructor(
        IGovernanceSettings _governanceSettings,
        address _initialGovernance,
        address _addressUpdater,
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        address _manager,
        uint256 _firstMonthStartTs
    )
        Governed(_governanceSettings, _initialGovernance) IncentivePoolReceiver(_addressUpdater)
    {
        require(_firstMonthStartTs <= block.timestamp, "first month start in the future");
        _checkNonzeroAddress(_manager);
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        manager = _manager;
        firstMonthStartTs = _firstMonthStartTs;
    }

    /**
     * External payable function to receive rewards from the funding address.
     */
    function receiveRewards() external payable mustBalance {
        require(msg.sender == fundingAddress, "not a funding address");
        totalAssignableRewards += uint128(msg.value);
    }

    //////////////////////////// Protocol's distributor functions ////////////////////////////

    /**
     * @inheritdoc IRNat
     */
    function distributeRewards(
        uint256 _projectId,
        uint256 _month,
        address[] calldata _recipients,
        uint128[] calldata _amountsWei
    )
        external
    {
        require(_recipients.length == _amountsWei.length, "lengths mismatch");
        Project storage project = _getProject(_projectId);
        _checkDistributionEnabled(project);
        uint256 currentMonth = _getCurrentMonth();
        require(currentMonth == _month + 1 || (project.currentMonthDistributionEnabled && currentMonth == _month),
            "distribution for month disabled");
        require(project.distributor == msg.sender, "only distributor");
        uint128 totalAmount = 0;
        MonthlyRewards storage monthlyRewards = project.monthlyRewards[_month];
        for (uint256 i = 0; i < _recipients.length; i++) {
            _checkNonzeroAddress(_recipients[i]);
            monthlyRewards.rewards[_recipients[i]].assignedRewards += _amountsWei[i];
            totalAmount += _amountsWei[i];
        }
        require(monthlyRewards.distributedRewards + totalAmount <= monthlyRewards.assignedRewards,
            "exceeds assigned rewards");
        monthlyRewards.distributedRewards += totalAmount;
        project.totalDistributedRewards += totalAmount;
        emit RewardsDistributed(_projectId, _month, _recipients, _amountsWei);
    }

    //////////////////////////// User's functions ////////////////////////////

    /**
     * @inheritdoc IRNat
     */
    //slither-disable-next-line reentrancy-eth
    function claimRewards(
        uint256[] calldata _projectIds,
        uint256 _month
    )
        external
        mustBalance
        nonReentrant
        returns (
            uint128 _claimedRewardsWei
        )
    {
        uint256 currentMonth = _getCurrentMonth();
        require(_month <= currentMonth, "month in the future");
        for (uint256 i = 0; i < _projectIds.length; i++) {
            _claimedRewardsWei += _claimRewards(_projectIds[i], _month, currentMonth);
        }
        totalClaimedRewards += _claimedRewardsWei;
        emit Transfer(address(0), msg.sender, _claimedRewardsWei);
    }

    /**
     * @inheritdoc IRNat
     */
    function setClaimExecutors(address[] calldata _executors) external payable {
        _getOrCreateRNatAccount().setClaimExecutors{value: msg.value}(claimSetupManager, _executors);
    }

    /**
     * @inheritdoc IRNat
     */
    function withdraw(uint128 _amount, bool _wrap) external mustBalance {
        uint128 amount = _getOrCreateRNatAccount().withdraw(wNat, firstMonthStartTs, _amount, _wrap);
        totalWithdrawnRewards += amount;
        emit Transfer(msg.sender, address(0), amount);
    }

    /**
     * @inheritdoc IRNat
     */
    function withdrawAll(bool _wrap) external mustBalance {
        uint128 amount = _getOrCreateRNatAccount().withdrawAll(wNat, firstMonthStartTs, _wrap);
        totalWithdrawnRewards += amount;
        emit Transfer(msg.sender, address(0), amount);
    }

    /**
     * @inheritdoc IRNat
     */
    function transferExternalToken(IERC20 _token, uint256 _amount) external nonReentrant {
        _getOrCreateRNatAccount().transferExternalToken(wNat, _token, _amount);
    }

    //////////////////////////// Manager's functions ////////////////////////////

    /**
     * @inheritdoc IIRNat
     */
    function addProjects(
        string[] calldata _names,
        address[] calldata _distributors,
        bool[] calldata _currentMonthDistributionEnabledList
    )
        external
        onlyManager
    {
        require(_names.length == _distributors.length && _names.length == _currentMonthDistributionEnabledList.length,
            "lengths mismatch");
        for (uint256 i = 0; i < _names.length; i++) {
            _checkNonzeroAddress(_distributors[i]);
            uint256 projectId = projects.length;
            projects.push();
            Project storage project = projects[projectId];
            project.name = _names[i];
            project.distributor = _distributors[i];
            project.currentMonthDistributionEnabled = _currentMonthDistributionEnabledList[i];
            emit ProjectAdded(projectId, _names[i], _distributors[i], _currentMonthDistributionEnabledList[i]);
        }
    }

    /**
     * @inheritdoc IIRNat
     */
    function updateProject(
        uint256 _projectId,
        string calldata _name,
        address _distributor,
        bool _currentMonthDistributionEnabled
    )
        external
        onlyManager
    {
        Project storage project = _getProject(_projectId);
        _checkNonzeroAddress(_distributor);
        project.name = _name;
        project.distributor = _distributor;
        project.currentMonthDistributionEnabled = _currentMonthDistributionEnabled;
        emit ProjectUpdated(_projectId, _name, _distributor, _currentMonthDistributionEnabled);
    }

    /**
     * @inheritdoc IIRNat
     */
    function assignRewards(
        uint256 _month,
        uint256[] calldata _projectIds,
        uint128[] calldata _amountsWei
    )
        external
        onlyManager
    {
        require(_month + 1 >= _getCurrentMonth(), "month too far in the past");
        require(_projectIds.length == _amountsWei.length, "lengths mismatch");
        uint128 totalAmount = 0;
        for (uint256 i = 0; i < _projectIds.length; i++) {
            Project storage project = _getProject(_projectIds[i]);
            _checkDistributionEnabled(project);
            project.totalAssignedRewards += _amountsWei[i];
            MonthlyRewards storage monthlyRewards = project.monthlyRewards[_month];
            monthlyRewards.assignedRewards += _amountsWei[i];
            totalAmount += _amountsWei[i];
            uint256 index = project.monthsWithRewards.length;
            if (index == 0 || project.monthsWithRewards[index - 1] < _month) {
                project.monthsWithRewards.push(_month); // this should  be true most of the time
            } else {
                while (index > 0 && project.monthsWithRewards[index - 1] >= _month) {
                    index--;
                }
                if (project.monthsWithRewards[index] != _month) {
                    project.monthsWithRewards.push();
                    for (uint256 j = project.monthsWithRewards.length - 1; j > index; j--) {
                        project.monthsWithRewards[j] = project.monthsWithRewards[j - 1];
                    }
                    project.monthsWithRewards[index] = _month;
                }
            }
            emit RewardsAssigned(_projectIds[i], _month, _amountsWei[i]);
        }
        require(totalAssignedRewards + totalAmount <= totalAssignableRewards, "exceeds assignable rewards");
        totalAssignedRewards += totalAmount;
    }

    /**
     * @inheritdoc IIRNat
     */
    function disableDistribution(uint256[] memory _projectIds) external onlyManager {
        for (uint256 i = 0; i < _projectIds.length; i++) {
            Project storage project = _getProject(_projectIds[i]);
            project.distributionDisabled = true;
        }
        emit DistributionPermissionUpdated(_projectIds, true);
    }

    /**
     * @inheritdoc IIRNat
     */
    function disableClaiming(uint256[] memory _projectIds) external onlyManager {
        for (uint256 i = 0; i < _projectIds.length; i++) {
            Project storage project = _getProject(_projectIds[i]);
            project.claimingDisabled = true;
        }
        emit ClaimingPermissionUpdated(_projectIds, true);
    }

    //////////////////////////// Manager's + Governance's functions ////////////////////////////

    /**
     * @inheritdoc IIRNat
     */
    function unassignRewards(uint256 _projectId, uint256[] memory _months) external {
        require (msg.sender == manager || msg.sender == governance(), "only manager or governance");
        Project storage project = _getProject(_projectId);
        uint256 currentMonth = _getCurrentMonth();
        uint128 totalAmount = 0;
        for (uint256 i = 0; i < _months.length; i++) {
            require(_months[i] + 1 < currentMonth || (project.distributionDisabled && msg.sender == governance()),
                "unassignment not allowed");
            MonthlyRewards storage monthlyRewards = project.monthlyRewards[_months[i]];
            uint128 amount = monthlyRewards.assignedRewards - monthlyRewards.distributedRewards;
            monthlyRewards.assignedRewards -= amount;
            totalAmount += amount;
            emit RewardsUnassigned(_projectId, _months[i], amount);
        }
        project.totalAssignedRewards -= totalAmount;
        totalAssignedRewards -= totalAmount;
    }

    //////////////////////////// Governance's functions ////////////////////////////

    /**
     * Method for unassigning unclaimed rewards from the project. Can only be called by governance when the claiming
     * is disabled for the project. In case of non-zero unassigned unclaimed rewards this permanently disables the
     * distribution and claiming of the rewards for the project.
     * @param _projectId The project id.
     * @param _months The months for which the rewards are unassigned.
     */
    function unassignUnclaimedRewards(uint256 _projectId, uint256[] memory _months) external onlyImmediateGovernance {
        Project storage project = _getProject(_projectId);
        require(project.claimingDisabled, "claiming not disabled");
        uint128 totalAmount = 0;
        for (uint256 i = 0; i < _months.length; i++) {
            MonthlyRewards storage monthlyRewards = project.monthlyRewards[_months[i]];
            uint128 amount = monthlyRewards.distributedRewards -
                monthlyRewards.unassignedUnclaimedRewards - monthlyRewards.claimedRewards;
            monthlyRewards.unassignedUnclaimedRewards += amount;
            totalAmount += amount;
            emit UnclaimedRewardsUnassigned(_projectId, _months[i], amount);
        }

        project.totalUnassignedUnclaimedRewards += totalAmount;
        totalAssignedRewards -= totalAmount;
        project.distributionDisabled = true;
        uint256[] memory projectIds = new uint256[](1);
        projectIds[0] = _projectId;
        emit DistributionPermissionUpdated(projectIds, true);
    }

    /**
     * Method for enabling the distribution for the projects. It reverts in case of permanently disabled claiming.
     * @param _projectIds The ids of the projects.
     */
    function enableDistribution(uint256[] memory _projectIds) external onlyImmediateGovernance {
        for (uint256 i = 0; i < _projectIds.length; i++) {
            Project storage project = _getProject(_projectIds[i]);
            _checkClaimingNotPermanentlyDisabled(project);
            project.distributionDisabled = false;
        }
        emit DistributionPermissionUpdated(_projectIds, false);
    }

    /**
     * Method for enabling the claiming for the projects. It reverts in case of permanently disabled claiming.
     * @param _projectIds The ids of the projects.
     */
    function enableClaiming(uint256[] memory _projectIds) external onlyImmediateGovernance {
        for (uint256 i = 0; i < _projectIds.length; i++) {
            Project storage project = _getProject(_projectIds[i]);
            _checkClaimingNotPermanentlyDisabled(project);
            project.claimingDisabled = false;
        }
        emit ClaimingPermissionUpdated(_projectIds, false);
    }

    /**
     * Method for setting the manager address.
     * @param _manager The manager address.
     */
    function setManager(address _manager) external onlyImmediateGovernance {
        _checkNonzeroAddress(_manager);
        manager = _manager;
    }

    /**
     * Method for setting the funding address.
     * @param _fundingAddress The funding address.
     */
    function setFundingAddress(address _fundingAddress) external onlyGovernance {
        fundingAddress = _fundingAddress;
    }

    /**
     * Sets the library address.
     * @dev Only governance can call this.
     */
    function setLibraryAddress(address _libraryAddress) external onlyGovernance {
        require(_isContract(_libraryAddress), "not a contract");
        libraryAddress = _libraryAddress;
        emit LibraryAddressSet(libraryAddress);
    }

    /**
     * Method for withdrawing unassigned rewards from this contract. Can be used for moving the rewards to the
     * new contract or for burning. Only governance can call this.
     * @param _recipient The recipient of the rewards.
     * @param _amount The amount of the rewards.
     */
    function withdrawUnassignedRewards(address _recipient, uint128 _amount) external mustBalance onlyGovernance {
        _checkNonzeroAddress(_recipient);
        require(totalAssignableRewards - totalAssignedRewards >= _amount, "insufficient assignable rewards");
        totalAssignableRewards -= _amount;
        totalWithdrawnAssignableRewards += _amount;
        emit UnassignedRewardsWithdrawn(_recipient, _amount);
        /* solhint-disable avoid-low-level-calls */
        //slither-disable-next-line arbitrary-send-eth
        (bool success, ) = _recipient.call{value: _amount}("");
        /* solhint-enable avoid-low-level-calls */
        require(success, "Transfer failed");
    }

    /**
     * Enables the incentive pool.
     */
    function enableIncentivePool() external onlyGovernance {
        incentivePoolEnabled = true;
    }

    //////////////////////////// View functions ////////////////////////////

    /**
     * @inheritdoc IRNat
     */
    function getRNatAccount(address _owner) external view returns (IRNatAccount) {
        return _getRNatAccount(_owner);
    }

    /**
     * @inheritdoc IRNat
     */
    function getCurrentMonth() external view returns (uint256) {
        return _getCurrentMonth();
    }

    /**
     * @inheritdoc IRNat
     */
    function getProjectsCount() external view returns (uint256) {
        return projects.length;
    }

    /**
     * @inheritdoc IRNat
     */
    function getProjectsBasicInfo() external view returns (string[] memory _names, bool[] memory _claimingDisabled) {
        _names = new string[](projects.length);
        _claimingDisabled = new bool[](projects.length);
        for (uint256 i = 0; i < projects.length; i++) {
            _names[i] = projects[i].name;
            _claimingDisabled[i] = projects[i].claimingDisabled;
        }
    }

    /**
     * @inheritdoc IRNat
     */
    function getProjectInfo(uint256 _projectId)
        external view
        returns (
            string memory _name,
            address _distributor,
            bool _currentMonthDistributionEnabled,
            bool _distributionDisabled,
            bool _claimingDisabled,
            uint128 _totalAssignedRewards,
            uint128 _totalDistributedRewards,
            uint128 _totalClaimedRewards,
            uint128 _totalUnassignedUnclaimedRewards,
            uint256[] memory _monthsWithRewards
        )
    {
        Project storage project = _getProject(_projectId);
        return (
            project.name,
            project.distributor,
            project.currentMonthDistributionEnabled,
            project.distributionDisabled,
            project.claimingDisabled,
            project.totalAssignedRewards,
            project.totalDistributedRewards,
            project.totalClaimedRewards,
            project.totalUnassignedUnclaimedRewards,
            project.monthsWithRewards
        );
    }

    /**
     * @inheritdoc IRNat
     */
    function getProjectRewardsInfo(uint256 _projectId, uint256 _month)
        external view
        returns (
            uint128 _assignedRewards,
            uint128 _distributedRewards,
            uint128 _claimedRewards,
            uint128 _unassignedUnclaimedRewards
        )
    {
        Project storage project = _getProject(_projectId);
        MonthlyRewards storage monthlyRewards = project.monthlyRewards[_month];
        return (
            monthlyRewards.assignedRewards,
            monthlyRewards.distributedRewards,
            monthlyRewards.claimedRewards,
            monthlyRewards.unassignedUnclaimedRewards
        );
    }

    /**
     * @inheritdoc IRNat
     */
    function getOwnerRewardsInfo(uint256 _projectId, uint256 _month, address _owner)
        external view
        returns (
            uint128 _assignedRewards,
            uint128 _claimedRewards,
            bool _claimable
        )
    {
        Project storage project = _getProject(_projectId);
        if (_month > _getCurrentMonth()) {
            return (0, 0, false);
        }
        MonthlyRewards storage monthlyRewards = project.monthlyRewards[_month];
        Rewards storage rewards = monthlyRewards.rewards[_owner];
        return (
            rewards.assignedRewards,
            rewards.claimedRewards,
            !project.claimingDisabled
        );
    }

    /**
     * @inheritdoc IRNat
     */
    function getClaimableRewards(uint256 _projectId, address _owner) external view returns (uint128) {
        Project storage project = _getProject(_projectId);
        if (project.claimingDisabled) {
            return 0;
        }
        uint256 currentMonth = _getCurrentMonth();
        uint256 claimingMonthIndex = project.lastClaimingMonthIndex[_owner];
        uint256 length = project.monthsWithRewards.length - claimingMonthIndex;
        uint128 totalAmount = 0;
        for (uint256 i = 0; i < length; i++) {
            uint256 month = project.monthsWithRewards[claimingMonthIndex];
            if (currentMonth < month) { // future months are not claimable
                break;
            }
            MonthlyRewards storage monthlyRewards = project.monthlyRewards[month];
            Rewards storage rewards = monthlyRewards.rewards[_owner];
            totalAmount += rewards.assignedRewards - rewards.claimedRewards;
            claimingMonthIndex++;
        }
        return totalAmount;
    }

    /**
     * @inheritdoc IERC20
     */
    function totalSupply() external view returns (uint256) {
        return totalClaimedRewards - totalWithdrawnRewards;
    }

    /**
     * @inheritdoc IERC20
     */
    function balanceOf(address _owner) external view returns(uint256) {
        return _getRNatAccount(_owner).rNatBalance();
    }

    /**
     * @inheritdoc IRNat
     */
    function getBalancesOf(
        address _owner
    )
        external view
        returns (
            uint256 _wNatBalance,
            uint256 _rNatBalance,
            uint256 _lockedBalance
        )
    {
        IIRNatAccount rNatAccount = _getRNatAccount(_owner);
        _wNatBalance = rNatAccount.wNatBalance(wNat);
        _rNatBalance = rNatAccount.rNatBalance();
        _lockedBalance = rNatAccount.lockedBalance(firstMonthStartTs);
    }

    /**
     * @inheritdoc IRNat
     */
    function getRewardsInfo()
        external view
        returns (
            uint256 _totalAssignableRewards,
            uint256 _totalAssignedRewards,
            uint256 _totalClaimedRewards,
            uint256 _totalWithdrawnRewards,
            uint256 _totalWithdrawnAssignableRewards
        )
    {
        return (
            totalAssignableRewards,
            totalAssignedRewards,
            totalClaimedRewards,
            totalWithdrawnRewards,
            totalWithdrawnAssignableRewards
        );
    }

    /**
     * @inheritdoc IITokenPool
     */
    function getTokenPoolSupplyData()
        external view
        returns (
            uint256 _lockedFundsWei,
            uint256 _totalInflationAuthorizedWei,
            uint256 _totalClaimedWei
        )
    {
        // values should not decrease
        _lockedFundsWei = totalAssignableRewards + totalWithdrawnAssignableRewards;
        _totalInflationAuthorizedWei = 0;
        _totalClaimedWei = totalWithdrawnRewards + totalWithdrawnAssignableRewards;
    }

    /**
     * Implement this function to allow updating incentive receiver contracts through `AddressUpdater`.
     * @return Contract name.
     */
    function getContractName() external pure returns (string memory) {
        return "RNat";
    }

    //////////////////////////// ERC20 functions (disabled) ////////////////////////////

    /**
     * @inheritdoc IERC20
     * @dev Disabled. Non-transferable token.
     */
    function transfer(address, uint256) external pure returns (bool) {
        revert("transfer not supported");
    }

    /**
     * @inheritdoc IERC20
     * @dev Disabled. Non-transferable token.
     */
    function allowance(address, address) external pure returns (uint256) {
        revert("allowance not supported");
    }

    /**
     * @inheritdoc IERC20
     * @dev Disabled. Non-transferable token.
     */
    function approve(address, uint256) external pure returns (bool) {
        revert("approval not supported");
    }

    /**
     * @inheritdoc IERC20
     * @dev Disabled. Non-transferable token.
     */
    function transferFrom(address, address, uint256) external pure returns (bool) {
        revert("transfer not supported");
    }

    //////////////////////////// Internal functions ////////////////////////////

    /**
     * Returns the RNat account data. If the account for the msg.sender does not exist, it creates a new one.
     */
    function _getOrCreateRNatAccount() internal returns (IIRNatAccount _rNatAccount) {
        _rNatAccount = ownerToRNatAccount[msg.sender];
        if (address(_rNatAccount) != address(0)) {
            return _rNatAccount;
        }
        require(libraryAddress != address(0), "library address not set yet");

        // create RNat account
        _rNatAccount = IIRNatAccount(payable(createClone(libraryAddress)));
        require(_isContract(address(_rNatAccount)), "clone not created successfully");
        _rNatAccount.initialize(msg.sender, this);
        rNatAccountToOwner[_rNatAccount] = msg.sender;
        ownerToRNatAccount[msg.sender] = _rNatAccount;
        emit RNatAccountCreated(msg.sender, _rNatAccount);

        // register owner as executor if not a registered executor (fee == 0)
        uint256 fee = claimSetupManager.getExecutorCurrentFeeValue(msg.sender);
        if (fee == 0) {
            _rNatAccount.setClaimExecutors(claimSetupManager, new address[](0));
        }

        return _rNatAccount;
    }

    /**
     * Claims rewards for the sender for the given project, up to the given month.
     * @param _projectId The project id.
     * @param _month The month up to which to claim rewards.
     * @param _currentMonth The current month.
     * @return _totalAmount The total amount of claimed rewards.
     */
    function _claimRewards(
        uint256 _projectId,
        uint256 _month,
        uint256 _currentMonth
    )
        internal
        returns (uint128 _totalAmount)
    {
        Project storage project = _getProject(_projectId);
        require(!project.claimingDisabled, "claiming disabled");
        uint256 claimingMonthIndex = project.lastClaimingMonthIndex[msg.sender];
        uint256 length = project.monthsWithRewards.length - claimingMonthIndex;
        uint256[] memory months = new uint256[](length);
        uint256[] memory amounts = new uint256[](length);
        for (uint256 i = 0; i < length; i++) {
            uint256 month = project.monthsWithRewards[claimingMonthIndex];
            if (_month < month) { // can be a month in the future
                break;
            }
            MonthlyRewards storage monthlyRewards = project.monthlyRewards[month];
            Rewards storage rewards = monthlyRewards.rewards[msg.sender];
            months[i] = month;
            uint128 amount = rewards.assignedRewards - rewards.claimedRewards;
            _totalAmount += amount;
            monthlyRewards.claimedRewards += amount;
            rewards.claimedRewards += amount;
            if (amount > 0) {
                amounts[i] = amount;
                emit RewardsClaimed(_projectId, month, msg.sender, amount);
            }
            claimingMonthIndex++;
        }
        project.totalClaimedRewards += _totalAmount;

        // decrease claimingMonthIndex to the last month with assignable rewards (one month before the current month)
        while (claimingMonthIndex > 0 && project.monthsWithRewards[claimingMonthIndex - 1] + 1 >= _currentMonth) {
            claimingMonthIndex--;
        }
        // can be equal to project.monthsWithRewards.length
        project.lastClaimingMonthIndex[msg.sender] = claimingMonthIndex;
        // transfer (wrap) rewards
        _getOrCreateRNatAccount().receiveRewards{value: _totalAmount}(wNat, months, amounts);
    }

    /**
     * @inheritdoc AddressUpdatable
     */
    function _updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    )
        internal override
    {
        if (incentivePoolEnabled) {
            super._updateContractAddresses(_contractNameHashes, _contractAddresses);
        }
        claimSetupManager = IIClaimSetupManager(
            _getContractAddress(_contractNameHashes, _contractAddresses, "ClaimSetupManager"));
        IWNat newWNat = IWNat(payable(_getContractAddress(_contractNameHashes, _contractAddresses, "WNat")));
        if (address(wNat) == address(0)) {
            wNat = newWNat;
            require(wNat.decimals() == decimals, "decimals mismatch");
        } else if (newWNat != wNat) {
            revert("wrong wNat address");
        }
    }

    /**
     * @inheritdoc IncentivePoolReceiver
     */
    function _receiveIncentive() internal override {
        totalAssignableRewards += uint128(msg.value);
    }

    /**
     * @inheritdoc IncentivePoolReceiver
     */
    function _getExpectedBalance() internal override view returns(uint256 _balanceExpectedWei) {
        return totalAssignableRewards - totalClaimedRewards;
    }

    /**
     * Returns the project by id.
     */
    function _getProject(uint256 _projectId) internal view returns (Project storage) {
        require(_projectId < projects.length, "invalid project id");
        return projects[_projectId];
    }

    /**
     * Returns the RNat account of the owner.
     */
    function _getRNatAccount(
        address _owner
    )
        internal view
        returns (
            IIRNatAccount _rNatAccount
        )
    {
        _rNatAccount = ownerToRNatAccount[_owner];
        require(address(_rNatAccount) != address(0), "no RNat account");
    }

    /**
     * Returns the current month.
     */
    function _getCurrentMonth() internal view returns (uint256) {
        return (block.timestamp - firstMonthStartTs) / MONTH;
    }

    /**
     * @inheritdoc IncentivePoolReceiver
     */
    function _setDailyAuthorizedIncentive(uint256 _toAuthorizeWei) internal pure override {
        // do nothing
    }

    /**
     * Checks if the address is a contract.
     */
    function _isContract(address _addr) private view returns (bool){
        uint32 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(_addr)
        }
        return (size > 0);
    }

    /**
     * Checks if distribution is enabled.
     */
    function _checkDistributionEnabled(Project storage _project) private view {
        require(!_project.distributionDisabled, "distribution disabled");
    }

    /**
     * Checks if claiming is not permanently disabled.
     */
    function _checkClaimingNotPermanentlyDisabled(Project storage _project) private view {
        require(_project.totalUnassignedUnclaimedRewards == 0, "claiming permanently disabled");
    }

    /**
     * Checks if the sender is the manager.
     */
    function _checkOnlyManager() private view {
        require(msg.sender == manager, "only manager");
    }

    /**
     * Checks if the address is not zero.
     */
    function _checkNonzeroAddress(address _address) private pure {
        require(_address != address(0), "address zero");
    }
}
        

contracts/governance/implementation/Governed.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { GovernedBase } from "./GovernedBase.sol";
import { IGovernanceSettings } from "flare-smart-contracts/contracts/userInterfaces/IGovernanceSettings.sol";


/**
 * @title Governed
 * @dev For deployed, governed contracts, enforce non-zero addresses at create time.
 **/
contract Governed is GovernedBase {
    constructor(IGovernanceSettings _governanceSettings, address _initialGovernance) {
        initialise(_governanceSettings, _initialGovernance);
    }
}
          

contracts/governance/implementation/GovernedBase.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "flare-smart-contracts/contracts/userInterfaces/IGovernanceSettings.sol";


/**
 * @title Governed Base
 * This abstract base class defines behaviors for a governed contract.
 * @dev This class is abstract so that specific behaviors can be defined for the constructor.
 *   Contracts should not be left ungoverned, but not all contract will have a constructor
 *   (for example those pre-defined in genesis).
 * @dev This version is compatible with both Flare (where governance settings is in genesis at the address
 *   0x1000000000000000000000000000000000000007) and Songbird (where governance settings is a deployed contract).
 **/
abstract contract GovernedBase {
    struct TimelockedCall {
        uint256 allowedAfterTimestamp;
        bytes encodedCall;
    }

    IGovernanceSettings public governanceSettings;

    bool private initialised;

    bool public productionMode;

    bool private executing;

    address private initialGovernance;

    mapping(bytes4 selector => TimelockedCall) public timelockedCalls;

    event GovernanceCallTimelocked(bytes4 selector, uint256 allowedAfterTimestamp, bytes encodedCall);
    event TimelockedGovernanceCallExecuted(bytes4 selector, uint256 timestamp);
    event TimelockedGovernanceCallCanceled(bytes4 selector, uint256 timestamp);

    event GovernanceInitialised(address initialGovernance);
    event GovernedProductionModeEntered(address governanceSettings);

    modifier onlyGovernance {
        if (executing || !productionMode) {
            _beforeExecute();
            _;
        } else {
            _recordTimelockedCall(msg.data);
        }
    }

    modifier onlyImmediateGovernance () {
        _checkOnlyGovernance();
        _;
    }

    constructor() {
    }

    /**
     * Execute the timelocked governance calls once the timelock period expires.
     * @dev Only executor can call this method.
     * @param _selector The method selector (only one timelocked call per method is stored).
     */
    function executeGovernanceCall(bytes4 _selector) external {
        require(isExecutor(msg.sender), "only executor");
        TimelockedCall storage call = timelockedCalls[_selector];
        require(call.allowedAfterTimestamp != 0, "timelock: invalid selector");
        require(block.timestamp >= call.allowedAfterTimestamp, "timelock: not allowed yet");
        bytes memory encodedCall = call.encodedCall;
        delete timelockedCalls[_selector];
        executing = true;
        //solhint-disable-next-line avoid-low-level-calls
        (bool success,) = address(this).call(encodedCall);
        executing = false;
        emit TimelockedGovernanceCallExecuted(_selector, block.timestamp);
        _passReturnOrRevert(success);
    }

    /**
     * Cancel a timelocked governance call before it has been executed.
     * @dev Only governance can call this method.
     * @param _selector The method selector.
     */
    function cancelGovernanceCall(bytes4 _selector) external onlyImmediateGovernance {
        require(timelockedCalls[_selector].allowedAfterTimestamp != 0, "timelock: invalid selector");
        emit TimelockedGovernanceCallCanceled(_selector, block.timestamp);
        delete timelockedCalls[_selector];
    }

    /**
     * Enter the production mode after all the initial governance settings have been set.
     * This enables timelocks and the governance is afterwards obtained by calling
     * governanceSettings.getGovernanceAddress().
     */
    function switchToProductionMode() external {
        _checkOnlyGovernance();
        require(!productionMode, "already in production mode");
        initialGovernance = address(0);
        productionMode = true;
        emit GovernedProductionModeEntered(address(governanceSettings));
    }

    /**
     * Initialize the governance address if not first initialized.
     */
    function initialise(IGovernanceSettings _governanceSettings, address _initialGovernance) public virtual {
        require(initialised == false, "initialised != false");
        require(address(_governanceSettings) != address(0), "governance settings zero");
        require(_initialGovernance != address(0), "_governance zero");
        initialised = true;
        governanceSettings = _governanceSettings;
        initialGovernance = _initialGovernance;
        emit GovernanceInitialised(_initialGovernance);
    }

    /**
     * Returns the current effective governance address.
     */
    function governance() public view returns (address) {
        return productionMode ? governanceSettings.getGovernanceAddress() : initialGovernance;
    }

    /**
     * Internal function to check if an address is executor.
     */
    function isExecutor(address _address) public view returns (bool) {
        return initialised && governanceSettings.isExecutor(_address);
    }

    function _beforeExecute() private {
        if (executing) {
            // can only be run from executeGovernanceCall(), where we check that only executor can call
            // make sure nothing else gets executed, even in case of reentrancy
            assert(msg.sender == address(this));
            executing = false;
        } else {
            // must be called with: productionMode=false
            // must check governance in this case
            _checkOnlyGovernance();
        }
    }

    function _recordTimelockedCall(bytes calldata _data) private {
        _checkOnlyGovernance();
        bytes4 selector;
        //solhint-disable-next-line no-inline-assembly
        assembly {
            selector := calldataload(_data.offset)
        }
        uint256 timelock = governanceSettings.getTimelock();
        uint256 allowedAt = block.timestamp + timelock;
        timelockedCalls[selector] = TimelockedCall({
            allowedAfterTimestamp: allowedAt,
            encodedCall: _data
        });
        emit GovernanceCallTimelocked(selector, allowedAt, _data);
    }

    function _checkOnlyGovernance() private view {
        require(msg.sender == governance(), "only governance");
    }

    function _passReturnOrRevert(bool _success) private pure {
        // pass exact return or revert data - needs to be done in assembly
        //solhint-disable-next-line no-inline-assembly
        assembly {
            let size := returndatasize()
            let ptr := mload(0x40)
            mstore(0x40, add(ptr, size))
            returndatacopy(ptr, 0, size)
            if _success {
                return(ptr, size)
            }
            revert(ptr, size)
        }
    }
}
          

contracts/userInterfaces/IRNatAccount.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import "./IRNat.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IRNatAccount {

    event FundsWithdrawn(uint256 amount, bool wrap);
    event LockedAmountBurned(uint256 amount);
    event ExternalTokenTransferred(IERC20 token, uint256 amount);
    event Initialized(address owner, IRNat rNat);
    event ClaimExecutorsSet(address[] executors);

    /**
     * Returns the owner of the contract.
     */
    function owner() external view returns (address);

    /**
     * Returns the `RNat` contract.
     */
    function rNat() external view returns (IRNat);

    /**
     * Returns the total amount of rewards received ever.
     */
    function receivedRewards() external view returns (uint128);

    /**
     * Returns the total amount of rewards withdrawn ever.
     */
    function withdrawnRewards() external view returns (uint128);
}
          

contracts/incentivePool/implementation/IncentivePoolReceiver.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "flare-smart-contracts/contracts/tokenPools/interface/IIIncentivePoolReceiver.sol";
import "../../utils/implementation/TokenPoolBase.sol";
import "../../utils/implementation/AddressUpdatable.sol";


abstract contract IncentivePoolReceiver is TokenPoolBase, IIIncentivePoolReceiver, AddressUpdatable {

    // totals
    uint256 internal totalIncentiveAuthorizedWei;
    uint256 internal totalIncentiveReceivedWei;
    uint256 internal lastIncentiveAuthorizationReceivedTs;
    uint256 internal dailyAuthorizedIncentive;

    // addresses
    address internal incentivePool;

    event DailyAuthorizedIncentiveSet(uint256 authorizedAmountWei);
    event IncentiveReceived(uint256 amountReceivedWei);

    /**
     * @dev This modifier ensures that method can only be called by incentive pool.
     */
    modifier onlyIncentivePool {
        _checkOnlyIncentivePool();
        _;
    }

    constructor(address _addressUpdater) AddressUpdatable(_addressUpdater) {}

    /**
     * @notice Notify the receiver that it is entitled to receive `_toAuthorizeWei` incentive amount.
     * @param _toAuthorizeWei the amount of incentive that can be awarded in the coming day
     */
    function setDailyAuthorizedIncentive(uint256 _toAuthorizeWei) external onlyIncentivePool {
        dailyAuthorizedIncentive = _toAuthorizeWei;
        totalIncentiveAuthorizedWei = totalIncentiveAuthorizedWei + _toAuthorizeWei;
        lastIncentiveAuthorizationReceivedTs = block.timestamp;

        _setDailyAuthorizedIncentive(_toAuthorizeWei);

        emit DailyAuthorizedIncentiveSet(_toAuthorizeWei);
    }

    /**
     * @notice Receive native tokens from incentive pool.
     */
    function receiveIncentive() external payable mustBalance onlyIncentivePool {
        totalIncentiveReceivedWei = totalIncentiveReceivedWei + msg.value;

        _receiveIncentive();

        emit IncentiveReceived(msg.value);
    }

    /**
     * @notice Incentive pool receivers have a reference to the incentive pool contract.
     */
    function getIncentivePoolAddress() external view returns(address) {
        return incentivePool;
    }

    /**
     * @notice Return expected balance of reward manager ignoring sent self-destruct funds
     */
    function getExpectedBalance() external view returns(uint256) {
        return _getExpectedBalance();
    }

    function getIncentivePoolReceiverInfo()
        external view
        returns(
            uint256 _totalIncentiveAuthorizedWei,
            uint256 _totalIncentiveReceivedWei,
            uint256 _lastIncentiveAuthorizationReceivedTs,
            uint256 _dailyAuthorizedIncentive
        )
    {
        return (
            totalIncentiveAuthorizedWei,
            totalIncentiveReceivedWei,
            lastIncentiveAuthorizationReceivedTs,
            dailyAuthorizedIncentive
        );
    }

    /**
     * @notice Implementation of the AddressUpdatable abstract method.
     * @dev It can be overridden if other contracts are needed.
     */
    function _updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    )
        internal virtual override
    {
        incentivePool = _getContractAddress(_contractNameHashes, _contractAddresses, "IncentivePool");
    }

    /**
     * @dev Method that is called when new daily incentive is authorized.
     */
    function _setDailyAuthorizedIncentive(uint256 _toAuthorizeWei) internal virtual;

    /**
     * @dev Method that is called when new incentive is received.
     */
    function _receiveIncentive() internal virtual;

    /**
     * @dev Method that is used in `mustBalance` modifier. It should return expected balance after
     *      triggered function completes (claiming, burning, receiving incentive,...).
     */
    function _getExpectedBalance() internal virtual override view returns(uint256 _balanceExpectedWei) {
        return totalIncentiveReceivedWei;
    }

    function _checkOnlyIncentivePool() private view {
        require(msg.sender == incentivePool, "incentive pool only");
    }
}
          

contracts/protocol/interface/IIClaimSetupManager.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import "flare-smart-contracts/contracts/userInterfaces/IClaimSetupManager.sol";
import "../../userInterfaces/IWNat.sol";

/**
 * Internal interface for the `ClaimSetupManager contract.
 */
interface IIClaimSetupManager is IClaimSetupManager {
    /**
     * Emitted when the `libraryAddress` has been set.
     */
    event SetLibraryAddress(address libraryAddress);

    /**
     * Sets new library address.
     */
    function setLibraryAddress(address _libraryAddress) external;

    /**
     * Sets minimum fee allowed for executors, in wei.
     */
    function setMinFeeValueWei(uint256 _minFeeValueWei) external;

    /**
     * Sets maximum fee allowed for executors, in wei.
     */
    function setMaxFeeValueWei(uint256 _maxFeeValueWei) external;

    /**
     * Sets the fee required to register an executor, which must be higher than 0.
     */
    function setRegisterExecutorFeeValueWei(uint256 _registerExecutorFeeValueWei) external;

    /**
     * Returns the `WNat` contract.
     */
    function wNat() external view returns(IWNat);

    /**
     * Gets the [Personal Delegation Account](https://docs.flare.network/tech/personal-delegation-account) (PDA) for
     * a list of accounts for which an executor is claiming.
     * Returns owner address instead if the PDA is not created yet or not enabled.
     * @param _executor Executor to query.
     * @param _owners Array of reward owners which must have set `_executor` as their executor.
     * @return _recipients Addresses which will receive the claimed rewards. Can be the reward owners or their PDAs.
     * @return _executorFeeValue Executor's fee value, in wei.
     */
    function getAutoClaimAddressesAndExecutorFee(address _executor, address[] memory _owners)
        external view returns (address[] memory _recipients, uint256 _executorFeeValue);

    /**
     * Checks if an executor can claim on behalf of a given account and send funds to a given recipient address.
     *
     * Reverts if claiming is not possible, does nothing otherwise.
     * @param _executor The executor to query.
     * @param _owner The reward owner to query.
     * @param _recipient The address where the reward would be sent.
     */
    function checkExecutorAndAllowedRecipient(address _executor, address _owner, address _recipient)
        external view;
}
          

contracts/rNat/implementation/CloneFactory.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

/*
The MIT License (MIT)

Copyright (c) 2018 Murray Software, LLC.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//solhint-disable max-line-length
//solhint-disable no-inline-assembly

/**
 * Simple clone contract factory.
 *
 * This code (intended to be called from an implementor factory contract) will allow you to install a master copy of a
 * contract, then easily (cheaply) create clones with separate state.
 * The deployed bytecode just delegates all calls to the master contract address.
 *
 * [Source attribution](https://github.com/optionality/clone-factory).
 */
contract CloneFactory {

  function createClone(address target) internal returns (address result) {
    bytes20 targetBytes = bytes20(target);
    assembly {
      let clone := mload(0x40)
      mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
      mstore(add(clone, 0x14), targetBytes)
      mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
      result := create(0, clone, 0x37)
    }
  }

  function isClone(address target, address query) internal view returns (bool result) {
    bytes20 targetBytes = bytes20(target);
    assembly {
      let clone := mload(0x40)
      mstore(clone, 0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000)
      mstore(add(clone, 0xa), targetBytes)
      mstore(add(clone, 0x1e), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)

      let other := add(clone, 0x40)
      extcodecopy(query, other, 0, 0x2d)
      result := and(
        eq(mload(clone), mload(other)),
        eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
      )
    }
  }
}
          

contracts/rNat/interface/IIRNat.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;


import "../../userInterfaces/IRNat.sol";

/**
 * Internal interface for the `RNat` contract.
 */
interface IIRNat is IRNat {
    /**
     * Emitted when the `libraryAddress` has been set.
     */
    event LibraryAddressSet(address libraryAddress);

    /**
     * Method for adding new projects.
     * @param _names The names of the projects.
     * @param _distributors The addresses of the distributors.
     * @param _currentMonthDistributionEnabledList The list of booleans indicating if the distribution
     *          is enabled for the current month.
     */
    function addProjects(
        string[] calldata _names,
        address[] calldata _distributors,
        bool[] calldata _currentMonthDistributionEnabledList
    )
        external;

    /**
     * Method for updating the project.
     * @param _projectId The project id.
     * @param _name The name of the project.
     * @param _distributor The address of the distributor.
     * @param _currentMonthDistributionEnabled The boolean indicating if the distribution
     *          is enabled for the current month.
     */
    function updateProject(
        uint256 _projectId,
        string calldata _name,
        address _distributor,
        bool _currentMonthDistributionEnabled
    )
        external;

    /**
     * Method for assigning rewards to the projects.
     * @param _month The month for which the rewards are assigned.
     * @param _projectIds The ids of the projects.
     * @param _amountsWei The amounts of the rewards (in wei).
     */
    function assignRewards(
        uint256 _month,
        uint256[] calldata _projectIds,
        uint128[] calldata _amountsWei
    )
        external;

    /**
     * Disables the distribution for the projects.
     * @param _projectIds The ids of the projects.
     */
    function disableDistribution(uint256[] memory _projectIds) external;

    /**
     * Disables the claiming for the projects.
     * @param _projectIds The ids of the projects.
     */
    function disableClaiming(uint256[] memory _projectIds) external;

    /**
     * Method for unassigning rewards from the project. Can only be called for the past months with expired
     * distributon deadline. In case of disabled distribution governance can call this for all months.
     * @param _projectId The project id.
     * @param _months The months for which the rewards will be unassigned.
     */
    function unassignRewards(uint256 _projectId, uint256[] memory _months) external;

}
          

contracts/rNat/interface/IIRNatAccount.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;


import "../../userInterfaces/IRNatAccount.sol";
import "../../protocol/interface/IIClaimSetupManager.sol";

interface IIRNatAccount is IRNatAccount {

    /**
     * Initialization of a new deployed contract.
     * @param _owner contract owner address
     * @param _rNat contract rNat address
     */
    function initialize(address _owner, IRNat _rNat) external;

    /**
     * Allows the owner to transfer `WNat` wrapped tokens from this contract to the owner account.
     * In case there are some self-destruct native tokens left on the contract,
     * they can be transferred to the owner account using this method and `_wrap = false`.
     * @param _wNat The `WNat` contract.
     * @param _firstMonthStartTs The start timestamp of the first month.
     * @param _amount Amount of tokens to transfer, in wei.
     * @param _wrap If `true`, the tokens will be sent wrapped in `WNat`. If `false`, they will be sent as `Nat`.
     */
    function withdraw(IWNat _wNat, uint256 _firstMonthStartTs, uint128 _amount, bool _wrap) external returns(uint128);

    /**
     * Allows the owner to transfer `WNat` wrapped tokens from this contact to the owner account.
     * In case there are some self-destruct native tokens left on the contract,
     * they can be transferred to the owner account using this method and `_wrap = false`.
     * @param _wNat The `WNat` contract.
     * @param _firstMonthStartTs The start timestamp of the first month.
     * @param _wrap If `true`, the tokens will be sent wrapped in `WNat`. If `false`, they will be sent as `Nat`.
     */
    function withdrawAll(IWNat _wNat, uint256 _firstMonthStartTs, bool _wrap) external returns(uint128);

    /**
     * Sets the addresses of executors and adds the owner as an executor.
     *
     * If any of the executors is a registered executor, some fee needs to be paid.
     * @param _claimSetupManager The `ClaimSetupManager` contract.
     * @param _executors The new executors. All old executors will be deleted and replaced by these.
     */
    function setClaimExecutors(IIClaimSetupManager _claimSetupManager, address[] memory _executors) external payable;

    /**
     * Receives rewards from the `RNat` contract and wraps them on `WNat` contract.
     * @param _wNat The `WNat` contract.
     * @param _months The months for which the rewards are being received.
     * @param _amounts The amounts of rewards being received.
     */
    function receiveRewards(IWNat _wNat, uint256[] memory _months, uint256[] memory _amounts) external payable;

    /**
     * Allows the owner to transfer ERC-20 tokens from this contact to the owner account.
     *
     * The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the
     * RNat account and move them into the main account, where they can be more easily managed.
     *
     * Reverts if the target token is the `WNat` contract: use method `withdraw` or `withdrawAll` for that.
          * @param _wNat The `WNat` contract.
     * @param _token Target token contract address.
     * @param _amount Amount of tokens to transfer.
     */
    function transferExternalToken(IWNat _wNat, IERC20 _token, uint256 _amount) external;

    /**
     * Returns the balance of the `RNat` tokens held by this contract.
     */
    function rNatBalance() external view returns(uint256);

    /**
     * Returns the balance of the `WNat` tokens held by this contract. It is a sum of the `RNat` balance and the
     * additionally wrapped tokens.
     */
    function wNatBalance(IWNat _wNat) external view returns(uint256);

    /**
     * Returns the vested/locked balance of the `RNat` tokens held by this contract.
     */
    function lockedBalance(uint256 _firstMonthStartTs) external view returns(uint256);
}
          

contracts/userInterfaces/IRNat.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import "./IRNatAccount.sol";
import "./IWNat.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

interface IRNat is IERC20Metadata {

    event RNatAccountCreated(address owner, IRNatAccount rNatAccount);
    event ProjectAdded(uint256 indexed id, string name, address distributor, bool currentMonthDistributionEnabled);
    event ProjectUpdated(uint256 indexed id, string name, address distributor, bool currentMonthDistributionEnabled);
    event RewardsAssigned(uint256 indexed projectId, uint256 indexed month, uint128 amount);
    event RewardsUnassigned(uint256 indexed projectId, uint256 indexed month, uint128 amount);
    event RewardsDistributed(
        uint256 indexed projectId,
        uint256 indexed month,
        address[] recipients,
        uint128[] amounts
    );
    event RewardsClaimed(uint256 indexed projectId, uint256 indexed month, address indexed owner, uint128 amount);
    event UnclaimedRewardsUnassigned(uint256 indexed projectId, uint256 indexed month, uint128 amount);
    event UnassignedRewardsWithdrawn(address recipient, uint128 amount);
    event DistributionPermissionUpdated(uint256[] projectIds, bool disabled);
    event ClaimingPermissionUpdated(uint256[] projectIds, bool disabled);

    /**
     * Distributes the rewards of a project for a given month to a list of recipients.
     * It must be called by the project's distributor.
     * It can only be called for the last or current month (if enabled).
     * @param _projectId The id of the project.
     * @param _month The month of the rewards.
     * @param _recipients The addresses of the recipients.
     * @param _amountsWei The amounts of rewards to distribute to each recipient (in wei).
     */
    function distributeRewards(
        uint256 _projectId,
        uint256 _month,
        address[] calldata _recipients,
        uint128[] calldata _amountsWei
    )
        external;

    /**
     * Claim rewards for a list of projects up to the given month.
     * @param _projectIds The ids of the projects.
     * @param _month The month up to which (including) rewards will be claimed.
     * @return _claimedRewardsWei The total amount of rewards claimed (in wei).
     */
    function claimRewards(
        uint256[] calldata _projectIds,
        uint256 _month
    )
        external
        returns (
            uint128 _claimedRewardsWei
        );

    /**
     * Sets the addresses of executors and adds the owner as an executor.
     *
     * If any of the executors is a registered executor, some fee needs to be paid.
     * @param _executors The new executors. All old executors will be deleted and replaced by these.
     */
    function setClaimExecutors(address[] calldata _executors) external payable;

    /**
     * Allows the caller to withdraw `WNat` wrapped tokens from their RNat account to the owner account.
     * In case there are some self-destruct native tokens left on the contract,
     * they can be transferred to the owner account using this method and `_wrap = false`.
     * @param _amount Amount of tokens to transfer (in wei).
     * @param _wrap If `true`, the tokens will be sent wrapped in `WNat`. If `false`, they will be sent as `Nat`.
     */
    function withdraw(uint128 _amount, bool _wrap) external;

    /**
     * Allows the caller to withdraw `WNat` wrapped tokens from their RNat account to the owner account.
     * If some tokens are still locked, only 50% of them will be withdrawn, the rest will be burned as a penalty.
     * In case there are some self-destruct native tokens left on the contract,
     * they can be transferred to the owner account using this method and `_wrap = false`.
     * @param _wrap If `true`, the tokens will be sent wrapped in `WNat`. If `false`, they will be sent as `Nat`.
     */
    function withdrawAll(bool _wrap) external;

    /**
     * Allows the caller to transfer ERC-20 tokens from their RNat account to the owner account.
     *
     * The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the
     * RNat account and move them into the main account, where they can be more easily managed.
     *
     * Reverts if the target token is the `WNat` contract: use method `withdraw` or `withdrawAll` for that.
     * @param _token Target token contract address.
     * @param _amount Amount of tokens to transfer.
     */
    function transferExternalToken(IERC20 _token, uint256 _amount) external;

    /**
     * Gets owner's RNat account. If it doesn't exist it reverts.
     * @param _owner Account to query.
     * @return Address of its RNat account.
     */
    function getRNatAccount(address _owner) external view returns (IRNatAccount);

    /**
     * Returns the timestamp of the start of the first month.
     */
    function firstMonthStartTs() external view returns (uint256);

    /**
     * Returns the `WNat` contract.
     */
    function wNat() external view returns(IWNat);

    /**
     * Gets the current month.
     * @return The current month.
     */
    function getCurrentMonth() external view returns (uint256);

    /**
     * Gets the total number of projects.
     * @return The total number of projects.
     */
    function getProjectsCount() external view returns (uint256);

    /**
     * Gets the basic information of all projects.
     * @return _names The names of the projects.
     * @return _claimingDisabled Whether claiming is disabled for each project.
     */
    function getProjectsBasicInfo() external view returns (string[] memory _names, bool[] memory _claimingDisabled);

    /**
     * Gets the information of a project.
     * @param _projectId The id of the project.
     * @return _name The name of the project.
     * @return _distributor The address of the distributor.
     * @return _currentMonthDistributionEnabled Whether distribution is enabled for the current month.
     * @return _distributionDisabled Whether distribution is disabled.
     * @return _claimingDisabled Whether claiming is disabled.
     * @return _totalAssignedRewards The total amount of rewards assigned to the project (in wei).
     * @return _totalDistributedRewards The total amount of rewards distributed by the project (in wei).
     * @return _totalClaimedRewards The total amount of rewards claimed from the project (in wei).
     * @return _totalUnassignedUnclaimedRewards The total amount of unassigned unclaimed rewards (in wei).
     * @return _monthsWithRewards The months with rewards.
     */
    function getProjectInfo(uint256 _projectId)
        external view
        returns (
            string memory _name,
            address _distributor,
            bool _currentMonthDistributionEnabled,
            bool _distributionDisabled,
            bool _claimingDisabled,
            uint128 _totalAssignedRewards,
            uint128 _totalDistributedRewards,
            uint128 _totalClaimedRewards,
            uint128 _totalUnassignedUnclaimedRewards,
            uint256[] memory _monthsWithRewards
        );

    /**
     * Gets the rewards information of a project for a given month.
     * @param _projectId The id of the project.
     * @param _month The month of the rewards.
     * @return _assignedRewards The amount of rewards assigned to the project for the month (in wei).
     * @return _distributedRewards The amount of rewards distributed by the project for the month (in wei).
     * @return _claimedRewards The amount of rewards claimed from the project for the month (in wei).
     * @return _unassignedUnclaimedRewards The amount of unassigned unclaimed rewards for the month (in wei).
     */
    function getProjectRewardsInfo(uint256 _projectId, uint256 _month)
        external view
        returns (
            uint128 _assignedRewards,
            uint128 _distributedRewards,
            uint128 _claimedRewards,
            uint128 _unassignedUnclaimedRewards
        );

    /**
     * Gets the rewards information of a project for a given month and owner.
     * @param _projectId The id of the project.
     * @param _month The month of the rewards.
     * @param _owner The address of the owner.
     * @return _assignedRewards The amount of rewards assigned to the owner for the month (in wei).
     * @return _claimedRewards The amount of rewards claimed by the owner for the month (in wei).
     * @return _claimable Whether the rewards are claimable by the owner.
     */
    function getOwnerRewardsInfo(uint256 _projectId, uint256 _month, address _owner)
        external view
        returns (
            uint128 _assignedRewards,
            uint128 _claimedRewards,
            bool _claimable
        );

    /**
     * Gets the claimable rewards of a project for a given owner.
     * @param _projectId The id of the project.
     * @param _owner The address of the owner.
     * @return The amount of rewards claimable by the owner (in wei).
     */
    function getClaimableRewards(uint256 _projectId, address _owner) external view returns (uint128);

    /**
     * Gets owner's balances of `WNat`, `RNat` and locked tokens.
     * @param _owner The address of the owner.
     * @return _wNatBalance The balance of `WNat` (in wei).
     * @return _rNatBalance The balance of `RNat` (in wei).
     * @return _lockedBalance The locked/vested balance (in wei).
     */
    function getBalancesOf(
        address _owner
    )
        external view
        returns (
            uint256 _wNatBalance,
            uint256 _rNatBalance,
            uint256 _lockedBalance
        );

    /**
     * Gets totals rewards information.
     * @return _totalAssignableRewards The total amount of assignable rewards (in wei).
     * @return _totalAssignedRewards The total amount of assigned rewards (in wei).
     * @return _totalClaimedRewards The total amount of claimed rewards (in wei).
     * @return _totalWithdrawnRewards The total amount of withdrawn rewards (in wei).
     * @return _totalWithdrawnAssignableRewards The total amount of withdrawn once assignable rewards (in wei).
     */
    function getRewardsInfo()
        external view
        returns (
            uint256 _totalAssignableRewards,
            uint256 _totalAssignedRewards,
            uint256 _totalClaimedRewards,
            uint256 _totalWithdrawnRewards,
            uint256 _totalWithdrawnAssignableRewards
        );
}
          

contracts/userInterfaces/IWNat.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import "flare-smart-contracts/contracts/userInterfaces/IVPToken.sol";
import "flare-smart-contracts/contracts/token/interface/IICleanable.sol";


/**
 * @title Wrapped Native token
 * Accept native token deposits and mint ERC20 WNAT (wrapped native) tokens 1-1.
 */
interface IWNat is IVPToken, IICleanable {
    /**
     * Deposit Native and mint wNat ERC20.
     */
    function deposit() external payable;

    /**
     * Deposit Native from msg.sender and mints WNAT ERC20 to recipient address.
     * @param recipient An address to receive minted WNAT.
     */
    function depositTo(address recipient) external payable;

    /**
     * Withdraw Native and burn WNAT ERC20.
     * @param amount The amount to withdraw.
     */
    function withdraw(uint256 amount) external;

    /**
     * Withdraw WNAT from an owner and send native tokens to msg.sender given an allowance.
     * @param owner An address spending the Native tokens.
     * @param amount The amount to spend.
     *
     * Requirements:
     *
     * - `owner` must have a balance of at least `amount`.
     * - the caller must have allowance for `owners`'s tokens of at least
     * `amount`.
     */
    function withdrawFrom(address owner, uint256 amount) external;
}
          

contracts/utils/implementation/AddressUpdatable.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "flare-smart-contracts/contracts/addressUpdater/interface/IIAddressUpdatable.sol";


abstract contract AddressUpdatable is IIAddressUpdatable {

    // https://docs.soliditylang.org/en/v0.8.7/contracts.html#constant-and-immutable-state-variables
    // No storage slot is allocated
    bytes32 internal constant ADDRESS_STORAGE_POSITION =
        keccak256("flare.diamond.AddressUpdatable.ADDRESS_STORAGE_POSITION");

    modifier onlyAddressUpdater() {
        require(msg.sender == getAddressUpdater(), "only address updater");
        _;
    }

    constructor(address _addressUpdater) {
        setAddressUpdaterValue(_addressUpdater);
    }

    /**
     * external method called from AddressUpdater only
     */
    function updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    )
        external
        onlyAddressUpdater
    {
        // update addressUpdater address
        setAddressUpdaterValue(_getContractAddress(_contractNameHashes, _contractAddresses, "AddressUpdater"));
        // update all other addresses
        _updateContractAddresses(_contractNameHashes, _contractAddresses);
    }

    function getAddressUpdater() public view returns (address _addressUpdater) {
        // Only direct constants are allowed in inline assembly, so we assign it here
        bytes32 position = ADDRESS_STORAGE_POSITION;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            _addressUpdater := sload(position)
        }
    }

    /**
     * virtual method that a contract extending AddressUpdatable must implement
     */
    function _updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
    ) internal virtual;

    function setAddressUpdaterValue(address _addressUpdater) internal {
        // Only direct constants are allowed in inline assembly, so we assign it here
        bytes32 position = ADDRESS_STORAGE_POSITION;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(position, _addressUpdater)
        }
    }

    /**
     * helper method to get contract address
     * @dev it reverts if contract name does not exist
     */
    function _getContractAddress(
        bytes32[] memory _nameHashes,
        address[] memory _addresses,
        string memory _nameToFind
    )
        internal pure
        returns(address)
    {
        bytes32 nameHash = keccak256(abi.encode(_nameToFind));
        address a = address(0);
        for (uint256 i = 0; i < _nameHashes.length; i++) {
            if (nameHash == _nameHashes[i]) {
                a = _addresses[i];
                break;
            }
        }
        require(a != address(0), "address zero");
        return a;
    }
}
          

contracts/utils/implementation/TokenPoolBase.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "flare-smart-contracts/contracts/tokenPools/interface/IITokenPool.sol";


abstract contract TokenPoolBase is IITokenPool {

    address payable constant internal BURN_ADDRESS = payable(0x000000000000000000000000000000000000dEaD);

    /**
     * @dev This modifier ensures that this contract's balance matches the expected balance.
     *      It also burns all funds that came from self-destructor sending a balance to this contract.
     *      Should be used in all methods changing the balance (claiming, receiving funds,...).
     */
    modifier mustBalance {
        _handleSelfDestructProceeds();
        _;
        _checkMustBalance();
    }

    /**
     * @dev Method that is used in `mustBalance` modifier. It should return expected balance after
     *      triggered function completes (claiming, burning, receiving funds,...).
     */
    function _getExpectedBalance() internal virtual view returns(uint256 _balanceExpectedWei);

    /**
     * Burn all funds that came from self-destructor sending a balance to this contract.
     */
    function _handleSelfDestructProceeds() private {
        uint256 expectedBalance = _getExpectedBalance() + msg.value;
        uint256 currentBalance = address(this).balance;
        if (currentBalance > expectedBalance) {
            // Then assume extra were self-destruct proceeds and burn it
            //slither-disable-next-line arbitrary-send-eth
            BURN_ADDRESS.transfer(currentBalance - expectedBalance);
        } else if (currentBalance < expectedBalance) {
            // This is a coding error
            assert(false);
        }
    }

    function _checkMustBalance() private view {
        require(address(this).balance == _getExpectedBalance(), "out of balance");
    }
}
          

node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
          

node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
          

node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}
          

node_modules/flare-smart-contracts/contracts/addressUpdater/interface/IIAddressUpdatable.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;


/**
 * Internal interface for contracts that depend on other contracts whose addresses can change.
 *
 * See `AddressUpdatable`.
 */
interface IIAddressUpdatable {
    /**
     * Updates contract addresses.
     * Can only be called from the `AddressUpdater` contract typically set at construction time.
     * @param _contractNameHashes List of keccak256(abi.encode(...)) contract names.
     * @param _contractAddresses List of contract addresses corresponding to the contract names.
     */
    function updateContractAddresses(
        bytes32[] memory _contractNameHashes,
        address[] memory _contractAddresses
        ) external;
}
          

node_modules/flare-smart-contracts/contracts/token/interface/IICleanable.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

/**
 * Internal interface for entities that can have their block history cleaned.
 */
interface IICleanable {
    /**
     * Set the contract that is allowed to call history cleaning methods.
     * @param _cleanerContract Address of the cleanup contract.
     * Usually this will be an instance of `CleanupBlockNumberManager`.
     */
    function setCleanerContract(address _cleanerContract) external;

    /**
     * Set the cleanup block number.
     * Historic data for the blocks before `cleanupBlockNumber` can be erased.
     * History before that block should never be used since it can be inconsistent.
     * In particular, cleanup block number must be lower than the current vote power block.
     * @param _blockNumber The new cleanup block number.
     */
    function setCleanupBlockNumber(uint256 _blockNumber) external;

    /**
     * Get the current cleanup block number set with `setCleanupBlockNumber()`.
     * @return The currently set cleanup block number.
     */
    function cleanupBlockNumber() external view returns (uint256);
}
          

node_modules/flare-smart-contracts/contracts/tokenPools/interface/IIIncentivePoolReceiver.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

interface IIIncentivePoolReceiver {
    /**
     * Notify the receiver that it is entitled to receive `_toAuthorizeWei` incentive amount.
     * @param _toAuthorizeWei the amount of incentive that can be awarded in the coming day
     */
    function setDailyAuthorizedIncentive(uint256 _toAuthorizeWei) external;

    /**
     * Receive native tokens from incentive pool.
     */
    function receiveIncentive() external payable;

    /**
     * Incentive pool receivers have a reference to the IncentivePool contract.
     */
    function getIncentivePoolAddress() external returns(address);

    /**
     * Incentive pool receivers have a method to get their expected balance
     * (actual balance can be higher due to self-destruct funds)
     */
    function getExpectedBalance() external view returns(uint256);

    /**
     * Implement this function for updating incentive pool receiver contracts through AddressUpdater.
     */
    function getContractName() external view returns (string memory);
}
          

node_modules/flare-smart-contracts/contracts/tokenPools/interface/IITokenPool.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

/**
 * Internal interface for token pools.
 */
interface IITokenPool {

    /**
     * Returns token pool supply data.
     * @return _lockedFundsWei Total amount of funds ever locked in the token pool (wei).
     * `_lockedFundsWei` - `_totalClaimedWei` is the amount currently locked and outside the circulating supply.
     * @return _totalInflationAuthorizedWei Total inflation authorized amount (wei).
     * @return _totalClaimedWei Total claimed amount (wei).
     */
    function getTokenPoolSupplyData() external returns (
        uint256 _lockedFundsWei,
        uint256 _totalInflationAuthorizedWei,
        uint256 _totalClaimedWei
    );
}
          

node_modules/flare-smart-contracts/contracts/userInterfaces/IClaimSetupManager.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import "./IDelegationAccount.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * Public interface for the `ClaimSetupManager contract.
 */
interface IClaimSetupManager {

    event DelegationAccountCreated(address owner, IDelegationAccount delegationAccount);
    event DelegationAccountUpdated(address owner, IDelegationAccount delegationAccount, bool enabled);
    event ClaimExecutorsChanged(address owner, address[] executors);
    event AllowedClaimRecipientsChanged(address owner, address[] recipients);
    event ClaimExecutorFeeValueChanged(address executor, uint256 validFromRewardEpoch, uint256 feeValueWei);
    event ExecutorRegistered(address executor);
    event ExecutorUnregistered(address executor, uint256 validFromRewardEpoch);
    event MinFeeSet(uint256 minFeeValueWei);
    event MaxFeeSet(uint256 maxFeeValueWei);
    event RegisterExecutorFeeSet(uint256 registerExecutorFeeValueWei);
    event SetExecutorsExcessAmountRefunded(address owner, uint256 excessAmount);

    /**
     * Sets the addresses of executors and optionally enables (creates) a
     * [Personal Delegation Account](https://docs.flare.network/tech/personal-delegation-account) (PDA).
     *
     * If any of the executors is a registered executor, some fee needs to be paid.
     * @param _executors The new executors. All old executors will be deleted and replaced by these.
     * @param _enableDelegationAccount Whether the PDA should be enabled.
     */
    function setAutoClaiming(address[] memory _executors, bool _enableDelegationAccount) external payable;

    /**
     * Sets the addresses of executors.
     *
     * If any of the executors is a registered executor, some fee needs to be paid.
     * @param _executors The new executors. All old executors will be deleted and replaced by these.
     */
    function setClaimExecutors(address[] memory _executors) external payable;

    /**
     * Set the addresses of allowed recipients.
     * The reward owner is always an allowed recipient.
     * @param _recipients The new allowed recipients. All old recipients will be deleted and replaced by these.
     */
    function setAllowedClaimRecipients(address[] memory _recipients) external;

    /**
     * Enables (or creates) a
     * [Personal Delegation Account](https://docs.flare.network/tech/personal-delegation-account) (PDA).
     *
     * When using automatic claiming, all airdrops and FTSO rewards will be sent to the PDA, and any rewards
     * accrued by the PDA will be claimed too.
     * @return Address of the delegation account contract.
     */
    function enableDelegationAccount() external returns (IDelegationAccount);

    /**
     * Disables the
     * [Personal Delegation Account](https://docs.flare.network/tech/personal-delegation-account) (PDA).
     *
     * When using automatic claiming, all airdrops and FTSO rewards will be sent to the owner's account.
     * Rewards accrued by the PDA will no longer be automatically claimed.
     *
     * Reverts if there is no PDA.
     */
    function disableDelegationAccount() external;

    /**
     * Registers the caller as an executor and sets its initial fee value.
     *
     * If the executor was already registered, this method only updates the fee, which will take effect after
     * `feeValueUpdateOffset` reward epochs have elapsed.
     *
     * Executor must pay a fee in order to register. See `registerExecutorFeeValueWei`.
     * @param _feeValue Desired fee, in wei. Must be between `minFeeValueWei` and `maxFeeValueWei`. 0 means no fee.
     * @return Reward epoch ID when the changes become effective.
     */
    function registerExecutor(uint256 _feeValue) external payable returns (uint256);

    /**
     * Unregisters the caller as an executor.
     * @return Reward epoch ID when the change becomes effective.
     */
    function unregisterExecutor() external returns (uint256);

    /**
     * Sets the caller's executor fee. The caller must be an executor registered through `registerExecutor`.
     *
     * When called multiple times inside the same reward epoch, only the last value remains.
     * @param _feeValue Desired fee, in wei. Must be between `minFeeValueWei` and `maxFeeValueWei`. 0 means no fee.
     * @return Reward epoch ID when the changes become effective.
     */
    function updateExecutorFeeValue(uint256 _feeValue) external returns(uint256);

    /**
     * Delegates a percentage of the caller's
     * [PDA](https://docs.flare.network/tech/personal-delegation-account)'s voting power to another address.
     * @param _to The address of the recipient.
     * @param _bips The percentage of voting power to be delegated expressed in basis points (1/100 of one percent).
     * Not cumulative: Every call resets the delegation value. A value of 0 revokes delegation.
     */
    function delegate(address _to, uint256 _bips) external;

    /**
     * Undelegates all percentage delegations from the caller's
     * [PDA](https://docs.flare.network/tech/personal-delegation-account) and then delegate to a list of accounts.
     *
     * See `delegate`.
     * @param _delegatees The addresses of the new recipients.
     * @param _bips The percentage of voting power to be delegated to each delegatee, expressed in basis points
     * (1/100 of one percent).
     * Total of all `_bips` values must be lower than 10000.
     */
    function batchDelegate(address[] memory _delegatees, uint256[] memory _bips) external;

    /**
     * Removes all delegations from the caller's [PDA](https://docs.flare.network/tech/personal-delegation-account).
     */
    function undelegateAll() external;

    /**
     * Revokes all delegation from the caller's [PDA](https://docs.flare.network/tech/personal-delegation-account)
     * to a given account at a given block.
     *
     * Only affects the reads via `votePowerOfAtCached()` in the specified block.
     *
     * This method should be used only to prevent rogue delegate voting in the current voting block.
     * To stop delegating use `delegate` with percentage of 0 or `undelegateAll`.
     * @param _who The account to revoke.
     * @param _blockNumber Block number where the revoking will take place. Must be in the past.
     */
    function revokeDelegationAt(address _who, uint256 _blockNumber) external;

    /**
     * Delegates all the [governance](https://docs.flare.network/tech/governance/) vote power of the caller's
     * [PDA](https://docs.flare.network/tech/personal-delegation-account) to another account.
     * @param _to Address of the recipient of the delegation.
     */
    function delegateGovernance(address _to) external;

    /**
     * Undelegates all [governance](https://docs.flare.network/tech/governance/) vote power currently delegated by
     * the caller's [PDA](https://docs.flare.network/tech/personal-delegation-account).
     */
    function undelegateGovernance() external;

    /**
     * Allows the caller to transfer `WNat` wrapped tokens from their
     * [PDA](https://docs.flare.network/tech/personal-delegation-account) to the owner account.
     * @param _amount Amount of tokens to transfer, in wei.
     */
    function withdraw(uint256 _amount) external;

    /**
     * Allows the caller to transfer ERC-20 tokens from their
     * [PDA](https://docs.flare.network/tech/personal-delegation-account) to the owner account.
     *
     * The main use case is to move ERC-20 tokes received by mistake (by an airdrop, for example) out of the PDA
     * and into the main account, where they can be more easily managed.
     *
     * Reverts if the target token is the `WNat` contract: use method `withdraw` for that.
     * @param _token Target token contract address.
     * @param _amount Amount of tokens to transfer.
     */
    function transferExternalToken(IERC20 _token, uint256 _amount) external;

    /**
     * Gets the [PDA](https://docs.flare.network/tech/personal-delegation-account) of an account.
     * @param _owner Account to query.
     * @return Address of its PDA or `address(0)` if it has not been created yet.
     */
    function accountToDelegationAccount(address _owner) external view returns (address);

    /**
     * Gets [PDA](https://docs.flare.network/tech/personal-delegation-account) data for an account.
     * @param _owner Account to query.
     * @return _delegationAccount Account's PDA address or `address(0)` if it has not been created yet.
     * @return _enabled Whether the PDA is enabled.
     */
    function getDelegationAccountData(
        address _owner
    )
        external view
        returns (IDelegationAccount _delegationAccount, bool _enabled);

    /**
     * Gets the addresses of executors authorized to claim for an account.
     * See `setClaimExecutors`.
     * @param _owner The account to query.
     * @return Addresses of all set executors.
     */
    function claimExecutors(address _owner) external view returns (address[] memory);

    /**
     * Gets the addresses of recipients allowed to receive rewards on behalf of an account.
     * Beside these, the owner of the rewards is always authorized.
     * See `setAllowedClaimRecipients`.
     * @param _rewardOwner The account to query.
     * @return Addresses of all set authorized recipients.
     */
    function allowedClaimRecipients(address _rewardOwner) external view returns (address[] memory);

    /**
     * Returns whether an executor is authorized to claim on behalf of a reward owner.
     * See `setClaimExecutors`.
     * @param _owner The reward owner to query.
     * @param _executor The executor to query.
     */
    function isClaimExecutor(address _owner, address _executor) external view returns(bool);

    /**
     * Returns the list of executors registered through `registerExecutor`.
     * Supports paging.
     * @param _start First executor to return.
     * @param _end Last executor to return.
     * @return _registeredExecutors Addresses of the registered executors.
     * @return _totalLength Total amount of executors.
     */
    function getRegisteredExecutors(
        uint256 _start,
        uint256 _end
    )
        external view
        returns (address[] memory _registeredExecutors, uint256 _totalLength);

    /**
     * Returns information about an executor.
     * @param _executor The executor to query.
     * @return _registered Whether the executor is registered.
     * @return _currentFeeValue Executor's current fee value, if registered.
     */
    function getExecutorInfo(address _executor) external view returns (bool _registered, uint256 _currentFeeValue);

    /**
     * Returns the current fee of a registered executor.
     * Reverts if the executor is not registered.
     * @param _executor The executor to query.
     * @return Fee in wei.
     */
    function getExecutorCurrentFeeValue(address _executor) external view  returns (uint256);

    /**
     * Returns the fee of an executor at a given reward epoch.
     * @param _executor The executor to query.
     * @param _rewardEpoch Reward Epoch ID to query.
     * @return Fee in wei at that reward epoch.
     */
    function getExecutorFeeValue(address _executor, uint256 _rewardEpoch) external view returns (uint256);

    /**
     * Returns the currently scheduled fee changes of an executor.
     * @param _executor Executor to query.
     * @return _feeValue Array of scheduled fees.
     * @return _validFromEpoch Array of reward epochs ID where the scheduled fees will become effective.
     * @return _fixed Array of booleans indicating if an scheduled fee change is fixed or it might still be changed.
     */
    function getExecutorScheduledFeeValueChanges(address _executor)
        external view
        returns (
            uint256[] memory _feeValue,
            uint256[] memory _validFromEpoch,
            bool[] memory _fixed
        );
}
          

node_modules/flare-smart-contracts/contracts/userInterfaces/IDelegationAccount.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import "./IClaimSetupManager.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IDelegationAccount {

    event DelegateFtso(address to, uint256 bips);
    event RevokeFtso(address to, uint256 blockNumber);
    event UndelegateAllFtso();
    event DelegateGovernance(address to);
    event UndelegateGovernance();
    event WithdrawToOwner(uint256 amount);
    event ExternalTokenTransferred(IERC20 token, uint256 amount);
    event ExecutorFeePaid(address executor, uint256 amount);
    event Initialize(address owner, IClaimSetupManager manager);
}
          

node_modules/flare-smart-contracts/contracts/userInterfaces/IGovernanceSettings.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;


/**
 * Interface for the `GovernanceSettings` that hold the Flare governance address and its timelock.
 *
 * All governance calls are delayed by the timelock specified in this contract.
 *
 * **NOTE**: This contract enables updating the governance address and timelock only
 * by hard-forking the network, meaning only by updating validator code.
 */
interface IGovernanceSettings {
    /**
     * Gets the governance account address.
     * The governance address can only be changed by a hard fork.
     * @return _address The governance account address.
     */
    function getGovernanceAddress() external view returns (address _address);

    /**
     * Gets the time in seconds that must pass between a governance call and its execution.
     * The timelock value can only be changed by a hard fork.
     * @return _timelock Time in seconds that passes between the governance call and execution.
     */
    function getTimelock() external view returns (uint256 _timelock);

    /**
     * Gets the addresses of the accounts that are allowed to execute the timelocked governance calls,
     * once the timelock period expires.
     * Executors can be changed without a hard fork, via a normal governance call.
     * @return _addresses Array of executor addresses.
     */
    function getExecutors() external view returns (address[] memory _addresses);

    /**
     * Checks whether an address is one of the allowed executors. See `getExecutors`.
     * @param _address The address to check.
     * @return True if `_address` is in the executors list.
     */
    function isExecutor(address _address) external view returns (bool);
}
          

node_modules/flare-smart-contracts/contracts/userInterfaces/IGovernanceVotePower.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

/**
 * Interface for contracts delegating their governance vote power.
 */
interface IGovernanceVotePower {
    /**
     * Delegates all governance vote power of `msg.sender` to address `_to`.
     * @param _to The address of the recipient.
     */
    function delegate(address _to) external;

    /**
     * Undelegates all governance vote power of `msg.sender`.
     */
    function undelegate() external;

    /**
     * Gets the governance vote power of an address at a given block number, including
     * all delegations made to it.
     * @param _who The address being queried.
     * @param _blockNumber The block number at which to fetch the vote power.
     * @return Governance vote power of `_who` at `_blockNumber`.
     */
    function votePowerOfAt(address _who, uint256 _blockNumber) external view returns(uint256);

    /**
     * Gets the governance vote power of an address at the latest block, including
     * all delegations made to it.
     * @param _who The address being queried.
     * @return Governance vote power of `account` at the lastest block.
     */
    function getVotes(address _who) external view returns (uint256);

    /**
     * Gets the address an account is delegating its governance vote power to, at a given block number.
     * @param _who The address being queried.
     * @param _blockNumber The block number at which to fetch the address.
     * @return Address where `_who` was delegating its governance vote power at block `_blockNumber`.
     */
    function getDelegateOfAt(address _who, uint256 _blockNumber) external view returns (address);

    /**
     * Gets the address an account is delegating its governance vote power to, at the latest block number.
     * @param _who The address being queried.
     * @return Address where `_who` is currently delegating its governance vote power.
     */
    function getDelegateOfAtNow(address _who) external view returns (address);
}
          

node_modules/flare-smart-contracts/contracts/userInterfaces/IVPContractEvents.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

/**
 * Events interface for vote-power related operations.
 */
interface IVPContractEvents {
    /**
     * Emitted when the amount of vote power delegated from one account to another changes.
     *
     * **Note**: This event is always emitted from VPToken's `writeVotePowerContract`.
     * @param from The account that has changed the amount of vote power it is delegating.
     * @param to The account whose received vote power has changed.
     * @param priorVotePower The vote power originally delegated.
     * @param newVotePower The new vote power that triggered this event.
     * It can be 0 if the delegation is completely canceled.
     */
    event Delegate(address indexed from, address indexed to, uint256 priorVotePower, uint256 newVotePower);

    /**
     * Emitted when an account revokes its vote power delegation to another account
     * for a single current or past block (typically the current vote block).
     *
     * **Note**: This event is always emitted from VPToken's `writeVotePowerContract` or `readVotePowerContract`.
     *
     * See `revokeDelegationAt` in `IVPToken`.
     * @param delegator The account that revoked the delegation.
     * @param delegatee The account that has been revoked.
     * @param votePower The revoked vote power.
     * @param blockNumber The block number at which the delegation has been revoked.
     */
    event Revoke(address indexed delegator, address indexed delegatee, uint256 votePower, uint256 blockNumber);
}
          

node_modules/flare-smart-contracts/contracts/userInterfaces/IVPToken.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.9;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IGovernanceVotePower} from "./IGovernanceVotePower.sol";
import {IVPContractEvents} from "./IVPContractEvents.sol";

/**
 * Vote power token interface.
 */
interface IVPToken is IERC20 {
    /**
     * Delegate voting power to account `_to` from `msg.sender`, by percentage.
     * @param _to The address of the recipient.
     * @param _bips The percentage of voting power to be delegated expressed in basis points (1/100 of one percent).
     *   Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
     */
    function delegate(address _to, uint256 _bips) external;

    /**
     * Undelegate all percentage delegations from the sender and then delegate corresponding
     *   `_bips` percentage of voting power from the sender to each member of the `_delegatees` array.
     * @param _delegatees The addresses of the new recipients.
     * @param _bips The percentages of voting power to be delegated expressed in basis points (1/100 of one percent).
     *   The sum of all `_bips` values must be at most 10000 (100%).
     */
    function batchDelegate(address[] memory _delegatees, uint256[] memory _bips) external;

    /**
     * Explicitly delegate `_amount` voting power to account `_to` from `msg.sender`.
     * Compare with `delegate` which delegates by percentage.
     * @param _to The address of the recipient.
     * @param _amount An explicit vote power amount to be delegated.
     *   Not cumulative: every call resets the delegation value (and a value of 0 revokes all previous delegations).
     */
    function delegateExplicit(address _to, uint _amount) external;

    /**
    * Revoke all delegation from sender to `_who` at given block.
    * Only affects the reads via `votePowerOfAtCached()` in the block `_blockNumber`.
    * Block `_blockNumber` must be in the past.
    * This method should be used only to prevent rogue delegate voting in the current voting block.
    * To stop delegating use delegate / delegateExplicit with value of 0 or undelegateAll / undelegateAllExplicit.
    * @param _who Address of the delegatee.
    * @param _blockNumber The block number at which to revoke delegation..
    */
    function revokeDelegationAt(address _who, uint _blockNumber) external;

    /**
     * Undelegate all voting power of `msg.sender`. This effectively revokes all previous delegations.
     * Can only be used with percentage delegation.
     * Does not reset delegation mode back to NOT SET.
     */
    function undelegateAll() external;

    /**
     * Undelegate all explicit vote power by amount of `msg.sender`.
     * Can only be used with explicit delegation.
     * Does not reset delegation mode back to NOT SET.
     * @param _delegateAddresses Explicit delegation does not store delegatees' addresses,
     *   so the caller must supply them.
     * @return The amount still delegated (in case the list of delegates was incomplete).
     */
    function undelegateAllExplicit(address[] memory _delegateAddresses) external returns (uint256);


    /**
     * Returns the name of the token.
     * @dev Should be compatible with ERC20 method.
     */
    function name() external view returns (string memory);

    /**
     * Returns the symbol of the token, usually a shorter version of the name.
     * @dev Should be compatible with ERC20 method.
     */
    function symbol() external view returns (string memory);

    /**
     * Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals 2, a balance of 505 tokens should
     * be displayed to a user as 5.05 (505 / 10<sup>2</sup>).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * balanceOf and transfer.
     * @dev Should be compatible with ERC20 method.
     */
    function decimals() external view returns (uint8);


    /**
     * Total amount of tokens held by all accounts at a specific block number.
     * @param _blockNumber The block number to query.
     * @return The total amount of tokens at `_blockNumber`.
     */
    function totalSupplyAt(uint _blockNumber) external view returns(uint256);

    /**
     * Queries the token balance of `_owner` at a specific `_blockNumber`.
     * @param _owner The address from which the balance will be retrieved.
     * @param _blockNumber The block number to query.
     * @return The balance at `_blockNumber`.
     */
    function balanceOfAt(address _owner, uint _blockNumber) external view returns (uint256);


    /**
     * Get the current total vote power.
     * @return The current total vote power (sum of all accounts' vote power).
     */
    function totalVotePower() external view returns(uint256);

    /**
     * Get the total vote power at block `_blockNumber`.
     * @param _blockNumber The block number to query.
     * @return The total vote power at the queried block (sum of all accounts' vote powers).
     */
    function totalVotePowerAt(uint _blockNumber) external view returns(uint256);

    /**
     * Get the current vote power of `_owner`.
     * @param _owner The address to query.
     * @return Current vote power of `_owner`.
     */
    function votePowerOf(address _owner) external view returns(uint256);

    /**
     * Get the vote power of `_owner` at block `_blockNumber`
     * @param _owner The address to query.
     * @param _blockNumber The block number to query.
     * @return Vote power of `_owner` at block number `_blockNumber`.
     */
    function votePowerOfAt(address _owner, uint256 _blockNumber) external view returns(uint256);

    /**
     * Get the vote power of `_owner` at block `_blockNumber`, ignoring revocation information (and cache).
     * @param _owner The address to query.
     * @param _blockNumber The block number to query.
     * @return Vote power of `_owner` at block number `_blockNumber`. Result doesn't change if vote power is revoked.
     */
    function votePowerOfAtIgnoringRevocation(address _owner, uint256 _blockNumber) external view returns(uint256);

    /**
     * Get the delegation mode for account '_who'. This mode determines whether vote power is
     * allocated by percentage or by explicit amount. Once the delegation mode is set,
     * it can never be changed, even if all delegations are removed.
     * @param _who The address to get delegation mode.
     * @return Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
     */
    function delegationModeOf(address _who) external view returns(uint256);

    /**
     * Get current delegated vote power from delegator `_from` to delegatee `_to`.
     * @param _from Address of delegator.
     * @param _to Address of delegatee.
     * @return votePower The delegated vote power.
     */
    function votePowerFromTo(address _from, address _to) external view returns(uint256);

    /**
     * Get delegated vote power from delegator `_from` to delegatee `_to` at `_blockNumber`.
     * @param _from Address of delegator.
     * @param _to Address of delegatee.
     * @param _blockNumber The block number to query.
     * @return The delegated vote power.
     */
    function votePowerFromToAt(address _from, address _to, uint _blockNumber) external view returns(uint256);

    /**
     * Compute the current undelegated vote power of the `_owner` account.
     * @param _owner The address to query.
     * @return The unallocated vote power of `_owner`.
     */
    function undelegatedVotePowerOf(address _owner) external view returns(uint256);

    /**
     * Get the undelegated vote power of the `_owner` account at a given block number.
     * @param _owner The address to query.
     * @param _blockNumber The block number to query.
     * @return The unallocated vote power of `_owner`.
     */
    function undelegatedVotePowerOfAt(address _owner, uint256 _blockNumber) external view returns(uint256);

    /**
     * Get the list of addresses to which `_who` is delegating, and their percentages.
     * @param _who The address to query.
     * @return _delegateAddresses Positional array of addresses being delegated to.
     * @return _bips Positional array of delegation percents specified in basis points (1/100 of 1 percent).
     *    Each one matches the address in the same position in the `_delegateAddresses` array.
     * @return _count The number of delegates.
     * @return _delegationMode Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
     */
    function delegatesOf(address _who)
        external view
        returns (
            address[] memory _delegateAddresses,
            uint256[] memory _bips,
            uint256 _count,
            uint256 _delegationMode
        );

    /**
     * Get the list of addresses to which `_who` is delegating, and their percentages, at the given block.
     * @param _who The address to query.
     * @param _blockNumber The block number to query.
     * @return _delegateAddresses Positional array of addresses being delegated to.
     * @return _bips Positional array of delegation percents specified in basis points (1/100 of 1 percent).
     *    Each one matches the address in the same position in the `_delegateAddresses` array.
     * @return _count The number of delegates.
     * @return _delegationMode Delegation mode: 0 = NOT SET, 1 = PERCENTAGE, 2 = AMOUNT (i.e. explicit).
     */
    function delegatesOfAt(address _who, uint256 _blockNumber)
        external view
        returns (
            address[] memory _delegateAddresses,
            uint256[] memory _bips,
            uint256 _count,
            uint256 _delegationMode
        );

    /**
     * Returns VPContract event interface used for read-only operations (view methods).
     * The only non-view method that might be called on it is `revokeDelegationAt`.
     *
     * `readVotePowerContract` is almost always equal to `writeVotePowerContract`
     * except during an upgrade from one `VPContract` to a new version (which should happen
     * rarely or never and will be announced beforehand).
     *
     * Do not call any methods on `VPContract` directly.
     * State changing methods are forbidden from direct calls.
     * All methods are exposed via `VPToken`.
     * This is the reason that this method returns `IVPContractEvents`.
     * Use it only for listening to events and revoking.
     */
    function readVotePowerContract() external view returns (IVPContractEvents);

    /**
     * Returns VPContract event interface used for state-changing operations (non-view methods).
     * The only non-view method that might be called on it is `revokeDelegationAt`.
     *
     * `writeVotePowerContract` is almost always equal to `readVotePowerContract`,
     * except during upgrade from one `VPContract` to a new version (which should happen
     * rarely or never and will be announced beforehand).
     * In the case of an upgrade, `writeVotePowerContract` is replaced first to establish delegations.
     * After some period (e.g., after a reward epoch ends), `readVotePowerContract` is set equal to it.
     *
     * Do not call any methods on `VPContract` directly.
     * State changing methods are forbidden from direct calls.
     * All are exposed via `VPToken`.
     * This is the reason that this method returns `IVPContractEvents`
     * Use it only for listening to events, delegating, and revoking.
     */
    function writeVotePowerContract() external view returns (IVPContractEvents);

    /**
     * When set, allows token owners to participate in governance voting
     * and delegating governance vote power.
     */
    function governanceVotePower() external view returns (IGovernanceVotePower);
}
          

Compiler Settings

{"viaIR":false,"remappings":["forge-std/=lib/forge-std/src/","@ensdomains/=node_modules/@ensdomains/","@gnosis.pm/=node_modules/@gnosis.pm/","@openzeppelin/=node_modules/@openzeppelin/","@solidity-parser/=node_modules/flare-smart-contracts/node_modules/solhint/node_modules/@solidity-parser/","flare-smart-contracts/=node_modules/flare-smart-contracts/","hardhat/=node_modules/hardhat/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"london"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_governanceSettings","internalType":"contract IGovernanceSettings"},{"type":"address","name":"_initialGovernance","internalType":"address"},{"type":"address","name":"_addressUpdater","internalType":"address"},{"type":"string","name":"_name","internalType":"string"},{"type":"string","name":"_symbol","internalType":"string"},{"type":"uint8","name":"_decimals","internalType":"uint8"},{"type":"address","name":"_manager","internalType":"address"},{"type":"uint256","name":"_firstMonthStartTs","internalType":"uint256"}]},{"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimingPermissionUpdated","inputs":[{"type":"uint256[]","name":"projectIds","internalType":"uint256[]","indexed":false},{"type":"bool","name":"disabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"DailyAuthorizedIncentiveSet","inputs":[{"type":"uint256","name":"authorizedAmountWei","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DistributionPermissionUpdated","inputs":[{"type":"uint256[]","name":"projectIds","internalType":"uint256[]","indexed":false},{"type":"bool","name":"disabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceCallTimelocked","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256","indexed":false},{"type":"bytes","name":"encodedCall","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceInitialised","inputs":[{"type":"address","name":"initialGovernance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernedProductionModeEntered","inputs":[{"type":"address","name":"governanceSettings","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"IncentiveReceived","inputs":[{"type":"uint256","name":"amountReceivedWei","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LibraryAddressSet","inputs":[{"type":"address","name":"libraryAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ProjectAdded","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"string","name":"name","internalType":"string","indexed":false},{"type":"address","name":"distributor","internalType":"address","indexed":false},{"type":"bool","name":"currentMonthDistributionEnabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ProjectUpdated","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"string","name":"name","internalType":"string","indexed":false},{"type":"address","name":"distributor","internalType":"address","indexed":false},{"type":"bool","name":"currentMonthDistributionEnabled","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"RNatAccountCreated","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"address","name":"rNatAccount","internalType":"contract IRNatAccount","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsAssigned","inputs":[{"type":"uint256","name":"projectId","internalType":"uint256","indexed":true},{"type":"uint256","name":"month","internalType":"uint256","indexed":true},{"type":"uint128","name":"amount","internalType":"uint128","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsClaimed","inputs":[{"type":"uint256","name":"projectId","internalType":"uint256","indexed":true},{"type":"uint256","name":"month","internalType":"uint256","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"uint128","name":"amount","internalType":"uint128","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsDistributed","inputs":[{"type":"uint256","name":"projectId","internalType":"uint256","indexed":true},{"type":"uint256","name":"month","internalType":"uint256","indexed":true},{"type":"address[]","name":"recipients","internalType":"address[]","indexed":false},{"type":"uint128[]","name":"amounts","internalType":"uint128[]","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsUnassigned","inputs":[{"type":"uint256","name":"projectId","internalType":"uint256","indexed":true},{"type":"uint256","name":"month","internalType":"uint256","indexed":true},{"type":"uint128","name":"amount","internalType":"uint128","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallCanceled","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallExecuted","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UnassignedRewardsWithdrawn","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":false},{"type":"uint128","name":"amount","internalType":"uint128","indexed":false}],"anonymous":false},{"type":"event","name":"UnclaimedRewardsUnassigned","inputs":[{"type":"uint256","name":"projectId","internalType":"uint256","indexed":true},{"type":"uint256","name":"month","internalType":"uint256","indexed":true},{"type":"uint128","name":"amount","internalType":"uint128","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MONTH","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addProjects","inputs":[{"type":"string[]","name":"_names","internalType":"string[]"},{"type":"address[]","name":"_distributors","internalType":"address[]"},{"type":"bool[]","name":"_currentMonthDistributionEnabledList","internalType":"bool[]"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"assignRewards","inputs":[{"type":"uint256","name":"_month","internalType":"uint256"},{"type":"uint256[]","name":"_projectIds","internalType":"uint256[]"},{"type":"uint128[]","name":"_amountsWei","internalType":"uint128[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint128","name":"_claimedRewardsWei","internalType":"uint128"}],"name":"claimRewards","inputs":[{"type":"uint256[]","name":"_projectIds","internalType":"uint256[]"},{"type":"uint256","name":"_month","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IIClaimSetupManager"}],"name":"claimSetupManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableClaiming","inputs":[{"type":"uint256[]","name":"_projectIds","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableDistribution","inputs":[{"type":"uint256[]","name":"_projectIds","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"distributeRewards","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"uint256","name":"_month","internalType":"uint256"},{"type":"address[]","name":"_recipients","internalType":"address[]"},{"type":"uint128[]","name":"_amountsWei","internalType":"uint128[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableClaiming","inputs":[{"type":"uint256[]","name":"_projectIds","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableDistribution","inputs":[{"type":"uint256[]","name":"_projectIds","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableIncentivePool","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"firstMonthStartTs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"fundingAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"_addressUpdater","internalType":"address"}],"name":"getAddressUpdater","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_wNatBalance","internalType":"uint256"},{"type":"uint256","name":"_rNatBalance","internalType":"uint256"},{"type":"uint256","name":"_lockedBalance","internalType":"uint256"}],"name":"getBalancesOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"","internalType":"uint128"}],"name":"getClaimableRewards","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"getContractName","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentMonth","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getExpectedBalance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getIncentivePoolAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_totalIncentiveAuthorizedWei","internalType":"uint256"},{"type":"uint256","name":"_totalIncentiveReceivedWei","internalType":"uint256"},{"type":"uint256","name":"_lastIncentiveAuthorizationReceivedTs","internalType":"uint256"},{"type":"uint256","name":"_dailyAuthorizedIncentive","internalType":"uint256"}],"name":"getIncentivePoolReceiverInfo","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"_assignedRewards","internalType":"uint128"},{"type":"uint128","name":"_claimedRewards","internalType":"uint128"},{"type":"bool","name":"_claimable","internalType":"bool"}],"name":"getOwnerRewardsInfo","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"uint256","name":"_month","internalType":"uint256"},{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"_name","internalType":"string"},{"type":"address","name":"_distributor","internalType":"address"},{"type":"bool","name":"_currentMonthDistributionEnabled","internalType":"bool"},{"type":"bool","name":"_distributionDisabled","internalType":"bool"},{"type":"bool","name":"_claimingDisabled","internalType":"bool"},{"type":"uint128","name":"_totalAssignedRewards","internalType":"uint128"},{"type":"uint128","name":"_totalDistributedRewards","internalType":"uint128"},{"type":"uint128","name":"_totalClaimedRewards","internalType":"uint128"},{"type":"uint128","name":"_totalUnassignedUnclaimedRewards","internalType":"uint128"},{"type":"uint256[]","name":"_monthsWithRewards","internalType":"uint256[]"}],"name":"getProjectInfo","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"_assignedRewards","internalType":"uint128"},{"type":"uint128","name":"_distributedRewards","internalType":"uint128"},{"type":"uint128","name":"_claimedRewards","internalType":"uint128"},{"type":"uint128","name":"_unassignedUnclaimedRewards","internalType":"uint128"}],"name":"getProjectRewardsInfo","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"uint256","name":"_month","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string[]","name":"_names","internalType":"string[]"},{"type":"bool[]","name":"_claimingDisabled","internalType":"bool[]"}],"name":"getProjectsBasicInfo","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getProjectsCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IRNatAccount"}],"name":"getRNatAccount","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_totalAssignableRewards","internalType":"uint256"},{"type":"uint256","name":"_totalAssignedRewards","internalType":"uint256"},{"type":"uint256","name":"_totalClaimedRewards","internalType":"uint256"},{"type":"uint256","name":"_totalWithdrawnRewards","internalType":"uint256"},{"type":"uint256","name":"_totalWithdrawnAssignableRewards","internalType":"uint256"}],"name":"getRewardsInfo","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_lockedFundsWei","internalType":"uint256"},{"type":"uint256","name":"_totalInflationAuthorizedWei","internalType":"uint256"},{"type":"uint256","name":"_totalClaimedWei","internalType":"uint256"}],"name":"getTokenPoolSupplyData","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IGovernanceSettings"}],"name":"governanceSettings","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"incentivePoolEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_governanceSettings","internalType":"contract IGovernanceSettings"},{"type":"address","name":"_initialGovernance","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExecutor","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"libraryAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"manager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"receiveIncentive","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"receiveRewards","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"setClaimExecutors","inputs":[{"type":"address[]","name":"_executors","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDailyAuthorizedIncentive","inputs":[{"type":"uint256","name":"_toAuthorizeWei","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFundingAddress","inputs":[{"type":"address","name":"_fundingAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLibraryAddress","inputs":[{"type":"address","name":"_libraryAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setManager","inputs":[{"type":"address","name":"_manager","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"switchToProductionMode","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256"},{"type":"bytes","name":"encodedCall","internalType":"bytes"}],"name":"timelockedCalls","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferExternalToken","inputs":[{"type":"address","name":"_token","internalType":"contract IERC20"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unassignRewards","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"uint256[]","name":"_months","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unassignUnclaimedRewards","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"uint256[]","name":"_months","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateContractAddresses","inputs":[{"type":"bytes32[]","name":"_contractNameHashes","internalType":"bytes32[]"},{"type":"address[]","name":"_contractAddresses","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateProject","inputs":[{"type":"uint256","name":"_projectId","internalType":"uint256"},{"type":"string","name":"_name","internalType":"string"},{"type":"address","name":"_distributor","internalType":"address"},{"type":"bool","name":"_currentMonthDistributionEnabled","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IWNat"}],"name":"wNat","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint128","name":"_amount","internalType":"uint128"},{"type":"bool","name":"_wrap","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawAll","inputs":[{"type":"bool","name":"_wrap","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawUnassignedRewards","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint128","name":"_amount","internalType":"uint128"}]}]
              

Contract Creation Code

Verify & Publish
0x60c06040523480156200001157600080fd5b50604051620062f0380380620062f08339810160408190526200003491620003da565b858089896200004482826200012e565b50620000709050817f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b5050600160085542811115620000cd5760405162461bcd60e51b815260206004820152601f60248201527f6669727374206d6f6e746820737461727420696e20746865206675747572650060448201526064015b60405180910390fd5b620000d882620002a3565b6009620000e686826200054a565b50600a620000f585826200054a565b5060ff90921660a052601180546001600160a01b039092166001600160a01b031990921691909117905560805250620006169350505050565b600054600160a01b900460ff16156200018a5760405162461bcd60e51b815260206004820152601460248201527f696e697469616c6973656420213d2066616c73650000000000000000000000006044820152606401620000c4565b6001600160a01b038216620001e25760405162461bcd60e51b815260206004820152601860248201527f676f7665726e616e63652073657474696e6773207a65726f00000000000000006044820152606401620000c4565b6001600160a01b0381166200022d5760405162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b6044820152606401620000c4565b600080546001600160a01b038481166001600160a81b031990921691909117600160a01b17909155600180549183166001600160a01b0319909216821790556040519081527f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db9060200160405180910390a15050565b6001600160a01b038116620002ea5760405162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b6044820152606401620000c4565b50565b6001600160a01b0381168114620002ea57600080fd5b80516200031081620002ed565b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200033d57600080fd5b81516001600160401b03808211156200035a576200035a62000315565b604051601f8301601f19908116603f0116810190828211818310171562000385576200038562000315565b81604052838152602092508683858801011115620003a257600080fd5b600091505b83821015620003c65785820183015181830184015290820190620003a7565b600093810190920192909252949350505050565b600080600080600080600080610100898b031215620003f857600080fd5b88516200040581620002ed565b60208a01519098506200041881620002ed565b60408a01519097506200042b81620002ed565b60608a01519096506001600160401b03808211156200044957600080fd5b620004578c838d016200032b565b965060808b01519150808211156200046e57600080fd5b506200047d8b828c016200032b565b94505060a089015160ff811681146200049557600080fd5b9250620004a560c08a0162000303565b915060e089015190509295985092959890939650565b600181811c90821680620004d057607f821691505b602082108103620004f157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200054557600081815260208120601f850160051c81016020861015620005205750805b601f850160051c820191505b8181101562000541578281556001016200052c565b5050505b505050565b81516001600160401b0381111562000566576200056662000315565b6200057e81620005778454620004bb565b84620004f7565b602080601f831160018114620005b657600084156200059d5750858301515b600019600386901b1c1916600185901b17855562000541565b600085815260208120601f198616915b82811015620005e757888601518255948401946001909101908401620005c6565b5085821015620006065787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051615c916200065f6000396000818161058a0152614aa50152600081816107e701528181610fb501528181612c3c015281816133830152613cd60152615c916000f3fe6080604052600436106103d95760003560e01c80638f2b3605116101fd578063d3b7bfb411610118578063de6feb78116100ab578063eb23070e1161007a578063eb23070e14610c5a578063ef88bf1314610c7a578063f5a9838314610c9a578063f5f5ba7214610caf578063fabf596814610cdc57600080fd5b8063de6feb7814610be4578063debfda3014610c04578063e17f212e14610c24578063e4a8f18b14610c4557600080fd5b8063d808f743116100e7578063d808f74314610b3c578063dc905d5b14610b8f578063dd62ed3e14610baf578063ddd1b67e14610bcf57600080fd5b8063d3b7bfb414610ac2578063d5999a5c14610ae2578063d6ab3b7f14610af9578063d7dd16ff14610b1957600080fd5b8063ad523fe111610190578063b92f3d541161015f578063b92f3d5414610a29578063c4db961914610a49578063cb12b3a014610a69578063d0ebdbe714610aa257600080fd5b8063ad523fe11461097a578063af04cd3b146109d4578063b00c0b76146109e9578063b816f51314610a0957600080fd5b80639edbf007116101cc5780639edbf007146108ff578063a50d5f3d1461091f578063a9059cbb1461093f578063ab60df901461095a57600080fd5b80638f2b3605146108975780639119c494146108b757806395d89b41146108ca5780639cb93f57146108df57600080fd5b80634863ba17116102f8578063631cbe3c1161028b57806368e79c6f1161025a57806368e79c6f146107d55780636f76339c1461080957806370a082311461082957806374e6310e146108495780638a3147261461087757600080fd5b8063631cbe3c1461076d578063679adc881461077557806367a3fde71461079557806367fc4029146107b557600080fd5b80635aa6e675116102c75780635aa6e675146107035780635c039af2146107185780635ff270791461072d57806362354e031461074d57600080fd5b80634863ba1714610687578063489a8a47146106a75780635267a15d146106c757806353b1e258146106fb57600080fd5b80632dc57334116103705780633bd4fbc61161033f5780633bd4fbc6146106065780633be976bf146106265780633e6afd7b14610646578063481c6a751461066757600080fd5b80632dc573341461053857806330147b7714610558578063313ce5671461057857806336116ad5146105be57600080fd5b806318160ddd116103ac57806318160ddd146104a35780631c1c6fe5146104c657806323b872dd146104e85780632dafdbbf1461050857600080fd5b806306fdde03146103de578063095ea7b3146104095780630ac4d982146104395780630f1d1e311461046b575b600080fd5b3480156103ea57600080fd5b506103f3610d12565b6040516104009190614ced565b60405180910390f35b34801561041557600080fd5b50610429610424366004614d15565b610da0565b6040519015158152602001610400565b34801561044557600080fd5b506007546001600160a01b03165b6040516001600160a01b039091168152602001610400565b34801561047757600080fd5b5061048b610486366004614d8c565b610de9565b6040516001600160801b039091168152602001610400565b3480156104af57600080fd5b506104b8610f51565b604051908152602001610400565b3480156104d257600080fd5b506104e66104e1366004614de5565b610f81565b005b3480156104f457600080fd5b50610429610503366004614e02565b6110e1565b34801561051457600080fd5b5061051d611125565b60408051938452602084019290925290820152606001610400565b34801561054457600080fd5b506104e6610553366004614e43565b611185565b34801561056457600080fd5b506104e6610573366004614f99565b61151e565b34801561058457600080fd5b506105ac7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610400565b3480156105ca57600080fd5b506105de6105d9366004614fd5565b6115bb565b604080516001600160801b039485168152939092166020840152151590820152606001610400565b34801561061257600080fd5b5061045361062136600461500e565b61164b565b34801561063257600080fd5b506104e661064136600461502b565b61165c565b34801561065257600080fd5b50600d5461042990600160801b900460ff1681565b34801561067357600080fd5b50601154610453906001600160a01b031681565b34801561069357600080fd5b506104e66106a236600461500e565b61186b565b3480156106b357600080fd5b506104e66106c2366004614d15565b611938565b3480156106d357600080fd5b507f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771954610453565b6104e66119c3565b34801561070f57600080fd5b50610453611a29565b34801561072457600080fd5b506104e6611ac5565b34801561073957600080fd5b506104e66107483660046150a5565b611b14565b34801561075957600080fd5b50600054610453906001600160a01b031681565b6104e6611d9a565b34801561078157600080fd5b506104e661079036600461500e565b611e3e565b3480156107a157600080fd5b506104e66107b03660046150cf565b611e8d565b3480156107c157600080fd5b506104e66107d03660046150a5565b61233a565b3480156107e157600080fd5b506104b87f000000000000000000000000000000000000000000000000000000000000000081565b34801561081557600080fd5b506104e6610824366004615148565b61241b565b34801561083557600080fd5b506104b861084436600461500e565b61271e565b34801561085557600080fd5b506108696108643660046150a5565b61278a565b60405161040092919061518e565b34801561088357600080fd5b506104e6610892366004614f99565b61282f565b3480156108a357600080fd5b506104e66108b23660046151bc565b6128b4565b6104e66108c53660046151f5565b612b05565b3480156108d657600080fd5b506103f3612b72565b3480156108eb57600080fd5b506104e66108fa366004614f99565b612b7f565b34801561090b57600080fd5b50600f54610453906001600160a01b031681565b34801561092b57600080fd5b506104e661093a366004615236565b612c08565b34801561094b57600080fd5b50610429610503366004614d15565b34801561096657600080fd5b5061048b610975366004615264565b612d74565b34801561098657600080fd5b50600b54600c54600d54604080516001600160801b038086168252600160801b958690048116602083015280851692820192909252939092048216606084015216608082015260a001610400565b3480156109e057600080fd5b506104b8612e9c565b3480156109f557600080fd5b506104e6610a043660046152ed565b612ea6565b348015610a1557600080fd5b50601054610453906001600160a01b031681565b348015610a3557600080fd5b506104e6610a44366004615148565b612f81565b348015610a5557600080fd5b50600e54610453906001600160a01b031681565b348015610a7557600080fd5b50600354600454600554600654604080519485526020850193909352918301526060820152608001610400565b348015610aae57600080fd5b506104e6610abd36600461500e565b61325e565b348015610ace57600080fd5b50601254610453906001600160a01b031681565b348015610aee57600080fd5b506104b862278d0081565b348015610b0557600080fd5b5061051d610b1436600461500e565b613291565b348015610b2557600080fd5b50610b2e613408565b60405161040092919061539b565b348015610b4857600080fd5b50610b5c610b57366004615438565b6135e6565b604080516001600160801b0395861681529385166020850152918416918301919091529091166060820152608001610400565b348015610b9b57600080fd5b506104e6610baa366004614f99565b61363a565b348015610bbb57600080fd5b506104b8610bca36600461545a565b6136c3565b348015610bdb57600080fd5b506104b861370e565b348015610bf057600080fd5b506104e6610bff366004615488565b613718565b348015610c1057600080fd5b50610429610c1f36600461500e565b61376a565b348015610c3057600080fd5b5060005461042990600160a81b900460ff1681565b348015610c5157600080fd5b506013546104b8565b348015610c6657600080fd5b506104e6610c753660046154a1565b6137ed565b348015610c8657600080fd5b506104e6610c9536600461545a565b613889565b348015610ca657600080fd5b506104e66139ef565b348015610cbb57600080fd5b506040805180820190915260048152631493985d60e21b60208201526103f3565b348015610ce857600080fd5b50610cfc610cf7366004615488565b613ab5565b6040516104009a9998979695949392919061557f565b60098054610d1f90615608565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4b90615608565b8015610d985780601f10610d6d57610100808354040283529160200191610d98565b820191906000526020600020905b815481529060010190602001808311610d7b57829003601f168201915b505050505081565b60405162461bcd60e51b8152602060048201526016602482015275185c1c1c9bdd985b081b9bdd081cdd5c1c1bdc9d195960521b60448201526000906064015b60405180910390fd5b6000610df3613c39565b610dfb613ca1565b6000610e05613ccb565b905080831115610e4d5760405162461bcd60e51b81526020600482015260136024820152726d6f6e746820696e207468652066757475726560681b6044820152606401610de0565b60005b84811015610e9957610e7b868683818110610e6d57610e6d615642565b905060200201358584613d05565b610e85908461566e565b925080610e9181615695565b915050610e50565b50600c8054839190600090610eb89084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550336001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610f2f91906001600160801b0391909116815260200190565b60405180910390a350610f426001600855565b610f4a614140565b9392505050565b600c54600090610f73906001600160801b03600160801b8204811691166156ae565b6001600160801b0316905090565b610f89613c39565b6000610f93614187565b600f54604051631474538b60e21b81526001600160a01b0391821660048201527f0000000000000000000000000000000000000000000000000000000000000000602482015284151560448201529116906351d14e2c906064016020604051808303816000875af115801561100c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103091906156ce565b905080600c60108282829054906101000a90046001600160801b0316611056919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060006001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516110cd91906001600160801b0391909116815260200190565b60405180910390a3506110de614140565b50565b60405162461bcd60e51b81526020600482015260166024820152751d1c985b9cd9995c881b9bdd081cdd5c1c1bdc9d195960521b6044820152600090606401610de0565b600d54600b5460009182918291611148916001600160801b03918216911661566e565b600d54600c546001600160801b039283169550600094506111759291821691600160801b9091041661566e565b6001600160801b03169050909192565b8281146111a45760405162461bcd60e51b8152600401610de0906156eb565b60006111af87614435565b90506111ba816144a6565b60006111c4613ccb565b90506111d1876001615715565b8114806111f357506001820154600160a01b900460ff1680156111f357508681145b61123f5760405162461bcd60e51b815260206004820152601f60248201527f646973747269627574696f6e20666f72206d6f6e74682064697361626c6564006044820152606401610de0565b60018201546001600160a01b0316331461128e5760405162461bcd60e51b815260206004820152601060248201526f37b7363c903234b9ba3934b13aba37b960811b6044820152606401610de0565b60008781526004830160205260408120815b878110156113c8576112d78989838181106112bd576112bd615642565b90506020020160208101906112d2919061500e565b6144fa565b8686828181106112e9576112e9615642565b90506020020160208101906112fe9190615728565b8260020160008b8b8581811061131657611316615642565b905060200201602081019061132b919061500e565b6001600160a01b0316815260208101919091526040016000908120805490919061135f9084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555086868281811061139557611395615642565b90506020020160208101906113aa9190615728565b6113b4908461566e565b9250806113c081615695565b9150506112a0565b5080546001600160801b03808216916113ea918591600160801b90041661566e565b6001600160801b031611156114415760405162461bcd60e51b815260206004820152601860248201527f657863656564732061737369676e6564207265776172647300000000000000006044820152606401610de0565b805482908290601090611465908490600160801b90046001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550818460020160108282829054906101000a90046001600160801b03166114af919061566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550888a7fd6d0645796a75512d193f0777de35db76867294cabe5495f80180876f6af2c518a8a8a8a60405161150a9493929190615783565b60405180910390a350505050505050505050565b61152661453f565b60005b815181101561157d57600061155683838151811061154957611549615642565b6020026020010151614435565b600101805460ff60a81b1916600160a81b179055508061157581615695565b915050611529565b507fb70968995a4c1e44f87ceefe95859ff83302d137a4c16289b2852e6c9f3a59838160016040516115b09291906157e8565b60405180910390a150565b6000806000806115ca87614435565b90506115d4613ccb565b8611156115ec57600080600093509350935050611642565b600086815260048201602090815260408083206001600160a01b03891684526002019091529020546001909101546001600160801b038083169550600160801b9092049091169250600160b01b900460ff161590505b93509350939050565b600061165682614588565b92915050565b61166461453f565b848314801561167257508481145b61168e5760405162461bcd60e51b8152600401610de0906156eb565b60005b85811015611862576116ae8585838181106112bd576112bd615642565b60138054600181018083556000838152919290839081106116d1576116d1615642565b906000526020600020906007020190508888848181106116f3576116f3615642565b9050602002810190611705919061580c565b82916117129190836158a0565b5086868481811061172557611725615642565b905060200201602081019061173a919061500e565b6001820180546001600160a01b0319166001600160a01b039290921691909117905584848481811061176e5761176e615642565b90506020020160208101906117839190614de5565b600182018054911515600160a01b0260ff60a01b19909216919091179055817fbb0a7330b774a82e3f64257cf07307a3d9466d2c9c45cc6f2ba7c39b746301378a8a868181106117d5576117d5615642565b90506020028101906117e7919061580c565b8a8a888181106117f9576117f9615642565b905060200201602081019061180e919061500e565b89898981811061182057611820615642565b90506020020160208101906118359190614de5565b6040516118459493929190615989565b60405180910390a25050808061185a90615695565b915050611691565b50505050505050565b600054600160b01b900460ff168061188d5750600054600160a81b900460ff16155b1561192d5761189a6145e7565b803b63ffffffff166118df5760405162461bcd60e51b815260206004820152600e60248201526d1b9bdd08184818dbdb9d1c9858dd60921b6044820152606401610de0565b601080546001600160a01b0319166001600160a01b0383169081179091556040519081527fe88d6753e299a05129ac6a16302484e9cf5aa95c7d045575196b97ec5282ee9d906020016115b0565b6110de60003661461f565b611940613ca1565b611948614187565b600f546040516317de921960e11b81526001600160a01b039182166004820152848216602482015260448101849052911690632fbd243290606401600060405180830381600087803b15801561199d57600080fd5b505af11580156119b1573d6000803e3d6000fd5b505050506119bf6001600855565b5050565b6119cb613c39565b6119d361475c565b346004546119e19190615715565b6004556119ec6147ac565b6040513481527f315f313628a86fd313dacf173d9ea6d987a528c9c0c7161c5571099645198b4d9060200160405180910390a1611a27614140565b565b60008054600160a81b900460ff16611a4b57506001546001600160a01b031690565b60008054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac091906159be565b905090565b600054600160b01b900460ff1680611ae75750600054600160a81b900460ff16155b15611b0957611af46145e7565b600d805460ff60801b1916600160801b179055565b611a2760003661461f565b611b1d3361376a565b611b595760405162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b6044820152606401610de0565b6001600160e01b0319811660009081526002602052604081208054909103611bc35760405162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f720000000000006044820152606401610de0565b8054421015611c145760405162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f77656420796574000000000000006044820152606401610de0565b6000816001018054611c2590615608565b80601f0160208091040260200160405190810160405280929190818152602001828054611c5190615608565b8015611c9e5780601f10611c7357610100808354040283529160200191611c9e565b820191906000526020600020905b815481529060010190602001808311611c8157829003601f168201915b505050506001600160e01b0319851660009081526002602052604081208181559293509050611cd06001830182614c53565b50506000805460ff60b01b1916600160b01b1781556040513090611cf59084906159db565b6000604051808303816000865af19150503d8060008114611d32576040519150601f19603f3d011682016040523d82523d6000602084013e611d37565b606091505b50506000805460ff60b01b19169055604080516001600160e01b0319871681524260208201529192507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438910160405180910390a1611d94816147f0565b50505050565b611da2613c39565b6012546001600160a01b03163314611df45760405162461bcd60e51b81526020600482015260156024820152746e6f7420612066756e64696e67206164647265737360581b6044820152606401610de0565b600b8054349190600090611e129084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550611a27614140565b600054600160b01b900460ff1680611e605750600054600160a81b900460ff16155b1561192d57611e6d6145e7565b601280546001600160a01b0383166001600160a01b031990911617905550565b611e9561453f565b611e9d613ccb565b611ea8866001615715565b1015611ef65760405162461bcd60e51b815260206004820152601960248201527f6d6f6e746820746f6f2066617220696e207468652070617374000000000000006044820152606401610de0565b828114611f155760405162461bcd60e51b8152600401610de0906156eb565b6000805b84811015612270576000611f44878784818110611f3857611f38615642565b90506020020135614435565b9050611f4f816144a6565b848483818110611f6157611f61615642565b9050602002016020810190611f769190615728565b600282018054600090611f939084906001600160801b031661566e565b82546001600160801b039182166101009390930a92830291909202199091161790555060008881526004820160205260409020858584818110611fd857611fd8615642565b9050602002016020810190611fed9190615728565b815482906000906120089084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555085858481811061203e5761203e615642565b90506020020160208101906120539190615728565b61205d908561566e565b600583015490945080158061209a5750896005840161207d6001846159f7565b8154811061208d5761208d615642565b9060005260206000200154105b156120be5760058301805460018101825560009182526020909120018a90556121dd565b6000811180156120f7575089600584016120d96001846159f7565b815481106120e9576120e9615642565b906000526020600020015410155b1561210e578061210681615a0a565b9150506120be565b8983600501828154811061212457612124615642565b9060005260206000200154146121dd576005830180546001908101808355600092835261215191906159f7565b90505b818111156121b9576005840161216b6001836159f7565b8154811061217b5761217b615642565b906000526020600020015484600501828154811061219b5761219b615642565b600091825260209091200155806121b181615a0a565b915050612154565b50898360050182815481106121d0576121d0615642565b6000918252602090912001555b898989868181106121f0576121f0615642565b905060200201357fc9dfdb5ed8fa6de49575d26514d4301e875c50a796b1563948d63b5c99a4537489898881811061222a5761222a615642565b905060200201602081019061223f9190615728565b6040516001600160801b03909116815260200160405180910390a3505050808061226890615695565b915050611f19565b50600b546001600160801b0380821691612293918491600160801b90041661566e565b6001600160801b031611156122ea5760405162461bcd60e51b815260206004820152601a60248201527f657863656564732061737369676e61626c6520726577617264730000000000006044820152606401610de0565b80600b60108282829054906101000a90046001600160801b031661230e919061566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050565b61234261480d565b6001600160e01b0319811660009081526002602052604081205490036123aa5760405162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f720000000000006044820152606401610de0565b604080516001600160e01b0319831681524260208201527f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8910160405180910390a16001600160e01b031981166000908152600260205260408120818155906124166001830182614c53565b505050565b6011546001600160a01b031633148061244c5750612437611a29565b6001600160a01b0316336001600160a01b0316145b6124985760405162461bcd60e51b815260206004820152601a60248201527f6f6e6c79206d616e61676572206f7220676f7665726e616e63650000000000006044820152606401610de0565b60006124a383614435565b905060006124af613ccb565b90506000805b845181101561268a57828582815181106124d1576124d1615642565b602002602001015160016124e59190615715565b108061251f57506001840154600160a81b900460ff16801561251f575061250a611a29565b6001600160a01b0316336001600160a01b0316145b61256b5760405162461bcd60e51b815260206004820152601860248201527f756e61737369676e6d656e74206e6f7420616c6c6f77656400000000000000006044820152606401610de0565b600084600401600087848151811061258557612585615642565b6020908102919091018101518252810191909152604001600090812080549092506125c2906001600160801b03600160801b8204811691166156ae565b8254909150819083906000906125e29084906001600160801b03166156ae565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508084612612919061566e565b935086838151811061262657612626615642565b6020026020010151887f16be1ab033a9347c799232ac4f36a27199e48d81dac92c2bb429182d06b3c1a78360405161266d91906001600160801b0391909116815260200190565b60405180910390a35050808061268290615695565b9150506124b5565b506002830180548291906000906126ab9084906001600160801b03166156ae565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080600b60108282829054906101000a90046001600160801b03166126f391906156ae565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505050505050565b600061272982614588565b6001600160a01b03166327fda4de6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612766573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116569190615a21565b600260205260009081526040902080546001820180549192916127ac90615608565b80601f01602080910402602001604051908101604052809291908181526020018280546127d890615608565b80156128255780601f106127fa57610100808354040283529160200191612825565b820191906000526020600020905b81548152906001019060200180831161280857829003601f168201915b5050505050905082565b61283761453f565b60005b815181101561288157600061285a83838151811061154957611549615642565b600101805460ff60b01b1916600160b01b179055508061287981615695565b91505061283a565b507f9254840a31138efc80f83032ab4395d9581ff3d4965cf12c2a936a91ae63a1378160016040516115b09291906157e8565b6128bc613c39565b600054600160b01b900460ff16806128de5750600054600160a81b900460ff16155b15612af2576128eb6145e7565b6128f4826144fa565b600b546001600160801b038083169161291791600160801b8204811691166156ae565b6001600160801b0316101561296e5760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e742061737369676e61626c652072657761726473006044820152606401610de0565b600b805482919060009061298c9084906001600160801b03166156ae565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080600d60008282829054906101000a90046001600160801b03166129d4919061566e565b92506101000a8154816001600160801b0302191690836001600160801b031602179055507f4bd5444026d69324862c7672167ce81f25889ccc877c7ed481e4276183b6948a8282604051612a469291906001600160a01b039290921682526001600160801b0316602082015260400190565b60405180910390a16000826001600160a01b0316826001600160801b031660405160006040518083038185875af1925050503d8060008114612aa4576040519150601f19603f3d011682016040523d82523d6000602084013e612aa9565b606091505b5050905080612aec5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610de0565b50612afd565b612afd60003661461f565b6119bf614140565b612b0d614187565b600e54604051632571bd6960e11b81526001600160a01b0392831692634ae37ad2923492612b45929091169087908790600401615a3a565b6000604051808303818588803b158015612b5e57600080fd5b505af1158015611862573d6000803e3d6000fd5b600a8054610d1f90615608565b612b8761480d565b60005b8151811015612bd5576000612baa83838151811061154957611549615642565b9050612bb581614867565b600101805460ff60b01b1916905580612bcd81615695565b915050612b8a565b507f9254840a31138efc80f83032ab4395d9581ff3d4965cf12c2a936a91ae63a1378160006040516115b09291906157e8565b612c10613c39565b6000612c1a614187565b600f546040516348a6394f60e01b81526001600160a01b0391821660048201527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160801b038616604482015284151560648201529116906348a6394f906084016020604051808303816000875af1158015612ca2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc691906156ce565b905080600c60108282829054906101000a90046001600160801b0316612cec919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060006001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612d6391906001600160801b0391909116815260200190565b60405180910390a3506119bf614140565b600080612d8084614435565b6001810154909150600160b01b900460ff1615612da1576000915050611656565b6000612dab613ccb565b6001600160a01b0385166000908152600684016020526040812054600585015492935091612dda9083906159f7565b90506000805b82811015612e90576000866005018581548110612dff57612dff615642565b9060005260206000200154905080861015612e1a5750612e90565b600081815260048801602090815260408083206001600160a01b038d168452600281019092529091208054612e61906001600160801b03600160801b8204811691166156ae565b612e6b908661566e565b945086612e7781615695565b9750505050508080612e8890615695565b915050612de0565b50979650505050505050565b6000611ac06148c9565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e7719546001600160a01b0316336001600160a01b031614612f1f5760405162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b6044820152606401610de0565b612f77612f5383836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b8152506148e8565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b6119bf82826149c3565b612f8961480d565b6000612f9483614435565b6001810154909150600160b01b900460ff16612fea5760405162461bcd60e51b815260206004820152601560248201527418db185a5b5a5b99c81b9bdd08191a5cd8589b1959605a1b6044820152606401610de0565b6000805b835181101561313557600083600401600086848151811061301157613011615642565b60209081029190910181015182528101919091526040016000908120600181015481549193506001600160801b038082169261305b92600160801b908190048316929104166156ae565b61306591906156ae565b9050808260010160108282829054906101000a90046001600160801b031661308d919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080846130bd919061566e565b93508583815181106130d1576130d1615642565b6020026020010151877f33aa7fa8693d9d4619857267f831d8a7ec7183176c4e0a0759e7604c5771e3088360405161311891906001600160801b0391909116815260200190565b60405180910390a35050808061312d90615695565b915050612fee565b50808260030160108282829054906101000a90046001600160801b031661315c919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080600b60108282829054906101000a90046001600160801b03166131a491906156ae565b82546001600160801b039182166101009390930a9283029190920219909116179055506001828101805460ff60a81b1916600160a81b1790556040805182815280820190915260009160208083019080368337019050509050848160008151811061321157613211615642565b6020026020010181815250507fb70968995a4c1e44f87ceefe95859ff83302d137a4c16289b2852e6c9f3a598381600160405161324f9291906157e8565b60405180910390a15050505050565b61326661480d565b61326f816144fa565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000806132a085614588565b600f54604051632d985e7b60e21b81526001600160a01b03918216600482015291925082169063b66179ec90602401602060405180830381865afa1580156132ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133109190615a21565b9350806001600160a01b03166327fda4de6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133749190615a21565b6040516302b5eedb60e21b81527f000000000000000000000000000000000000000000000000000000000000000060048201529093506001600160a01b03821690630ad7bb6c90602401602060405180830381865afa1580156133db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ff9190615a21565b93959294505050565b60135460609081906001600160401b0381111561342757613427614ec5565b60405190808252806020026020018201604052801561345a57816020015b60608152602001906001900390816134455790505b506013549092506001600160401b0381111561347857613478614ec5565b6040519080825280602002602001820160405280156134a1578160200160208202803683370190505b50905060005b6013548110156135e157601381815481106134c4576134c4615642565b906000526020600020906007020160000180546134e090615608565b80601f016020809104026020016040519081016040528092919081815260200182805461350c90615608565b80156135595780601f1061352e57610100808354040283529160200191613559565b820191906000526020600020905b81548152906001019060200180831161353c57829003601f168201915b505050505083828151811061357057613570615642565b60200260200101819052506013818154811061358e5761358e615642565b906000526020600020906007020160010160169054906101000a900460ff168282815181106135bf576135bf615642565b91151560209283029190910190910152806135d981615695565b9150506134a7565b509091565b60008060008060006135f787614435565b60009687526004016020525050604090932080546001909101546001600160801b0380831697600160801b93849004821697508183169650929091041692509050565b61364261480d565b60005b815181101561369057600061366583838151811061154957611549615642565b905061367081614867565b600101805460ff60a81b191690558061368881615695565b915050613645565b507fb70968995a4c1e44f87ceefe95859ff83302d137a4c16289b2852e6c9f3a59838160006040516115b09291906157e8565b60405162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206e6f7420737570706f727465640000000000000000006044820152600090606401610de0565b6000611ac0613ccb565b61372061475c565b6006819055600354613733908290615715565b600355426005556040518181527fcf636cc80b637bbb81f27bae78adac0fb5b5dee402042a20c6febb1630d5b81b906020016115b0565b60008054600160a01b900460ff1680156116565750600054604051630debfda360e41b81526001600160a01b0384811660048301529091169063debfda3090602401602060405180830381865afa1580156137c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116569190615a5f565b6137f561453f565b600061380086614435565b905061380b836144fa565b806138178587836158a0565b50600181018054831515600160a01b026001600160a81b03199091166001600160a01b0386161717905560405186907f505f02470b9795494019aba2982a68c1c6fea88fcbe5d80bafc28963fbe3bbab90613879908890889088908890615989565b60405180910390a2505050505050565b600054600160a01b900460ff16156138da5760405162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b6044820152606401610de0565b6001600160a01b0382166139305760405162461bcd60e51b815260206004820152601860248201527f676f7665726e616e63652073657474696e6773207a65726f00000000000000006044820152606401610de0565b6001600160a01b0381166139795760405162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b6044820152606401610de0565b600080546001600160a01b038481166001600160a81b031990921691909117600160a01b17909155600180549183166001600160a01b0319909216821790556040519081527f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db9060200160405180910390a15050565b6139f761480d565b600054600160a81b900460ff1615613a515760405162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f64650000000000006044820152606401610de0565b600180546001600160a01b031916905560008054600160a81b60ff60a81b198216179091556040516001600160a01b0390911681527f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9060200160405180910390a1565b606060008060008060008060008060606000613ad08c614435565b600181015460028201546003830154835493945084936001600160a01b0384169360ff600160a01b8204811694600160a81b8304821694600160b01b909304909116926001600160801b0380831693600160801b938490048216938183169391049091169060058a01908a90613b4590615608565b80601f0160208091040260200160405190810160405280929190818152602001828054613b7190615608565b8015613bbe5780601f10613b9357610100808354040283529160200191613bbe565b820191906000526020600020905b815481529060010190602001808311613ba157829003601f168201915b5050505050995080805480602002602001604051908101604052809291908181526020018280548015613c1057602002820191906000526020600020905b815481526020019060010190808311613bfc575b505050505090509a509a509a509a509a509a509a509a509a509a50509193959799509193959799565b600034613c446148c9565b613c4e9190615715565b90504781811115613c915761dead6108fc613c6984846159f7565b6040518115909202916000818181858888f19350505050158015612416573d6000803e3d6000fd5b818110156119bf576119bf615a7c565b600260085403613cc457604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b600062278d00613cfb7f0000000000000000000000000000000000000000000000000000000000000000426159f7565b611ac09190615a92565b600080613d1185614435565b6001810154909150600160b01b900460ff1615613d645760405162461bcd60e51b815260206004820152601160248201527018db185a5b5a5b99c8191a5cd8589b1959607a1b6044820152606401610de0565b3360009081526006820160205260408120546005830154909190613d899083906159f7565b90506000816001600160401b03811115613da557613da5614ec5565b604051908082528060200260200182016040528015613dce578160200160208202803683370190505b5090506000826001600160401b03811115613deb57613deb614ec5565b604051908082528060200260200182016040528015613e14578160200160208202803683370190505b50905060005b83811015614003576000866005018681548110613e3957613e39615642565b90600052602060002001549050808a1015613e545750614003565b600081815260048801602090815260408083203384526002810190925290912085518390879086908110613e8a57613e8a615642565b60209081029190910101528054600090613eb6906001600160801b03600160801b8204811691166156ae565b9050613ec2818c61566e565b600184018054919c508291600090613ee49084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550808260000160108282829054906101000a90046001600160801b0316613f2e919061566e565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506000816001600160801b03161115613fdf57806001600160801b0316868681518110613f8057613f80615642565b602002602001018181525050336001600160a01b0316848f7f991476c3a75b7c98873b2a3ff8ea47ece4cad28a0b122c8064f619d37787424a84604051613fd691906001600160801b0391909116815260200190565b60405180910390a45b88613fe981615695565b995050505050508080613ffb90615695565b915050613e1a565b506003850180548791906000906140249084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b60008411801561408e575086600586016140646001876159f7565b8154811061407457614074615642565b9060005260206000200154600161408b9190615715565b10155b156140a5578361409d81615a0a565b945050614049565b33600090815260068601602052604090208490556140c1614187565b600f54604051632b8f98e160e21b81526001600160a01b039283169263ae3e6384926001600160801b038b1692614102929091169087908790600401615ab4565b6000604051808303818588803b15801561411b57600080fd5b505af115801561412f573d6000803e3d6000fd5b505050505050505050509392505050565b6141486148c9565b4714611a275760405162461bcd60e51b815260206004820152600e60248201526d6f7574206f662062616c616e636560901b6044820152606401610de0565b336000908152601460205260409020546001600160a01b031680156141a95790565b6010546001600160a01b03166142015760405162461bcd60e51b815260206004820152601b60248201527f6c6962726172792061646472657373206e6f74207365742079657400000000006044820152606401610de0565b601054614216906001600160a01b0316614bad565b9050803b63ffffffff1661426c5760405162461bcd60e51b815260206004820152601e60248201527f636c6f6e65206e6f742063726561746564207375636365737366756c6c7900006044820152606401610de0565b60405163485cc95560e01b81523360048201523060248201526001600160a01b0382169063485cc95590604401600060405180830381600087803b1580156142b357600080fd5b505af11580156142c7573d6000803e3d6000fd5b505050506001600160a01b03811660008181526015602090815260408083208054336001600160a01b031991821681179092558185526014845293829020805490941685179093558051928352908201929092527fc96ec7c29cf26f4d6ae403b80302646eb294d9eabdf83f1e9dcf0d5b30e5ae9e910160405180910390a1600e54604051631c4aa8ff60e31b81523360048201526000916001600160a01b03169063e25547f890602401602060405180830381865afa15801561438f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143b39190615a21565b90508060000361443157600e5460408051600081526020810191829052632571bd6960e11b9091526001600160a01b0384811692634ae37ad2926143fe929091169060248101615af4565b600060405180830381600087803b15801561441857600080fd5b505af115801561442c573d6000803e3d6000fd5b505050505b5090565b601354600090821061447e5760405162461bcd60e51b81526020600482015260126024820152711a5b9d985b1a59081c1c9bda9958dd081a5960721b6044820152606401610de0565b6013828154811061449157614491615642565b90600052602060002090600702019050919050565b6001810154600160a81b900460ff16156110de5760405162461bcd60e51b8152602060048201526015602482015274191a5cdd1c9a589d5d1a5bdb88191a5cd8589b1959605a1b6044820152606401610de0565b6001600160a01b0381166110de5760405162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b6044820152606401610de0565b6011546001600160a01b03163314611a275760405162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b6044820152606401610de0565b6001600160a01b0380821660009081526014602052604090205416806145e25760405162461bcd60e51b815260206004820152600f60248201526e1b9bc81493985d081858d8dbdd5b9d608a1b6044820152606401610de0565b919050565b600054600160b01b900460ff16156146175733301461460857614608615a7c565b6000805460ff60b01b19169055565b611a2761480d565b61462761480d565b6000805460408051636221a54b60e01b81529051853593926001600160a01b031691636221a54b9160048083019260209291908290030181865afa158015614673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146979190615a21565b905060006146a58242615715565b9050604051806040016040528082815260200186868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250506001600160e01b031986168152600260209081526040909120835181559083015190915060018201906147239082615b50565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405161324f9493929190615c0f565b6007546001600160a01b03163314611a275760405162461bcd60e51b8152602060048201526013602482015272696e63656e7469766520706f6f6c206f6e6c7960681b6044820152606401610de0565b600b80543491906000906147ca9084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550565b3d604051818101604052816000823e8215614809578181f35b8181fd5b614815611a29565b6001600160a01b0316336001600160a01b031614611a275760405162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b6044820152606401610de0565b6003810154600160801b90046001600160801b0316156110de5760405162461bcd60e51b815260206004820152601d60248201527f636c61696d696e67207065726d616e656e746c792064697361626c65640000006044820152606401610de0565b600c54600b54600091610f73916001600160801b0391821691166156ae565b600080826040516020016148fc9190614ced565b6040516020818303038152906040528051906020012090506000805b86518110156149745786818151811061493357614933615642565b602002602001015183036149625785818151811061495357614953615642565b60200260200101519150614974565b8061496c81615695565b915050614918565b506001600160a01b0381166149ba5760405162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b6044820152606401610de0565b95945050505050565b600d54600160801b900460ff16156149df576149df8282614bff565b614a1382826040518060400160405280601181526020017021b630b4b6a9b2ba3ab826b0b730b3b2b960791b8152506148e8565b600e60006101000a8154816001600160a01b0302191690836001600160a01b031602179055506000614a6283836040518060400160405280600481526020016315d3985d60e21b8152506148e8565b600f549091506001600160a01b0316614b5b57600f80546001600160a01b0319166001600160a01b0383169081179091556040805163313ce56760e01b815290517f000000000000000000000000000000000000000000000000000000000000000060ff16929163313ce5679160048083019260209291908290030181865afa158015614af3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b179190615c38565b60ff16146124165760405162461bcd60e51b81526020600482015260116024820152700c8cac6d2dac2d8e640dad2e6dac2e8c6d607b1b6044820152606401610de0565b600f546001600160a01b038281169116146124165760405162461bcd60e51b815260206004820152601260248201527177726f6e6720774e6174206164647265737360701b6044820152606401610de0565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b614c2f82826040518060400160405280600d81526020016c125b98d95b9d1a5d99541bdbdb609a1b8152506148e8565b600780546001600160a01b0319166001600160a01b03929092169190911790555050565b508054614c5f90615608565b6000825580601f10614c6f575050565b601f0160209004906000526020600020908101906110de91905b808211156144315760008155600101614c89565b60005b83811015614cb8578181015183820152602001614ca0565b50506000910152565b60008151808452614cd9816020860160208601614c9d565b601f01601f19169290920160200192915050565b602081526000610f4a6020830184614cc1565b6001600160a01b03811681146110de57600080fd5b60008060408385031215614d2857600080fd5b8235614d3381614d00565b946020939093013593505050565b60008083601f840112614d5357600080fd5b5081356001600160401b03811115614d6a57600080fd5b6020830191508360208260051b8501011115614d8557600080fd5b9250929050565b600080600060408486031215614da157600080fd5b83356001600160401b03811115614db757600080fd5b614dc386828701614d41565b909790965060209590950135949350505050565b80151581146110de57600080fd5b600060208284031215614df757600080fd5b8135610f4a81614dd7565b600080600060608486031215614e1757600080fd5b8335614e2281614d00565b92506020840135614e3281614d00565b929592945050506040919091013590565b60008060008060008060808789031215614e5c57600080fd5b863595506020870135945060408701356001600160401b0380821115614e8157600080fd5b614e8d8a838b01614d41565b90965094506060890135915080821115614ea657600080fd5b50614eb389828a01614d41565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614f0357614f03614ec5565b604052919050565b60006001600160401b03821115614f2457614f24614ec5565b5060051b60200190565b600082601f830112614f3f57600080fd5b81356020614f54614f4f83614f0b565b614edb565b82815260059290921b84018101918181019086841115614f7357600080fd5b8286015b84811015614f8e5780358352918301918301614f77565b509695505050505050565b600060208284031215614fab57600080fd5b81356001600160401b03811115614fc157600080fd5b614fcd84828501614f2e565b949350505050565b600080600060608486031215614fea57600080fd5b8335925060208401359150604084013561500381614d00565b809150509250925092565b60006020828403121561502057600080fd5b8135610f4a81614d00565b6000806000806000806060878903121561504457600080fd5b86356001600160401b038082111561505b57600080fd5b6150678a838b01614d41565b9098509650602089013591508082111561508057600080fd5b61508c8a838b01614d41565b90965094506040890135915080821115614ea657600080fd5b6000602082840312156150b757600080fd5b81356001600160e01b031981168114610f4a57600080fd5b6000806000806000606086880312156150e757600080fd5b8535945060208601356001600160401b038082111561510557600080fd5b61511189838a01614d41565b9096509450604088013591508082111561512a57600080fd5b5061513788828901614d41565b969995985093965092949392505050565b6000806040838503121561515b57600080fd5b8235915060208301356001600160401b0381111561517857600080fd5b61518485828601614f2e565b9150509250929050565b828152604060208201526000614fcd6040830184614cc1565b6001600160801b03811681146110de57600080fd5b600080604083850312156151cf57600080fd5b82356151da81614d00565b915060208301356151ea816151a7565b809150509250929050565b6000806020838503121561520857600080fd5b82356001600160401b0381111561521e57600080fd5b61522a85828601614d41565b90969095509350505050565b6000806040838503121561524957600080fd5b8235615254816151a7565b915060208301356151ea81614dd7565b6000806040838503121561527757600080fd5b8235915060208301356151ea81614d00565b600082601f83011261529a57600080fd5b813560206152aa614f4f83614f0b565b82815260059290921b840181019181810190868411156152c957600080fd5b8286015b84811015614f8e5780356152e081614d00565b83529183019183016152cd565b6000806040838503121561530057600080fd5b82356001600160401b038082111561531757600080fd5b818501915085601f83011261532b57600080fd5b8135602061533b614f4f83614f0b565b82815260059290921b8401810191818101908984111561535a57600080fd5b948201945b838610156153785785358252948201949082019061535f565b9650508601359250508082111561538e57600080fd5b5061518485828601615289565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156153f257605f198887030185526153e0868351614cc1565b955093820193908201906001016153c4565b50508584038187015286518085528782019482019350915060005b8281101561542b57845115158452938101939281019260010161540d565b5091979650505050505050565b6000806040838503121561544b57600080fd5b50508035926020909101359150565b6000806040838503121561546d57600080fd5b823561547881614d00565b915060208301356151ea81614d00565b60006020828403121561549a57600080fd5b5035919050565b6000806000806000608086880312156154b957600080fd5b8535945060208601356001600160401b03808211156154d757600080fd5b818801915088601f8301126154eb57600080fd5b8135818111156154fa57600080fd5b89602082850101111561550c57600080fd5b602083019650809550505050604086013561552681614d00565b9150606086013561553681614dd7565b809150509295509295909350565b600081518084526020808501945080840160005b8381101561557457815187529582019590820190600101615558565b509495945050505050565b60006101408083526155938184018e614cc1565b6001600160a01b038d1660208501528b151560408501528a1515606085015289151560808501526001600160801b0389811660a086015288811660c086015287811660e0860152861661010085015283810361012085015290506155f78185615544565b9d9c50505050505050505050505050565b600181811c9082168061561c57607f821691505b60208210810361563c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160801b0381811683821601908082111561568e5761568e615658565b5092915050565b6000600182016156a7576156a7615658565b5060010190565b6001600160801b0382811682821603908082111561568e5761568e615658565b6000602082840312156156e057600080fd5b8151610f4a816151a7565b60208082526010908201526f0d8cadccee8d0e640dad2e6dac2e8c6d60831b604082015260600190565b8082018082111561165657611656615658565b60006020828403121561573a57600080fd5b8135610f4a816151a7565b8183526000602080850194508260005b8581101561557457813561576881614d00565b6001600160a01b031687529582019590820190600101615755565b604081526000615797604083018688615745565b8281036020848101919091528482528591810160005b868110156157db5783356157c0816151a7565b6001600160801b0316825292820192908201906001016157ad565b5098975050505050505050565b6040815260006157fb6040830185615544565b905082151560208301529392505050565b6000808335601e1984360301811261582357600080fd5b8301803591506001600160401b0382111561583d57600080fd5b602001915036819003821315614d8557600080fd5b601f82111561241657600081815260208120601f850160051c810160208610156158795750805b601f850160051c820191505b8181101561589857828155600101615885565b505050505050565b6001600160401b038311156158b7576158b7614ec5565b6158cb836158c58354615608565b83615852565b6000601f8411600181146158ff57600085156158e75750838201355b600019600387901b1c1916600186901b178355615959565b600083815260209020601f19861690835b828110156159305786850135825560209485019460019092019101615910565b508682101561594d5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60608152600061599d606083018688615960565b6001600160a01b039490941660208301525090151560409091015292915050565b6000602082840312156159d057600080fd5b8151610f4a81614d00565b600082516159ed818460208701614c9d565b9190910192915050565b8181038181111561165657611656615658565b600081615a1957615a19615658565b506000190190565b600060208284031215615a3357600080fd5b5051919050565b6001600160a01b03841681526040602082018190526000906149ba9083018486615745565b600060208284031215615a7157600080fd5b8151610f4a81614dd7565b634e487b7160e01b600052600160045260246000fd5b600082615aaf57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0384168152606060208201819052600090615ad890830185615544565b8281036040840152615aea8185615544565b9695505050505050565b6001600160a01b038381168252604060208084018290528451918401829052600092858201929091906060860190855b81811015615b42578551851683529483019491830191600101615b24565b509098975050505050505050565b81516001600160401b03811115615b6957615b69614ec5565b615b7d81615b778454615608565b84615852565b602080601f831160018114615bb25760008415615b9a5750858301515b600019600386901b1c1916600185901b178555615898565b600085815260208120601f198616915b82811015615be157888601518255948401946001909101908401615bc2565b5085821015615bff5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b63ffffffff60e01b85168152836020820152606060408201526000615aea606083018486615960565b600060208284031215615c4a57600080fd5b815160ff81168114610f4a57600080fdfea264697066735822122037bfc3eac522e6bbc328dc81a107e5ef6e7fe6b6678501c5c11260cc56d08a9564736f6c6343000814003300000000000000000000000010000000000000000000000000000000000000070000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d290000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d290000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000120000000000000000000000004a0565f8960feb35dc0e0c2ce0fe1ffbea12fca3000000000000000000000000000000000000000000000000000000006661a4c0000000000000000000000000000000000000000000000000000000000000000c52657761726420466c6172650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000472464c5200000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x6080604052600436106103d95760003560e01c80638f2b3605116101fd578063d3b7bfb411610118578063de6feb78116100ab578063eb23070e1161007a578063eb23070e14610c5a578063ef88bf1314610c7a578063f5a9838314610c9a578063f5f5ba7214610caf578063fabf596814610cdc57600080fd5b8063de6feb7814610be4578063debfda3014610c04578063e17f212e14610c24578063e4a8f18b14610c4557600080fd5b8063d808f743116100e7578063d808f74314610b3c578063dc905d5b14610b8f578063dd62ed3e14610baf578063ddd1b67e14610bcf57600080fd5b8063d3b7bfb414610ac2578063d5999a5c14610ae2578063d6ab3b7f14610af9578063d7dd16ff14610b1957600080fd5b8063ad523fe111610190578063b92f3d541161015f578063b92f3d5414610a29578063c4db961914610a49578063cb12b3a014610a69578063d0ebdbe714610aa257600080fd5b8063ad523fe11461097a578063af04cd3b146109d4578063b00c0b76146109e9578063b816f51314610a0957600080fd5b80639edbf007116101cc5780639edbf007146108ff578063a50d5f3d1461091f578063a9059cbb1461093f578063ab60df901461095a57600080fd5b80638f2b3605146108975780639119c494146108b757806395d89b41146108ca5780639cb93f57146108df57600080fd5b80634863ba17116102f8578063631cbe3c1161028b57806368e79c6f1161025a57806368e79c6f146107d55780636f76339c1461080957806370a082311461082957806374e6310e146108495780638a3147261461087757600080fd5b8063631cbe3c1461076d578063679adc881461077557806367a3fde71461079557806367fc4029146107b557600080fd5b80635aa6e675116102c75780635aa6e675146107035780635c039af2146107185780635ff270791461072d57806362354e031461074d57600080fd5b80634863ba1714610687578063489a8a47146106a75780635267a15d146106c757806353b1e258146106fb57600080fd5b80632dc57334116103705780633bd4fbc61161033f5780633bd4fbc6146106065780633be976bf146106265780633e6afd7b14610646578063481c6a751461066757600080fd5b80632dc573341461053857806330147b7714610558578063313ce5671461057857806336116ad5146105be57600080fd5b806318160ddd116103ac57806318160ddd146104a35780631c1c6fe5146104c657806323b872dd146104e85780632dafdbbf1461050857600080fd5b806306fdde03146103de578063095ea7b3146104095780630ac4d982146104395780630f1d1e311461046b575b600080fd5b3480156103ea57600080fd5b506103f3610d12565b6040516104009190614ced565b60405180910390f35b34801561041557600080fd5b50610429610424366004614d15565b610da0565b6040519015158152602001610400565b34801561044557600080fd5b506007546001600160a01b03165b6040516001600160a01b039091168152602001610400565b34801561047757600080fd5b5061048b610486366004614d8c565b610de9565b6040516001600160801b039091168152602001610400565b3480156104af57600080fd5b506104b8610f51565b604051908152602001610400565b3480156104d257600080fd5b506104e66104e1366004614de5565b610f81565b005b3480156104f457600080fd5b50610429610503366004614e02565b6110e1565b34801561051457600080fd5b5061051d611125565b60408051938452602084019290925290820152606001610400565b34801561054457600080fd5b506104e6610553366004614e43565b611185565b34801561056457600080fd5b506104e6610573366004614f99565b61151e565b34801561058457600080fd5b506105ac7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff9091168152602001610400565b3480156105ca57600080fd5b506105de6105d9366004614fd5565b6115bb565b604080516001600160801b039485168152939092166020840152151590820152606001610400565b34801561061257600080fd5b5061045361062136600461500e565b61164b565b34801561063257600080fd5b506104e661064136600461502b565b61165c565b34801561065257600080fd5b50600d5461042990600160801b900460ff1681565b34801561067357600080fd5b50601154610453906001600160a01b031681565b34801561069357600080fd5b506104e66106a236600461500e565b61186b565b3480156106b357600080fd5b506104e66106c2366004614d15565b611938565b3480156106d357600080fd5b507f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771954610453565b6104e66119c3565b34801561070f57600080fd5b50610453611a29565b34801561072457600080fd5b506104e6611ac5565b34801561073957600080fd5b506104e66107483660046150a5565b611b14565b34801561075957600080fd5b50600054610453906001600160a01b031681565b6104e6611d9a565b34801561078157600080fd5b506104e661079036600461500e565b611e3e565b3480156107a157600080fd5b506104e66107b03660046150cf565b611e8d565b3480156107c157600080fd5b506104e66107d03660046150a5565b61233a565b3480156107e157600080fd5b506104b87f000000000000000000000000000000000000000000000000000000006661a4c081565b34801561081557600080fd5b506104e6610824366004615148565b61241b565b34801561083557600080fd5b506104b861084436600461500e565b61271e565b34801561085557600080fd5b506108696108643660046150a5565b61278a565b60405161040092919061518e565b34801561088357600080fd5b506104e6610892366004614f99565b61282f565b3480156108a357600080fd5b506104e66108b23660046151bc565b6128b4565b6104e66108c53660046151f5565b612b05565b3480156108d657600080fd5b506103f3612b72565b3480156108eb57600080fd5b506104e66108fa366004614f99565b612b7f565b34801561090b57600080fd5b50600f54610453906001600160a01b031681565b34801561092b57600080fd5b506104e661093a366004615236565b612c08565b34801561094b57600080fd5b50610429610503366004614d15565b34801561096657600080fd5b5061048b610975366004615264565b612d74565b34801561098657600080fd5b50600b54600c54600d54604080516001600160801b038086168252600160801b958690048116602083015280851692820192909252939092048216606084015216608082015260a001610400565b3480156109e057600080fd5b506104b8612e9c565b3480156109f557600080fd5b506104e6610a043660046152ed565b612ea6565b348015610a1557600080fd5b50601054610453906001600160a01b031681565b348015610a3557600080fd5b506104e6610a44366004615148565b612f81565b348015610a5557600080fd5b50600e54610453906001600160a01b031681565b348015610a7557600080fd5b50600354600454600554600654604080519485526020850193909352918301526060820152608001610400565b348015610aae57600080fd5b506104e6610abd36600461500e565b61325e565b348015610ace57600080fd5b50601254610453906001600160a01b031681565b348015610aee57600080fd5b506104b862278d0081565b348015610b0557600080fd5b5061051d610b1436600461500e565b613291565b348015610b2557600080fd5b50610b2e613408565b60405161040092919061539b565b348015610b4857600080fd5b50610b5c610b57366004615438565b6135e6565b604080516001600160801b0395861681529385166020850152918416918301919091529091166060820152608001610400565b348015610b9b57600080fd5b506104e6610baa366004614f99565b61363a565b348015610bbb57600080fd5b506104b8610bca36600461545a565b6136c3565b348015610bdb57600080fd5b506104b861370e565b348015610bf057600080fd5b506104e6610bff366004615488565b613718565b348015610c1057600080fd5b50610429610c1f36600461500e565b61376a565b348015610c3057600080fd5b5060005461042990600160a81b900460ff1681565b348015610c5157600080fd5b506013546104b8565b348015610c6657600080fd5b506104e6610c753660046154a1565b6137ed565b348015610c8657600080fd5b506104e6610c9536600461545a565b613889565b348015610ca657600080fd5b506104e66139ef565b348015610cbb57600080fd5b506040805180820190915260048152631493985d60e21b60208201526103f3565b348015610ce857600080fd5b50610cfc610cf7366004615488565b613ab5565b6040516104009a9998979695949392919061557f565b60098054610d1f90615608565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4b90615608565b8015610d985780601f10610d6d57610100808354040283529160200191610d98565b820191906000526020600020905b815481529060010190602001808311610d7b57829003601f168201915b505050505081565b60405162461bcd60e51b8152602060048201526016602482015275185c1c1c9bdd985b081b9bdd081cdd5c1c1bdc9d195960521b60448201526000906064015b60405180910390fd5b6000610df3613c39565b610dfb613ca1565b6000610e05613ccb565b905080831115610e4d5760405162461bcd60e51b81526020600482015260136024820152726d6f6e746820696e207468652066757475726560681b6044820152606401610de0565b60005b84811015610e9957610e7b868683818110610e6d57610e6d615642565b905060200201358584613d05565b610e85908461566e565b925080610e9181615695565b915050610e50565b50600c8054839190600090610eb89084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550336001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610f2f91906001600160801b0391909116815260200190565b60405180910390a350610f426001600855565b610f4a614140565b9392505050565b600c54600090610f73906001600160801b03600160801b8204811691166156ae565b6001600160801b0316905090565b610f89613c39565b6000610f93614187565b600f54604051631474538b60e21b81526001600160a01b0391821660048201527f000000000000000000000000000000000000000000000000000000006661a4c0602482015284151560448201529116906351d14e2c906064016020604051808303816000875af115801561100c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103091906156ce565b905080600c60108282829054906101000a90046001600160801b0316611056919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060006001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516110cd91906001600160801b0391909116815260200190565b60405180910390a3506110de614140565b50565b60405162461bcd60e51b81526020600482015260166024820152751d1c985b9cd9995c881b9bdd081cdd5c1c1bdc9d195960521b6044820152600090606401610de0565b600d54600b5460009182918291611148916001600160801b03918216911661566e565b600d54600c546001600160801b039283169550600094506111759291821691600160801b9091041661566e565b6001600160801b03169050909192565b8281146111a45760405162461bcd60e51b8152600401610de0906156eb565b60006111af87614435565b90506111ba816144a6565b60006111c4613ccb565b90506111d1876001615715565b8114806111f357506001820154600160a01b900460ff1680156111f357508681145b61123f5760405162461bcd60e51b815260206004820152601f60248201527f646973747269627574696f6e20666f72206d6f6e74682064697361626c6564006044820152606401610de0565b60018201546001600160a01b0316331461128e5760405162461bcd60e51b815260206004820152601060248201526f37b7363c903234b9ba3934b13aba37b960811b6044820152606401610de0565b60008781526004830160205260408120815b878110156113c8576112d78989838181106112bd576112bd615642565b90506020020160208101906112d2919061500e565b6144fa565b8686828181106112e9576112e9615642565b90506020020160208101906112fe9190615728565b8260020160008b8b8581811061131657611316615642565b905060200201602081019061132b919061500e565b6001600160a01b0316815260208101919091526040016000908120805490919061135f9084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555086868281811061139557611395615642565b90506020020160208101906113aa9190615728565b6113b4908461566e565b9250806113c081615695565b9150506112a0565b5080546001600160801b03808216916113ea918591600160801b90041661566e565b6001600160801b031611156114415760405162461bcd60e51b815260206004820152601860248201527f657863656564732061737369676e6564207265776172647300000000000000006044820152606401610de0565b805482908290601090611465908490600160801b90046001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550818460020160108282829054906101000a90046001600160801b03166114af919061566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550888a7fd6d0645796a75512d193f0777de35db76867294cabe5495f80180876f6af2c518a8a8a8a60405161150a9493929190615783565b60405180910390a350505050505050505050565b61152661453f565b60005b815181101561157d57600061155683838151811061154957611549615642565b6020026020010151614435565b600101805460ff60a81b1916600160a81b179055508061157581615695565b915050611529565b507fb70968995a4c1e44f87ceefe95859ff83302d137a4c16289b2852e6c9f3a59838160016040516115b09291906157e8565b60405180910390a150565b6000806000806115ca87614435565b90506115d4613ccb565b8611156115ec57600080600093509350935050611642565b600086815260048201602090815260408083206001600160a01b03891684526002019091529020546001909101546001600160801b038083169550600160801b9092049091169250600160b01b900460ff161590505b93509350939050565b600061165682614588565b92915050565b61166461453f565b848314801561167257508481145b61168e5760405162461bcd60e51b8152600401610de0906156eb565b60005b85811015611862576116ae8585838181106112bd576112bd615642565b60138054600181018083556000838152919290839081106116d1576116d1615642565b906000526020600020906007020190508888848181106116f3576116f3615642565b9050602002810190611705919061580c565b82916117129190836158a0565b5086868481811061172557611725615642565b905060200201602081019061173a919061500e565b6001820180546001600160a01b0319166001600160a01b039290921691909117905584848481811061176e5761176e615642565b90506020020160208101906117839190614de5565b600182018054911515600160a01b0260ff60a01b19909216919091179055817fbb0a7330b774a82e3f64257cf07307a3d9466d2c9c45cc6f2ba7c39b746301378a8a868181106117d5576117d5615642565b90506020028101906117e7919061580c565b8a8a888181106117f9576117f9615642565b905060200201602081019061180e919061500e565b89898981811061182057611820615642565b90506020020160208101906118359190614de5565b6040516118459493929190615989565b60405180910390a25050808061185a90615695565b915050611691565b50505050505050565b600054600160b01b900460ff168061188d5750600054600160a81b900460ff16155b1561192d5761189a6145e7565b803b63ffffffff166118df5760405162461bcd60e51b815260206004820152600e60248201526d1b9bdd08184818dbdb9d1c9858dd60921b6044820152606401610de0565b601080546001600160a01b0319166001600160a01b0383169081179091556040519081527fe88d6753e299a05129ac6a16302484e9cf5aa95c7d045575196b97ec5282ee9d906020016115b0565b6110de60003661461f565b611940613ca1565b611948614187565b600f546040516317de921960e11b81526001600160a01b039182166004820152848216602482015260448101849052911690632fbd243290606401600060405180830381600087803b15801561199d57600080fd5b505af11580156119b1573d6000803e3d6000fd5b505050506119bf6001600855565b5050565b6119cb613c39565b6119d361475c565b346004546119e19190615715565b6004556119ec6147ac565b6040513481527f315f313628a86fd313dacf173d9ea6d987a528c9c0c7161c5571099645198b4d9060200160405180910390a1611a27614140565b565b60008054600160a81b900460ff16611a4b57506001546001600160a01b031690565b60008054906101000a90046001600160a01b03166001600160a01b031663732524946040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac091906159be565b905090565b600054600160b01b900460ff1680611ae75750600054600160a81b900460ff16155b15611b0957611af46145e7565b600d805460ff60801b1916600160801b179055565b611a2760003661461f565b611b1d3361376a565b611b595760405162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b6044820152606401610de0565b6001600160e01b0319811660009081526002602052604081208054909103611bc35760405162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f720000000000006044820152606401610de0565b8054421015611c145760405162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f77656420796574000000000000006044820152606401610de0565b6000816001018054611c2590615608565b80601f0160208091040260200160405190810160405280929190818152602001828054611c5190615608565b8015611c9e5780601f10611c7357610100808354040283529160200191611c9e565b820191906000526020600020905b815481529060010190602001808311611c8157829003601f168201915b505050506001600160e01b0319851660009081526002602052604081208181559293509050611cd06001830182614c53565b50506000805460ff60b01b1916600160b01b1781556040513090611cf59084906159db565b6000604051808303816000865af19150503d8060008114611d32576040519150601f19603f3d011682016040523d82523d6000602084013e611d37565b606091505b50506000805460ff60b01b19169055604080516001600160e01b0319871681524260208201529192507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438910160405180910390a1611d94816147f0565b50505050565b611da2613c39565b6012546001600160a01b03163314611df45760405162461bcd60e51b81526020600482015260156024820152746e6f7420612066756e64696e67206164647265737360581b6044820152606401610de0565b600b8054349190600090611e129084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550611a27614140565b600054600160b01b900460ff1680611e605750600054600160a81b900460ff16155b1561192d57611e6d6145e7565b601280546001600160a01b0383166001600160a01b031990911617905550565b611e9561453f565b611e9d613ccb565b611ea8866001615715565b1015611ef65760405162461bcd60e51b815260206004820152601960248201527f6d6f6e746820746f6f2066617220696e207468652070617374000000000000006044820152606401610de0565b828114611f155760405162461bcd60e51b8152600401610de0906156eb565b6000805b84811015612270576000611f44878784818110611f3857611f38615642565b90506020020135614435565b9050611f4f816144a6565b848483818110611f6157611f61615642565b9050602002016020810190611f769190615728565b600282018054600090611f939084906001600160801b031661566e565b82546001600160801b039182166101009390930a92830291909202199091161790555060008881526004820160205260409020858584818110611fd857611fd8615642565b9050602002016020810190611fed9190615728565b815482906000906120089084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555085858481811061203e5761203e615642565b90506020020160208101906120539190615728565b61205d908561566e565b600583015490945080158061209a5750896005840161207d6001846159f7565b8154811061208d5761208d615642565b9060005260206000200154105b156120be5760058301805460018101825560009182526020909120018a90556121dd565b6000811180156120f7575089600584016120d96001846159f7565b815481106120e9576120e9615642565b906000526020600020015410155b1561210e578061210681615a0a565b9150506120be565b8983600501828154811061212457612124615642565b9060005260206000200154146121dd576005830180546001908101808355600092835261215191906159f7565b90505b818111156121b9576005840161216b6001836159f7565b8154811061217b5761217b615642565b906000526020600020015484600501828154811061219b5761219b615642565b600091825260209091200155806121b181615a0a565b915050612154565b50898360050182815481106121d0576121d0615642565b6000918252602090912001555b898989868181106121f0576121f0615642565b905060200201357fc9dfdb5ed8fa6de49575d26514d4301e875c50a796b1563948d63b5c99a4537489898881811061222a5761222a615642565b905060200201602081019061223f9190615728565b6040516001600160801b03909116815260200160405180910390a3505050808061226890615695565b915050611f19565b50600b546001600160801b0380821691612293918491600160801b90041661566e565b6001600160801b031611156122ea5760405162461bcd60e51b815260206004820152601a60248201527f657863656564732061737369676e61626c6520726577617264730000000000006044820152606401610de0565b80600b60108282829054906101000a90046001600160801b031661230e919061566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050565b61234261480d565b6001600160e01b0319811660009081526002602052604081205490036123aa5760405162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f720000000000006044820152606401610de0565b604080516001600160e01b0319831681524260208201527f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8910160405180910390a16001600160e01b031981166000908152600260205260408120818155906124166001830182614c53565b505050565b6011546001600160a01b031633148061244c5750612437611a29565b6001600160a01b0316336001600160a01b0316145b6124985760405162461bcd60e51b815260206004820152601a60248201527f6f6e6c79206d616e61676572206f7220676f7665726e616e63650000000000006044820152606401610de0565b60006124a383614435565b905060006124af613ccb565b90506000805b845181101561268a57828582815181106124d1576124d1615642565b602002602001015160016124e59190615715565b108061251f57506001840154600160a81b900460ff16801561251f575061250a611a29565b6001600160a01b0316336001600160a01b0316145b61256b5760405162461bcd60e51b815260206004820152601860248201527f756e61737369676e6d656e74206e6f7420616c6c6f77656400000000000000006044820152606401610de0565b600084600401600087848151811061258557612585615642565b6020908102919091018101518252810191909152604001600090812080549092506125c2906001600160801b03600160801b8204811691166156ae565b8254909150819083906000906125e29084906001600160801b03166156ae565b92506101000a8154816001600160801b0302191690836001600160801b031602179055508084612612919061566e565b935086838151811061262657612626615642565b6020026020010151887f16be1ab033a9347c799232ac4f36a27199e48d81dac92c2bb429182d06b3c1a78360405161266d91906001600160801b0391909116815260200190565b60405180910390a35050808061268290615695565b9150506124b5565b506002830180548291906000906126ab9084906001600160801b03166156ae565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080600b60108282829054906101000a90046001600160801b03166126f391906156ae565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505050505050565b600061272982614588565b6001600160a01b03166327fda4de6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612766573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116569190615a21565b600260205260009081526040902080546001820180549192916127ac90615608565b80601f01602080910402602001604051908101604052809291908181526020018280546127d890615608565b80156128255780601f106127fa57610100808354040283529160200191612825565b820191906000526020600020905b81548152906001019060200180831161280857829003601f168201915b5050505050905082565b61283761453f565b60005b815181101561288157600061285a83838151811061154957611549615642565b600101805460ff60b01b1916600160b01b179055508061287981615695565b91505061283a565b507f9254840a31138efc80f83032ab4395d9581ff3d4965cf12c2a936a91ae63a1378160016040516115b09291906157e8565b6128bc613c39565b600054600160b01b900460ff16806128de5750600054600160a81b900460ff16155b15612af2576128eb6145e7565b6128f4826144fa565b600b546001600160801b038083169161291791600160801b8204811691166156ae565b6001600160801b0316101561296e5760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e742061737369676e61626c652072657761726473006044820152606401610de0565b600b805482919060009061298c9084906001600160801b03166156ae565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080600d60008282829054906101000a90046001600160801b03166129d4919061566e565b92506101000a8154816001600160801b0302191690836001600160801b031602179055507f4bd5444026d69324862c7672167ce81f25889ccc877c7ed481e4276183b6948a8282604051612a469291906001600160a01b039290921682526001600160801b0316602082015260400190565b60405180910390a16000826001600160a01b0316826001600160801b031660405160006040518083038185875af1925050503d8060008114612aa4576040519150601f19603f3d011682016040523d82523d6000602084013e612aa9565b606091505b5050905080612aec5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610de0565b50612afd565b612afd60003661461f565b6119bf614140565b612b0d614187565b600e54604051632571bd6960e11b81526001600160a01b0392831692634ae37ad2923492612b45929091169087908790600401615a3a565b6000604051808303818588803b158015612b5e57600080fd5b505af1158015611862573d6000803e3d6000fd5b600a8054610d1f90615608565b612b8761480d565b60005b8151811015612bd5576000612baa83838151811061154957611549615642565b9050612bb581614867565b600101805460ff60b01b1916905580612bcd81615695565b915050612b8a565b507f9254840a31138efc80f83032ab4395d9581ff3d4965cf12c2a936a91ae63a1378160006040516115b09291906157e8565b612c10613c39565b6000612c1a614187565b600f546040516348a6394f60e01b81526001600160a01b0391821660048201527f000000000000000000000000000000000000000000000000000000006661a4c060248201526001600160801b038616604482015284151560648201529116906348a6394f906084016020604051808303816000875af1158015612ca2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc691906156ce565b905080600c60108282829054906101000a90046001600160801b0316612cec919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555060006001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612d6391906001600160801b0391909116815260200190565b60405180910390a3506119bf614140565b600080612d8084614435565b6001810154909150600160b01b900460ff1615612da1576000915050611656565b6000612dab613ccb565b6001600160a01b0385166000908152600684016020526040812054600585015492935091612dda9083906159f7565b90506000805b82811015612e90576000866005018581548110612dff57612dff615642565b9060005260206000200154905080861015612e1a5750612e90565b600081815260048801602090815260408083206001600160a01b038d168452600281019092529091208054612e61906001600160801b03600160801b8204811691166156ae565b612e6b908661566e565b945086612e7781615695565b9750505050508080612e8890615695565b915050612de0565b50979650505050505050565b6000611ac06148c9565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e7719546001600160a01b0316336001600160a01b031614612f1f5760405162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b6044820152606401610de0565b612f77612f5383836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b8152506148e8565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b6119bf82826149c3565b612f8961480d565b6000612f9483614435565b6001810154909150600160b01b900460ff16612fea5760405162461bcd60e51b815260206004820152601560248201527418db185a5b5a5b99c81b9bdd08191a5cd8589b1959605a1b6044820152606401610de0565b6000805b835181101561313557600083600401600086848151811061301157613011615642565b60209081029190910181015182528101919091526040016000908120600181015481549193506001600160801b038082169261305b92600160801b908190048316929104166156ae565b61306591906156ae565b9050808260010160108282829054906101000a90046001600160801b031661308d919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080846130bd919061566e565b93508583815181106130d1576130d1615642565b6020026020010151877f33aa7fa8693d9d4619857267f831d8a7ec7183176c4e0a0759e7604c5771e3088360405161311891906001600160801b0391909116815260200190565b60405180910390a35050808061312d90615695565b915050612fee565b50808260030160108282829054906101000a90046001600160801b031661315c919061566e565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555080600b60108282829054906101000a90046001600160801b03166131a491906156ae565b82546001600160801b039182166101009390930a9283029190920219909116179055506001828101805460ff60a81b1916600160a81b1790556040805182815280820190915260009160208083019080368337019050509050848160008151811061321157613211615642565b6020026020010181815250507fb70968995a4c1e44f87ceefe95859ff83302d137a4c16289b2852e6c9f3a598381600160405161324f9291906157e8565b60405180910390a15050505050565b61326661480d565b61326f816144fa565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000806132a085614588565b600f54604051632d985e7b60e21b81526001600160a01b03918216600482015291925082169063b66179ec90602401602060405180830381865afa1580156132ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133109190615a21565b9350806001600160a01b03166327fda4de6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613350573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133749190615a21565b6040516302b5eedb60e21b81527f000000000000000000000000000000000000000000000000000000006661a4c060048201529093506001600160a01b03821690630ad7bb6c90602401602060405180830381865afa1580156133db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ff9190615a21565b93959294505050565b60135460609081906001600160401b0381111561342757613427614ec5565b60405190808252806020026020018201604052801561345a57816020015b60608152602001906001900390816134455790505b506013549092506001600160401b0381111561347857613478614ec5565b6040519080825280602002602001820160405280156134a1578160200160208202803683370190505b50905060005b6013548110156135e157601381815481106134c4576134c4615642565b906000526020600020906007020160000180546134e090615608565b80601f016020809104026020016040519081016040528092919081815260200182805461350c90615608565b80156135595780601f1061352e57610100808354040283529160200191613559565b820191906000526020600020905b81548152906001019060200180831161353c57829003601f168201915b505050505083828151811061357057613570615642565b60200260200101819052506013818154811061358e5761358e615642565b906000526020600020906007020160010160169054906101000a900460ff168282815181106135bf576135bf615642565b91151560209283029190910190910152806135d981615695565b9150506134a7565b509091565b60008060008060006135f787614435565b60009687526004016020525050604090932080546001909101546001600160801b0380831697600160801b93849004821697508183169650929091041692509050565b61364261480d565b60005b815181101561369057600061366583838151811061154957611549615642565b905061367081614867565b600101805460ff60a81b191690558061368881615695565b915050613645565b507fb70968995a4c1e44f87ceefe95859ff83302d137a4c16289b2852e6c9f3a59838160006040516115b09291906157e8565b60405162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206e6f7420737570706f727465640000000000000000006044820152600090606401610de0565b6000611ac0613ccb565b61372061475c565b6006819055600354613733908290615715565b600355426005556040518181527fcf636cc80b637bbb81f27bae78adac0fb5b5dee402042a20c6febb1630d5b81b906020016115b0565b60008054600160a01b900460ff1680156116565750600054604051630debfda360e41b81526001600160a01b0384811660048301529091169063debfda3090602401602060405180830381865afa1580156137c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116569190615a5f565b6137f561453f565b600061380086614435565b905061380b836144fa565b806138178587836158a0565b50600181018054831515600160a01b026001600160a81b03199091166001600160a01b0386161717905560405186907f505f02470b9795494019aba2982a68c1c6fea88fcbe5d80bafc28963fbe3bbab90613879908890889088908890615989565b60405180910390a2505050505050565b600054600160a01b900460ff16156138da5760405162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b6044820152606401610de0565b6001600160a01b0382166139305760405162461bcd60e51b815260206004820152601860248201527f676f7665726e616e63652073657474696e6773207a65726f00000000000000006044820152606401610de0565b6001600160a01b0381166139795760405162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b6044820152606401610de0565b600080546001600160a01b038481166001600160a81b031990921691909117600160a01b17909155600180549183166001600160a01b0319909216821790556040519081527f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db9060200160405180910390a15050565b6139f761480d565b600054600160a81b900460ff1615613a515760405162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f64650000000000006044820152606401610de0565b600180546001600160a01b031916905560008054600160a81b60ff60a81b198216179091556040516001600160a01b0390911681527f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9060200160405180910390a1565b606060008060008060008060008060606000613ad08c614435565b600181015460028201546003830154835493945084936001600160a01b0384169360ff600160a01b8204811694600160a81b8304821694600160b01b909304909116926001600160801b0380831693600160801b938490048216938183169391049091169060058a01908a90613b4590615608565b80601f0160208091040260200160405190810160405280929190818152602001828054613b7190615608565b8015613bbe5780601f10613b9357610100808354040283529160200191613bbe565b820191906000526020600020905b815481529060010190602001808311613ba157829003601f168201915b5050505050995080805480602002602001604051908101604052809291908181526020018280548015613c1057602002820191906000526020600020905b815481526020019060010190808311613bfc575b505050505090509a509a509a509a509a509a509a509a509a509a50509193959799509193959799565b600034613c446148c9565b613c4e9190615715565b90504781811115613c915761dead6108fc613c6984846159f7565b6040518115909202916000818181858888f19350505050158015612416573d6000803e3d6000fd5b818110156119bf576119bf615a7c565b600260085403613cc457604051633ee5aeb560e01b815260040160405180910390fd5b6002600855565b600062278d00613cfb7f000000000000000000000000000000000000000000000000000000006661a4c0426159f7565b611ac09190615a92565b600080613d1185614435565b6001810154909150600160b01b900460ff1615613d645760405162461bcd60e51b815260206004820152601160248201527018db185a5b5a5b99c8191a5cd8589b1959607a1b6044820152606401610de0565b3360009081526006820160205260408120546005830154909190613d899083906159f7565b90506000816001600160401b03811115613da557613da5614ec5565b604051908082528060200260200182016040528015613dce578160200160208202803683370190505b5090506000826001600160401b03811115613deb57613deb614ec5565b604051908082528060200260200182016040528015613e14578160200160208202803683370190505b50905060005b83811015614003576000866005018681548110613e3957613e39615642565b90600052602060002001549050808a1015613e545750614003565b600081815260048801602090815260408083203384526002810190925290912085518390879086908110613e8a57613e8a615642565b60209081029190910101528054600090613eb6906001600160801b03600160801b8204811691166156ae565b9050613ec2818c61566e565b600184018054919c508291600090613ee49084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550808260000160108282829054906101000a90046001600160801b0316613f2e919061566e565b92506101000a8154816001600160801b0302191690836001600160801b031602179055506000816001600160801b03161115613fdf57806001600160801b0316868681518110613f8057613f80615642565b602002602001018181525050336001600160a01b0316848f7f991476c3a75b7c98873b2a3ff8ea47ece4cad28a0b122c8064f619d37787424a84604051613fd691906001600160801b0391909116815260200190565b60405180910390a45b88613fe981615695565b995050505050508080613ffb90615695565b915050613e1a565b506003850180548791906000906140249084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b031602179055505b60008411801561408e575086600586016140646001876159f7565b8154811061407457614074615642565b9060005260206000200154600161408b9190615715565b10155b156140a5578361409d81615a0a565b945050614049565b33600090815260068601602052604090208490556140c1614187565b600f54604051632b8f98e160e21b81526001600160a01b039283169263ae3e6384926001600160801b038b1692614102929091169087908790600401615ab4565b6000604051808303818588803b15801561411b57600080fd5b505af115801561412f573d6000803e3d6000fd5b505050505050505050509392505050565b6141486148c9565b4714611a275760405162461bcd60e51b815260206004820152600e60248201526d6f7574206f662062616c616e636560901b6044820152606401610de0565b336000908152601460205260409020546001600160a01b031680156141a95790565b6010546001600160a01b03166142015760405162461bcd60e51b815260206004820152601b60248201527f6c6962726172792061646472657373206e6f74207365742079657400000000006044820152606401610de0565b601054614216906001600160a01b0316614bad565b9050803b63ffffffff1661426c5760405162461bcd60e51b815260206004820152601e60248201527f636c6f6e65206e6f742063726561746564207375636365737366756c6c7900006044820152606401610de0565b60405163485cc95560e01b81523360048201523060248201526001600160a01b0382169063485cc95590604401600060405180830381600087803b1580156142b357600080fd5b505af11580156142c7573d6000803e3d6000fd5b505050506001600160a01b03811660008181526015602090815260408083208054336001600160a01b031991821681179092558185526014845293829020805490941685179093558051928352908201929092527fc96ec7c29cf26f4d6ae403b80302646eb294d9eabdf83f1e9dcf0d5b30e5ae9e910160405180910390a1600e54604051631c4aa8ff60e31b81523360048201526000916001600160a01b03169063e25547f890602401602060405180830381865afa15801561438f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143b39190615a21565b90508060000361443157600e5460408051600081526020810191829052632571bd6960e11b9091526001600160a01b0384811692634ae37ad2926143fe929091169060248101615af4565b600060405180830381600087803b15801561441857600080fd5b505af115801561442c573d6000803e3d6000fd5b505050505b5090565b601354600090821061447e5760405162461bcd60e51b81526020600482015260126024820152711a5b9d985b1a59081c1c9bda9958dd081a5960721b6044820152606401610de0565b6013828154811061449157614491615642565b90600052602060002090600702019050919050565b6001810154600160a81b900460ff16156110de5760405162461bcd60e51b8152602060048201526015602482015274191a5cdd1c9a589d5d1a5bdb88191a5cd8589b1959605a1b6044820152606401610de0565b6001600160a01b0381166110de5760405162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b6044820152606401610de0565b6011546001600160a01b03163314611a275760405162461bcd60e51b815260206004820152600c60248201526b37b7363c9036b0b730b3b2b960a11b6044820152606401610de0565b6001600160a01b0380821660009081526014602052604090205416806145e25760405162461bcd60e51b815260206004820152600f60248201526e1b9bc81493985d081858d8dbdd5b9d608a1b6044820152606401610de0565b919050565b600054600160b01b900460ff16156146175733301461460857614608615a7c565b6000805460ff60b01b19169055565b611a2761480d565b61462761480d565b6000805460408051636221a54b60e01b81529051853593926001600160a01b031691636221a54b9160048083019260209291908290030181865afa158015614673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146979190615a21565b905060006146a58242615715565b9050604051806040016040528082815260200186868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250506001600160e01b031986168152600260209081526040909120835181559083015190915060018201906147239082615b50565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405161324f9493929190615c0f565b6007546001600160a01b03163314611a275760405162461bcd60e51b8152602060048201526013602482015272696e63656e7469766520706f6f6c206f6e6c7960681b6044820152606401610de0565b600b80543491906000906147ca9084906001600160801b031661566e565b92506101000a8154816001600160801b0302191690836001600160801b03160217905550565b3d604051818101604052816000823e8215614809578181f35b8181fd5b614815611a29565b6001600160a01b0316336001600160a01b031614611a275760405162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b6044820152606401610de0565b6003810154600160801b90046001600160801b0316156110de5760405162461bcd60e51b815260206004820152601d60248201527f636c61696d696e67207065726d616e656e746c792064697361626c65640000006044820152606401610de0565b600c54600b54600091610f73916001600160801b0391821691166156ae565b600080826040516020016148fc9190614ced565b6040516020818303038152906040528051906020012090506000805b86518110156149745786818151811061493357614933615642565b602002602001015183036149625785818151811061495357614953615642565b60200260200101519150614974565b8061496c81615695565b915050614918565b506001600160a01b0381166149ba5760405162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b6044820152606401610de0565b95945050505050565b600d54600160801b900460ff16156149df576149df8282614bff565b614a1382826040518060400160405280601181526020017021b630b4b6a9b2ba3ab826b0b730b3b2b960791b8152506148e8565b600e60006101000a8154816001600160a01b0302191690836001600160a01b031602179055506000614a6283836040518060400160405280600481526020016315d3985d60e21b8152506148e8565b600f549091506001600160a01b0316614b5b57600f80546001600160a01b0319166001600160a01b0383169081179091556040805163313ce56760e01b815290517f000000000000000000000000000000000000000000000000000000000000001260ff16929163313ce5679160048083019260209291908290030181865afa158015614af3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b179190615c38565b60ff16146124165760405162461bcd60e51b81526020600482015260116024820152700c8cac6d2dac2d8e640dad2e6dac2e8c6d607b1b6044820152606401610de0565b600f546001600160a01b038281169116146124165760405162461bcd60e51b815260206004820152601260248201527177726f6e6720774e6174206164647265737360701b6044820152606401610de0565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b614c2f82826040518060400160405280600d81526020016c125b98d95b9d1a5d99541bdbdb609a1b8152506148e8565b600780546001600160a01b0319166001600160a01b03929092169190911790555050565b508054614c5f90615608565b6000825580601f10614c6f575050565b601f0160209004906000526020600020908101906110de91905b808211156144315760008155600101614c89565b60005b83811015614cb8578181015183820152602001614ca0565b50506000910152565b60008151808452614cd9816020860160208601614c9d565b601f01601f19169290920160200192915050565b602081526000610f4a6020830184614cc1565b6001600160a01b03811681146110de57600080fd5b60008060408385031215614d2857600080fd5b8235614d3381614d00565b946020939093013593505050565b60008083601f840112614d5357600080fd5b5081356001600160401b03811115614d6a57600080fd5b6020830191508360208260051b8501011115614d8557600080fd5b9250929050565b600080600060408486031215614da157600080fd5b83356001600160401b03811115614db757600080fd5b614dc386828701614d41565b909790965060209590950135949350505050565b80151581146110de57600080fd5b600060208284031215614df757600080fd5b8135610f4a81614dd7565b600080600060608486031215614e1757600080fd5b8335614e2281614d00565b92506020840135614e3281614d00565b929592945050506040919091013590565b60008060008060008060808789031215614e5c57600080fd5b863595506020870135945060408701356001600160401b0380821115614e8157600080fd5b614e8d8a838b01614d41565b90965094506060890135915080821115614ea657600080fd5b50614eb389828a01614d41565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614f0357614f03614ec5565b604052919050565b60006001600160401b03821115614f2457614f24614ec5565b5060051b60200190565b600082601f830112614f3f57600080fd5b81356020614f54614f4f83614f0b565b614edb565b82815260059290921b84018101918181019086841115614f7357600080fd5b8286015b84811015614f8e5780358352918301918301614f77565b509695505050505050565b600060208284031215614fab57600080fd5b81356001600160401b03811115614fc157600080fd5b614fcd84828501614f2e565b949350505050565b600080600060608486031215614fea57600080fd5b8335925060208401359150604084013561500381614d00565b809150509250925092565b60006020828403121561502057600080fd5b8135610f4a81614d00565b6000806000806000806060878903121561504457600080fd5b86356001600160401b038082111561505b57600080fd5b6150678a838b01614d41565b9098509650602089013591508082111561508057600080fd5b61508c8a838b01614d41565b90965094506040890135915080821115614ea657600080fd5b6000602082840312156150b757600080fd5b81356001600160e01b031981168114610f4a57600080fd5b6000806000806000606086880312156150e757600080fd5b8535945060208601356001600160401b038082111561510557600080fd5b61511189838a01614d41565b9096509450604088013591508082111561512a57600080fd5b5061513788828901614d41565b969995985093965092949392505050565b6000806040838503121561515b57600080fd5b8235915060208301356001600160401b0381111561517857600080fd5b61518485828601614f2e565b9150509250929050565b828152604060208201526000614fcd6040830184614cc1565b6001600160801b03811681146110de57600080fd5b600080604083850312156151cf57600080fd5b82356151da81614d00565b915060208301356151ea816151a7565b809150509250929050565b6000806020838503121561520857600080fd5b82356001600160401b0381111561521e57600080fd5b61522a85828601614d41565b90969095509350505050565b6000806040838503121561524957600080fd5b8235615254816151a7565b915060208301356151ea81614dd7565b6000806040838503121561527757600080fd5b8235915060208301356151ea81614d00565b600082601f83011261529a57600080fd5b813560206152aa614f4f83614f0b565b82815260059290921b840181019181810190868411156152c957600080fd5b8286015b84811015614f8e5780356152e081614d00565b83529183019183016152cd565b6000806040838503121561530057600080fd5b82356001600160401b038082111561531757600080fd5b818501915085601f83011261532b57600080fd5b8135602061533b614f4f83614f0b565b82815260059290921b8401810191818101908984111561535a57600080fd5b948201945b838610156153785785358252948201949082019061535f565b9650508601359250508082111561538e57600080fd5b5061518485828601615289565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156153f257605f198887030185526153e0868351614cc1565b955093820193908201906001016153c4565b50508584038187015286518085528782019482019350915060005b8281101561542b57845115158452938101939281019260010161540d565b5091979650505050505050565b6000806040838503121561544b57600080fd5b50508035926020909101359150565b6000806040838503121561546d57600080fd5b823561547881614d00565b915060208301356151ea81614d00565b60006020828403121561549a57600080fd5b5035919050565b6000806000806000608086880312156154b957600080fd5b8535945060208601356001600160401b03808211156154d757600080fd5b818801915088601f8301126154eb57600080fd5b8135818111156154fa57600080fd5b89602082850101111561550c57600080fd5b602083019650809550505050604086013561552681614d00565b9150606086013561553681614dd7565b809150509295509295909350565b600081518084526020808501945080840160005b8381101561557457815187529582019590820190600101615558565b509495945050505050565b60006101408083526155938184018e614cc1565b6001600160a01b038d1660208501528b151560408501528a1515606085015289151560808501526001600160801b0389811660a086015288811660c086015287811660e0860152861661010085015283810361012085015290506155f78185615544565b9d9c50505050505050505050505050565b600181811c9082168061561c57607f821691505b60208210810361563c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160801b0381811683821601908082111561568e5761568e615658565b5092915050565b6000600182016156a7576156a7615658565b5060010190565b6001600160801b0382811682821603908082111561568e5761568e615658565b6000602082840312156156e057600080fd5b8151610f4a816151a7565b60208082526010908201526f0d8cadccee8d0e640dad2e6dac2e8c6d60831b604082015260600190565b8082018082111561165657611656615658565b60006020828403121561573a57600080fd5b8135610f4a816151a7565b8183526000602080850194508260005b8581101561557457813561576881614d00565b6001600160a01b031687529582019590820190600101615755565b604081526000615797604083018688615745565b8281036020848101919091528482528591810160005b868110156157db5783356157c0816151a7565b6001600160801b0316825292820192908201906001016157ad565b5098975050505050505050565b6040815260006157fb6040830185615544565b905082151560208301529392505050565b6000808335601e1984360301811261582357600080fd5b8301803591506001600160401b0382111561583d57600080fd5b602001915036819003821315614d8557600080fd5b601f82111561241657600081815260208120601f850160051c810160208610156158795750805b601f850160051c820191505b8181101561589857828155600101615885565b505050505050565b6001600160401b038311156158b7576158b7614ec5565b6158cb836158c58354615608565b83615852565b6000601f8411600181146158ff57600085156158e75750838201355b600019600387901b1c1916600186901b178355615959565b600083815260209020601f19861690835b828110156159305786850135825560209485019460019092019101615910565b508682101561594d5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60608152600061599d606083018688615960565b6001600160a01b039490941660208301525090151560409091015292915050565b6000602082840312156159d057600080fd5b8151610f4a81614d00565b600082516159ed818460208701614c9d565b9190910192915050565b8181038181111561165657611656615658565b600081615a1957615a19615658565b506000190190565b600060208284031215615a3357600080fd5b5051919050565b6001600160a01b03841681526040602082018190526000906149ba9083018486615745565b600060208284031215615a7157600080fd5b8151610f4a81614dd7565b634e487b7160e01b600052600160045260246000fd5b600082615aaf57634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0384168152606060208201819052600090615ad890830185615544565b8281036040840152615aea8185615544565b9695505050505050565b6001600160a01b038381168252604060208084018290528451918401829052600092858201929091906060860190855b81811015615b42578551851683529483019491830191600101615b24565b509098975050505050505050565b81516001600160401b03811115615b6957615b69614ec5565b615b7d81615b778454615608565b84615852565b602080601f831160018114615bb25760008415615b9a5750858301515b600019600386901b1c1916600185901b178555615898565b600085815260208120601f198616915b82811015615be157888601518255948401946001909101908401615bc2565b5085821015615bff5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b63ffffffff60e01b85168152836020820152606060408201526000615aea606083018486615960565b600060208284031215615c4a57600080fd5b815160ff81168114610f4a57600080fdfea264697066735822122037bfc3eac522e6bbc328dc81a107e5ef6e7fe6b6678501c5c11260cc56d08a9564736f6c63430008140033