ETH Price: $2,475.73 (+1.02%)

Contract

0x5A3591001DfB63FAc81d2976C150BB38df2cd71C
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Create Share Pro...209104062024-10-07 1:30:355 days ago1728264635IN
0x5A359100...8df2cd71C
0 ETH0.011343369.53976337
Vote208283492024-09-25 14:55:2317 days ago1727276123IN
0x5A359100...8df2cd71C
0 ETH0.006941626.33114441
Propose New Mana...208283452024-09-25 14:54:3517 days ago1727276075IN
0x5A359100...8df2cd71C
0 ETH0.004037927.30308685
Increase Vote Po...208283432024-09-25 14:54:1117 days ago1727276051IN
0x5A359100...8df2cd71C
0 ETH0.002257126.83393761
Vote207866202024-09-19 19:06:2323 days ago1726772783IN
0x5A359100...8df2cd71C
0 ETH0.0044149316.74767906
Propose New Mana...207866032024-09-19 19:02:5923 days ago1726772579IN
0x5A359100...8df2cd71C
0 ETH0.0022122114.95956146
Create Share Pro...207610322024-09-16 5:15:3526 days ago1726463735IN
0x5A359100...8df2cd71C
0 ETH0.001695651.42604603
Create Share Pro...207556232024-09-15 11:09:2327 days ago1726398563IN
0x5A359100...8df2cd71C
0 ETH0.002347761.95754433
Vote207289002024-09-11 17:36:2331 days ago1726076183IN
0x5A359100...8df2cd71C
0 ETH0.000777252.81643348
Propose New Hard...207288972024-09-11 17:35:4731 days ago1726076147IN
0x5A359100...8df2cd71C
0 ETH0.001054542.64954135
Vote207215122024-09-10 16:50:4732 days ago1725987047IN
0x5A359100...8df2cd71C
0 ETH0.000850993.43163757
Propose New Hard...207215082024-09-10 16:49:5932 days ago1725986999IN
0x5A359100...8df2cd71C
0 ETH0.00160954.04376124
Vote207214992024-09-10 16:48:1132 days ago1725986891IN
0x5A359100...8df2cd71C
0 ETH0.002299523.83065925
Propose New Hard...207214972024-09-10 16:47:4732 days ago1725986867IN
0x5A359100...8df2cd71C
0 ETH0.001591493.99849843
Increase Vote Po...207214942024-09-10 16:47:1132 days ago1725986831IN
0x5A359100...8df2cd71C
0 ETH0.000305273.62929163
Create Share Pro...206957002024-09-07 2:22:1135 days ago1725675731IN
0x5A359100...8df2cd71C
0 ETH0.001830251.52602954
Create Share Pro...205860782024-08-22 18:56:4751 days ago1724353007IN
0x5A359100...8df2cd71C
0 ETH0.001543491.29808219
Create Share Pro...205651992024-08-19 20:56:3554 days ago1724100995IN
0x5A359100...8df2cd71C
0 ETH0.002400252.00126406
Create Share Pro...204662422024-08-06 1:27:3567 days ago1722907655IN
0x5A359100...8df2cd71C
0 ETH0.006416185.39606124
Create Share Pro...204662192024-08-06 1:22:5967 days ago1722907379IN
0x5A359100...8df2cd71C
0 ETH0.006909215.7608355
Create Share Pro...204484972024-08-03 14:04:5970 days ago1722693899IN
0x5A359100...8df2cd71C
0 ETH0.002279911.94540462
Create Share Pro...204368572024-08-01 23:03:2371 days ago1722553403IN
0x5A359100...8df2cd71C
0 ETH0.008473147.20378212
Create Share Pro...204155682024-07-29 23:39:4774 days ago1722296387IN
0x5A359100...8df2cd71C
0 ETH0.002433462.04656631
Create Share Pro...204155422024-07-29 23:34:3574 days ago1722296075IN
0x5A359100...8df2cd71C
0 ETH0.002174081.84753611
Create Share Pro...204155042024-07-29 23:26:5974 days ago1722295619IN
0x5A359100...8df2cd71C
0 ETH0.002202371.87155362
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HyperCycleShareManager

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 20 : HyperCycleShareManager.sol
// SPDX-License-Identifier: MIT
/*
    Version 1 of the HyperCycle Share Manager contract.
*/

pragma solidity 0.8.19;

import {Context} from '@openzeppelin/contracts/utils/Context.sol';
import {ERC721Holder} from '@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol';
import {ERC1155Holder} from '@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol';
import {ShareManagerErrors as Errors} from '../libs/ShareManagerErrors.sol';
import {ShareManagerEvents as Events} from '../libs/ShareManagerEvents.sol';
import {ShareManagerTypes as Types, IHYPCSwapV2, IHyperCycleLicense, IHyperCycleShareTokensV2, IHYPC} from '../libs/ShareManagerTypes.sol';

/**
@title HyperCycle Share Manager, revenue sharing manager.
@author Rodolfo Cova, Barry Rowe
@notice HyperCycle is a network of AI computation nodes offering different AI services in a 
        decentralized manner. In this system, there are license holders, token holders, hardware
        operators, and AI developers. Using the HyperCycleSwapV2 contract, an amount of HyPC (erc20)
        can be swapped for a cHyPC (containerized HyPC) token, which can then point towards a
        license (HyperCycleLicense) NFT id. At this point, the owner of this license can assign
        their license to some hardware running the HyperCycle Node Manager, and can from then
        on accept AI service requests on the network. 

        The HyperCycle Share Manager (This contract) allows the chypc owner to create a revenue sharing proposal, 
        to understand in deep the Share Token Contract, please refer to he Share Token Contract 
        documentation, See {HyperCycleShareTokensV2}.

        The main idea of the Share Manager is to be the one holding and managing the Share Token,
        being able to use the same benefits of the Share Tokens and extend it with the votations that
        share token holders can execute for the Share.

        To create a Share Proposal with the Share Manager, the chypc owner needs to call 
        `createShareProposal` function, this function will create a new Share Proposal and transfer
        the chypc to the Share Manager, the Share Manager will be the one holding the chypc until
        the Share Proposal is ended, in case the Share Proposal is ended, the chypc will be redeemed
        into hypc tokens, in which the share holders will be able to claim the proportional amount
        of share tokens to hypc tokens.

        The Share Proposal will be created with the following data:
            - CHyPC Data: CHyPC Id, CHyPC Owner, CHyPC Level, Initial Revenue Tokens, Initial Wealth Tokens
            - License Data: License Number, License Owner, License Level, Initial Revenue Tokens, Initial Wealth Tokens
            - Operator Data: Operator Revenue, Operator Assigned String, Operator Address
            - Share Token Data: Share Token Number, Revenue Deposit Delay, Revenue Token Id, Wealth Token Id, Valid End Timestamp
            - Status: Pending
        
        The Share Proposal can have the following status in the entire lifecycle of the Share Proposal:
            - Pending: The Share Proposal is created and waiting for the CHyPC NFT to be transfered to the Share Manager
            - Started: The Share Proposal is started and the Share Tokens are created, the CHyPC NFT is transfered to the Share Manager
            - Ended: The Share Proposal is ended and the license is transfered to the License Owner, 
                    the CHyPC NFT will be redeem for HyPC tokens and will be claimable by the Share Token Holders.

        The Share Manager contract had a DAO system where share token holderes can be able to create votations to change 
        the hardware operator, the hardware operator revenue, the manager contract and to cancel the share proposal, 
        the votations will be created by the Share Manager and the share token holders will be able to vote.

        The Share Proposal can be ended by the share token holders any time the consensus is reached, for this 100% or 90% (depends on the
        actual `SELECTED_VOTATION_PORCENT`) of the wealth tokens needs to be voted to end the Share Proposal, in case the Share Proposal is 
        ended, the ending process will be executed.

        The Share Manager contract can be changed by the share token holders any time the consensus is reached, for this 100% of the wealth tokens
        needs to be voted to change the Share Manager, in case the Share Manager is changed,  the transfer of the Share Token Ownership will be executed.

        The Hardware Operator can be changed by the share token holders any time the consensus is reached, for this 50% of the wealth tokens
        needs to be voted to change the Hardware Operator, in case the Hardware Operator is changed, the Operator Revenue will be transfered
        to the older operator and the new operator will be set.

        The Hardware Operator Revenue can be changed by the share token holders any time the consensus is reached, 
        for this 50% of the wealth tokens needs to be voted to change the Hardware Operator Revenue, 
        in case the Hardware Operator Revenue is changed, the new operator revenue will be set.

        Another important feature of the Share Manager is the ability to migrate the Share Tokens from the Share Tokens contract
        to the Share Manager, this will allow the Share Manager to be the one holding the Share Tokens and be able to manage the Share
        Proposal and Votations. The Share Manager will be able to claim the Hypc tokens, based in the amount of wealth tokens available, 
        in case the Share Proposal is ended and the CHyPC exists.

        To migrate the Share Tokens to the Share Manager contract, the Share Token owner needs to call `startShareProposalMigration` function,
        this function will start the migration and the Share Manager contract will be able to finish the migration only if the ownership
        of the share token is changed to the Share Manager contract, and the Share Proposal is pending.
*/
contract HyperCycleShareManager is ERC721Holder, ERC1155Holder, Context {
    Types.ManagerData public managerData;

    uint256 public sharesProposalsAmount;

    uint256 constant ONE_HUNDRED_PERCENT = 1e18;

    uint256 public SELECTED_VOTATION_PERCENT;

    mapping(uint256 shareProposalId => mapping(address user => uint256)) private _votePower;

    mapping(uint256 shareProposalId => mapping(uint256 votationIndex =>mapping(address user => bool))) private _voted;

    mapping(uint256 shareProposalId => uint256) private _votationId;

    mapping(uint256 shareProposalId => mapping(uint256 votationId => Types.Votation)) private _votations;

    mapping(uint256 shareProposalId => Types.ShareProposalData) private _shareProposals;

    mapping(uint256 shareTokenNumber => bool) private _shareTokenExists;

    modifier onlyVoter(uint256 shareProposalId) {
        if (_votePower[shareProposalId][_msgSender()] == 0) revert Errors.NoWealthTokensAvailable();

        _;
    }

    modifier onlyCHyPCOwner(uint256 shareProposalId) {
        if (_shareProposals[shareProposalId].chypcData.tokenOwner != _msgSender()) revert Errors.InvalidCHYPCOwner();

        _;
    }

    modifier onlyLicenseOwner(uint256 licenseNumber) {
        if (managerData.licenseContract.ownerOf(licenseNumber) != _msgSender()) revert Errors.InvalidLicenseOwner();
        _;
    }

    /**
        @dev The constructor takes in the contract addresses for the HyPC token, license, cHyPC NFTs and Share Tokens contract.
        @param _consensusOption: The consensus option to be used for the votations.
        @param _hypcToken: The HyPC ERC20 contract address.
        @param _chypcV2: The cHyPC ERC721 contract address.
        @param _licenseContract: The license ERC721 contract address.
        @param _hypcShareTokens: The license ERC721 contract address.
    */
    constructor(Types.ConsensusOptions _consensusOption, address _hypcToken, address _chypcV2, address _licenseContract, address _hypcShareTokens) payable {
        if (_hypcToken == address(0)) revert Errors.InvalidHYPCTokenAddress();

        if (_chypcV2 == address(0)) revert Errors.InvalidCHYPCAddress();

        if (_licenseContract == address(0)) revert Errors.InvalidLicenseAddress();

        if (_hypcShareTokens == address(0)) revert Errors.InvalidShareTokenContract();

        _consensusOption == Types.ConsensusOptions.ONE_HUNDRED_PERCENT ?
            SELECTED_VOTATION_PERCENT = ONE_HUNDRED_PERCENT :
            SELECTED_VOTATION_PERCENT = ONE_HUNDRED_PERCENT * 9 / 10;

        managerData = Types.ManagerData({
            hypcToken: IHYPC(_hypcToken),
            chypcV2: IHYPCSwapV2(_chypcV2),
            licenseContract: IHyperCycleLicense(_licenseContract),
            hypcShareTokens: IHyperCycleShareTokensV2(_hypcShareTokens)
        });
    }

    // Share proposal management functions

    /**
    @notice Allows a user to create a new share.
    @param proposalData The encoded data needed to create a new share proposal, should have encoded: 
                        (uint256,uint256,uint256,uint256,uint256,string,address,bool,bool).
    @notice chypcId: should be the license number to be used for the share.
    @notice revenueToAssignToChypc: should be the amount of revenue tokens to be assigned to the chypc owner.
    @notice wealthToAssignToChypc: should be the amount of wealth tokens to be assigned to the chypc owner.
    @notice revenueDepositDelay: should be the amount of time in seconds that the revenue tokens will be locked.
    @notice operatorAssignedString: should be the string to be used as the operator assigned string for the share.
    @notice hardwareOperator: should be the address of the hardware operator to be used for the share.
    @notice chypcExist: should be true if the share will be completed by a cHyPC NFT, false in case the license is already backed.
    */
    function createShareProposal(bytes memory proposalData) external {
        (
            uint256 chypcId,
            uint256 revenueToAssignToChypc,
            uint256 wealthToAssignToChypc,
            uint256 revenueDepositDelay,
            uint256 licenseNumber,
            string memory operatorAssignedString,
            address hardwareOperator
        ) = abi.decode(proposalData, (uint256, uint256, uint256, uint256, uint256, string, address));

        uint256 chypcLevel = managerData.chypcV2.getTokenLevel(chypcId);

        if (managerData.chypcV2.ownerOf(chypcId) != _msgSender()) revert Errors.InvalidCHYPCOwner();

        if (hardwareOperator == address(0)) revert Errors.InvalidProposedAddress();

        if (bytes(operatorAssignedString).length == 0) revert Errors.InvalidProposedString();

        if (
            revenueToAssignToChypc > (1 << chypcLevel) * 7 / 10 ||
            wealthToAssignToChypc > (1 << chypcLevel)
        ) revert Errors.InvalidTokenAmount();

        uint256 shareProposalId = sharesProposalsAmount++;

        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        shareProposal.operatorData = Types.HardwareOperatorData({
            operatorRevenue: (1 << chypcLevel) * 2 / 10,
            operatorAssignedString: operatorAssignedString,
            operatorAddress: hardwareOperator
        });

        shareProposal.status = Types.ShareProposalStatus.PENDING;

        shareProposal.chypcData = Types.TokenHolderData({
            tokenNumber: chypcId,
            tokenOwner: _msgSender(),
            tokenLevel: chypcLevel,
            initialRevenueTokens: revenueToAssignToChypc,
            initialWealthTokens: wealthToAssignToChypc
        });

        shareProposal.shareTokenData.revenueDepositDelay = revenueDepositDelay;

        uint256 votationId = _votationId[shareProposalId];

        _votations[shareProposalId][votationId] = Types.Votation({
            votationId: votationId,
            votesFor: 0,
            votesAgainst: 0,
            deadline: type(uint256).max,
            proposedData: '',
            option: Types.VotationOptions.CANCEL_SHARE,
            amountReached: false
        });

        _votationId[shareProposalId]++;
        emit Events.VoteStarted(shareProposalId, votationId, Types.VotationOptions.CANCEL_SHARE);

        managerData.chypcV2.safeTransferFrom(_msgSender(), address(this), chypcId);

        if (licenseNumber != 0) {
            _completeProposal(shareProposalId, licenseNumber);
        }

        emit Events.ShareProposalCreated(shareProposalId);
    }

    /// @notice Allows the owner of the cHyPC to cancel a pending share proposal.
    /// @param shareProposalId the share proposal Id to be cancelled.
    function cancelPendingShareProposal(uint256 shareProposalId) external onlyCHyPCOwner(shareProposalId) {
        if (_shareProposals[shareProposalId].status != Types.ShareProposalStatus.PENDING)
            revert Errors.ShareProposalIsNotPending();

        _endShareProposal(shareProposalId);
    }

    /// @notice Allows the owner of the License to complete a pending share proposal.
    /// @param shareProposalId The share proposal Id to be used to complete the share.
    /// @param licenseNumber The License NFT id to be used to start the share.
    function completeShareProposal(uint256 shareProposalId, uint256 licenseNumber) external onlyLicenseOwner(licenseNumber) {
        if (_shareProposals[shareProposalId].status != Types.ShareProposalStatus.PENDING)
            revert Errors.ShareProposalIsNotPending();

        _completeProposal(shareProposalId, licenseNumber);
    }

    /// @notice Internal function to allow the License NFT owner to complete a pending share proposal.
    /// @param shareProposalId The share proposal Id to be used to complete the share.
    /// @param licenseNumber The License NFT id to be used to start the share.
    function _completeProposal(uint256 shareProposalId, uint256 licenseNumber) private {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        uint256 licenseLevel = managerData.licenseContract.getLicenseHeight(licenseNumber);
        uint256 totalSupply = 1 << shareProposal.chypcData.tokenLevel;

        if (licenseLevel != shareProposal.chypcData.tokenLevel)
            revert Errors.TokenLevelMismatch();

        shareProposal.status = Types.ShareProposalStatus.STARTED;

        shareProposal.licenseData = Types.TokenHolderData({
            tokenNumber: licenseNumber,
            tokenOwner: _msgSender(),
            tokenLevel: licenseLevel,
            initialRevenueTokens: (totalSupply * 7 / 10) - shareProposal.chypcData.initialRevenueTokens,
            initialWealthTokens: totalSupply - shareProposal.chypcData.initialWealthTokens
        });

        uint256 currentShareNumber = managerData.hypcShareTokens.currentShareNumber();

        _shareTokenExists[currentShareNumber] = true;

        shareProposal.shareTokenData = Types.ShareTokenData({
            shareTokenNumber: currentShareNumber,
            revenueDepositDelay: shareProposal.shareTokenData.revenueDepositDelay,
            rTokenId: currentShareNumber << 1,
            wTokenId: (currentShareNumber << 1) + 1,
            validEndTimestamp: block.timestamp + 1 days
        });

        managerData.licenseContract.safeTransferFrom(_msgSender(), address(this), licenseNumber);

        managerData.licenseContract.approve(
            address(managerData.hypcShareTokens),
            licenseNumber
        );

        managerData.chypcV2.approve(address(managerData.hypcShareTokens), shareProposal.chypcData.tokenNumber);

        managerData.hypcShareTokens.createShareTokens(
            licenseNumber,
            shareProposal.chypcData.tokenNumber,
            true,
            shareProposal.operatorData.operatorAssignedString,
            shareProposal.shareTokenData.revenueDepositDelay
        );

        _sendRevenueAndWealthTokens(
            shareProposal.licenseData.tokenOwner,
            shareProposal.shareTokenData.rTokenId,
            shareProposal.shareTokenData.wTokenId,
            shareProposal.licenseData.initialRevenueTokens,
            shareProposal.licenseData.initialWealthTokens
        );

        _sendRevenueAndWealthTokens(
            shareProposal.chypcData.tokenOwner,
            shareProposal.shareTokenData.rTokenId,
            shareProposal.shareTokenData.wTokenId,
            shareProposal.chypcData.initialRevenueTokens,
            shareProposal.chypcData.initialWealthTokens
        );

        emit Events.ShareProposalStarted(shareProposalId);
    }

    /// @notice Private function to send the share proposal tokens
    /// @param to address to send tokens
    /// @param rTokenId id of the revenue token
    /// @param wTokenId id of the wealth token
    /// @param rTokenAmount amount of revenue to send
    /// @param wTokenAmount amount of wealth to send
    function _sendRevenueAndWealthTokens(
        address to,
        uint256 rTokenId,
        uint256 wTokenId,
        uint256 rTokenAmount,
        uint256 wTokenAmount
    ) private {
        uint256[] memory amounts = new uint256[](2);
        (amounts[0], amounts[1]) = (rTokenAmount, wTokenAmount);
        uint256[] memory tokenIds = new uint256[](2);
        (tokenIds[0], tokenIds[1]) = (rTokenId, wTokenId);

        managerData.hypcShareTokens.safeBatchTransferFrom(address(this), to, tokenIds, amounts, '');
    }
    
    /// @notice This contract will start the migration to the Share Manager contract
    ///         to be able to migrate the share proposal, it needs to be called by the share owner
    /// @param shareTokenNumber share token number to start migration from Share Tokens contract
    /// @param hardwareOperator address of the hardware operator to be used for the share
    function startShareProposalMigration(
        uint256 shareTokenNumber,
        address hardwareOperator,
        string memory operatorAssignedString
    ) external {
        if (managerData.hypcShareTokens.getShareOwner(shareTokenNumber) != msg.sender)
            revert Errors.InvalidShareTokenOwner();

        if (!managerData.hypcShareTokens.isShareActive(shareTokenNumber)) revert Errors.GetShareDataFailed();

        if (hardwareOperator == address(0)) revert Errors.InvalidProposedAddress();

        (uint256 revenueDepositDelay, bool chypcExists) = _getShareData(shareTokenNumber);

        if (!chypcExists) revert Errors.ChypcIsNotHeld();

        uint256 shareProposalId = sharesProposalsAmount++;

        _shareProposals[shareProposalId].shareTokenData = Types.ShareTokenData({
            shareTokenNumber: shareTokenNumber,
            revenueDepositDelay: revenueDepositDelay,
            rTokenId: shareTokenNumber * 2,
            wTokenId: shareTokenNumber * 2 + 1,
            validEndTimestamp: managerData.hypcShareTokens.getShareStartTime(shareTokenNumber) + 1 days
        });

        uint256 chypcId = managerData.hypcShareTokens.getShareCHyPCId(shareTokenNumber);
        uint256 licenseId = managerData.hypcShareTokens.getShareLicenseId(shareTokenNumber);
        uint256 chypcLevel = managerData.chypcV2.getTokenLevel(chypcId);
        uint256 licenseLevel = managerData.licenseContract.getLicenseHeight(licenseId);
        uint256 wealthTokensSupply = managerData.hypcShareTokens.getRevenueTokenTotalSupply(shareTokenNumber);

        if (licenseLevel != chypcLevel)
            revert Errors.TokenLevelMismatch();

        _shareProposals[shareProposalId].chypcData = Types.TokenHolderData({
            tokenNumber: chypcId,
            tokenOwner: msg.sender,
            tokenLevel: chypcLevel,
            initialRevenueTokens: wealthTokensSupply * 7 / 10,
            initialWealthTokens: wealthTokensSupply
        });

        _shareProposals[shareProposalId].licenseData = Types.TokenHolderData({
            tokenNumber: licenseId,
            tokenOwner: msg.sender,
            tokenLevel: licenseLevel,
            initialRevenueTokens: 0,
            initialWealthTokens: 0
        });

        _shareProposals[shareProposalId].operatorData = Types.HardwareOperatorData({
            operatorRevenue: wealthTokensSupply * 2 / 10,
            operatorAssignedString: operatorAssignedString,
            operatorAddress: hardwareOperator
        });

        _shareProposals[shareProposalId].status = Types.ShareProposalStatus.PENDING;

        managerData.hypcShareTokens.safeTransferFrom(
            msg.sender, 
            address(this), 
            _shareProposals[shareProposalId].shareTokenData.rTokenId, 
            wealthTokensSupply * 3 / 10, 
            ''
        );

        emit Events.ShareProposalCreated(shareProposalId);
    }

    function cancelShareTokenMigration(uint256 shareProposalId) external {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        uint256 shareTokenNumber = shareProposal.shareTokenData.shareTokenNumber;

        if (shareProposal.status != Types.ShareProposalStatus.PENDING)
            revert Errors.ShareProposalIsNotPending();
        
        if (
            managerData.hypcShareTokens.getShareOwner(
                shareTokenNumber
            ) != address(this)
        ) revert Errors.InvalidShareTokenOwner();

        if (_msgSender() != shareProposal.chypcData.tokenOwner) revert Errors.InvalidCHYPCOwner();

        shareProposal.status = Types.ShareProposalStatus.ENDED;

        managerData.hypcShareTokens.transferShareOwnership(shareTokenNumber, _msgSender());

        uint256 wealthTokensSupply = managerData.hypcShareTokens.getRevenueTokenTotalSupply(shareTokenNumber);

        managerData.hypcShareTokens.safeTransferFrom(
            address(this),
            msg.sender,
            _shareProposals[shareProposalId].shareTokenData.rTokenId, 
            wealthTokensSupply * 3 / 10, 
            ''
        );

        emit Events.ShareProposalEnded(shareProposalId);
    }

    /// @notice This function will finish the migration to the Share Manager contract
    ///         The owner will be able to finish the migration only if the ownership of the share token
    ///         is changed to this contract, and the share proposal is pending
    /// @param shareProposalId Share proposal id to finish migration
    function finishShareTokenMigration(uint256 shareProposalId) external {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        uint256 shareTokenNumber = shareProposal.shareTokenData.shareTokenNumber;
        
        if (_shareTokenExists[shareTokenNumber]) revert Errors.ShareTokenAlreadyExists();

        if (managerData.hypcShareTokens.getShareOwner(shareTokenNumber) != address(this))
            revert Errors.InvalidShareTokenOwner();

        managerData.hypcShareTokens.setShareMessage(
            shareTokenNumber,
            shareProposal.operatorData.operatorAssignedString
        );

        _shareTokenExists[shareTokenNumber] = true;

        _shareProposals[shareProposalId].status = Types.ShareProposalStatus.STARTED;
    }

    /// @notice Private function to get the sharde data from the share token contract, 
    ///         and return the revenue deposit delay and if the share is backed by a cHyPC
    ///         Using the specific slot of the `ShareData` struct to initialize the variables
    /// @param shareNumber share number to get the data from
    /// @return revenueDepositDelay delay in seconds to unlock the revenue deposited
    /// @return chypcExists if the share was backed by a HyPC or using a cHyPC NFT
    function _getShareData(uint256 shareNumber) private view returns(uint256 revenueDepositDelay, bool chypcExists) {
        (bool success, bytes memory data) = address(managerData.hypcShareTokens).staticcall(abi.encodeWithSelector(managerData.hypcShareTokens.shareData.selector, shareNumber));
        
        if (!success) revert Errors.GetShareDataFailed();

        assembly {
            revenueDepositDelay := mload(add(data, 0x160))
            chypcExists := mload(add(data, 0x1A0))
        }
    }

    /// @notice Allows an user to claim Hypc tokens, based in the amount of wealth tokens available.
    ///         The Share Proposal needs to be ended and Chypc needs to exists.
    /// @param shareProposalId The share proposal Id to be used to claim the Hypc.
    function claimHypcPortion(uint256 shareProposalId) external {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        if (shareProposal.status != Types.ShareProposalStatus.ENDED) revert Errors.ShareProposalIsNotEnded();

        uint256 userWealthBalance = managerData.hypcShareTokens.balanceOf(
            _msgSender(),
            shareProposal.shareTokenData.wTokenId
        );

        uint256 userVotePower = _votePower[shareProposalId][_msgSender()];

        if (userWealthBalance == 0 && userVotePower == 0) revert Errors.NoWealthTokensAvailable();

        uint256 wealthTokenTotalSupply = managerData.hypcShareTokens.getWealthTokenTotalSupply(
            shareProposal.shareTokenData.shareTokenNumber
        );

        uint256 hypcBacked = 1 << shareProposal.chypcData.tokenLevel;

        uint256 userTransferAmount = (hypcBacked * (userWealthBalance + userVotePower)) / wealthTokenTotalSupply;

        delete _votePower[shareProposalId][_msgSender()];

        if (userWealthBalance > 0) {
            managerData.hypcShareTokens.safeTransferFrom(
                _msgSender(),
                address(this),
                shareProposal.shareTokenData.wTokenId,
                userWealthBalance,
                ''
            );
        }

        if (managerData.hypcToken.balanceOf(address(this)) < userTransferAmount)
            revert Errors.NotEnoughHYPC();

        managerData.hypcToken.transfer(
            _msgSender(),
            userTransferAmount
        );

        emit Events.HypcClaimed(shareProposalId, userTransferAmount);
    }

    /// @notice Allows an user to claim the surplus of a share proposal, the Share Proposal needs to be ended.
    /// @dev    The surplus is the amount of tokens that were locked to increase the hardware operator revenue.
    /// @dev    The amount will be sended to the license owner and the chypc owner.
    /// @param shareProposalId The share proposal Id to be used to claim the surplus amount of tokens.
    function claimSurplus(uint256 shareProposalId) external {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        if (shareProposal.status != Types.ShareProposalStatus.ENDED) revert Errors.ShareProposalIsNotEnded();

        uint256 surplus = shareProposal.hypcSurplus >> 1;
        uint256 surplusRemainder = shareProposal.hypcSurplus - surplus;

        delete shareProposal.hypcSurplus;

        managerData.hypcToken.transfer(shareProposal.chypcData.tokenOwner, surplus);
        managerData.hypcToken.transfer(shareProposal.licenseData.tokenOwner, surplusRemainder);
    }

    /// @notice Private function to end the finish the share proposal
    /// @dev It will send the license only if isn't splittable
    /// @dev It will send the cHyPC only if the token was transfered
    /// @dev It will send the hardware operator revenue only if proposal started
    /// @param shareProposalId The share proposal Id to be used to end the share.
    function _endShareProposal(uint256 shareProposalId) private {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        bool shareProposalStarted = shareProposal.status == Types.ShareProposalStatus.STARTED;

        shareProposal.status = Types.ShareProposalStatus.ENDED;

        if (!shareProposalStarted) {
            managerData.chypcV2.safeTransferFrom(
                address(this),
                shareProposal.chypcData.tokenOwner,
                shareProposal.chypcData.tokenNumber
            );
        } else {
            managerData.licenseContract.safeTransferFrom(
                address(this),
                shareProposal.licenseData.tokenOwner,
                shareProposal.licenseData.tokenNumber
            );

            _sendRevenueToHardwareOperator(shareProposalId);

            managerData.chypcV2.redeem(shareProposal.chypcData.tokenNumber);
        }

        emit Events.ShareProposalEnded(shareProposalId);
    }

    /// @notice Private function that will send the revenue collected to the hardware operator
    /// @param shareProposalId The share proposal Id to be used to get the data
    function _sendRevenueToHardwareOperator(uint256 shareProposalId) private {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        uint256 oldBalance = managerData.hypcToken.balanceOf(address(this));

        try managerData.hypcShareTokens.claimAndWithdraw(shareProposal.shareTokenData.shareTokenNumber) {
            // ...
        } catch (bytes memory err) {
            if (keccak256(abi.encodeWithSignature('NoRevenueToClaim()')) != keccak256(err)) {
                revert(string(err));
            }
        }

        uint256 newBalance = managerData.hypcToken.balanceOf(address(this));
        uint256 amountReceived = newBalance - oldBalance;

        uint256 hardwareOperatorRevenue = (amountReceived * shareProposal.operatorData.operatorRevenue) / (1 << shareProposal.chypcData.tokenLevel) * 3 / 10;

        shareProposal.hypcSurplus += amountReceived - hardwareOperatorRevenue;

        managerData.hypcToken.transfer(shareProposal.operatorData.operatorAddress, hardwareOperatorRevenue);
    }

    // Propose functions

    /// @notice Allows an user to create a new votation and propose a new Hardware Operator.
    /// @param shareProposalId The share proposal Id to be used to create the votation
    /// @param deadline Time to be waited to complete the votation
    /// @param newProposedString the new proposed assigned string for the hardware operator
    /// @param newHardwareOperator the new hardware operator address
    function proposeNewHardwareOperatorAddress(
        uint256 shareProposalId,
        uint256 deadline,
        string memory newProposedString,
        address newHardwareOperator
    ) external onlyVoter(shareProposalId) {
        if (newHardwareOperator == address(0)) revert Errors.InvalidProposedAddress();
        if (deadline <= block.timestamp) revert Errors.InvalidDeadline();

        uint256 votationId = _votationId[shareProposalId];

        _votations[shareProposalId][votationId] = Types.Votation({
            votationId: votationId,
            votesFor: 0,
            votesAgainst: 0,
            deadline: deadline,
            proposedData: abi.encode(newProposedString, newHardwareOperator),
            option: Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_ADDRESS,
            amountReached: false
        });

        _votationId[shareProposalId]++;
        emit Events.VoteStarted(shareProposalId, votationId, Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_ADDRESS);
    }

    /// @notice Allows an user to create a new votation and propose a new Hardware Operator Revenue.
    /// @param shareProposalId The share proposal Id to be used to create the votation
    /// @param deadline Time to be waited to complete the votation
    /// @param newRevenue the new proposed hardware operator revenue
    /// @dev `newRevenue` should be greater or equal than 1/10 of the W Token total supply
    /// @dev `newRevenue` should be less or equal than 3/10 of the W Token total supply
    function proposeNewHardwareOperatorRevenue(
        uint256 shareProposalId,
        uint256 deadline,
        uint256 newRevenue
    ) external onlyVoter(shareProposalId) {
        uint256 revenueTotalSupply = managerData.hypcShareTokens.getRevenueTokenTotalSupply(
            _shareProposals[shareProposalId].shareTokenData.shareTokenNumber
        );

        if (
            newRevenue < revenueTotalSupply / 10 || newRevenue > revenueTotalSupply * 3 / 10
        ) {
            revert Errors.InvalidTokenAmount();
        }

        if (deadline <= block.timestamp) revert Errors.InvalidDeadline();

        uint256 votationId = _votationId[shareProposalId];

        _votations[shareProposalId][votationId] = Types.Votation({
            votationId: votationId,
            votesFor: 0,
            votesAgainst: 0,
            deadline: deadline,
            proposedData: abi.encode(newRevenue),
            option: Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_REVENUE,
            amountReached: false
        });
        _votationId[shareProposalId]++;
        emit Events.VoteStarted(shareProposalId, votationId, Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_REVENUE);
    }

    /// @notice Allows an user to create a new votation and propose a new share manager
    /// @param shareProposalId The share proposal Id to be used to create the votation
    /// @param deadline Time to be waited to complete the votation
    /// @param newShareManager The new share manager address
    function proposeNewManager(
        uint256 shareProposalId,
        uint256 deadline,
        address newShareManager
    ) external onlyVoter(shareProposalId) {
        if (
            newShareManager == address(0) ||
            newShareManager == address(this)
        ) revert Errors.InvalidProposedAddress();
        if (deadline <= block.timestamp) revert Errors.InvalidDeadline();

        uint256 votationId = _votationId[shareProposalId];

        _votations[shareProposalId][votationId] = Types.Votation({
            votationId: votationId,
            votesFor: 0,
            votesAgainst: 0,
            deadline: deadline,
            proposedData: abi.encode(newShareManager),
            option: Types.VotationOptions.CHANGE_MANAGER_CONTRACT,
            amountReached: false
        });

        _votationId[shareProposalId]++;
        emit Events.VoteStarted(shareProposalId, votationId, Types.VotationOptions.CHANGE_MANAGER_CONTRACT);
    }

    function proposeNewDepositRevenueDelay(
        uint256 shareProposalId,
        uint256 deadline,
        uint256 newDepositRevenueDelay
    ) external onlyVoter(shareProposalId) {
        if (newDepositRevenueDelay < 1 days) revert Errors.InvalidDepositRevenueDelay();
        if (deadline <= block.timestamp) revert Errors.InvalidDeadline();

        uint256 votationId = _votationId[shareProposalId];

        _votations[shareProposalId][votationId] = Types.Votation({
            votationId: votationId,
            votesFor: 0,
            votesAgainst: 0,
            deadline: deadline,
            proposedData: abi.encode(newDepositRevenueDelay),
            option: Types.VotationOptions.CHANGE_DEPOSIT_REVENUE_DELAY,
            amountReached: false
        });

        _votationId[shareProposalId]++;
        emit Events.VoteStarted(shareProposalId, votationId, Types.VotationOptions.CHANGE_DEPOSIT_REVENUE_DELAY);
    }

    // Votation functions

    /// @notice Function to execute or finish a votation, only able to vote if user increase the vote power
    /// @param shareProposalId Share Proposal Id to get the votations
    /// @param votationIndex Index of the votation to vote
    /// @param voteFor If true will increase the votes to execute the votation, otherwise will increase the votes to finish it.
    function vote(uint256 shareProposalId, uint256 votationIndex, bool voteFor) external onlyVoter(shareProposalId) {
        Types.Votation storage votation = _votations[shareProposalId][votationIndex];

        if (_shareProposals[shareProposalId].status == Types.ShareProposalStatus.ENDED)
            revert Errors.ShareTokenIsNotActive();

        if (votation.votationId == 0 && votationIndex != 0) revert Errors.InvalidVotationOption();

        if (votation.amountReached) revert Errors.VotationAmountReached();

        if (block.timestamp > votation.deadline) revert Errors.VotationDeadlineReached();

        if (_voted[shareProposalId][votation.votationId][_msgSender()]) revert Errors.ParticipantAlreadyVote();

        _voted[shareProposalId][votation.votationId][_msgSender()] = true;

        uint256 votePower = _votePower[shareProposalId][_msgSender()];

        voteFor ? votation.votesFor += votePower : votation.votesAgainst += votePower;

        uint256 wealthTokenSupply = managerData.hypcShareTokens.getWealthTokenTotalSupply(
            _shareProposals[shareProposalId].shareTokenData.shareTokenNumber
        );

        if (
            votation.option == Types.VotationOptions.CANCEL_SHARE ||
            votation.option == Types.VotationOptions.CHANGE_MANAGER_CONTRACT
        ) {
            if (
                votation.votesFor >= wealthTokenSupply * SELECTED_VOTATION_PERCENT / ONE_HUNDRED_PERCENT
            ) {
                votation.amountReached = true;
            }
        } else {
            if (
                (voteFor ? votation.votesFor : votation.votesAgainst) > (wealthTokenSupply >> 1) * SELECTED_VOTATION_PERCENT / ONE_HUNDRED_PERCENT
            ) {
                votation.amountReached = true;
            }
        }

        if (votation.amountReached) {
            if(voteFor) {
                _executeVotationAction(shareProposalId, votationIndex);
            }
            emit Events.VotationEnded(shareProposalId, votationIndex, voteFor);
        }

        emit Events.VoteEmmited(shareProposalId, _msgSender(), votationIndex);
    }

    /// @notice Increase the caller votation power, transfering the wealth tokens from the user to the contract
    /// @param shareProposalId Id of the Share Proposal to increase the vote power
    function increaseVotePower(uint256 shareProposalId) external {
        Types.ShareTokenData storage shareTokenData = _shareProposals[shareProposalId].shareTokenData;

        uint256 balance = managerData.hypcShareTokens.balanceOf(_msgSender(), shareTokenData.wTokenId);

        if (balance == 0) revert Errors.NoWealthTokensAvailable();

        managerData.hypcShareTokens.safeTransferFrom(_msgSender(), address(this), shareTokenData.wTokenId, balance, '');

        _votePower[shareProposalId][_msgSender()] += balance;
    }

    /// @notice Decrease the caller votation power, transfering the wealth tokens from the contract to the user
    /// @param shareProposalId Id of the Share Proposal to decrease the vote power
    function decreaseVotePower(uint256 shareProposalId) external {
        if (_shareProposals[shareProposalId].status == Types.ShareProposalStatus.ENDED)
            revert Errors.ShareTokenIsNotActive();

        Types.ShareTokenData storage shareTokenData = _shareProposals[shareProposalId].shareTokenData;

        uint256 balance = _votePower[shareProposalId][_msgSender()];

        delete _votePower[shareProposalId][_msgSender()];

        managerData.hypcShareTokens.safeTransferFrom(address(this), _msgSender(), shareTokenData.wTokenId, balance, '');
    }

    // Votation Actions

    /// Private function that will execute the votations actions based on the votation type
    /// @param shareProposalId Id of the Share Proposal to execute the action
    /// @param votationIndex Index of the votation to execute the action
    /// @dev If `votationIndex` is zero the proposal will be cancelled
    function _executeVotationAction(uint256 shareProposalId, uint256 votationIndex) private {
        Types.VotationOptions votationOption = _votations[shareProposalId][votationIndex].option;

        if (votationOption == Types.VotationOptions.CANCEL_SHARE) {
            _cancelShareProposal(shareProposalId);
        }

        if (votationOption == Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_ADDRESS) {
            _changeHardwareOperatorAddress(shareProposalId, votationIndex);
        }

        if (votationOption == Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_REVENUE) {
            _changeHardwareOperatorRevenue(shareProposalId, votationIndex);
        }

        if (votationOption == Types.VotationOptions.CHANGE_MANAGER_CONTRACT) {
            _changeShareManagerContract(shareProposalId, votationIndex);
        }

        if (votationOption == Types.VotationOptions.CHANGE_DEPOSIT_REVENUE_DELAY) {
            _changeDepositRevenueDelay(shareProposalId, votationIndex);
        }
    }

    /// Private function that will execute the cancel action
    /// @param shareProposalId Id of the Share Proposal to be cancelled
    function _cancelShareProposal(uint256 shareProposalId) private {
        if (_shareProposals[shareProposalId].shareTokenData.validEndTimestamp > block.timestamp)
            revert Errors.ShareProposalEndTimeNotReached();

        managerData.hypcShareTokens.cancelShareTokens(_shareProposals[shareProposalId].shareTokenData.shareTokenNumber);

        _endShareProposal(shareProposalId);

        emit Events.VoteActionExecuted(shareProposalId, Types.VotationOptions.CANCEL_SHARE);
    }

    /// Private function that will execute the change hardware operator action
    /// @param shareProposalId Id of the Share Proposal to be changed
    /// @param votationIndex Index of the votation to execute
    function _changeHardwareOperatorAddress(uint256 shareProposalId, uint256 votationIndex) private {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        _sendRevenueToHardwareOperator(shareProposalId);

        (string memory newHardwareOperatorString, address newHardwareOperatorAddress) = abi.decode(
            _votations[shareProposalId][votationIndex].proposedData,
            (string, address)
        );

        shareProposal.operatorData.operatorAddress = newHardwareOperatorAddress;
        shareProposal.operatorData.operatorAssignedString = newHardwareOperatorString;

        managerData.hypcShareTokens.setShareMessage(
            shareProposal.shareTokenData.shareTokenNumber,
            shareProposal.operatorData.operatorAssignedString
        );

        emit Events.VoteActionExecuted(shareProposalId, Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_ADDRESS);
    }

    /// Private function that will execute the change hardware operator revenue action
    /// @param shareProposalId Id of the Share Proposal to be changed
    /// @param votationIndex Index of the votation to execute
    function _changeHardwareOperatorRevenue(uint256 shareProposalId, uint256 votationIndex) private {

        _shareProposals[shareProposalId].operatorData.operatorRevenue = abi.decode(_votations[shareProposalId][votationIndex].proposedData, (uint256));

        emit Events.VoteActionExecuted(shareProposalId, Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_REVENUE);
    }

    /// Private function that will execute the change share manager action
    /// @param shareProposalId Id of the Share Proposal to be changed
    /// @param votationIndex Index of the votation to execute
    /// @dev The share proposal will be ended afterward
    function _changeShareManagerContract(uint256 shareProposalId, uint256 votationIndex) private {
        Types.ShareProposalData storage shareProposal = _shareProposals[shareProposalId];

        shareProposal.status = Types.ShareProposalStatus.ENDED;

        address newManager = abi.decode(_votations[shareProposalId][votationIndex].proposedData, (address));

        managerData.hypcShareTokens.transferShareOwnership(shareProposal.shareTokenData.shareTokenNumber, newManager);

        _sendRevenueToHardwareOperator(shareProposalId);

        _sendRevenueAndWealthTokens(
            newManager,
            shareProposal.shareTokenData.rTokenId,
            shareProposal.shareTokenData.wTokenId,
            managerData.hypcShareTokens.balanceOf(
                address(this),
                shareProposal.shareTokenData.rTokenId
            ),
            managerData.hypcShareTokens.balanceOf(
                address(this),
                shareProposal.shareTokenData.wTokenId
            )
        );

        emit Events.VoteActionExecuted(shareProposalId, Types.VotationOptions.CHANGE_MANAGER_CONTRACT);
    }

    /// Private function that will execute the change deposit revenue delay
    /// @param shareProposalId Id of the Share Proposal to be changed
    /// @param votationIndex Index of the votation to execute
    function _changeDepositRevenueDelay(uint256 shareProposalId, uint256 votationIndex) private {

        _shareProposals[shareProposalId].shareTokenData.revenueDepositDelay = abi.decode(_votations[shareProposalId][votationIndex].proposedData, (uint256));

        managerData.hypcShareTokens.changePendingRevenueDelay(
            _shareProposals[shareProposalId].shareTokenData.shareTokenNumber,
            _shareProposals[shareProposalId].shareTokenData.revenueDepositDelay
        );

        emit Events.VoteActionExecuted(shareProposalId, Types.VotationOptions.CHANGE_DEPOSIT_REVENUE_DELAY);
    }

    // Get functions

    // ManagerData getters

    /// @notice Get the setted swap V2 contract
    /// @return Swap V2 contract address
    function getCHYPC() external view returns (address) {
        return address(managerData.chypcV2);
    }

    /// @notice Get the setted License contract
    /// @return License contract address
    function getLicenseContract() external view returns (address) {
        return address(managerData.licenseContract);
    }

    /// @notice Get the setted HyperCycle Share Token contract
    /// @return HyperCycle Share Token contract address
    function getHypcShareTokenContract() external view returns (address) {
        return address(managerData.hypcShareTokens);
    }

    /// @notice Get the setted HyperCycle Token contract
    /// @return HyperCycle ERC 20 token
    function getHypcToken() external view returns (address) {
        return address(managerData.hypcToken);
    }

    // ShareProposalData getters

    /// @notice Get the data of a selected share proposal
    /// @param shareProposalId Id of the Share Proposal
    /// @return Share Proposal Data
    function getShareProposalData(uint256 shareProposalId) external view returns (Types.ShareProposalData memory) {
        return _shareProposals[shareProposalId];
    }

    /// @notice Get the status of a selected share proposal
    /// @param shareProposalId Id of the share proposal
    /// @return Share proposal status
    function getShareProposalStatus(uint256 shareProposalId) external view returns (Types.ShareProposalStatus) {
        return _shareProposals[shareProposalId].status;
    }
    
    /// @notice Get the revenue deposit delay of a selected share proposal
    /// @param shareProposalId Id of the share proposal
    /// @return Revenue deposit delay
    function getRevenueDelay(uint256 shareProposalId) external view returns (uint256) {
        return _shareProposals[shareProposalId].shareTokenData.revenueDepositDelay;
    }

    /// @notice Get the actual Hardware Operator Revenue of a selected share proposal
    /// @param shareProposalId Id of the share proposal
    /// @return Hardware Operator Revenue
    function getShareProposalHardwareOperatorRevenue(uint256 shareProposalId) external view returns (uint256) {
        return _shareProposals[shareProposalId].operatorData.operatorRevenue;
    }

    /// @notice Get the License token id
    /// @param shareProposalId Id of the share proposal
    /// @return License token id
    function getShareProposalLicenseNumber(uint256 shareProposalId) external view returns (uint256) {
        return _shareProposals[shareProposalId].licenseData.tokenNumber;
    }

    /// @notice Get the License Owner
    /// @param shareProposalId Id of the share proposal
    /// @return License Owner
    function getShareProposalLicenseOwner(uint256 shareProposalId) external view returns (address) {
        return _shareProposals[shareProposalId].licenseData.tokenOwner;
    }

    /// @notice Get the License Level
    /// @param shareProposalId Id of the share proposal
    /// @return License level
    function getShareProposalLicenseLevel(uint256 shareProposalId) external view returns (uint256) {
        return _shareProposals[shareProposalId].licenseData.tokenLevel;
    }

    /// @notice Get the cHyPc token id
    /// @param shareProposalId Id of the share proposal
    /// @return cHyPc token id
    function getShareProposalCHYPCNumber(uint256 shareProposalId) external view returns (uint256) {
        return _shareProposals[shareProposalId].chypcData.tokenNumber;
    }

    /// @notice Get the cHyPc owner
    /// @param shareProposalId Id of the share proposal
    /// @return cHyPc owner
    function getShareProposalCHYPCOwner(uint256 shareProposalId) external view returns (address) {
        return _shareProposals[shareProposalId].chypcData.tokenOwner;
    }

    /// @notice Get the cHyPc level
    /// @param shareProposalId Id of the share proposal
    /// @return cHyPc level
    function getShareProposalCHYPCLevel(uint256 shareProposalId) external view returns (uint256) {
        return _shareProposals[shareProposalId].chypcData.tokenLevel;
    }

    /// @notice Get the Hardware Operator address
    /// @param shareProposalId Id of the share proposal
    /// @return Hardware Operator address
    function getShareProposalHardwareOperator(uint256 shareProposalId) external view returns (address) {
        return _shareProposals[shareProposalId].operatorData.operatorAddress;
    }

    // NewProposedShareData getters

    /// @notice Get the proposed hardware operator address
    /// @dev Should revert if the votation option isn't the expected
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return operator proposed hardware operator
    function getProposedHardwareOperatorAddress(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (address operator) {
        if (
            _votations[shareProposalId][votationIndex].option != Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_ADDRESS
        ) {
            revert Errors.InvalidVotationOption();
        }
        (, operator) = abi.decode(_votations[shareProposalId][votationIndex].proposedData, (string, address));
    }

    /// @notice Get the proposed hardware operator revenue
    /// @dev Should revert if the votation option isn't the expected
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return Proposed hardware operator revenue
    function getProposedHardwareOperatorRevenue(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (uint256) {
        if (
            _votations[shareProposalId][votationIndex].option != Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_REVENUE
        ) {
            revert Errors.InvalidVotationOption();
        }
        return abi.decode(_votations[shareProposalId][votationIndex].proposedData, (uint256));
    }

    /// @notice Get the proposed revenue deposit delay
    /// @dev Should revert if the votation option isn't the expected
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return Proposed revenue deposit delay
    function getProposedDepositRevenueDelay(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (uint256) {
        if (
            _votations[shareProposalId][votationIndex].option != Types.VotationOptions.CHANGE_DEPOSIT_REVENUE_DELAY
        ) {
            revert Errors.InvalidVotationOption();
        }
        return abi.decode(_votations[shareProposalId][votationIndex].proposedData, (uint256));
    }

    /// @notice Get the proposed hardware operator string
    /// @dev Should revert if the votation option isn't the expected
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return proposedString proposed hardware operator string
    function getProposedNewShareMessage(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (string memory proposedString) {
        if (
            _votations[shareProposalId][votationIndex].option != Types.VotationOptions.CHANGE_HARDWARE_OPERATOR_ADDRESS
        ) {
            revert Errors.InvalidVotationOption();
        }
        (proposedString, ) = abi.decode(_votations[shareProposalId][votationIndex].proposedData, (string, address));
    }

    // Votation getters

    /// @notice Get the amount of votes on behalf to execute the votation
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return Amount of votes
    function getShareProposalVotationVotesFor(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (uint256) {
        return _votations[shareProposalId][votationIndex].votesFor;
    }

    /// @notice Get the amount of votes against execute the votation
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return Amount of votes
    function getShareProposalVotationVotesAgainst(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (uint256) {
        return _votations[shareProposalId][votationIndex].votesAgainst;
    }

    /// @notice Get the amount of votes needed to execute or finish the votation
    /// @return Votes needed
    function getVotationConsensus(uint256 shareProposalId, Types.VotationOptions votationOption) external view returns (uint256) {
        uint256 totalSupply = managerData.hypcShareTokens.getWealthTokenTotalSupply(
            _shareProposals[shareProposalId].shareTokenData.shareTokenNumber
        );
        if (votationOption == Types.VotationOptions.CANCEL_SHARE || votationOption == Types.VotationOptions.CHANGE_MANAGER_CONTRACT) {
            return totalSupply * SELECTED_VOTATION_PERCENT / ONE_HUNDRED_PERCENT;
        } else {
            return (totalSupply >> 1) * SELECTED_VOTATION_PERCENT / ONE_HUNDRED_PERCENT;
        }
    }

    /// @notice Get if the votation amount was reached to execute or finish it
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return If votation amount was reached
    function getShareProposalVotationAmountReached(
        uint256 shareProposalId,
        uint256 votationIndex
    ) external view returns (bool) {
        return _votations[shareProposalId][votationIndex].amountReached;
    }

    /// @notice Get if a selected address has voted in a specific votation
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @param voter address of the voter to check
    /// @return If voter has voted
    function getUserVote(uint256 shareProposalId, uint256 votationIndex, address voter) external view returns (bool) {
        return _voted[shareProposalId][votationIndex][voter];
    }

    /// @notice Get the vote power a voter has
    /// @param shareProposalId Id of the share proposal
    /// @param voter address of the voter to check
    /// @return Vote power
    function getVotePower(uint256 shareProposalId, address voter) external view returns (uint256) {
        return _votePower[shareProposalId][voter];
    }

    /// @notice Get the amount of votations a share proposal has
    /// @param shareProposalId Id of the share proposal
    /// @return Amount of votations
    function getVotationsAmount(uint256 shareProposalId) external view returns (uint256) {
        return _votationId[shareProposalId];
    }

    /// @notice Get the votation data
    /// @param shareProposalId Id of the share proposal
    /// @param votationIndex Index of the votation
    /// @return Votation data
    function getVotationData(
        uint256 shareProposalId,
        uint256 votationIndex,
        address voter
    ) external view returns (Types.Votation memory, bool) {
        return (
            _votations[shareProposalId][votationIndex],
            _voted[shareProposalId][votationIndex][voter]
        );
    }
}

File 2 of 20 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)

pragma solidity ^0.8.0;

import "../token/ERC721/IERC721.sol";

File 3 of 20 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 4 of 20 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 5 of 20 : ERC1155Holder.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)

pragma solidity ^0.8.0;

import "./ERC1155Receiver.sol";

/**
 * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
 *
 * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
 * stuck.
 *
 * @dev _Available since v3.1._
 */
contract ERC1155Holder is ERC1155Receiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}

File 6 of 20 : ERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";

/**
 * @dev _Available since v3.1._
 */
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
    }
}

File 7 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

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

File 8 of 20 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

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

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 10 of 20 : ERC721Holder.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol)

pragma solidity ^0.8.0;

import "../IERC721Receiver.sol";

/**
 * @dev Implementation of the {IERC721Receiver} interface.
 *
 * Accepts all token transfers.
 * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
 */
contract ERC721Holder is IERC721Receiver {
    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     *
     * Always returns `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

File 12 of 20 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 14 of 20 : IHYPC.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

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

/// @notice Interface for the HyperCycleToken.sol contract.
interface IHYPC is IERC20 {
    /*
     * Accesses the ERC20 functions of the HYPC contract. The burn function
     * is also exposed for future contracts.
    */
    /// @notice Burns an amount of the HyPC ERC20.
    function burn(uint256 amount) external;
}

File 15 of 20 : IHYPCSwapV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "@openzeppelin/contracts/interfaces/IERC721.sol";

/// @notice Interface for the HYPCSwap.sol contract.
interface IHYPCSwapV2 is IERC721 {
    /**
     * Accesses the addNFT function so that the CHYPC contract can
     * add the newly created NFT into this contract.
     */

    function addRootTokens(uint256 tokens) external;

    function splitHeldToken(uint256 level, uint256 skipLevels) external;

    function swapV2(uint256 level) external;

    function redeem(uint256 tokenNumber) external;

    function assignNumber(uint256 tokenNumber, uint256 targetNumber) external;

    function assignString(uint256 tokenNumber, string memory data) external;

    function burn(uint256 tokenNumber, string memory data) external;

    function assign(uint256 tokenNumber, string memory data) external;

    function swap() external;


    function getAssignment(uint256 tokenNumber) external view returns (string memory);
    function getAssignmentNumber(uint256 tokenNumber) external view returns (uint256);
    function getAssignmentString(uint256 tokenNumber) external view returns (string memory);



    function getBurnData(uint256 tokenNumber) external view returns (string memory);

    function getAvailableToken(uint256 level, uint256 index) external view returns (uint256);

    function getTokenLevel(uint256 tokenNumber) external view returns (uint256);

    function getAssignmentTargetNumber(uint256 targetNumber) external view returns (uint256);
}

File 16 of 20 : IHyperCycleLicense.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

/// @notice Interface for the CHYPC.sol contract.
interface IHyperCycleLicense is IERC721 {
    /**
     * Accesses the assignment function of c_HyPC so the swap can remove 
     * the assignment data when a token is redeemed or swapped.
     */
    /// @notice Creates a new root token inside this contract, with a specified licenseID.
    function mint(
        uint256 numTokens
    ) external;

    /// @notice Splits a given token into two new tokens, with corresponding licenseID's.
    function split(
        uint256 tokenId
    ) external;

    /// @notice Burns a given tokenId with a specified burn string.
    function burn(
        uint256 tokenId,
        string memory burnString          
    ) external;

    /// @notice Merges together two child licenses into a parent license.
    function merge(
        uint256 tokenId
    ) external;

    /// @notice Returns the burn data from the given tokenId.
    function getBurnData(
        uint256 tokenId
    ) external view returns (string memory);

    /// @notice Returns the license height of the given tokenId.
    function getLicenseHeight(
        uint256 licenseId
    ) external view returns (uint8);

    /// @notice Returns the license height of the given tokenId.
    function getLicenseStatus(
        uint256 licenseId
    ) external view returns (uint256);
}

File 17 of 20 : IHyperCycleShareTokensV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol';

/// @notice Interface for the HyperCycleShareTokens.sol contract.
interface IHyperCycleShareTokensV2 is IERC1155 {
    struct PendingDeposit {
        uint256 availableAtTimestamp;
        uint256 amount;
    }

    function shareData(
        uint256 shareNumber
    )
        external
        pure
        returns (
            uint256 licenseId,
            uint256 chypcId,
            uint256 status,
            address owner,
            uint256 rTokenNumber,
            uint256 wTokenNumber,
            uint256 rTokenSupply,
            uint256 wTokenSupply,
            uint256 startTimestamp,
            uint256 revenueDeposited,
            uint256 revenueDepositDelay,
            string memory message,
            bool chypcTokenHeld
        );

    function currentShareNumber() external returns (uint256);

    function increaseShareLimit(uint256 number) external;

    function createShareTokens(
        uint256 licenseNumber,
        uint256 chypcNumber,
        bool chypcTokenHeld,
        string memory startingMessage,
        uint256 maxRevenueDeposit
    ) external;

    function changePendingRevenueDelay(uint256 shareNumber, uint256 newDelay) external;

    function transferShareOwnership(uint256 shareNumber, address to) external;

    function cancelShareTokens(uint256 shareNumber) external;

    function depositRevenue(uint256 shareNumber, uint256 amt) external;

    function claimRevenue(uint256 shareNumber) external;

    function withdrawEarnings(uint256 shareNumber) external;

    function claimAndWithdraw(uint256 shareNumber) external;

    function setShareMessage(uint256 shareNumber, string memory message) external;

    function burnRevenueTokens(uint256 shareNumber, uint256 amount) external;

    function burnWealthTokens(uint256 shareNumber, uint256 amount) external;

    function getShareLicenseId(uint256 shareNumber) external view returns (uint256);

    function getShareCHyPCId(uint256 shareNumber) external view returns (uint256);

    function getShareOwner(uint256 shareNumber) external view returns (address);

    function getShareRevenueTokenId(uint256 shareNumber) external view returns (uint256);

    function getShareWealthTokenId(uint256 shareNumber) external view returns (uint256);

    function getShareTotalRevenue(uint256 shareNumber) external view returns (uint256);

    function getShareStartTime(uint256 shareNumber) external view returns (uint256);

    function getShareMessage(uint256 shareNumber) external view returns (string memory);

    function isShareActive(uint256 shareNumber) external view returns (bool);

    function shareCreated(uint256 shareNumber) external view returns (bool);

    function getRevenueTokenTotalSupply(uint256 shareNumber) external view returns (uint256);

    function getWealthTokenTotalSupply(uint256 shareNumber) external view returns (uint256);

    function getPendingDeposit(uint256 shareNumber, uint256 index) external view returns (PendingDeposit memory);

    function getPendingDepositsLength(uint256 shareNumber) external view returns (uint256);
}

File 18 of 20 : ShareManagerErrors.sol
// SPDX-License-Identifier: MIT
/*
    Share Manager Errors
*/

pragma solidity 0.8.19;

library ShareManagerErrors {
    error ShareProposalIsNotPending();

    error ShareProposalIsNotEnded();

    error ShareProposalEndTimeNotReached();

    error InvalidProposedAddress();

    error InvalidHYPCTokenAddress();

    error InvalidCHYPCAddress();

    error InvalidCHYPCOwner();

    error InvalidTokenAmount();

    error InvalidShareTokenContract();

    error InvalidProposedString();

    error InvalidLicenseAddress();

    error InvalidLicenseOwner();

    error InvalidVotationOption();

    error InvalidDeadline();

    error ChypcIsNotHeld();

    error ParticipantAlreadyVote();

    error NoWealthTokensAvailable();

    error VotationAmountReached();

    error VotationDeadlineReached();

    error TokenLevelMismatch();

    error ShareTokenAlreadyExists();

    error InvalidShareTokenOwner();

    error GetShareDataFailed();

    error ShareTokenIsNotActive();

    error NotEnoughHYPC();

    error InvalidDepositRevenueDelay();
}

File 19 of 20 : ShareManagerEvents.sol
// SPDX-License-Identifier: MIT
/*
    Share Manager Events
*/

pragma solidity 0.8.19;

import {ShareManagerTypes} from './ShareManagerTypes.sol';

library ShareManagerEvents {
    event ShareProposalCreated(uint256 shareProposalId);

    event ShareProposalStarted(uint256 shareProposalId);

    event ShareProposalEnded(uint256 shareProposalId);

    event HypcClaimed(uint256 shareProposalId, uint256 hypcClaimed);

    event VoteStarted(uint256 shareProposalId, uint256 votationIndex, ShareManagerTypes.VotationOptions selectedOption);

    event VoteActionExecuted(uint256 shareProposalId, ShareManagerTypes.VotationOptions selectedOption);

    event VoteEmmited(uint256 shareProposalId, address voter, uint256 votationIndex);

    event VotationEnded(uint256 shareProposalId, uint256 votationIndex, bool voteForWinner);
}

File 20 of 20 : ShareManagerTypes.sol
// SPDX-License-Identifier: MIT
/*
    Share Manager Types
*/

pragma solidity 0.8.19;

import {IHYPCSwapV2} from '../interfaces/IHYPCSwapV2.sol';
import {IHyperCycleLicense} from '../interfaces/IHyperCycleLicense.sol';
import {IHyperCycleShareTokensV2} from '../interfaces/IHyperCycleShareTokensV2.sol';
import {IHYPC} from '../interfaces/IHYPC.sol';

library ShareManagerTypes {
    enum ShareProposalStatus {
        NOT_CREATED,
        PENDING,
        STARTED,
        ENDED
    }

    enum VotationOptions {
        CANCEL_SHARE,
        CHANGE_HARDWARE_OPERATOR_ADDRESS,
        CHANGE_HARDWARE_OPERATOR_REVENUE,
        CHANGE_MANAGER_CONTRACT,
        CHANGE_DEPOSIT_REVENUE_DELAY
    }

    enum ConsensusOptions {
        ONE_HUNDRED_PERCENT,
        NINETY_PERCENT
    }

    struct ManagerData {
        IHYPC hypcToken;
        IHYPCSwapV2 chypcV2;
        IHyperCycleLicense licenseContract;
        IHyperCycleShareTokensV2 hypcShareTokens;
    }

    struct ShareProposalData {
        ShareTokenData shareTokenData;
        TokenHolderData licenseData;
        TokenHolderData chypcData;
        HardwareOperatorData operatorData;
        ShareProposalStatus status;
        uint256 hypcSurplus;
    }

    struct ShareTokenData {
        uint256 validEndTimestamp;
        uint256 shareTokenNumber;
        uint256 rTokenId;
        uint256 wTokenId;
        uint256 revenueDepositDelay;
    }

    struct TokenHolderData {
        uint256 tokenNumber;
        uint256 tokenLevel;
        uint256 initialRevenueTokens;
        uint256 initialWealthTokens;
        address tokenOwner;
    }

    struct HardwareOperatorData {
        uint256 operatorRevenue;
        string operatorAssignedString;
        address operatorAddress;
    }

    struct Votation {
        uint256 votationId;
        uint256 votesFor;
        uint256 votesAgainst;
        uint256 deadline;
        bytes proposedData;
        VotationOptions option;
        bool amountReached;
    }

    struct ShareData {
        uint256 licenseId;
        uint256 chypcId;
        uint256 status;
        address owner;
        uint256 rTokenNumber;
        uint256 wTokenNumber;
        uint256 rTokenSupply;
        uint256 wTokenSupply;
        uint256 startTimestamp;
        uint256 revenueDeposited;
        uint256 revenueDepositDelay;
        string message;
        bool chypcTokenHeld;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"enum ShareManagerTypes.ConsensusOptions","name":"_consensusOption","type":"uint8"},{"internalType":"address","name":"_hypcToken","type":"address"},{"internalType":"address","name":"_chypcV2","type":"address"},{"internalType":"address","name":"_licenseContract","type":"address"},{"internalType":"address","name":"_hypcShareTokens","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"ChypcIsNotHeld","type":"error"},{"inputs":[],"name":"GetShareDataFailed","type":"error"},{"inputs":[],"name":"InvalidCHYPCAddress","type":"error"},{"inputs":[],"name":"InvalidCHYPCOwner","type":"error"},{"inputs":[],"name":"InvalidDeadline","type":"error"},{"inputs":[],"name":"InvalidDepositRevenueDelay","type":"error"},{"inputs":[],"name":"InvalidHYPCTokenAddress","type":"error"},{"inputs":[],"name":"InvalidLicenseAddress","type":"error"},{"inputs":[],"name":"InvalidLicenseOwner","type":"error"},{"inputs":[],"name":"InvalidProposedAddress","type":"error"},{"inputs":[],"name":"InvalidProposedString","type":"error"},{"inputs":[],"name":"InvalidShareTokenContract","type":"error"},{"inputs":[],"name":"InvalidShareTokenOwner","type":"error"},{"inputs":[],"name":"InvalidTokenAmount","type":"error"},{"inputs":[],"name":"InvalidVotationOption","type":"error"},{"inputs":[],"name":"NoWealthTokensAvailable","type":"error"},{"inputs":[],"name":"NotEnoughHYPC","type":"error"},{"inputs":[],"name":"ParticipantAlreadyVote","type":"error"},{"inputs":[],"name":"ShareProposalEndTimeNotReached","type":"error"},{"inputs":[],"name":"ShareProposalIsNotEnded","type":"error"},{"inputs":[],"name":"ShareProposalIsNotPending","type":"error"},{"inputs":[],"name":"ShareTokenAlreadyExists","type":"error"},{"inputs":[],"name":"ShareTokenIsNotActive","type":"error"},{"inputs":[],"name":"TokenLevelMismatch","type":"error"},{"inputs":[],"name":"VotationAmountReached","type":"error"},{"inputs":[],"name":"VotationDeadlineReached","type":"error"},{"inputs":[],"name":"SELECTED_VOTATION_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"cancelPendingShareProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"cancelShareTokenMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"claimHypcPortion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"claimSurplus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"licenseNumber","type":"uint256"}],"name":"completeShareProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"proposalData","type":"bytes"}],"name":"createShareProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"decreaseVotePower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"finishShareTokenMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCHYPC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHypcShareTokenContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHypcToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLicenseContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getProposedDepositRevenueDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getProposedHardwareOperatorAddress","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getProposedHardwareOperatorRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getProposedNewShareMessage","outputs":[{"internalType":"string","name":"proposedString","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getRevenueDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalCHYPCLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalCHYPCNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalCHYPCOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalData","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"validEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"shareTokenNumber","type":"uint256"},{"internalType":"uint256","name":"rTokenId","type":"uint256"},{"internalType":"uint256","name":"wTokenId","type":"uint256"},{"internalType":"uint256","name":"revenueDepositDelay","type":"uint256"}],"internalType":"struct ShareManagerTypes.ShareTokenData","name":"shareTokenData","type":"tuple"},{"components":[{"internalType":"uint256","name":"tokenNumber","type":"uint256"},{"internalType":"uint256","name":"tokenLevel","type":"uint256"},{"internalType":"uint256","name":"initialRevenueTokens","type":"uint256"},{"internalType":"uint256","name":"initialWealthTokens","type":"uint256"},{"internalType":"address","name":"tokenOwner","type":"address"}],"internalType":"struct ShareManagerTypes.TokenHolderData","name":"licenseData","type":"tuple"},{"components":[{"internalType":"uint256","name":"tokenNumber","type":"uint256"},{"internalType":"uint256","name":"tokenLevel","type":"uint256"},{"internalType":"uint256","name":"initialRevenueTokens","type":"uint256"},{"internalType":"uint256","name":"initialWealthTokens","type":"uint256"},{"internalType":"address","name":"tokenOwner","type":"address"}],"internalType":"struct ShareManagerTypes.TokenHolderData","name":"chypcData","type":"tuple"},{"components":[{"internalType":"uint256","name":"operatorRevenue","type":"uint256"},{"internalType":"string","name":"operatorAssignedString","type":"string"},{"internalType":"address","name":"operatorAddress","type":"address"}],"internalType":"struct ShareManagerTypes.HardwareOperatorData","name":"operatorData","type":"tuple"},{"internalType":"enum ShareManagerTypes.ShareProposalStatus","name":"status","type":"uint8"},{"internalType":"uint256","name":"hypcSurplus","type":"uint256"}],"internalType":"struct ShareManagerTypes.ShareProposalData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalHardwareOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalHardwareOperatorRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalLicenseLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalLicenseNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalLicenseOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getShareProposalStatus","outputs":[{"internalType":"enum ShareManagerTypes.ShareProposalStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getShareProposalVotationAmountReached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getShareProposalVotationVotesAgainst","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"}],"name":"getShareProposalVotationVotesFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"},{"internalType":"address","name":"voter","type":"address"}],"name":"getUserVote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"enum ShareManagerTypes.VotationOptions","name":"votationOption","type":"uint8"}],"name":"getVotationConsensus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"},{"internalType":"address","name":"voter","type":"address"}],"name":"getVotationData","outputs":[{"components":[{"internalType":"uint256","name":"votationId","type":"uint256"},{"internalType":"uint256","name":"votesFor","type":"uint256"},{"internalType":"uint256","name":"votesAgainst","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"proposedData","type":"bytes"},{"internalType":"enum ShareManagerTypes.VotationOptions","name":"option","type":"uint8"},{"internalType":"bool","name":"amountReached","type":"bool"}],"internalType":"struct ShareManagerTypes.Votation","name":"","type":"tuple"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"getVotationsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"address","name":"voter","type":"address"}],"name":"getVotePower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"}],"name":"increaseVotePower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"managerData","outputs":[{"internalType":"contract IHYPC","name":"hypcToken","type":"address"},{"internalType":"contract IHYPCSwapV2","name":"chypcV2","type":"address"},{"internalType":"contract IHyperCycleLicense","name":"licenseContract","type":"address"},{"internalType":"contract IHyperCycleShareTokensV2","name":"hypcShareTokens","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"newDepositRevenueDelay","type":"uint256"}],"name":"proposeNewDepositRevenueDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"string","name":"newProposedString","type":"string"},{"internalType":"address","name":"newHardwareOperator","type":"address"}],"name":"proposeNewHardwareOperatorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"newRevenue","type":"uint256"}],"name":"proposeNewHardwareOperatorRevenue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"newShareManager","type":"address"}],"name":"proposeNewManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sharesProposalsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareTokenNumber","type":"uint256"},{"internalType":"address","name":"hardwareOperator","type":"address"},{"internalType":"string","name":"operatorAssignedString","type":"string"}],"name":"startShareProposalMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareProposalId","type":"uint256"},{"internalType":"uint256","name":"votationIndex","type":"uint256"},{"internalType":"bool","name":"voteFor","type":"bool"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405162005a5538038062005a558339810160408190526200002691620001b5565b6001600160a01b0384166200004e57604051635412f96d60e01b815260040160405180910390fd5b6001600160a01b038316620000765760405163a21c5c7f60e01b815260040160405180910390fd5b6001600160a01b0382166200009e576040516373cfb64f60e11b815260040160405180910390fd5b6001600160a01b038116620000c65760405163f7468e4f60e01b815260040160405180910390fd5b6000856001811115620000dd57620000dd6200022a565b146200011157600a620000fa670de0b6b3a7640000600962000240565b6200010691906200026c565b600581905562000120565b670de0b6b3a764000060058190555b50604080516080810182526001600160a01b0395861680825294861660208201819052938616918101829052919094166060909101819052600080546001600160a01b03199081169094179055600180548416909217909155600280548316909317909255600380549091169091179055506200028f565b80516001600160a01b0381168114620001b057600080fd5b919050565b600080600080600060a08688031215620001ce57600080fd5b855160028110620001de57600080fd5b9450620001ee6020870162000198565b9350620001fe6040870162000198565b92506200020e6060870162000198565b91506200021e6080870162000198565b90509295509295909350565b634e487b7160e01b600052602160045260246000fd5b80820281158282048414176200026657634e487b7160e01b600052601160045260246000fd5b92915050565b6000826200028a57634e487b7160e01b600052601260045260246000fd5b500490565b6157b6806200029f6000396000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c80637d2c1bc411610182578063cc5b60f2116100e9578063d7b53a0e116100a2578063e7039a841161007c578063e7039a841461082e578063ef7ec0011461085c578063f23a6e611461086f578063f482e9621461088e57600080fd5b8063d7b53a0e146107e6578063d92b3456146107f9578063ddcbde9a1461080a57600080fd5b8063cc5b60f214610749578063cce84c8a1461075c578063cf2bd5981461077c578063d17fafb11461078f578063d4696177146107a0578063d577d06d146107c357600080fd5b8063b5348aa91161013b578063b5348aa9146106b8578063bc197c81146106c1578063c0c68a6b146106e0578063c0d700fd146106f3578063c143249614610706578063c1474a3b1461072957600080fd5b80637d2c1bc4146105f257806383d845e21461064b5780638a5d70941461065e57806393bf51a2146106815780639518a2b5146106945780639eb40277146106a557600080fd5b806346feda08116102265780636b3048cc116101df5780636b3048cc146105105780636c975f461461053c5780636e8153ae1461054f57806372a127f91461057b578063739e340d146105bb5780637b48227a146105c457600080fd5b806346feda08146104815780634cb77103146104a15780635d02c5e3146104b457806361271e13146104c75780636811a5c0146104da5780636a18ff7a146104fd57600080fd5b8063199789fb11610278578063199789fb146103d65780631b2522bc146103e95780632f7c5eeb146103fc578063337d12041461042157806340368d0c1461044257806342f39a3d1461046e57600080fd5b806301ffc9a7146102c05780630a8f2a65146102e857806310f7c9861461031e578063115cd40914610333578063150b7a02146103665780631864472614610392575b600080fd5b6102d36102ce3660046149ef565b6108a1565b60405190151581526020015b60405180910390f35b6102d36102f6366004614a19565b6000918252600960209081526040808420928452919052902060050154610100900460ff1690565b61033161032c366004614b18565b6108d8565b005b610359610341366004614b7b565b6000908152600a602052604090206012015460ff1690565b6040516102df9190614bbe565b610379610374366004614bcc565b610ab0565b6040516001600160e01b031990911681526020016102df565b6103c86103a0366004614c38565b60009182526006602090815260408084206001600160a01b0393909316845291905290205490565b6040519081526020016102df565b6103316103e4366004614c68565b610ac1565b6103316103f7366004614b7b565b610d34565b6003546001600160a01b03165b6040516001600160a01b0390911681526020016102df565b61043461042f366004614c94565b610e9b565b6040516102df929190614d2d565b610409610450366004614b7b565b6000908152600a60205260409020600e01546001600160a01b031690565b61033161047c366004614c68565b611003565b6103c861048f366004614b7b565b60009081526008602052604090205490565b6103c86104af366004614a19565b6111d7565b6103316104c2366004614da3565b6112ea565b6103316104d5366004614b7b565b6117ce565b6103c86104e8366004614b7b565b6000908152600a602052604090206004015490565b61033161050b366004614de6565b611915565b61040961051e366004614b7b565b6000908152600a60205260409020601101546001600160a01b031690565b6103c861054a366004614a19565b611cfd565b61040961055d366004614b7b565b6000908152600a60205260409020600901546001600160a01b031690565b6102d3610589366004614c94565b60009283526007602090815260408085209385529281528284206001600160a01b039290921684525290205460ff1690565b6103c860045481565b6103c86105d2366004614a19565b600091825260096020908152604080842092845291905290206002015490565b600054600154600254600354610618936001600160a01b03908116938116928116911684565b604080516001600160a01b03958616815293851660208501529184169183019190915290911660608201526080016102df565b610331610659366004614b7b565b611d06565b6103c861066c366004614b7b565b6000908152600a602052604090206006015490565b61040961068f366004614a19565b611de4565b6000546001600160a01b0316610409565b6103316106b3366004614e14565b611eef565b6103c860055481565b6103796106cf366004614eed565b63bc197c8160e01b95945050505050565b6103316106ee366004614b7b565b612699565b610331610701366004614b7b565b612a03565b6103c8610714366004614b7b565b6000908152600a60205260409020600b015490565b61073c610737366004614a19565b612b7a565b6040516102df9190614f9b565b610331610757366004614b7b565b612c8d565b61076f61076a366004614b7b565b612d1c565b6040516102df9190614fea565b61033161078a366004614c94565b612f08565b6001546001600160a01b0316610409565b6103c86107ae366004614b7b565b6000908152600a602052604090206005015490565b6103c86107d1366004614b7b565b6000908152600a60205260409020600f015490565b6103316107f4366004614a19565b6130d1565b6002546001600160a01b0316610409565b6103c8610818366004614b7b565b6000908152600a60208190526040909120015490565b6103c861083c366004614a19565b600091825260096020908152604080842092845291905290206001015490565b6103c861086a3660046150ef565b6131c0565b61037961087d366004615118565b63f23a6e6160e01b95945050505050565b61033161089c366004614b7b565b6132c0565b60006001600160e01b03198216630271189760e51b14806108d257506301ffc9a760e01b6001600160e01b03198316145b92915050565b60008481526006602090815260408083203384529091528120548591036109125760405163bfe6236760e01b815260040160405180910390fd5b6001600160a01b03821661093957604051639792926760e01b815260040160405180910390fd5b42841161095957604051631da7447960e21b815260040160405180910390fd5b6000600860008781526020019081526020016000205490506040518060e00160405280828152602001600081526020016000815260200186815260200185856040516020016109a9929190615181565b60408051601f19818403018152919052815260200160018152600060209182018190528881526009825260408082208583528352908190208351815591830151600183015582015160028201556060820151600382015560808201516004820190610a149082615233565b5060a082015160058201805460ff19166001836004811115610a3857610a38614b94565b021790555060c09190910151600590910180549115156101000261ff00199092169190911790556000868152600860205260408120805491610a7983615309565b919050555060008051602061576183398151915286826001604051610aa093929190615322565b60405180910390a1505050505050565b630a85bd0160e11b5b949350505050565b6000838152600660209081526040808320338452909152812054849103610afb5760405163bfe6236760e01b815260040160405180910390fd5b6003546000858152600a60205260408082206001015490516327143fdd60e21b815291926001600160a01b031691639c50ff7491610b3f9160040190815260200190565b602060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b80919061533d565b9050610b8d600a82615356565b831080610baf5750600a610ba2826003615378565b610bac9190615356565b83115b15610bcd57604051632160733960e01b815260040160405180910390fd5b428411610bed57604051631da7447960e21b815260040160405180910390fd5b6000600860008781526020019081526020016000205490506040518060e00160405280828152602001600081526020016000815260200186815260200185604051602001610c3d91815260200190565b60408051601f19818403018152919052815260200160028152600060209182018190528881526009825260408082208583528352908190208351815591830151600183015582015160028201556060820151600382015560808201516004820190610ca89082615233565b5060a082015160058201805460ff19166001836004811115610ccc57610ccc614b94565b021790555060c09190910151600590910180549115156101000261ff00199092169190911790556000868152600860205260408120805491610d0d83615309565b919050555060008051602061576183398151915286826002604051610aa093929190615322565b6000818152600a602052604090206003601282015460ff166003811115610d5d57610d5d614b94565b14610d7b57604051637bf390dd60e11b815260040160405180910390fd5b6013810154600181901c90600090610d9490839061538f565b60006013850181905554600e85015460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb92610dd592169086906004016153a2565b6020604051808303816000875af1158015610df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1891906153bb565b50600054600984015460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92610e519291169085906004016153a2565b6020604051808303816000875af1158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9491906153bb565b5050505050565b610ea36148cc565b600084815260096020908152604080832086845282528083208784526007835281842087855283528184206001600160a01b0387168552835281842054825160e0810184528254815260018301549481019490945260028201549284019290925260038101546060840152600481018054919360ff909316929184916080840191610f2d906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054610f59906151ab565b8015610fa65780601f10610f7b57610100808354040283529160200191610fa6565b820191906000526020600020905b815481529060010190602001808311610f8957829003601f168201915b5050509183525050600582015460209091019060ff166004811115610fcd57610fcd614b94565b6004811115610fde57610fde614b94565b815260059190910154610100900460ff16151560209091015297909650945050505050565b600083815260066020908152604080832033845290915281205484910361103d5760405163bfe6236760e01b815260040160405180910390fd5b620151808210156110615760405163363d956160e11b815260040160405180910390fd5b42831161108157604051631da7447960e21b815260040160405180910390fd5b6000600860008681526020019081526020016000205490506040518060e001604052808281526020016000815260200160008152602001858152602001846040516020016110d191815260200190565b60408051601f1981840301815291905281526020016004815260006020918201819052878152600982526040808220858352835290819020835181559183015160018301558201516002820155606082015160038201556080820151600482019061113c9082615233565b5060a082015160058201805460ff1916600183600481111561116057611160614b94565b021790555060c09190910151600590910180549115156101000261ff001990921691909117905560008581526008602052604081208054916111a183615309565b9190505550600080516020615761833981519152858260046040516111c893929190615322565b60405180910390a15050505050565b600060045b600084815260096020908152604080832086845290915290206005015460ff16600481111561120d5761120d614b94565b1461122b5760405163e200563560e01b815260040160405180910390fd5b600083815260096020908152604080832085845290915290206004018054611252906151ab565b80601f016020809104026020016040519081016040528092919081815260200182805461127e906151ab565b80156112cb5780601f106112a0576101008083540402835291602001916112cb565b820191906000526020600020905b8154815290600101906020018083116112ae57829003601f168201915b50505050508060200190518101906112e3919061533d565b9392505050565b600080600080600080600087806020019051810190611309919061541d565b600154604051633404591760e21b815260048101899052979e50959c50939a509198509650945092506000916001600160a01b039091169063d011645c90602401602060405180830381865afa158015611367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138b919061533d565b9050336001546040516331a9108f60e11b8152600481018b90526001600160a01b039283169290911690636352211e90602401602060405180830381865afa1580156113db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ff919061549f565b6001600160a01b0316146114265760405163158980c760e21b815260040160405180910390fd5b6001600160a01b03821661144d57604051639792926760e01b815260040160405180910390fd5b825160000361146f57604051631c30bb4d60e01b815260040160405180910390fd5b600a61147f6001831b6007615378565b6114899190615356565b87118061149857506001811b86115b156114b657604051632160733960e01b815260040160405180910390fd5b60048054600091826114c783615309565b909155506000818152600a602081905260409182902082516060810190935292935081906114f96001871b6002615378565b6115039190615356565b8152602001868152602001856001600160a01b031681525081600f0160008201518160000155602082015181600101908161153e9190615233565b5060409182015160029190910180546001600160a01b0319166001600160a01b0390921691909117905560128201805460ff19166001179055805160a0810182528b8152602081018590529081018a90526060810189905260808101336001600160a01b039081169091528151600a840155602080830151600b850155604080840151600c860155606080850151600d870155608094850151600e870180546001600160a01b031916919095161790935560048086018c905560008781526008845282812054835160e08101855281815280860183815281860184815260001998830198895286518089018852858152998301998a5260a0830185905260c083018590528b8552600988528685208486529097529490922082518155935160018501559351600284015593516003830155935191939091908201906116839082615233565b5060a082015160058201805460ff191660018360048111156116a7576116a7614b94565b021790555060c09190910151600590910180549115156101000261ff001990921691909117905560008381526008602052604081208054916116e883615309565b91905055506000805160206157618339815191528382600060405161170f93929190615322565b60405180910390a16001546001600160a01b03166342842e0e33308e6040518463ffffffff1660e01b8152600401611749939291906154bc565b600060405180830381600087803b15801561176357600080fd5b505af1158015611777573d6000803e3d6000fd5b505050508660001461178d5761178d83886135a0565b6040518381527fe2d77c4a35bb326277ff28842c7df62528e9dfdf2fbd905b6847260baaa1544f9060200160405180910390a1505050505050505050505050565b6000818152600a602052604081206003549091906001600160a01b031662fdd58e3384600301546040518363ffffffff1660e01b81526004016118129291906153a2565b602060405180830381865afa15801561182f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611853919061533d565b9050806000036118765760405163bfe6236760e01b815260040160405180910390fd5b6003546001600160a01b031663f242432a33308560030154856040518563ffffffff1660e01b81526004016118ae94939291906154e0565b600060405180830381600087803b1580156118c857600080fd5b505af11580156118dc573d6000803e3d6000fd5b50505060008481526006602090815260408083203384529091528120805484935090919061190b908490615518565b9091555050505050565b600083815260066020908152604080832033845290915281205484910361194f5760405163bfe6236760e01b815260040160405180910390fd5b6000848152600960209081526040808320868452909152902060036000868152600a602052604090206012015460ff16600381111561199057611990614b94565b036119ae57604051633cb1a52960e11b815260040160405180910390fd5b80541580156119bc57508315155b156119da5760405163e200563560e01b815260040160405180910390fd5b6005810154610100900460ff1615611a05576040516331b7690560e21b815260040160405180910390fd5b8060030154421115611a2a5760405163e7110eeb60e01b815260040160405180910390fd5b600085815260076020908152604080832084548452825280832033845290915290205460ff1615611a6e57604051633526430d60e21b815260040160405180910390fd5b600085815260076020908152604080832084548452825280832033808552908352818420805460ff191660011790558884526006835281842090845290915290205483611ad45780826002016000828254611ac99190615518565b925050819055611aef565b80826001016000828254611ae89190615518565b9250508190555b506003546000878152600a60205260408082206001015490516314bd9ae160e21b815291926001600160a01b0316916352f66b8491611b349160040190815260200190565b602060405180830381865afa158015611b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b75919061533d565b90506000600584015460ff166004811115611b9257611b92614b94565b1480611bb657506003600584015460ff166004811115611bb457611bb4614b94565b145b15611bfd57670de0b6b3a764000060055482611bd29190615378565b611bdc9190615356565b836001015410611bf85760058301805461ff0019166101001790555b611c4f565b670de0b6b3a7640000600554600183901c611c189190615378565b611c229190615356565b85611c31578360020154611c37565b83600101545b1115611c4f5760058301805461ff0019166101001790555b6005830154610100900460ff1615611cb3578415611c7157611c718787613a38565b60408051888152602081018890528615158183015290517fb8ac4a4d36edbe09a20cdee3233447c1f9f8b2f96df83a710544665a6265c6349181900360600190a15b604080518881523360208201529081018790527f8b6f11e195d2a98aa7565e5689a460bfaaf522a64ccabb05adc3d8323066e208906060015b60405180910390a150505050505050565b600060026111dc565b60036000828152600a602052604090206012015460ff166003811115611d2e57611d2e614b94565b03611d4c57604051633cb1a52960e11b815260040160405180910390fd5b6000818152600a6020908152604080832060068352818420338086529352818420805494905560038054908201549251637921219560e11b81529194936001600160a01b039091169263f242432a92611dad923092909187906004016154e0565b600060405180830381600087803b158015611dc757600080fd5b505af1158015611ddb573d6000803e3d6000fd5b50505050505050565b60006001600084815260096020908152604080832086845290915290206005015460ff166004811115611e1957611e19614b94565b14611e375760405163e200563560e01b815260040160405180910390fd5b600083815260096020908152604080832085845290915290206004018054611e5e906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8a906151ab565b8015611ed75780601f10611eac57610100808354040283529160200191611ed7565b820191906000526020600020905b815481529060010190602001808311611eba57829003601f168201915b5050505050806020019051810190610ab9919061552b565b600354604051631819659760e01b81526004810185905233916001600160a01b031690631819659790602401602060405180830381865afa158015611f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5c919061549f565b6001600160a01b031614611f835760405163d47118cb60e01b815260040160405180910390fd5b600354604051634e8c72a160e11b8152600481018590526001600160a01b0390911690639d18e54290602401602060405180830381865afa158015611fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff091906153bb565b61200d57604051633022989960e01b815260040160405180910390fd5b6001600160a01b03821661203457604051639792926760e01b815260040160405180910390fd5b60008061204085613b05565b9150915080612062576040516329f38e3f60e21b815260040160405180910390fd5b600480546000918261207383615309565b909155506040805160a081019182905260035463174a4e2d60e21b90925260a4810189905291925081906001600160a01b0316635d2938b460c48301602060405180830381865afa1580156120cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f0919061533d565b6120fd9062015180615518565b815260208101889052604001612114886002615378565b8152602001612124886002615378565b61212f906001615518565b815260209081018590526000838152600a825260408082208451815592840151600184015583810151600284015560608401516003808501919091556080909401516004938401559254925163637c77f160e01b8152918201899052916001600160a01b03169063637c77f190602401602060405180830381865afa1580156121bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e0919061533d565b600354604051632cd3581b60e11b8152600481018a90529192506000916001600160a01b03909116906359a6b03690602401602060405180830381865afa15801561222f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612253919061533d565b600154604051633404591760e21b8152600481018590529192506000916001600160a01b039091169063d011645c90602401602060405180830381865afa1580156122a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c6919061533d565b6002546040516392680e9560e01b8152600481018590529192506000916001600160a01b03909116906392680e9590602401602060405180830381865afa158015612315573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123399190615572565b6003546040516327143fdd60e21b8152600481018d905260ff9290921692506000916001600160a01b0390911690639c50ff7490602401602060405180830381865afa15801561238d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b1919061533d565b90508282146123d35760405163042c06c160e51b815260040160405180910390fd5b6040518060a00160405280868152602001848152602001600a8360076123f99190615378565b6124039190615356565b8152602001828152602001336001600160a01b0316815250600a6000888152602001908152602001600020600a016000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050506040518060a001604052808581526020018381526020016000815260200160008152602001336001600160a01b0316815250600a60008881526020019081526020016000206005016000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050506040518060600160405280600a8360026125439190615378565b61254d9190615356565b815260208082018c90526001600160a01b038d166040928301526000898152600a8252919091208251600f8201908155918301516010909101906125919082615233565b50604091820151600291820180546001600160a01b0319166001600160a01b039283161790556000898152600a602081905293902060128101805460ff1916600117905560038054919093015491169263f242432a923392309290916125f8908890615378565b6126029190615356565b6040518563ffffffff1660e01b815260040161262194939291906154e0565b600060405180830381600087803b15801561263b57600080fd5b505af115801561264f573d6000803e3d6000fd5b505050507fe2d77c4a35bb326277ff28842c7df62528e9dfdf2fbd905b6847260baaa1544f8660405161268491815260200190565b60405180910390a15050505050505050505050565b6000818152600a602052604090206003601282015460ff1660038111156126c2576126c2614b94565b146126e057604051637bf390dd60e11b815260040160405180910390fd5b6003805490820154604051627eeac760e11b81526000926001600160a01b03169162fdd58e916127149133916004016153a2565b602060405180830381865afa158015612731573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612755919061533d565b60008481526006602090815260408083203384529091529020549091508115801561277e575080155b1561279c5760405163bfe6236760e01b815260040160405180910390fd5b60035460018401546040516314bd9ae160e21b815260048101919091526000916001600160a01b0316906352f66b8490602401602060405180830381865afa1580156127ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612810919061533d565b600b8501549091506001901b6000826128298587615518565b6128339084615378565b61283d9190615356565b6000888152600660209081526040808320338452909152812055905084156128ce576003546001600160a01b031663f242432a3360038901546040516001600160e01b031960e085901b16815261289b929130918b906004016154e0565b600060405180830381600087803b1580156128b557600080fd5b505af11580156128c9573d6000803e3d6000fd5b505050505b6000546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061293a919061533d565b10156129595760405163c760602d60e01b815260040160405180910390fd5b6000546001600160a01b031663a9059cbb33836040518363ffffffff1660e01b81526004016129899291906153a2565b6020604051808303816000875af11580156129a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cc91906153bb565b5060408051888152602081018390527f4a190041baaa7b7da28a2bb3ad8330bdfb955271be9959517121bfb1c2900f549101611cec565b6000818152600a602090815260408083206001810154808552600b90935292205460ff1615612a455760405163bafab1af60e01b815260040160405180910390fd5b600354604051631819659760e01b81526004810183905230916001600160a01b031690631819659790602401602060405180830381865afa158015612a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab2919061549f565b6001600160a01b031614612ad95760405163d47118cb60e01b815260040160405180910390fd5b600354604051631d1a064960e11b81526001600160a01b0390911690633a340c9290612b0e9084906010870190600401615612565b600060405180830381600087803b158015612b2857600080fd5b505af1158015612b3c573d6000803e3d6000fd5b505050600091825250600b60209081526040808320805460ff19908116600117909155948352600a9091529020601201805490921660021790915550565b60606001600084815260096020908152604080832086845290915290206005015460ff166004811115612baf57612baf614b94565b14612bcd5760405163e200563560e01b815260040160405180910390fd5b600083815260096020908152604080832085845290915290206004018054612bf4906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054612c20906151ab565b8015612c6d5780601f10612c4257610100808354040283529160200191612c6d565b820191906000526020600020905b815481529060010190602001808311612c5057829003601f168201915b5050505050806020019051810190612c85919061552b565b509392505050565b6000818152600a60205260409020600e015481906001600160a01b03163314612cc95760405163158980c760e21b815260040160405180910390fd5b60016000838152600a602052604090206012015460ff166003811115612cf157612cf1614b94565b14612d0f57604051633949e7c760e21b815260040160405180910390fd5b612d1882613bd7565b5050565b612d2461491a565b6000828152600a6020818152604092839020835161016081018552815460c08201908152600183015460e08301526002830154610100830152600383015461012083015260048301546101408301528152845160a0818101875260058401548252600684015482860152600784015482880152600884015460608084019190915260098501546001600160a01b039081166080808601919091528588019490945288519283018952968501548252600b85015482870152600c85015482890152600d85015482820152600e85015490961691810191909152818601528451808501909552600f82018054865260108301805492969395870194919291840191612e2c906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054612e58906151ab565b8015612ea55780601f10612e7a57610100808354040283529160200191612ea5565b820191906000526020600020905b815481529060010190602001808311612e8857829003601f168201915b5050509183525050600291909101546001600160a01b0316602091820152908252601283015491019060ff166003811115612ee257612ee2614b94565b6003811115612ef357612ef3614b94565b81526020016013820154815250509050919050565b6000838152600660209081526040808320338452909152812054849103612f425760405163bfe6236760e01b815260040160405180910390fd5b6001600160a01b0382161580612f6057506001600160a01b03821630145b15612f7e57604051639792926760e01b815260040160405180910390fd5b428311612f9e57604051631da7447960e21b815260040160405180910390fd5b600084815260086020908152604080832054815160e081018352818152808401858152818401868152606083018a815285516001600160a01b038b1681890152865180820389018152908701875260808501908152600360a0860181905260c086018a90528d8a5260098952878a20878b52909852959097208351815591516001830155516002820155945193850193909355905190929060048201906130459082615233565b5060a082015160058201805460ff1916600183600481111561306957613069614b94565b021790555060c09190910151600590910180549115156101000261ff001990921691909117905560008581526008602052604081208054916130aa83615309565b9190505550600080516020615761833981519152858260036040516111c893929190615322565b80336002546040516331a9108f60e11b8152600481018490526001600160a01b039283169290911690636352211e90602401602060405180830381865afa158015613120573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613144919061549f565b6001600160a01b03161461316b57604051636b0c6fd160e01b815260040160405180910390fd5b60016000848152600a602052604090206012015460ff16600381111561319357613193614b94565b146131b157604051633949e7c760e21b815260040160405180910390fd5b6131bb83836135a0565b505050565b6003546000838152600a60205260408082206001015490516314bd9ae160e21b81526004810191909152909182916001600160a01b03909116906352f66b8490602401602060405180830381865afa158015613220573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613244919061533d565b9050600083600481111561325a5761325a614b94565b14806132775750600383600481111561327557613275614b94565b145b156132a557670de0b6b3a7640000600554826132939190615378565b61329d9190615356565b9150506108d2565b670de0b6b3a7640000600554600183901c6132939190615378565b6000818152600a6020526040902060018082015490601283015460ff1660038111156132ee576132ee614b94565b1461330c57604051633949e7c760e21b815260040160405180910390fd5b600354604051631819659760e01b81526004810183905230916001600160a01b031690631819659790602401602060405180830381865afa158015613355573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613379919061549f565b6001600160a01b0316146133a05760405163d47118cb60e01b815260040160405180910390fd5b600e8201546001600160a01b0316336001600160a01b0316146133d65760405163158980c760e21b815260040160405180910390fd5b60128201805460ff19166003908117909155546001600160a01b0316639732d56f82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401600060405180830381600087803b15801561344057600080fd5b505af1158015613454573d6000803e3d6000fd5b50506003546040516327143fdd60e21b815260048101859052600093506001600160a01b039091169150639c50ff7490602401602060405180830381865afa1580156134a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c8919061533d565b600380546000878152600a60208190526040909120600201549394506001600160a01b039091169263f242432a923092339291613506908890615378565b6135109190615356565b6040518563ffffffff1660e01b815260040161352f94939291906154e0565b600060405180830381600087803b15801561354957600080fd5b505af115801561355d573d6000803e3d6000fd5b505050507f0b021add1edbb328ed48ca0a1905c666ab931678b4a7602d219c496d174bf0258460405161359291815260200190565b60405180910390a150505050565b6000828152600a602052604080822060025491516392680e9560e01b8152600481018590529092916001600160a01b0316906392680e9590602401602060405180830381865afa1580156135f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361c9190615572565b600b83015460ff9190911691506001811b90821461364d5760405163042c06c160e51b815260040160405180910390fd5b60128301805460ff191660021790556040805160a08101825285815260208101849052600c8501549091820190600a613687856007615378565b6136919190615356565b61369b919061538f565b815260200184600a0160030154836136b3919061538f565b815233602091820152815160058601558181015160068601556040808301516007870155606083015160088701556080909201516009860180546001600160a01b0319166001600160a01b039283161790556003548351636da58de360e01b815293516000949190921692636da58de392600480840193829003018187875af1158015613744573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613768919061533d565b6000818152600b602052604090819020805460ff19166001179055805160a081019091529091508061379d4262015180615518565b8152602001828152602001600183901b8152602001600183901b60016137c39190615518565b8152600486018054602092830152825187559082015160018701556040820151600280880191909155606083015160038801556080909201519055546001600160a01b03166342842e0e3330886040518463ffffffff1660e01b815260040161382e939291906154bc565b600060405180830381600087803b15801561384857600080fd5b505af115801561385c573d6000803e3d6000fd5b505060025460035460405163095ea7b360e01b81526001600160a01b03928316945063095ea7b39350613897929091169089906004016153a2565b600060405180830381600087803b1580156138b157600080fd5b505af11580156138c5573d6000803e3d6000fd5b5050600154600354600a88015460405163095ea7b360e01b81526001600160a01b03938416955063095ea7b3945061390393909216916004016153a2565b600060405180830381600087803b15801561391d57600080fd5b505af1158015613931573d6000803e3d6000fd5b5050600354600a8701546004808901546040516306badddb60e21b81526001600160a01b039094169550631aeb776c9450613979938b939260019260108d019290910161562b565b600060405180830381600087803b15801561399357600080fd5b505af11580156139a7573d6000803e3d6000fd5b505050600985015460028601546003870154600788015460088901546139d995506001600160a01b0390941693613daa565b600e84015460028501546003860154600c870154600d880154613a08946001600160a01b031693929190613daa565b6040518681527ff2fb170bc0fd9ce44083044170a7f85cd4887f40565b5439b1886f8f5ec0264290602001610aa0565b600082815260096020908152604080832084845290915281206005015460ff1690816004811115613a6b57613a6b614b94565b03613a7957613a7983613edd565b6001816004811115613a8d57613a8d614b94565b03613a9c57613a9c8383613fb7565b6002816004811115613ab057613ab0614b94565b03613abf57613abf8383614144565b6003816004811115613ad357613ad3614b94565b03613ae257613ae2838361423e565b6004816004811115613af657613af6614b94565b036131bb576131bb83836144a5565b60035460408051602480820185905282518083039091018152604490910182526020810180516001600160e01b03166323f0aa7160e11b17905290516000928392839283926001600160a01b031691613b5d91615664565b600060405180830381855afa9150503d8060008114613b98576040519150601f19603f3d011682016040523d82523d6000602084013e613b9d565b606091505b509150915081613bc057604051633022989960e01b815260040160405180910390fd5b61016081015193506101a081015192505050915091565b6000818152600a60205260408120906002601283015460ff166003811115613c0157613c01614b94565b60128401805460ff1916600317905514905080613c8e57600154600e830154600a840154604051632142170760e11b81526001600160a01b03938416936342842e0e93613c5793309392909116916004016154bc565b600060405180830381600087803b158015613c7157600080fd5b505af1158015613c85573d6000803e3d6000fd5b50505050613d72565b60025460098301546005840154604051632142170760e11b81526001600160a01b03938416936342842e0e93613ccd93309392909116916004016154bc565b600060405180830381600087803b158015613ce757600080fd5b505af1158015613cfb573d6000803e3d6000fd5b50505050613d0883614603565b600154600a83015460405163db006a7560e01b81526001600160a01b039092169163db006a7591613d3f9160040190815260200190565b600060405180830381600087803b158015613d5957600080fd5b505af1158015613d6d573d6000803e3d6000fd5b505050505b6040518381527f0b021add1edbb328ed48ca0a1905c666ab931678b4a7602d219c496d174bf0259060200160405180910390a1505050565b604080516002808252606082018352600092602083019080368337019050509050828282600081518110613de057613de0615680565b6020026020010183600181518110613dfa57613dfa615680565b60209081029190910101919091525260408051600280825260608201909252600091816020016020820280368337019050509050858582600081518110613e4357613e43615680565b6020026020010183600181518110613e5d57613e5d615680565b602090810291909101019190915252600354604051631759616b60e11b81526001600160a01b0390911690632eb2c2d690613ea29030908b90869088906004016156d1565b600060405180830381600087803b158015613ebc57600080fd5b505af1158015613ed0573d6000803e3d6000fd5b5050505050505050505050565b6000818152600a6020526040902054421015613f0c57604051631b64953f60e11b815260040160405180910390fd5b6003546000828152600a602052604090819020600101549051631444354960e01b81526001600160a01b0390921691631444354991613f519160040190815260200190565b600060405180830381600087803b158015613f6b57600080fd5b505af1158015613f7f573d6000803e3d6000fd5b50505050613f8c81613bd7565b600080516020615741833981519152816000604051613fac92919061572c565b60405180910390a150565b6000828152600a60205260409020613fce83614603565b600083815260096020908152604080832085845290915281206004018054829190613ff8906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054614024906151ab565b80156140715780601f1061404657610100808354040283529160200191614071565b820191906000526020600020905b81548152906001019060200180831161405457829003601f168201915b5050505050806020019051810190614089919061552b565b6011850180546001600160a01b0319166001600160a01b0383161790559092509050601083016140b98382615233565b506003546001840154604051631d1a064960e11b81526001600160a01b0390921691633a340c92916140f2916010880190600401615612565b600060405180830381600087803b15801561410c57600080fd5b505af1158015614120573d6000803e3d6000fd5b505050506000805160206157418339815191528560016040516111c892919061572c565b60008281526009602090815260408083208484529091529020600401805461416b906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054614197906151ab565b80156141e45780601f106141b9576101008083540402835291602001916141e4565b820191906000526020600020905b8154815290600101906020018083116141c757829003601f168201915b50505050508060200190518101906141fc919061533d565b6000838152600a602052604090819020600f0191909155516000805160206157418339815191529061423290849060029061572c565b60405180910390a15050565b6000828152600a6020908152604080832060128101805460ff19166003179055600983528184208585529092528220600401805491929161427e906151ab565b80601f01602080910402602001604051908101604052809291908181526020018280546142aa906151ab565b80156142f75780601f106142cc576101008083540402835291602001916142f7565b820191906000526020600020905b8154815290600101906020018083116142da57829003601f168201915b505050505080602001905181019061430f919061549f565b6003546001840154604051639732d56f60e01b815260048101919091526001600160a01b038084166024830152929350911690639732d56f90604401600060405180830381600087803b15801561436557600080fd5b505af1158015614379573d6000803e3d6000fd5b5050505061438684614603565b60028201546003808401549054604051627eeac760e11b8152614485938593909290916001600160a01b039091169062fdd58e906143ca90309086906004016153a2565b602060405180830381865afa1580156143e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061440b919061533d565b6003805490880154604051627eeac760e11b81526001600160a01b039092169162fdd58e9161443f913091906004016153a2565b602060405180830381865afa15801561445c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614480919061533d565b613daa565b60008051602061574183398151915284600360405161359292919061572c565b6000828152600960209081526040808320848452909152902060040180546144cc906151ab565b80601f01602080910402602001604051908101604052809291908181526020018280546144f8906151ab565b80156145455780601f1061451a57610100808354040283529160200191614545565b820191906000526020600020905b81548152906001019060200180831161452857829003601f168201915b505050505080602001905181019061455d919061533d565b6000838152600a6020526040908190206004808201849055600354600190920154925163f7ce46b760e01b81526001600160a01b039092169363f7ce46b7936145b193909201918252602082015260400190565b600060405180830381600087803b1580156145cb57600080fd5b505af11580156145df573d6000803e3d6000fd5b5050505060008051602061574183398151915282600460405161423292919061572c565b6000818152600a6020526040808220825491516370a0823160e01b81523060048201529092916001600160a01b0316906370a0823190602401602060405180830381865afa158015614659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061467d919061533d565b600354600184015460405163f62b46c960e01b815260048101919091529192506001600160a01b03169063f62b46c990602401600060405180830381600087803b1580156146ca57600080fd5b505af19250505080156146db575060015b614771573d808015614709576040519150601f19603f3d011682016040523d82523d6000602084013e61470e565b606091505b50805160208083019190912060408051600481526024810190915291820180516001600160e01b03166374d4d10160e11b17815291519091201461476f578060405162461bcd60e51b81526004016147669190614f9b565b60405180910390fd5b505b600080546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156147ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147de919061533d565b905060006147ec838361538f565b600b850154600f860154919250600091600a916001901b9061480e9085615378565b6148189190615356565b614823906003615378565b61482d9190615356565b9050614839818361538f565b85601301600082825461484c9190615518565b9091555050600054601186015460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb926148899291169085906004016153a2565b6020604051808303816000875af11580156148a8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddb91906153bb565b6040518060e0016040528060008152602001600081526020016000815260200160008152602001606081526020016000600481111561490d5761490d614b94565b8152600060209091015290565b6040518060c001604052806149576040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b81526020016149646149b7565b81526020016149716149b7565b81526020016149a36040518060600160405280600081526020016060815260200160006001600160a01b031681525090565b815260200160008152602001600081525090565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b600060208284031215614a0157600080fd5b81356001600160e01b0319811681146112e357600080fd5b60008060408385031215614a2c57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614a7a57614a7a614a3b565b604052919050565b600067ffffffffffffffff821115614a9c57614a9c614a3b565b50601f01601f191660200190565b600082601f830112614abb57600080fd5b8135614ace614ac982614a82565b614a51565b818152846020838601011115614ae357600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b0381168114614b1557600080fd5b50565b60008060008060808587031215614b2e57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115614b5357600080fd5b614b5f87828801614aaa565b9250506060850135614b7081614b00565b939692955090935050565b600060208284031215614b8d57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60048110614bba57614bba614b94565b9052565b602081016108d28284614baa565b60008060008060808587031215614be257600080fd5b8435614bed81614b00565b93506020850135614bfd81614b00565b925060408501359150606085013567ffffffffffffffff811115614c2057600080fd5b614c2c87828801614aaa565b91505092959194509250565b60008060408385031215614c4b57600080fd5b823591506020830135614c5d81614b00565b809150509250929050565b600080600060608486031215614c7d57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215614ca957600080fd5b83359250602084013591506040840135614cc281614b00565b809150509250925092565b60005b83811015614ce8578181015183820152602001614cd0565b50506000910152565b60008151808452614d09816020860160208601614ccd565b601f01601f19169290920160200192915050565b60058110614bba57614bba614b94565b60408152825160408201526020830151606082015260408301516080820152606083015160a08201526000608084015160e060c0840152614d72610120840182614cf1565b905060a0850151614d8660e0850182614d1d565b5060c0949094015115156101008301525090151560209091015290565b600060208284031215614db557600080fd5b813567ffffffffffffffff811115614dcc57600080fd5b610ab984828501614aaa565b8015158114614b1557600080fd5b600080600060608486031215614dfb57600080fd5b83359250602084013591506040840135614cc281614dd8565b600080600060608486031215614e2957600080fd5b833592506020840135614e3b81614b00565b9150604084013567ffffffffffffffff811115614e5757600080fd5b614e6386828701614aaa565b9150509250925092565b600082601f830112614e7e57600080fd5b8135602067ffffffffffffffff821115614e9a57614e9a614a3b565b8160051b614ea9828201614a51565b9283528481018201928281019087851115614ec357600080fd5b83870192505b84831015614ee257823582529183019190830190614ec9565b979650505050505050565b600080600080600060a08688031215614f0557600080fd5b8535614f1081614b00565b94506020860135614f2081614b00565b9350604086013567ffffffffffffffff80821115614f3d57600080fd5b614f4989838a01614e6d565b94506060880135915080821115614f5f57600080fd5b614f6b89838a01614e6d565b93506080880135915080821115614f8157600080fd5b50614f8e88828901614aaa565b9150509295509295909350565b6020815260006112e36020830184614cf1565b805182526000602082015160606020850152614fcd6060850182614cf1565b6040938401516001600160a01b0316949093019390935250919050565b602081526000825180516020840152602081015160408401526040810151606084015260608101516080840152608081015160a084015250602083015161506560c0840182805182526020808201519083015260408082015190830152606080820151908301526080908101516001600160a01b0316910152565b5060408381015180516101608501526020810151610180850152908101516101a084015260608101516101c084015260808101516001600160a01b03166101e0840152506060830151610240806102008501526150c6610260850183614fae565b915060808501516150db610220860182614baa565b5060a0949094015192909301919091525090565b6000806040838503121561510257600080fd5b82359150602083013560058110614c5d57600080fd5b600080600080600060a0868803121561513057600080fd5b853561513b81614b00565b9450602086013561514b81614b00565b93506040860135925060608601359150608086013567ffffffffffffffff81111561517557600080fd5b614f8e88828901614aaa565b6040815260006151946040830185614cf1565b905060018060a01b03831660208301529392505050565b600181811c908216806151bf57607f821691505b6020821081036151df57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156131bb57600081815260208120601f850160051c8101602086101561520c5750805b601f850160051c820191505b8181101561522b57828155600101615218565b505050505050565b815167ffffffffffffffff81111561524d5761524d614a3b565b6152618161525b84546151ab565b846151e5565b602080601f831160018114615296576000841561527e5750858301515b600019600386901b1c1916600185901b17855561522b565b600085815260208120601f198616915b828110156152c5578886015182559484019460019091019084016152a6565b50858210156152e35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b60006001820161531b5761531b6152f3565b5060010190565b8381526020810183905260608101610ab96040830184614d1d565b60006020828403121561534f57600080fd5b5051919050565b60008261537357634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108d2576108d26152f3565b818103818111156108d2576108d26152f3565b6001600160a01b03929092168252602082015260400190565b6000602082840312156153cd57600080fd5b81516112e381614dd8565b600082601f8301126153e957600080fd5b81516153f7614ac982614a82565b81815284602083860101111561540c57600080fd5b610ab9826020830160208701614ccd565b600080600080600080600060e0888a03121561543857600080fd5b875196506020880151955060408801519450606088015193506080880151925060a088015167ffffffffffffffff81111561547257600080fd5b61547e8a828b016153d8565b92505060c088015161548f81614b00565b8091505092959891949750929550565b6000602082840312156154b157600080fd5b81516112e381614b00565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b808201808211156108d2576108d26152f3565b6000806040838503121561553e57600080fd5b825167ffffffffffffffff81111561555557600080fd5b615561858286016153d8565b9250506020830151614c5d81614b00565b60006020828403121561558457600080fd5b815160ff811681146112e357600080fd5b600081546155a2816151ab565b8085526020600183811680156155bf57600181146155d957615607565b60ff1985168884015283151560051b880183019550615607565b866000528260002060005b858110156155ff5781548a82018601529083019084016155e4565b890184019650505b505050505092915050565b828152604060208201526000610ab96040830184615595565b858152846020820152831515604082015260a06060820152600061565260a0830185615595565b90508260808301529695505050505050565b60008251615676818460208701614ccd565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156156c6578151875295820195908201906001016156aa565b509495945050505050565b6001600160a01b0385811682528416602082015260a0604082018190526000906156fd90830185615696565b828103606084015261570f8185615696565b838103608090940193909352505060008152602001949350505050565b828152604081016112e36020830184614d1d56fe0131395fc2023e9f088126b582709c056a327bb71617c4c4eceddafa98a0e2d335f68360d987e6ac1824ca88be7cd548a5e6e7b37ed928147ca1e92ddff1981ba26469706673582212205fc0f076edfef5a7f64d5c37d4f858ab6986cc54a2dd88ba23d69433f093601564736f6c634300081300330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea7b7dc089c9a4a916b5a7a37617f59fd54e37e400000000000000000000000021468e63abf3783020750f7b2e57d4b34afafba6000000000000000000000000d32cb5f76989a27782e44c5297aaba728ad616690000000000000000000000004bfba79cf232361a53eddd17c67c6c77a6f00379

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c80637d2c1bc411610182578063cc5b60f2116100e9578063d7b53a0e116100a2578063e7039a841161007c578063e7039a841461082e578063ef7ec0011461085c578063f23a6e611461086f578063f482e9621461088e57600080fd5b8063d7b53a0e146107e6578063d92b3456146107f9578063ddcbde9a1461080a57600080fd5b8063cc5b60f214610749578063cce84c8a1461075c578063cf2bd5981461077c578063d17fafb11461078f578063d4696177146107a0578063d577d06d146107c357600080fd5b8063b5348aa91161013b578063b5348aa9146106b8578063bc197c81146106c1578063c0c68a6b146106e0578063c0d700fd146106f3578063c143249614610706578063c1474a3b1461072957600080fd5b80637d2c1bc4146105f257806383d845e21461064b5780638a5d70941461065e57806393bf51a2146106815780639518a2b5146106945780639eb40277146106a557600080fd5b806346feda08116102265780636b3048cc116101df5780636b3048cc146105105780636c975f461461053c5780636e8153ae1461054f57806372a127f91461057b578063739e340d146105bb5780637b48227a146105c457600080fd5b806346feda08146104815780634cb77103146104a15780635d02c5e3146104b457806361271e13146104c75780636811a5c0146104da5780636a18ff7a146104fd57600080fd5b8063199789fb11610278578063199789fb146103d65780631b2522bc146103e95780632f7c5eeb146103fc578063337d12041461042157806340368d0c1461044257806342f39a3d1461046e57600080fd5b806301ffc9a7146102c05780630a8f2a65146102e857806310f7c9861461031e578063115cd40914610333578063150b7a02146103665780631864472614610392575b600080fd5b6102d36102ce3660046149ef565b6108a1565b60405190151581526020015b60405180910390f35b6102d36102f6366004614a19565b6000918252600960209081526040808420928452919052902060050154610100900460ff1690565b61033161032c366004614b18565b6108d8565b005b610359610341366004614b7b565b6000908152600a602052604090206012015460ff1690565b6040516102df9190614bbe565b610379610374366004614bcc565b610ab0565b6040516001600160e01b031990911681526020016102df565b6103c86103a0366004614c38565b60009182526006602090815260408084206001600160a01b0393909316845291905290205490565b6040519081526020016102df565b6103316103e4366004614c68565b610ac1565b6103316103f7366004614b7b565b610d34565b6003546001600160a01b03165b6040516001600160a01b0390911681526020016102df565b61043461042f366004614c94565b610e9b565b6040516102df929190614d2d565b610409610450366004614b7b565b6000908152600a60205260409020600e01546001600160a01b031690565b61033161047c366004614c68565b611003565b6103c861048f366004614b7b565b60009081526008602052604090205490565b6103c86104af366004614a19565b6111d7565b6103316104c2366004614da3565b6112ea565b6103316104d5366004614b7b565b6117ce565b6103c86104e8366004614b7b565b6000908152600a602052604090206004015490565b61033161050b366004614de6565b611915565b61040961051e366004614b7b565b6000908152600a60205260409020601101546001600160a01b031690565b6103c861054a366004614a19565b611cfd565b61040961055d366004614b7b565b6000908152600a60205260409020600901546001600160a01b031690565b6102d3610589366004614c94565b60009283526007602090815260408085209385529281528284206001600160a01b039290921684525290205460ff1690565b6103c860045481565b6103c86105d2366004614a19565b600091825260096020908152604080842092845291905290206002015490565b600054600154600254600354610618936001600160a01b03908116938116928116911684565b604080516001600160a01b03958616815293851660208501529184169183019190915290911660608201526080016102df565b610331610659366004614b7b565b611d06565b6103c861066c366004614b7b565b6000908152600a602052604090206006015490565b61040961068f366004614a19565b611de4565b6000546001600160a01b0316610409565b6103316106b3366004614e14565b611eef565b6103c860055481565b6103796106cf366004614eed565b63bc197c8160e01b95945050505050565b6103316106ee366004614b7b565b612699565b610331610701366004614b7b565b612a03565b6103c8610714366004614b7b565b6000908152600a60205260409020600b015490565b61073c610737366004614a19565b612b7a565b6040516102df9190614f9b565b610331610757366004614b7b565b612c8d565b61076f61076a366004614b7b565b612d1c565b6040516102df9190614fea565b61033161078a366004614c94565b612f08565b6001546001600160a01b0316610409565b6103c86107ae366004614b7b565b6000908152600a602052604090206005015490565b6103c86107d1366004614b7b565b6000908152600a60205260409020600f015490565b6103316107f4366004614a19565b6130d1565b6002546001600160a01b0316610409565b6103c8610818366004614b7b565b6000908152600a60208190526040909120015490565b6103c861083c366004614a19565b600091825260096020908152604080842092845291905290206001015490565b6103c861086a3660046150ef565b6131c0565b61037961087d366004615118565b63f23a6e6160e01b95945050505050565b61033161089c366004614b7b565b6132c0565b60006001600160e01b03198216630271189760e51b14806108d257506301ffc9a760e01b6001600160e01b03198316145b92915050565b60008481526006602090815260408083203384529091528120548591036109125760405163bfe6236760e01b815260040160405180910390fd5b6001600160a01b03821661093957604051639792926760e01b815260040160405180910390fd5b42841161095957604051631da7447960e21b815260040160405180910390fd5b6000600860008781526020019081526020016000205490506040518060e00160405280828152602001600081526020016000815260200186815260200185856040516020016109a9929190615181565b60408051601f19818403018152919052815260200160018152600060209182018190528881526009825260408082208583528352908190208351815591830151600183015582015160028201556060820151600382015560808201516004820190610a149082615233565b5060a082015160058201805460ff19166001836004811115610a3857610a38614b94565b021790555060c09190910151600590910180549115156101000261ff00199092169190911790556000868152600860205260408120805491610a7983615309565b919050555060008051602061576183398151915286826001604051610aa093929190615322565b60405180910390a1505050505050565b630a85bd0160e11b5b949350505050565b6000838152600660209081526040808320338452909152812054849103610afb5760405163bfe6236760e01b815260040160405180910390fd5b6003546000858152600a60205260408082206001015490516327143fdd60e21b815291926001600160a01b031691639c50ff7491610b3f9160040190815260200190565b602060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b80919061533d565b9050610b8d600a82615356565b831080610baf5750600a610ba2826003615378565b610bac9190615356565b83115b15610bcd57604051632160733960e01b815260040160405180910390fd5b428411610bed57604051631da7447960e21b815260040160405180910390fd5b6000600860008781526020019081526020016000205490506040518060e00160405280828152602001600081526020016000815260200186815260200185604051602001610c3d91815260200190565b60408051601f19818403018152919052815260200160028152600060209182018190528881526009825260408082208583528352908190208351815591830151600183015582015160028201556060820151600382015560808201516004820190610ca89082615233565b5060a082015160058201805460ff19166001836004811115610ccc57610ccc614b94565b021790555060c09190910151600590910180549115156101000261ff00199092169190911790556000868152600860205260408120805491610d0d83615309565b919050555060008051602061576183398151915286826002604051610aa093929190615322565b6000818152600a602052604090206003601282015460ff166003811115610d5d57610d5d614b94565b14610d7b57604051637bf390dd60e11b815260040160405180910390fd5b6013810154600181901c90600090610d9490839061538f565b60006013850181905554600e85015460405163a9059cbb60e01b81529293506001600160a01b039182169263a9059cbb92610dd592169086906004016153a2565b6020604051808303816000875af1158015610df4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1891906153bb565b50600054600984015460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92610e519291169085906004016153a2565b6020604051808303816000875af1158015610e70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9491906153bb565b5050505050565b610ea36148cc565b600084815260096020908152604080832086845282528083208784526007835281842087855283528184206001600160a01b0387168552835281842054825160e0810184528254815260018301549481019490945260028201549284019290925260038101546060840152600481018054919360ff909316929184916080840191610f2d906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054610f59906151ab565b8015610fa65780601f10610f7b57610100808354040283529160200191610fa6565b820191906000526020600020905b815481529060010190602001808311610f8957829003601f168201915b5050509183525050600582015460209091019060ff166004811115610fcd57610fcd614b94565b6004811115610fde57610fde614b94565b815260059190910154610100900460ff16151560209091015297909650945050505050565b600083815260066020908152604080832033845290915281205484910361103d5760405163bfe6236760e01b815260040160405180910390fd5b620151808210156110615760405163363d956160e11b815260040160405180910390fd5b42831161108157604051631da7447960e21b815260040160405180910390fd5b6000600860008681526020019081526020016000205490506040518060e001604052808281526020016000815260200160008152602001858152602001846040516020016110d191815260200190565b60408051601f1981840301815291905281526020016004815260006020918201819052878152600982526040808220858352835290819020835181559183015160018301558201516002820155606082015160038201556080820151600482019061113c9082615233565b5060a082015160058201805460ff1916600183600481111561116057611160614b94565b021790555060c09190910151600590910180549115156101000261ff001990921691909117905560008581526008602052604081208054916111a183615309565b9190505550600080516020615761833981519152858260046040516111c893929190615322565b60405180910390a15050505050565b600060045b600084815260096020908152604080832086845290915290206005015460ff16600481111561120d5761120d614b94565b1461122b5760405163e200563560e01b815260040160405180910390fd5b600083815260096020908152604080832085845290915290206004018054611252906151ab565b80601f016020809104026020016040519081016040528092919081815260200182805461127e906151ab565b80156112cb5780601f106112a0576101008083540402835291602001916112cb565b820191906000526020600020905b8154815290600101906020018083116112ae57829003601f168201915b50505050508060200190518101906112e3919061533d565b9392505050565b600080600080600080600087806020019051810190611309919061541d565b600154604051633404591760e21b815260048101899052979e50959c50939a509198509650945092506000916001600160a01b039091169063d011645c90602401602060405180830381865afa158015611367573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138b919061533d565b9050336001546040516331a9108f60e11b8152600481018b90526001600160a01b039283169290911690636352211e90602401602060405180830381865afa1580156113db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ff919061549f565b6001600160a01b0316146114265760405163158980c760e21b815260040160405180910390fd5b6001600160a01b03821661144d57604051639792926760e01b815260040160405180910390fd5b825160000361146f57604051631c30bb4d60e01b815260040160405180910390fd5b600a61147f6001831b6007615378565b6114899190615356565b87118061149857506001811b86115b156114b657604051632160733960e01b815260040160405180910390fd5b60048054600091826114c783615309565b909155506000818152600a602081905260409182902082516060810190935292935081906114f96001871b6002615378565b6115039190615356565b8152602001868152602001856001600160a01b031681525081600f0160008201518160000155602082015181600101908161153e9190615233565b5060409182015160029190910180546001600160a01b0319166001600160a01b0390921691909117905560128201805460ff19166001179055805160a0810182528b8152602081018590529081018a90526060810189905260808101336001600160a01b039081169091528151600a840155602080830151600b850155604080840151600c860155606080850151600d870155608094850151600e870180546001600160a01b031916919095161790935560048086018c905560008781526008845282812054835160e08101855281815280860183815281860184815260001998830198895286518089018852858152998301998a5260a0830185905260c083018590528b8552600988528685208486529097529490922082518155935160018501559351600284015593516003830155935191939091908201906116839082615233565b5060a082015160058201805460ff191660018360048111156116a7576116a7614b94565b021790555060c09190910151600590910180549115156101000261ff001990921691909117905560008381526008602052604081208054916116e883615309565b91905055506000805160206157618339815191528382600060405161170f93929190615322565b60405180910390a16001546001600160a01b03166342842e0e33308e6040518463ffffffff1660e01b8152600401611749939291906154bc565b600060405180830381600087803b15801561176357600080fd5b505af1158015611777573d6000803e3d6000fd5b505050508660001461178d5761178d83886135a0565b6040518381527fe2d77c4a35bb326277ff28842c7df62528e9dfdf2fbd905b6847260baaa1544f9060200160405180910390a1505050505050505050505050565b6000818152600a602052604081206003549091906001600160a01b031662fdd58e3384600301546040518363ffffffff1660e01b81526004016118129291906153a2565b602060405180830381865afa15801561182f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611853919061533d565b9050806000036118765760405163bfe6236760e01b815260040160405180910390fd5b6003546001600160a01b031663f242432a33308560030154856040518563ffffffff1660e01b81526004016118ae94939291906154e0565b600060405180830381600087803b1580156118c857600080fd5b505af11580156118dc573d6000803e3d6000fd5b50505060008481526006602090815260408083203384529091528120805484935090919061190b908490615518565b9091555050505050565b600083815260066020908152604080832033845290915281205484910361194f5760405163bfe6236760e01b815260040160405180910390fd5b6000848152600960209081526040808320868452909152902060036000868152600a602052604090206012015460ff16600381111561199057611990614b94565b036119ae57604051633cb1a52960e11b815260040160405180910390fd5b80541580156119bc57508315155b156119da5760405163e200563560e01b815260040160405180910390fd5b6005810154610100900460ff1615611a05576040516331b7690560e21b815260040160405180910390fd5b8060030154421115611a2a5760405163e7110eeb60e01b815260040160405180910390fd5b600085815260076020908152604080832084548452825280832033845290915290205460ff1615611a6e57604051633526430d60e21b815260040160405180910390fd5b600085815260076020908152604080832084548452825280832033808552908352818420805460ff191660011790558884526006835281842090845290915290205483611ad45780826002016000828254611ac99190615518565b925050819055611aef565b80826001016000828254611ae89190615518565b9250508190555b506003546000878152600a60205260408082206001015490516314bd9ae160e21b815291926001600160a01b0316916352f66b8491611b349160040190815260200190565b602060405180830381865afa158015611b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b75919061533d565b90506000600584015460ff166004811115611b9257611b92614b94565b1480611bb657506003600584015460ff166004811115611bb457611bb4614b94565b145b15611bfd57670de0b6b3a764000060055482611bd29190615378565b611bdc9190615356565b836001015410611bf85760058301805461ff0019166101001790555b611c4f565b670de0b6b3a7640000600554600183901c611c189190615378565b611c229190615356565b85611c31578360020154611c37565b83600101545b1115611c4f5760058301805461ff0019166101001790555b6005830154610100900460ff1615611cb3578415611c7157611c718787613a38565b60408051888152602081018890528615158183015290517fb8ac4a4d36edbe09a20cdee3233447c1f9f8b2f96df83a710544665a6265c6349181900360600190a15b604080518881523360208201529081018790527f8b6f11e195d2a98aa7565e5689a460bfaaf522a64ccabb05adc3d8323066e208906060015b60405180910390a150505050505050565b600060026111dc565b60036000828152600a602052604090206012015460ff166003811115611d2e57611d2e614b94565b03611d4c57604051633cb1a52960e11b815260040160405180910390fd5b6000818152600a6020908152604080832060068352818420338086529352818420805494905560038054908201549251637921219560e11b81529194936001600160a01b039091169263f242432a92611dad923092909187906004016154e0565b600060405180830381600087803b158015611dc757600080fd5b505af1158015611ddb573d6000803e3d6000fd5b50505050505050565b60006001600084815260096020908152604080832086845290915290206005015460ff166004811115611e1957611e19614b94565b14611e375760405163e200563560e01b815260040160405180910390fd5b600083815260096020908152604080832085845290915290206004018054611e5e906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054611e8a906151ab565b8015611ed75780601f10611eac57610100808354040283529160200191611ed7565b820191906000526020600020905b815481529060010190602001808311611eba57829003601f168201915b5050505050806020019051810190610ab9919061552b565b600354604051631819659760e01b81526004810185905233916001600160a01b031690631819659790602401602060405180830381865afa158015611f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5c919061549f565b6001600160a01b031614611f835760405163d47118cb60e01b815260040160405180910390fd5b600354604051634e8c72a160e11b8152600481018590526001600160a01b0390911690639d18e54290602401602060405180830381865afa158015611fcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff091906153bb565b61200d57604051633022989960e01b815260040160405180910390fd5b6001600160a01b03821661203457604051639792926760e01b815260040160405180910390fd5b60008061204085613b05565b9150915080612062576040516329f38e3f60e21b815260040160405180910390fd5b600480546000918261207383615309565b909155506040805160a081019182905260035463174a4e2d60e21b90925260a4810189905291925081906001600160a01b0316635d2938b460c48301602060405180830381865afa1580156120cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f0919061533d565b6120fd9062015180615518565b815260208101889052604001612114886002615378565b8152602001612124886002615378565b61212f906001615518565b815260209081018590526000838152600a825260408082208451815592840151600184015583810151600284015560608401516003808501919091556080909401516004938401559254925163637c77f160e01b8152918201899052916001600160a01b03169063637c77f190602401602060405180830381865afa1580156121bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e0919061533d565b600354604051632cd3581b60e11b8152600481018a90529192506000916001600160a01b03909116906359a6b03690602401602060405180830381865afa15801561222f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612253919061533d565b600154604051633404591760e21b8152600481018590529192506000916001600160a01b039091169063d011645c90602401602060405180830381865afa1580156122a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c6919061533d565b6002546040516392680e9560e01b8152600481018590529192506000916001600160a01b03909116906392680e9590602401602060405180830381865afa158015612315573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123399190615572565b6003546040516327143fdd60e21b8152600481018d905260ff9290921692506000916001600160a01b0390911690639c50ff7490602401602060405180830381865afa15801561238d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b1919061533d565b90508282146123d35760405163042c06c160e51b815260040160405180910390fd5b6040518060a00160405280868152602001848152602001600a8360076123f99190615378565b6124039190615356565b8152602001828152602001336001600160a01b0316815250600a6000888152602001908152602001600020600a016000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050506040518060a001604052808581526020018381526020016000815260200160008152602001336001600160a01b0316815250600a60008881526020019081526020016000206005016000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a8154816001600160a01b0302191690836001600160a01b031602179055509050506040518060600160405280600a8360026125439190615378565b61254d9190615356565b815260208082018c90526001600160a01b038d166040928301526000898152600a8252919091208251600f8201908155918301516010909101906125919082615233565b50604091820151600291820180546001600160a01b0319166001600160a01b039283161790556000898152600a602081905293902060128101805460ff1916600117905560038054919093015491169263f242432a923392309290916125f8908890615378565b6126029190615356565b6040518563ffffffff1660e01b815260040161262194939291906154e0565b600060405180830381600087803b15801561263b57600080fd5b505af115801561264f573d6000803e3d6000fd5b505050507fe2d77c4a35bb326277ff28842c7df62528e9dfdf2fbd905b6847260baaa1544f8660405161268491815260200190565b60405180910390a15050505050505050505050565b6000818152600a602052604090206003601282015460ff1660038111156126c2576126c2614b94565b146126e057604051637bf390dd60e11b815260040160405180910390fd5b6003805490820154604051627eeac760e11b81526000926001600160a01b03169162fdd58e916127149133916004016153a2565b602060405180830381865afa158015612731573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612755919061533d565b60008481526006602090815260408083203384529091529020549091508115801561277e575080155b1561279c5760405163bfe6236760e01b815260040160405180910390fd5b60035460018401546040516314bd9ae160e21b815260048101919091526000916001600160a01b0316906352f66b8490602401602060405180830381865afa1580156127ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612810919061533d565b600b8501549091506001901b6000826128298587615518565b6128339084615378565b61283d9190615356565b6000888152600660209081526040808320338452909152812055905084156128ce576003546001600160a01b031663f242432a3360038901546040516001600160e01b031960e085901b16815261289b929130918b906004016154e0565b600060405180830381600087803b1580156128b557600080fd5b505af11580156128c9573d6000803e3d6000fd5b505050505b6000546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612916573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061293a919061533d565b10156129595760405163c760602d60e01b815260040160405180910390fd5b6000546001600160a01b031663a9059cbb33836040518363ffffffff1660e01b81526004016129899291906153a2565b6020604051808303816000875af11580156129a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cc91906153bb565b5060408051888152602081018390527f4a190041baaa7b7da28a2bb3ad8330bdfb955271be9959517121bfb1c2900f549101611cec565b6000818152600a602090815260408083206001810154808552600b90935292205460ff1615612a455760405163bafab1af60e01b815260040160405180910390fd5b600354604051631819659760e01b81526004810183905230916001600160a01b031690631819659790602401602060405180830381865afa158015612a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab2919061549f565b6001600160a01b031614612ad95760405163d47118cb60e01b815260040160405180910390fd5b600354604051631d1a064960e11b81526001600160a01b0390911690633a340c9290612b0e9084906010870190600401615612565b600060405180830381600087803b158015612b2857600080fd5b505af1158015612b3c573d6000803e3d6000fd5b505050600091825250600b60209081526040808320805460ff19908116600117909155948352600a9091529020601201805490921660021790915550565b60606001600084815260096020908152604080832086845290915290206005015460ff166004811115612baf57612baf614b94565b14612bcd5760405163e200563560e01b815260040160405180910390fd5b600083815260096020908152604080832085845290915290206004018054612bf4906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054612c20906151ab565b8015612c6d5780601f10612c4257610100808354040283529160200191612c6d565b820191906000526020600020905b815481529060010190602001808311612c5057829003601f168201915b5050505050806020019051810190612c85919061552b565b509392505050565b6000818152600a60205260409020600e015481906001600160a01b03163314612cc95760405163158980c760e21b815260040160405180910390fd5b60016000838152600a602052604090206012015460ff166003811115612cf157612cf1614b94565b14612d0f57604051633949e7c760e21b815260040160405180910390fd5b612d1882613bd7565b5050565b612d2461491a565b6000828152600a6020818152604092839020835161016081018552815460c08201908152600183015460e08301526002830154610100830152600383015461012083015260048301546101408301528152845160a0818101875260058401548252600684015482860152600784015482880152600884015460608084019190915260098501546001600160a01b039081166080808601919091528588019490945288519283018952968501548252600b85015482870152600c85015482890152600d85015482820152600e85015490961691810191909152818601528451808501909552600f82018054865260108301805492969395870194919291840191612e2c906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054612e58906151ab565b8015612ea55780601f10612e7a57610100808354040283529160200191612ea5565b820191906000526020600020905b815481529060010190602001808311612e8857829003601f168201915b5050509183525050600291909101546001600160a01b0316602091820152908252601283015491019060ff166003811115612ee257612ee2614b94565b6003811115612ef357612ef3614b94565b81526020016013820154815250509050919050565b6000838152600660209081526040808320338452909152812054849103612f425760405163bfe6236760e01b815260040160405180910390fd5b6001600160a01b0382161580612f6057506001600160a01b03821630145b15612f7e57604051639792926760e01b815260040160405180910390fd5b428311612f9e57604051631da7447960e21b815260040160405180910390fd5b600084815260086020908152604080832054815160e081018352818152808401858152818401868152606083018a815285516001600160a01b038b1681890152865180820389018152908701875260808501908152600360a0860181905260c086018a90528d8a5260098952878a20878b52909852959097208351815591516001830155516002820155945193850193909355905190929060048201906130459082615233565b5060a082015160058201805460ff1916600183600481111561306957613069614b94565b021790555060c09190910151600590910180549115156101000261ff001990921691909117905560008581526008602052604081208054916130aa83615309565b9190505550600080516020615761833981519152858260036040516111c893929190615322565b80336002546040516331a9108f60e11b8152600481018490526001600160a01b039283169290911690636352211e90602401602060405180830381865afa158015613120573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613144919061549f565b6001600160a01b03161461316b57604051636b0c6fd160e01b815260040160405180910390fd5b60016000848152600a602052604090206012015460ff16600381111561319357613193614b94565b146131b157604051633949e7c760e21b815260040160405180910390fd5b6131bb83836135a0565b505050565b6003546000838152600a60205260408082206001015490516314bd9ae160e21b81526004810191909152909182916001600160a01b03909116906352f66b8490602401602060405180830381865afa158015613220573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613244919061533d565b9050600083600481111561325a5761325a614b94565b14806132775750600383600481111561327557613275614b94565b145b156132a557670de0b6b3a7640000600554826132939190615378565b61329d9190615356565b9150506108d2565b670de0b6b3a7640000600554600183901c6132939190615378565b6000818152600a6020526040902060018082015490601283015460ff1660038111156132ee576132ee614b94565b1461330c57604051633949e7c760e21b815260040160405180910390fd5b600354604051631819659760e01b81526004810183905230916001600160a01b031690631819659790602401602060405180830381865afa158015613355573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613379919061549f565b6001600160a01b0316146133a05760405163d47118cb60e01b815260040160405180910390fd5b600e8201546001600160a01b0316336001600160a01b0316146133d65760405163158980c760e21b815260040160405180910390fd5b60128201805460ff19166003908117909155546001600160a01b0316639732d56f82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401600060405180830381600087803b15801561344057600080fd5b505af1158015613454573d6000803e3d6000fd5b50506003546040516327143fdd60e21b815260048101859052600093506001600160a01b039091169150639c50ff7490602401602060405180830381865afa1580156134a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c8919061533d565b600380546000878152600a60208190526040909120600201549394506001600160a01b039091169263f242432a923092339291613506908890615378565b6135109190615356565b6040518563ffffffff1660e01b815260040161352f94939291906154e0565b600060405180830381600087803b15801561354957600080fd5b505af115801561355d573d6000803e3d6000fd5b505050507f0b021add1edbb328ed48ca0a1905c666ab931678b4a7602d219c496d174bf0258460405161359291815260200190565b60405180910390a150505050565b6000828152600a602052604080822060025491516392680e9560e01b8152600481018590529092916001600160a01b0316906392680e9590602401602060405180830381865afa1580156135f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061361c9190615572565b600b83015460ff9190911691506001811b90821461364d5760405163042c06c160e51b815260040160405180910390fd5b60128301805460ff191660021790556040805160a08101825285815260208101849052600c8501549091820190600a613687856007615378565b6136919190615356565b61369b919061538f565b815260200184600a0160030154836136b3919061538f565b815233602091820152815160058601558181015160068601556040808301516007870155606083015160088701556080909201516009860180546001600160a01b0319166001600160a01b039283161790556003548351636da58de360e01b815293516000949190921692636da58de392600480840193829003018187875af1158015613744573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613768919061533d565b6000818152600b602052604090819020805460ff19166001179055805160a081019091529091508061379d4262015180615518565b8152602001828152602001600183901b8152602001600183901b60016137c39190615518565b8152600486018054602092830152825187559082015160018701556040820151600280880191909155606083015160038801556080909201519055546001600160a01b03166342842e0e3330886040518463ffffffff1660e01b815260040161382e939291906154bc565b600060405180830381600087803b15801561384857600080fd5b505af115801561385c573d6000803e3d6000fd5b505060025460035460405163095ea7b360e01b81526001600160a01b03928316945063095ea7b39350613897929091169089906004016153a2565b600060405180830381600087803b1580156138b157600080fd5b505af11580156138c5573d6000803e3d6000fd5b5050600154600354600a88015460405163095ea7b360e01b81526001600160a01b03938416955063095ea7b3945061390393909216916004016153a2565b600060405180830381600087803b15801561391d57600080fd5b505af1158015613931573d6000803e3d6000fd5b5050600354600a8701546004808901546040516306badddb60e21b81526001600160a01b039094169550631aeb776c9450613979938b939260019260108d019290910161562b565b600060405180830381600087803b15801561399357600080fd5b505af11580156139a7573d6000803e3d6000fd5b505050600985015460028601546003870154600788015460088901546139d995506001600160a01b0390941693613daa565b600e84015460028501546003860154600c870154600d880154613a08946001600160a01b031693929190613daa565b6040518681527ff2fb170bc0fd9ce44083044170a7f85cd4887f40565b5439b1886f8f5ec0264290602001610aa0565b600082815260096020908152604080832084845290915281206005015460ff1690816004811115613a6b57613a6b614b94565b03613a7957613a7983613edd565b6001816004811115613a8d57613a8d614b94565b03613a9c57613a9c8383613fb7565b6002816004811115613ab057613ab0614b94565b03613abf57613abf8383614144565b6003816004811115613ad357613ad3614b94565b03613ae257613ae2838361423e565b6004816004811115613af657613af6614b94565b036131bb576131bb83836144a5565b60035460408051602480820185905282518083039091018152604490910182526020810180516001600160e01b03166323f0aa7160e11b17905290516000928392839283926001600160a01b031691613b5d91615664565b600060405180830381855afa9150503d8060008114613b98576040519150601f19603f3d011682016040523d82523d6000602084013e613b9d565b606091505b509150915081613bc057604051633022989960e01b815260040160405180910390fd5b61016081015193506101a081015192505050915091565b6000818152600a60205260408120906002601283015460ff166003811115613c0157613c01614b94565b60128401805460ff1916600317905514905080613c8e57600154600e830154600a840154604051632142170760e11b81526001600160a01b03938416936342842e0e93613c5793309392909116916004016154bc565b600060405180830381600087803b158015613c7157600080fd5b505af1158015613c85573d6000803e3d6000fd5b50505050613d72565b60025460098301546005840154604051632142170760e11b81526001600160a01b03938416936342842e0e93613ccd93309392909116916004016154bc565b600060405180830381600087803b158015613ce757600080fd5b505af1158015613cfb573d6000803e3d6000fd5b50505050613d0883614603565b600154600a83015460405163db006a7560e01b81526001600160a01b039092169163db006a7591613d3f9160040190815260200190565b600060405180830381600087803b158015613d5957600080fd5b505af1158015613d6d573d6000803e3d6000fd5b505050505b6040518381527f0b021add1edbb328ed48ca0a1905c666ab931678b4a7602d219c496d174bf0259060200160405180910390a1505050565b604080516002808252606082018352600092602083019080368337019050509050828282600081518110613de057613de0615680565b6020026020010183600181518110613dfa57613dfa615680565b60209081029190910101919091525260408051600280825260608201909252600091816020016020820280368337019050509050858582600081518110613e4357613e43615680565b6020026020010183600181518110613e5d57613e5d615680565b602090810291909101019190915252600354604051631759616b60e11b81526001600160a01b0390911690632eb2c2d690613ea29030908b90869088906004016156d1565b600060405180830381600087803b158015613ebc57600080fd5b505af1158015613ed0573d6000803e3d6000fd5b5050505050505050505050565b6000818152600a6020526040902054421015613f0c57604051631b64953f60e11b815260040160405180910390fd5b6003546000828152600a602052604090819020600101549051631444354960e01b81526001600160a01b0390921691631444354991613f519160040190815260200190565b600060405180830381600087803b158015613f6b57600080fd5b505af1158015613f7f573d6000803e3d6000fd5b50505050613f8c81613bd7565b600080516020615741833981519152816000604051613fac92919061572c565b60405180910390a150565b6000828152600a60205260409020613fce83614603565b600083815260096020908152604080832085845290915281206004018054829190613ff8906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054614024906151ab565b80156140715780601f1061404657610100808354040283529160200191614071565b820191906000526020600020905b81548152906001019060200180831161405457829003601f168201915b5050505050806020019051810190614089919061552b565b6011850180546001600160a01b0319166001600160a01b0383161790559092509050601083016140b98382615233565b506003546001840154604051631d1a064960e11b81526001600160a01b0390921691633a340c92916140f2916010880190600401615612565b600060405180830381600087803b15801561410c57600080fd5b505af1158015614120573d6000803e3d6000fd5b505050506000805160206157418339815191528560016040516111c892919061572c565b60008281526009602090815260408083208484529091529020600401805461416b906151ab565b80601f0160208091040260200160405190810160405280929190818152602001828054614197906151ab565b80156141e45780601f106141b9576101008083540402835291602001916141e4565b820191906000526020600020905b8154815290600101906020018083116141c757829003601f168201915b50505050508060200190518101906141fc919061533d565b6000838152600a602052604090819020600f0191909155516000805160206157418339815191529061423290849060029061572c565b60405180910390a15050565b6000828152600a6020908152604080832060128101805460ff19166003179055600983528184208585529092528220600401805491929161427e906151ab565b80601f01602080910402602001604051908101604052809291908181526020018280546142aa906151ab565b80156142f75780601f106142cc576101008083540402835291602001916142f7565b820191906000526020600020905b8154815290600101906020018083116142da57829003601f168201915b505050505080602001905181019061430f919061549f565b6003546001840154604051639732d56f60e01b815260048101919091526001600160a01b038084166024830152929350911690639732d56f90604401600060405180830381600087803b15801561436557600080fd5b505af1158015614379573d6000803e3d6000fd5b5050505061438684614603565b60028201546003808401549054604051627eeac760e11b8152614485938593909290916001600160a01b039091169062fdd58e906143ca90309086906004016153a2565b602060405180830381865afa1580156143e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061440b919061533d565b6003805490880154604051627eeac760e11b81526001600160a01b039092169162fdd58e9161443f913091906004016153a2565b602060405180830381865afa15801561445c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614480919061533d565b613daa565b60008051602061574183398151915284600360405161359292919061572c565b6000828152600960209081526040808320848452909152902060040180546144cc906151ab565b80601f01602080910402602001604051908101604052809291908181526020018280546144f8906151ab565b80156145455780601f1061451a57610100808354040283529160200191614545565b820191906000526020600020905b81548152906001019060200180831161452857829003601f168201915b505050505080602001905181019061455d919061533d565b6000838152600a6020526040908190206004808201849055600354600190920154925163f7ce46b760e01b81526001600160a01b039092169363f7ce46b7936145b193909201918252602082015260400190565b600060405180830381600087803b1580156145cb57600080fd5b505af11580156145df573d6000803e3d6000fd5b5050505060008051602061574183398151915282600460405161423292919061572c565b6000818152600a6020526040808220825491516370a0823160e01b81523060048201529092916001600160a01b0316906370a0823190602401602060405180830381865afa158015614659573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061467d919061533d565b600354600184015460405163f62b46c960e01b815260048101919091529192506001600160a01b03169063f62b46c990602401600060405180830381600087803b1580156146ca57600080fd5b505af19250505080156146db575060015b614771573d808015614709576040519150601f19603f3d011682016040523d82523d6000602084013e61470e565b606091505b50805160208083019190912060408051600481526024810190915291820180516001600160e01b03166374d4d10160e11b17815291519091201461476f578060405162461bcd60e51b81526004016147669190614f9b565b60405180910390fd5b505b600080546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156147ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147de919061533d565b905060006147ec838361538f565b600b850154600f860154919250600091600a916001901b9061480e9085615378565b6148189190615356565b614823906003615378565b61482d9190615356565b9050614839818361538f565b85601301600082825461484c9190615518565b9091555050600054601186015460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb926148899291169085906004016153a2565b6020604051808303816000875af11580156148a8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddb91906153bb565b6040518060e0016040528060008152602001600081526020016000815260200160008152602001606081526020016000600481111561490d5761490d614b94565b8152600060209091015290565b6040518060c001604052806149576040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b81526020016149646149b7565b81526020016149716149b7565b81526020016149a36040518060600160405280600081526020016060815260200160006001600160a01b031681525090565b815260200160008152602001600081525090565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b600060208284031215614a0157600080fd5b81356001600160e01b0319811681146112e357600080fd5b60008060408385031215614a2c57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614a7a57614a7a614a3b565b604052919050565b600067ffffffffffffffff821115614a9c57614a9c614a3b565b50601f01601f191660200190565b600082601f830112614abb57600080fd5b8135614ace614ac982614a82565b614a51565b818152846020838601011115614ae357600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b0381168114614b1557600080fd5b50565b60008060008060808587031215614b2e57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115614b5357600080fd5b614b5f87828801614aaa565b9250506060850135614b7081614b00565b939692955090935050565b600060208284031215614b8d57600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60048110614bba57614bba614b94565b9052565b602081016108d28284614baa565b60008060008060808587031215614be257600080fd5b8435614bed81614b00565b93506020850135614bfd81614b00565b925060408501359150606085013567ffffffffffffffff811115614c2057600080fd5b614c2c87828801614aaa565b91505092959194509250565b60008060408385031215614c4b57600080fd5b823591506020830135614c5d81614b00565b809150509250929050565b600080600060608486031215614c7d57600080fd5b505081359360208301359350604090920135919050565b600080600060608486031215614ca957600080fd5b83359250602084013591506040840135614cc281614b00565b809150509250925092565b60005b83811015614ce8578181015183820152602001614cd0565b50506000910152565b60008151808452614d09816020860160208601614ccd565b601f01601f19169290920160200192915050565b60058110614bba57614bba614b94565b60408152825160408201526020830151606082015260408301516080820152606083015160a08201526000608084015160e060c0840152614d72610120840182614cf1565b905060a0850151614d8660e0850182614d1d565b5060c0949094015115156101008301525090151560209091015290565b600060208284031215614db557600080fd5b813567ffffffffffffffff811115614dcc57600080fd5b610ab984828501614aaa565b8015158114614b1557600080fd5b600080600060608486031215614dfb57600080fd5b83359250602084013591506040840135614cc281614dd8565b600080600060608486031215614e2957600080fd5b833592506020840135614e3b81614b00565b9150604084013567ffffffffffffffff811115614e5757600080fd5b614e6386828701614aaa565b9150509250925092565b600082601f830112614e7e57600080fd5b8135602067ffffffffffffffff821115614e9a57614e9a614a3b565b8160051b614ea9828201614a51565b9283528481018201928281019087851115614ec357600080fd5b83870192505b84831015614ee257823582529183019190830190614ec9565b979650505050505050565b600080600080600060a08688031215614f0557600080fd5b8535614f1081614b00565b94506020860135614f2081614b00565b9350604086013567ffffffffffffffff80821115614f3d57600080fd5b614f4989838a01614e6d565b94506060880135915080821115614f5f57600080fd5b614f6b89838a01614e6d565b93506080880135915080821115614f8157600080fd5b50614f8e88828901614aaa565b9150509295509295909350565b6020815260006112e36020830184614cf1565b805182526000602082015160606020850152614fcd6060850182614cf1565b6040938401516001600160a01b0316949093019390935250919050565b602081526000825180516020840152602081015160408401526040810151606084015260608101516080840152608081015160a084015250602083015161506560c0840182805182526020808201519083015260408082015190830152606080820151908301526080908101516001600160a01b0316910152565b5060408381015180516101608501526020810151610180850152908101516101a084015260608101516101c084015260808101516001600160a01b03166101e0840152506060830151610240806102008501526150c6610260850183614fae565b915060808501516150db610220860182614baa565b5060a0949094015192909301919091525090565b6000806040838503121561510257600080fd5b82359150602083013560058110614c5d57600080fd5b600080600080600060a0868803121561513057600080fd5b853561513b81614b00565b9450602086013561514b81614b00565b93506040860135925060608601359150608086013567ffffffffffffffff81111561517557600080fd5b614f8e88828901614aaa565b6040815260006151946040830185614cf1565b905060018060a01b03831660208301529392505050565b600181811c908216806151bf57607f821691505b6020821081036151df57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156131bb57600081815260208120601f850160051c8101602086101561520c5750805b601f850160051c820191505b8181101561522b57828155600101615218565b505050505050565b815167ffffffffffffffff81111561524d5761524d614a3b565b6152618161525b84546151ab565b846151e5565b602080601f831160018114615296576000841561527e5750858301515b600019600386901b1c1916600185901b17855561522b565b600085815260208120601f198616915b828110156152c5578886015182559484019460019091019084016152a6565b50858210156152e35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b60006001820161531b5761531b6152f3565b5060010190565b8381526020810183905260608101610ab96040830184614d1d565b60006020828403121561534f57600080fd5b5051919050565b60008261537357634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176108d2576108d26152f3565b818103818111156108d2576108d26152f3565b6001600160a01b03929092168252602082015260400190565b6000602082840312156153cd57600080fd5b81516112e381614dd8565b600082601f8301126153e957600080fd5b81516153f7614ac982614a82565b81815284602083860101111561540c57600080fd5b610ab9826020830160208701614ccd565b600080600080600080600060e0888a03121561543857600080fd5b875196506020880151955060408801519450606088015193506080880151925060a088015167ffffffffffffffff81111561547257600080fd5b61547e8a828b016153d8565b92505060c088015161548f81614b00565b8091505092959891949750929550565b6000602082840312156154b157600080fd5b81516112e381614b00565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b808201808211156108d2576108d26152f3565b6000806040838503121561553e57600080fd5b825167ffffffffffffffff81111561555557600080fd5b615561858286016153d8565b9250506020830151614c5d81614b00565b60006020828403121561558457600080fd5b815160ff811681146112e357600080fd5b600081546155a2816151ab565b8085526020600183811680156155bf57600181146155d957615607565b60ff1985168884015283151560051b880183019550615607565b866000528260002060005b858110156155ff5781548a82018601529083019084016155e4565b890184019650505b505050505092915050565b828152604060208201526000610ab96040830184615595565b858152846020820152831515604082015260a06060820152600061565260a0830185615595565b90508260808301529695505050505050565b60008251615676818460208701614ccd565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156156c6578151875295820195908201906001016156aa565b509495945050505050565b6001600160a01b0385811682528416602082015260a0604082018190526000906156fd90830185615696565b828103606084015261570f8185615696565b838103608090940193909352505060008152602001949350505050565b828152604081016112e36020830184614d1d56fe0131395fc2023e9f088126b582709c056a327bb71617c4c4eceddafa98a0e2d335f68360d987e6ac1824ca88be7cd548a5e6e7b37ed928147ca1e92ddff1981ba26469706673582212205fc0f076edfef5a7f64d5c37d4f858ab6986cc54a2dd88ba23d69433f093601564736f6c63430008130033

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

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea7b7dc089c9a4a916b5a7a37617f59fd54e37e400000000000000000000000021468e63abf3783020750f7b2e57d4b34afafba6000000000000000000000000d32cb5f76989a27782e44c5297aaba728ad616690000000000000000000000004bfba79cf232361a53eddd17c67c6c77a6f00379

-----Decoded View---------------
Arg [0] : _consensusOption (uint8): 0
Arg [1] : _hypcToken (address): 0xeA7B7DC089c9a4A916B5a7a37617f59fD54e37E4
Arg [2] : _chypcV2 (address): 0x21468e63abF3783020750F7b2e57d4B34aFAfba6
Arg [3] : _licenseContract (address): 0xd32CB5f76989A27782e44c5297AAba728Ad61669
Arg [4] : _hypcShareTokens (address): 0x4BFbA79CF232361a53eDdd17C67C6c77A6F00379

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 000000000000000000000000ea7b7dc089c9a4a916b5a7a37617f59fd54e37e4
Arg [2] : 00000000000000000000000021468e63abf3783020750f7b2e57d4b34afafba6
Arg [3] : 000000000000000000000000d32cb5f76989a27782e44c5297aaba728ad61669
Arg [4] : 0000000000000000000000004bfba79cf232361a53eddd17c67c6c77a6f00379


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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