ETH Price: $2,082.18 (-15.01%)
Gas: 0.77 Gwei

Contract

0x76B96e5B45f46B0681222aab5ea067B2Fc5D2029
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Aetos

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 9 : Aetos.sol
//SPDX-License-Identifier: UNLICENSED

//  ________  _______  _________  ________  ________
// |\   __  \|\  ___ \|\___   ___\\   __  \|\   ____\
// \ \  \|\  \ \   __/\|___ \  \_\ \  \|\  \ \  \___|_
//  \ \   __  \ \  \_|/__  \ \  \ \ \  \\\  \ \_____  \
//   \ \  \ \  \ \  \_|\ \  \ \  \ \ \  \\\  \|____|\  \
//    \ \__\ \__\ \_______\  \ \__\ \ \_______\____\_\  \
//     \|__|\|__|\|_______|   \|__|  \|_______|\_________\
//                                            \|_________|

pragma solidity ^0.8.9;
import "./utils/DAO.sol";
import "./interfaces/ICapitalVault.sol";
import "./interfaces/IOperationsVault.sol";
import "./interfaces/IReturnsVault.sol";
import "./interfaces/IProposalManager.sol";
import "./tokens/IERC20DP.sol";

contract Aetos is DAO {
    /************************* Events **************************/
    event ProposeProposal(uint256 indexed _id, Proposal _proposal);
    event VoteProposal(uint256 indexed _id, Vote indexed _vote);
    event ProcessProposal(uint256 indexed _id, Status _status);
    event MemberSlashed(address indexed _address, uint256 _index);
    event MemberPardoned(address indexed _address, uint256 _index);
    event MemberJoin(address indexed _address, uint256 _commitment);
    event MemberLeave(address indexed _address);
    event MemberMetadata(string _metadata);
    event Claimed(address indexed _address, uint256 _amount);
    event FundingRoundCalled(uint256 _index);
    event HonouredFundingCall(address indexed _address, uint256 _index);

    /******************** Config Variables *********************/
    uint256 constant STANDARD_DECIMAL_PRECISION = 10 ** 18;

    ConfigStruct public DAOConfig; //Main DAO config file, compressed to prevent solidity stack too deep error
    DirectoryStruct public VaultDirectory;

    uint256 public daoStartTime; //Start of the DAO
    uint256 public daoEndTime; //Timestamp the DAO will end
    uint256[] public callSchedulePercentage; //Array of the call schedule. All values must add to 100 (%)
    CallStatus[] public callScheduleStatus; //Tracker for call schedule status states
    uint256 public scheduleTime; //Period between each call schedule

    /******************** Public Variables *********************/
    uint256 public totalShares; // Total in DAO's lifecycle, calculated on signups ending and final numbers locked in
    uint256 public inflationShares; // Amount of shares that are inflationary, to be given out to council members, bonuses, ect.
    uint256 public totalCouncilSharesGiven; // Total number of shares given to council tracker
    uint256 public lastUpdatedCouncilShares; // Last timestamp the councils shares were updated

    uint256 public lastNominateCouncilVote; // Last timestamp for nominating a new council

    uint256 public bonusSharesUnlocked; // How many bonus shares are unlocked and can be voted to dish out
    uint256 public totalBonusSharesUnlocked; // Total number of bonus shares unlocked over the life of the contract

    bool public canJoin = false; // Allows new members to sign up to the DAO organisation
    bool public contractInit = false; // Initialise DAO boolean to prevent reconfiguring key aspects of the contract
    bool public daoInit = false; // Activates the DAO, allowing members to ask to join

    uint256 public numMembers; // Total number of members in the DAO (includes council)
    address[][] public councilMembers; // Tracks council members across all cycles

    uint256 public kickedClaimedTracker; // Tracks how much kicked members have claimed

    mapping(address => Members) public members;
    mapping(uint256 => uint256) public fundingCallTimeTracker; // Timestamp of when a funding call was called, used for penalty tracking

    /******************** Structs and Definitions *********************/
    struct ConfigStruct {
        uint256 COUNCIL_MEMBER_SIZE; //Required and max amount of council members, odd number
        uint256 BASE_INFLATION; // Base inflation for the council. Percent 100% = 1000, 5% = 50, 0.5% = 5; 1 DP precision
        uint256 OPERATION_INFLATION; // Inflation that occurs upon redistribution to the vaults
        uint256 BONUS_INFLATION; // Inflation set aside to give out as bonus shares
        uint256 PENALTY_PERCENT; // Penalty for getting slashed
        uint256 COUNCIL_VOTING_PERIOD; //Voting period required between each council election
        uint256 MIN_COMMITMENT; // Minimum commitment amount in tokens
        uint256 MAX_COMMITMENT; // Minimum commitment amount in tokens
        uint256 VOTING_PERIOD; //Period given to vote a proposal
        uint256 BASE_VOTING_THRESHOLD; //The base propVars.threshold required to be reached for successful votes 100% = 100
        uint256 QUORUM; //Minimum amount of votes required
        uint256 CLAIM_PERIOD; //Time to wait before you can claim from returns vault again
        string DAO_METADATA_URI; //DAO metadata ~ ipfs://QmT5NvUtoM5nWFfrQdV...
    }

    enum CommitStatus {
        Pending,
        Slashed,
        Met,
        Pardoned
    }

    struct Members {
        uint256 shares;
        MemberStatus status;
        uint256 commited;
        CommitStatus[] commitSchedule;
        uint256 claimed;
        uint256 lastClaimed;
    }

    enum CallStatus {
        Awaiting,
        Called
    }

    struct DirectoryStruct {
        address CapitalVault;
        address OperationsVault;
        address ReturnsVault;
        address ProposalManager;
    }

    /*********************** Constructor ************************/
    /**
     * @notice Unused, needed to deploy implementation
     */
    constructor() {}

    /**
     * @notice Initialize Aetos module upon deployment of proxy, basically a constructor for the proxy
     * @param  _DAOConfig Main DAO config file
     */
    function initialize(ConfigStruct memory _DAOConfig) external {
        /* Safety Checks for construction */
        require(!daoInit, "EA7"); //Already Initialised
        require(_DAOConfig.MIN_COMMITMENT < _DAOConfig.MAX_COMMITMENT, "EA2"); //Min commit >= Max Commit
        require(_DAOConfig.BASE_VOTING_THRESHOLD < 100, "EA3"); //Base voting threshold >= 100%
        require(_DAOConfig.BASE_INFLATION + _DAOConfig.BONUS_INFLATION + _DAOConfig.OPERATION_INFLATION < 999, "EA5"); //Inflation too high
        require(_DAOConfig.PENALTY_PERCENT <= 50, "EA6"); //Cant penalize more than 5%

        DAOConfig = _DAOConfig;
        canJoin = true;
        daoInit = true;
    }

    /**
     * @notice Initialize the remainder of the DAO configuration once all contracts are deployed
     * @param  _callSchedule Call schedule percentages (1000 = 100%)
     * @param  _scheduleTime Time between commitment calls in seconds
     * @param  _council Array of initial council addresses
     * @param  _commitments Array of initial council commitments
     * @param  _daoEndSec When the DAO ends in seconds from the function being run
     * @param  _vaultDirectory Directory object of all the vault proxy addresses
     */
    function initializeDAO(
        uint256[] memory _callSchedule,
        uint256 _scheduleTime,
        address[] memory _council,
        uint256[] memory _commitments,
        uint256 _daoEndSec,
        DirectoryStruct memory _vaultDirectory
    ) external {
        require(!contractInit, "EA7"); //Already Initialised
        _nullCheck(_vaultDirectory.CapitalVault);
        _nullCheck(_vaultDirectory.OperationsVault);
        _nullCheck(_vaultDirectory.ReturnsVault);
        _nullCheck(_vaultDirectory.ProposalManager);

        uint256 tempTotalPercent = 0;
        for (uint256 i = 0; i < _callSchedule.length; i++) {
            tempTotalPercent = tempTotalPercent + _callSchedule[i];
            require(_callSchedule[i] <= 100, "EA11"); //Individual call schedule can't be over 100
        }
        require(tempTotalPercent == 100, "EA12"); //Call schedule percentage must equal to 100%
        require(_council.length == DAOConfig.COUNCIL_MEMBER_SIZE && _commitments.length == DAOConfig.COUNCIL_MEMBER_SIZE, "EA13"); //Council too few/many or council commitments != council length
        require(_daoEndSec != 0, "EA16"); //Must specify when dao ends

        callSchedulePercentage = _callSchedule;
        scheduleTime = _scheduleTime;

        //Lock initial council for 6 months
        lastNominateCouncilVote = block.timestamp;
        councilMembers.push(); //Instantiate Array of Array

        for (uint256 i = 0; i < _council.length; i++) {
            _nullCheck(_council[i]);

            members[_council[i]].status = MemberStatus.Council;
            members[_council[i]].commited = _commitments[i];
            require(_commitments[i] <= DAOConfig.MAX_COMMITMENT && _commitments[i] >= DAOConfig.MIN_COMMITMENT, "EA17"); //Commitments not within range
            members[_council[i]].shares = _commitments[i];
            _addTotalShares(_commitments[i]);
            emit MemberJoin(_council[i], _commitments[i]);

            for (uint256 k = 0; k < callSchedulePercentage.length; k++) {
                members[_council[i]].commitSchedule.push(CommitStatus.Pending);
            }

            councilMembers[0].push(_council[i]);
            numMembers++;
        }

        //Instantiate call schedule
        for (uint256 i = 0; i < _callSchedule.length; i++) {
            callScheduleStatus.push(CallStatus.Awaiting);
        }

        //Call first funding round
        _setFundingCall(0);

        //Setup the core vaults
        VaultDirectory = _vaultDirectory;

        // Set start time and end time
        daoStartTime = block.timestamp;
        daoEndTime = block.timestamp + _daoEndSec;

        lastUpdatedCouncilShares = block.timestamp;

        contractInit = true;
    }

    /********************* Getter Functions *********************/
    /**
     * @notice Get the timestamp of the DAO end time
     * @return uint256
     */
    function getDAOEndTime() public view returns (uint256) {
        return daoEndTime;
    }

    /**
     * @notice Get the percent of votes required in order to pass a proposal (100 = 100%)
     * @return uint256
     */
    function getDAOConfigBaseVotingThreshold() public view returns (uint256) {
        return DAOConfig.BASE_VOTING_THRESHOLD;
    }

    /**
     * @notice Get the amount of time allowed for voting on a proposal
     * @return uint256
     */
    function getDAOConfigVotingPeriod() public view returns (uint256) {
        return DAOConfig.VOTING_PERIOD;
    }

    /**
     * @notice Get the amount of council members
     * @return uint256
     */
    function getDAOConfigCouncilMemberSize() public view returns (uint256) {
        return DAOConfig.COUNCIL_MEMBER_SIZE;
    }

    /**
     * @notice Get the total inflation in the DAO excluding operations inflation (1000 = 100%)
     * @dev Used in functions to calculate various things
     * @return uint256
     */
    function getDAOConfigTotalInflation() public view returns (uint256) {
        return DAOConfig.BONUS_INFLATION + DAOConfig.BASE_INFLATION;
    }

    /**
     * @notice Get total amount of members
     * @return uint256
     */
    function getNumMembers() public view returns (uint256) {
        return numMembers;
    }

    /**
     * @notice Get members commit status at a certain index
     * @return CommitStatus
     */
    function getMemberCommitStatus(address _member, uint256 _index) public view returns (CommitStatus) {
        return members[_member].commitSchedule[_index];
    }

    /**
     * @notice Get the total amount of council members in the current council
     * @dev V1 of Aetos enforces the council size in all interactions, this is more for custom deployments of Aetos that do not enforce
     * @return uint256
     */
    function getNumCurrentCouncil() public view returns (uint256) {
        return councilMembers[councilMembers.length - 1].length;
    }

    /**
     * @notice Get the total amount of council members in chosen council array
     * @dev V1 of Aetos enforces the council size in all interactions, this is more for custom deployments of Aetos that do not enforce
     * @return uint256
     */
    function getNumCouncil(uint256 _index) public view returns (uint256) {
        return councilMembers[_index].length;
    }

    /**
     * @notice Get the total length of the council array, represents the amount of times the council has been updated
     * @return uint256
     */
    function getTotalCouncilLength() public view returns (uint256) {
        return councilMembers.length;
    }

    /**
     * @notice Get the council members from a specified index
     * @return address[]
     */
    function getCouncilMembers(uint256 _index) public view returns (address[] memory) {
        return councilMembers[_index];
    }

    /**
     * @notice Return the address of a specific council member in any of the current or past council arrangments
     * @return address
     */
    function getCouncilMember(uint256 _council, uint256 _member) public view returns (address) {
        return councilMembers[_council][_member];
    }

    /**
     * @notice Gets an addresses status in the dao
     * @return memberStatus
     */
    function getMemberStatus(address _member) public view returns (MemberStatus) {
        return members[_member].status;
    }

    /**
     * @notice Get the address of the Operations Vault Directory
     * @return address
     */
    function getOperationsVault() public view returns (address) {
        return VaultDirectory.OperationsVault;
    }

    /**
     * @notice Get the address of the Returns Vault Directory
     * @return address
     */
    function getReturnsVault() public view returns (address) {
        return VaultDirectory.ReturnsVault;
    }

    /**
     * @notice Get the address of the Returns Vault Directory
     * @return address
     */
    function getProposalManager() public view returns (address) {
        return VaultDirectory.ProposalManager;
    }

    /**
     * @notice Get the length of the call schedule
     * @return address
     */
    function getCallScheduleLength() public view returns (uint256) {
        return callScheduleStatus.length;
    }

    /**
     * @notice Get the operations inflation percentage (1000 = 100%)
     * @return uint256
     */
    function getOperationsVaultPercentage() public view returns (uint256) {
        return DAOConfig.OPERATION_INFLATION;
    }

    /**
     * @notice Get whether new members can sign up to join the DAO
     * @return bool
     */
    function getCanJoin() public view returns (bool) {
        return canJoin;
    }

    /**
     * @notice Get the index of the current call schedule
     * @return uint256
     */
    function getCurrentRound() public view returns (uint256) {
        if (block.timestamp > daoStartTime + (callSchedulePercentage.length * scheduleTime)) {
            return _safeSubtract(callSchedulePercentage.length, 1);
        }

        return
            _safeSubtract(
                (callSchedulePercentage.length - 1),
                (_safeSubtract((daoStartTime + (callSchedulePercentage.length * scheduleTime)), block.timestamp) / scheduleTime)
            );
    }

    /**
     * @notice Downscales amounts with respect to the primary tokens decimals
     * @param _amount The scaled amount
     * @param _primaryToken The primary token of the returns vault
     * @return uint256
     */
    function getStandardisedDecimalPrecisionDownscale(uint256 _amount, address _primaryToken) public view returns (uint256) {
        return (_amount * (10 ** IERC20DP(_primaryToken).decimals())) / STANDARD_DECIMAL_PRECISION;
    }

    /**
     * @notice Upscales amounts with respect to the tokens decimals
     * @param _amount The amount to be scaled
     * @param _token The token that will be scaled against
     * @return uint256
     */
    function getStandardisedDecimalPrecisionUpscale(uint256 _amount, address _token) public view returns (uint256) {
        return (_amount * STANDARD_DECIMAL_PRECISION) / 10 ** IERC20DP(_token).decimals();
    }

    /********************* Setter Functions *********************/

    /**
     * @notice propose
     * @param  _proposalDraft Proposal being put forth to the DAO, All checks done on processing to avoid double proposals
     */
    function propose(ProposalDraft memory _proposalDraft) external {
        /*Checks*/
        _onlyMember();

        require(_proposalDraft.proposalType <= 11, "EA18"); //Proposal Type Out of Bounds
        require(bytes(_proposalDraft.propVarsDraft.detailsURI).length > 0, "EA0"); //Need details uri

        // Assign object to inherit most relevant members;
        _setProposalVars(proposalIndex, _proposalDraft);

        /* Text Proposal/Replace meta data */
        //if (_proposalDraft.proposalType == 0 || _proposalDraft.proposalType == 11) {}
        
        /* Replace Council Member*/
        if (_proposalDraft.proposalType == 1) {
            _signupsStopped();
            _nullCheck(_proposalDraft.newAddress);
            require(_proposalDraft.existingAddress == msg.sender);
            require(msg.sender != _proposalDraft.newAddress);
            require(getMemberStatus(_proposalDraft.newAddress) == MemberStatus.Member);
            require(getMemberStatus(msg.sender) == MemberStatus.Council);
        }
        /* Member Kick */
        if (_proposalDraft.proposalType == 2) {
            _signupsStopped();
            _tokenCheck(ICapitalVault(VaultDirectory.CapitalVault).getPrimaryToken(), _proposalDraft.token);
        }
        /* Stop Signups */
        if (_proposalDraft.proposalType == 3) {}
        /* Stop Dao */
        if (_proposalDraft.proposalType == 4) {
            _signupsStopped();
            proposals[proposalIndex].propVars.threshold = 90; /* 90% required to stop dao */
        }
        /* New Member */
        if (_proposalDraft.proposalType == 5) {
            revert("EA21"); //Use member joining dedicated function
        }

        /* Slash or Pardon Member */
        if (_proposalDraft.proposalType == 6 || _proposalDraft.proposalType == 7) {
            _signupsStopped();
            _nullCheck(_proposalDraft.existingAddress);
            require(callScheduleStatus[_proposalDraft.amountOrIndex] == CallStatus.Called);
            require(members[_proposalDraft.existingAddress].commitSchedule[_proposalDraft.amountOrIndex] == CommitStatus.Pending);
            require((fundingCallTimeTracker[_proposalDraft.amountOrIndex] + DAOConfig.VOTING_PERIOD) < (block.timestamp));
        }

        /* Give Bonus */
        if (_proposalDraft.proposalType == 8) {
            _signupsStopped();
            require(_proposalDraft.amountArray.length == _proposalDraft.addressArray.length, "EA22"); //Address/Amount arrays not synced
        }
        /* Nominate council */
        if (_proposalDraft.proposalType == 9) {
            _signupsStopped();
            require(block.timestamp > lastNominateCouncilVote + DAOConfig.COUNCIL_VOTING_PERIOD, "EA23"); //Not enough time has passed since last election
            require(_proposalDraft.addressArray.length == getDAOConfigCouncilMemberSize(), "EA13"); //Council too few/many
        }
        /* Assume role and withdraw */
        if (_proposalDraft.proposalType == 10) {
            require(block.timestamp > daoEndTime, "EA48"); //DAO must end
        }

        emit ProposeProposal(proposalIndex, proposals[proposalIndex]);

        proposalIndex++;
    }

    /**
     * @notice proposeMember
     * @param  _proposalDraft Proposal by external entities to join the DAO.
     */
    function proposeMember(ProposalDraft memory _proposalDraft) external {
        require(_proposalDraft.proposalType == 5, "EA18"); //Proposal Type Out of Bounds
        require(canJoin, "EA24"); //Signups have stopped
        require(getMemberStatus(msg.sender) != MemberStatus.Member || getMemberStatus(msg.sender) != MemberStatus.Council, "EA25"); //Already a member
        require(_proposalDraft.amountOrIndex >= DAOConfig.MIN_COMMITMENT && _proposalDraft.amountOrIndex <= DAOConfig.MAX_COMMITMENT, "EA26"); //Commitment does not meet the requirements

        // Assign object to inherit most relevant members;
        _setProposalVars(proposalIndex, _proposalDraft);

        proposals[proposalIndex].propVars.yesVotes = 0;
        proposals[proposalIndex].propVars.voters = new address[](0);

        emit ProposeProposal(proposalIndex, proposals[proposalIndex]);

        proposalIndex++;
    }

    /* Voting */

    /**
     * @notice vote
     * @param  _index The index of the proposal
     * @param _vote What vote the user is casting
     */
    function vote(uint256 _index, Vote _vote) external {
        /*Checks*/
        _onlyMember();

        proposals[_index].propVars = IProposalManager(VaultDirectory.ProposalManager).voteProposal(msg.sender, proposals[_index].propVars, _vote);
        proposals[_index].propVars.voters.push(msg.sender);

        emit VoteProposal(_index, _vote);
    }

    /* Processing */

    /**
     * @notice processInternalProposal
     * @param  _index The index of the proposal
     */
    function process(uint256 _index) external {
        /*Checks*/
        _onlyMember();

        proposals[_index].propVars = IProposalManager(VaultDirectory.ProposalManager).processProposalSecurity(proposals[_index].propVars);

        if (proposals[_index].propVars.status == Status.Passed) {
            /* Text Vote*/
            if (proposals[_index].proposalType == 0) {
                // Do nothing.
            }
            /* Replace Council Member*/
            if (proposals[_index].proposalType == 1) {
                replaceCouncilMember(proposals[_index].existingAddress, proposals[_index].newAddress);
            }

            /* Member Kick */
            if (proposals[_index].proposalType == 2) {
                require(
                    members[proposals[_index].existingAddress].status == MemberStatus.Member ||
                        members[proposals[_index].existingAddress].status == MemberStatus.Council
                );

                if (members[proposals[_index].existingAddress].status == MemberStatus.Council) {
                    replaceCouncilMember(proposals[_index].existingAddress, proposals[_index].newAddress);
                }
                numMembers--;
                removeMembership(proposals[_index].existingAddress, proposals[_index].token);
                emit MemberLeave(proposals[_index].existingAddress);
            }

            /* Stop Signups */
            if (proposals[_index].proposalType == 3) {
                require(canJoin, "EA19"); //Signups have already stopped
                canJoin = false;

                uint256 bufferedShares = (totalShares * 1000) / _safeSubtract(1000, getDAOConfigTotalInflation());

                inflationShares = _safeSubtract(bufferedShares, totalShares);

                totalShares = bufferedShares;
            }

            /* Stop Dao */
            if (proposals[_index].proposalType == 4) {
                _updateInflation();
                daoEndTime = block.timestamp;

                _subtractTotalShares(
                    _safeSubtract(
                        (_safeSubtract(inflationShares, totalCouncilSharesGiven)),
                        _safeSubtract(totalBonusSharesUnlocked, bonusSharesUnlocked)
                    )
                );

                bonusSharesUnlocked = 0;
            }

            /* New Member */
            if (proposals[_index].proposalType == 5) {}

            /* Space saving checker for the next 2 proposals */
            if (proposals[_index].proposalType == 6 || proposals[_index].proposalType == 7) {
                _pendingCommit(members[proposals[_index].existingAddress].commitSchedule[proposals[_index].amountOrIndex]);
            }
            /* Slash Member */
            if (proposals[_index].proposalType == 6) {
                uint256 memberCommit = members[proposals[_index].existingAddress].commited;

                uint256 slashAmount = (((memberCommit * callSchedulePercentage[proposals[_index].amountOrIndex]) / 100) +
                    ((memberCommit * DAOConfig.PENALTY_PERCENT) / 1000));

                members[proposals[_index].existingAddress].shares = _safeSubtract(members[proposals[_index].existingAddress].shares, slashAmount);
                members[proposals[_index].existingAddress].commitSchedule[proposals[_index].amountOrIndex] = CommitStatus.Slashed;

                _subtractTotalShares(slashAmount);

                emit MemberSlashed(proposals[_index].existingAddress, proposals[_index].amountOrIndex);
            }
            /* Pardon Member */
            if (proposals[_index].proposalType == 7) {
                uint256 pardonAmount = ((members[proposals[_index].existingAddress].commited *
                    callSchedulePercentage[proposals[_index].amountOrIndex]) / 100);

                members[proposals[_index].existingAddress].shares = _safeSubtract(members[proposals[_index].existingAddress].shares, pardonAmount);
                members[proposals[_index].existingAddress].commitSchedule[proposals[_index].amountOrIndex] = CommitStatus.Pardoned;

                _subtractTotalShares(pardonAmount);

                emit MemberPardoned(proposals[_index].existingAddress, proposals[_index].amountOrIndex);
            }

            /* Space saving checker for the next 2 proposals */
            if (proposals[_index].proposalType == 8 || proposals[_index].proposalType == 9) {
                _memberCheck(proposals[_index].addressArray);
            }
            /* Give Bonus */
            if (proposals[_index].proposalType == 8) {
                _updateInflation();
                uint256 totalBonus = 0;
                for (uint256 i = 0; i < proposals[_index].amountArray.length; i++) {
                    require(proposals[_index].amountArray[i] <= bonusSharesUnlocked, "EA28"); //Giving out too much bonus in one go

                    members[proposals[_index].addressArray[i]].shares =
                        members[proposals[_index].addressArray[i]].shares +
                        proposals[_index].amountArray[i];

                    totalBonus += proposals[_index].amountArray[i];
                }

                require(totalBonus <= bonusSharesUnlocked, "EA29"); //Giving out too much bonus in total

                bonusSharesUnlocked = _safeSubtract(bonusSharesUnlocked, totalBonus);
            }

            /* Nominate council */
            if (proposals[_index].proposalType == 9) {
                _updateInflation();
                lastNominateCouncilVote = block.timestamp;
                councilMembers.push(proposals[_index].addressArray);

                uint256 councilLength = getTotalCouncilLength();

                for (uint256 i = 0; i < getNumCouncil(councilLength - 2); i++) {
                    members[getCouncilMember(councilLength - 2, i)].status = MemberStatus.Member;
                }
                for (uint256 i = 0; i < getNumCouncil(councilLength - 2); i++) {
                    members[getCouncilMember(councilLength - 1, i)].status = MemberStatus.Council;
                }
            }

            /* Assume role and withdraw */
            if (proposals[_index].proposalType == 10) {
                uint256 extraTimeBuffer = 0;
                if (members[proposals[_index].existingAddress].lastClaimed < daoEndTime) {
                    if (members[proposals[_index].existingAddress].lastClaimed == 0) {
                        extraTimeBuffer = _safeSubtract(daoEndTime, daoStartTime);
                    } else {
                        extraTimeBuffer = _safeSubtract(daoEndTime, members[proposals[_index].existingAddress].lastClaimed);
                    }
                }
                require(
                    _safeSubtract(block.timestamp, members[proposals[_index].existingAddress].lastClaimed) > (extraTimeBuffer + 78 weeks),
                    "EA49"
                ); //Cant assume role if member has claimed within the last 1.5 years post DAO ending
                _claimReturns(
                    proposals[_index].token,
                    proposals[_index].amountOrIndex,
                    proposals[_index].existingAddress,
                    proposals[_index].newAddress
                );
            }

            /* Change DAO Metadata */
            if (proposals[_index].proposalType == 11) {
                DAOConfig.DAO_METADATA_URI = proposals[_index].propVars.detailsURI;
            }
        }
        emit ProcessProposal(_index, proposals[_index].propVars.status);
    }

    /**
     * @notice removeMembership
     * @param  _existingMember Member that will be removed
     * @param  _token Proposal by external entities to join the DAO. Allows interactions from anyone
     */
    function removeMembership(address _existingMember, address _token) private {
        _removeMembership(_existingMember, _token);
    }

    /* Aux Functions */

    /**
     * @notice setFundingCall
     */
    function setFundingCall(uint256 _index) external {
        /*Checks*/
        _daoActive();
        _onlyMember();
        _setFundingCall(_index);
    }

    /**
     * @notice honourFundingCall
     * @param _index which period to honor funding
     * @param _token the address of the token to honour the call with
     */
    function honourFundingCall(uint256 _index, address _token) public {
        /*Checks*/
        _onlyMember();

        //Should be in primary token
        require(
            ICapitalVault(VaultDirectory.CapitalVault).getWhitelistedTokens(_token) &&
                IOperationsVault(VaultDirectory.OperationsVault).getWhitelistedTokens(_token),
            "EA32"
        ); //Token not approved

        require(callScheduleStatus[_index] == CallStatus.Called, "EA34"); //This round has not been called

        require(members[msg.sender].commitSchedule[_index] != CommitStatus.Met, "EA35"); //This member has already honoured the call

        require(
            members[msg.sender].commitSchedule[_index] != CommitStatus.Slashed || members[msg.sender].commitSchedule[_index] != CommitStatus.Pardoned,
            "EA36"
        ); //This member has already been slashed

        uint256 totalAmount = (members[msg.sender].commited * callSchedulePercentage[_index]) / 100;
        uint256 operationsAmount = totalAmount / (1000 / DAOConfig.OPERATION_INFLATION);
        uint256 capitalAmount = _safeSubtract(totalAmount, operationsAmount);

        IERC20DP tempToken = IERC20DP(_token);

        tempToken.transferFrom(msg.sender, VaultDirectory.OperationsVault, getStandardisedDecimalPrecisionDownscale(operationsAmount, _token));
        tempToken.transferFrom(msg.sender, VaultDirectory.CapitalVault, getStandardisedDecimalPrecisionDownscale(capitalAmount, _token));

        members[msg.sender].commitSchedule[_index] = CommitStatus.Met;

        emit CurrentBalance(_token, tempToken.balanceOf(VaultDirectory.OperationsVault), VaultDirectory.OperationsVault);
        emit CurrentBalance(_token, tempToken.balanceOf(VaultDirectory.CapitalVault), VaultDirectory.CapitalVault);
        emit HonouredFundingCall(msg.sender, _index);
    }

    /**
     * @notice confirmMembership
     * @param _index the index of the proposal
     * @param _token the address of the token to honour the call with
     * Loophole exists that if a member gets kicked prior to fund starting, he can rejoin straight away. Not sure if we want to stop this loophole as he has to commit again.
     */
    function confirmMembership(uint256 _index, address _token) external {
        _daoActive();
        require(ICapitalVault(VaultDirectory.CapitalVault).getPrimaryToken() == _token, "EA50"); //This token is not approved

        require(canJoin, "EA24"); //Signups have stopped
        require((proposals[_index].propVars.closedDate < block.timestamp + 14 days), "EA37"); //2 weeks to join has passed, new proposal required
        require(proposals[_index].proposalType == 5, "EA38"); //Must be a new member proposal

        require(proposals[_index].propVars.status == Status.Passed, "EA39"); //Not enough votes
        require(proposals[_index].newAddress == msg.sender, "EA40"); //Not the right address
        require(members[msg.sender].status != MemberStatus.Member, "EA41"); //Already a member

        members[msg.sender].shares = proposals[_index].amountOrIndex;
        members[msg.sender].status = MemberStatus.Member;
        members[msg.sender].commited = proposals[_index].amountOrIndex;

        _addTotalShares(proposals[_index].amountOrIndex);

        for (uint256 i = 0; i < callScheduleStatus.length; i++) {
            members[msg.sender].commitSchedule.push(CommitStatus.Pending);
        }

        honourFundingCall(0, _token);

        numMembers++;

        emit MemberJoin(msg.sender, members[msg.sender].commited);
    }

    /**
     * @notice _removeMembership
     * @param _existingMember existing member address
     * @param _token Token address for refund from capital vault
     */
    function _removeMembership(address _existingMember, address _token) private {
        ICapitalVault capitalVault = ICapitalVault(VaultDirectory.CapitalVault);

        _tokenCheck(_token, capitalVault.getPrimaryToken());
        uint256 totalUserReturns = getStandardisedDecimalPrecisionDownscale(
            (
                ((members[_existingMember].shares *
                    getStandardisedDecimalPrecisionUpscale(IERC20(_token).balanceOf(VaultDirectory.CapitalVault), _token)) / totalShares)
            ),
            _token
        );

        _subtractTotalShares(members[_existingMember].shares);
        members[_existingMember].status = MemberStatus.NonMember;
        members[_existingMember].shares = 0;
        kickedClaimedTracker += members[_existingMember].claimed;
        capitalVault.withdraw(_token, _existingMember, totalUserReturns);
    }

    /**
     * @notice claimReturns
     * @param _token the address of the token to withdraw
     * @param _amount the amount of returns to withdraw
     */
    function claimReturns(address _token, uint256 _amount) external {
        /* Checks */
        _onlyMember();
        _signupsStopped();

        _claimReturns(_token, _amount, msg.sender, msg.sender);
    }

    /**
     * @notice updateInflation
     */
    function _updateInflation() internal {
        require(block.timestamp > lastUpdatedCouncilShares, "EA44"); //Not enough time has passed

        /* Check if DAO has ended and adjust final inflation to the enddate of the dao */
        uint256 timeTo = block.timestamp;
        if (timeTo > daoEndTime) {
            timeTo = daoEndTime;
        }

        // Conditional, this function is to stop the rest of the function running after dao has ended
        if (timeTo <= lastUpdatedCouncilShares) {
            return;
        }

        uint256 numCouncil = getNumCurrentCouncil();

        // 31540000 seconds in a year, maximum precision used to calculate inflation, used to prevent rounding attacks
        uint256 redeemableTime = ((_safeSubtract(daoEndTime, daoStartTime)) * 31540000) / _safeSubtract(timeTo, lastUpdatedCouncilShares);

        uint256 sharesPerMember = ((((inflationShares) * 31540000) / (numCouncil * redeemableTime)) *
            ((DAOConfig.BASE_INFLATION * 10000) / (getDAOConfigTotalInflation()))) / 10000;

        for (uint256 i = 0; i < numCouncil; i++) {
            members[councilMembers[councilMembers.length - 1][i]].shares += sharesPerMember;
            totalCouncilSharesGiven += sharesPerMember;
        }

        uint256 sharesBonusUnlock = ((((inflationShares) * 31540000) / (redeemableTime)) *
            ((DAOConfig.BONUS_INFLATION * 10000) / (getDAOConfigTotalInflation()))) / 10000;

        bonusSharesUnlocked += sharesBonusUnlock;
        totalBonusSharesUnlocked += sharesBonusUnlock;
        lastUpdatedCouncilShares = timeTo;
    }

    /**
     * @notice replaceCouncilMember
     * @param _oldAddress Existing council member
     * @param _newAddress New council member
     */
    function replaceCouncilMember(address _oldAddress, address _newAddress) private {
        _nullCheck(_oldAddress);
        _nullCheck(_newAddress);

        require(getMemberStatus(_newAddress) == MemberStatus.Member);
        require(getMemberStatus(_oldAddress) == MemberStatus.Council);
        _updateInflation();

        members[_oldAddress].status = MemberStatus.Member;
        members[_newAddress].status = MemberStatus.Council;

        councilMembers.push();

        uint256 councilLength = getTotalCouncilLength();

        for (uint256 i = 0; i < getNumCouncil(councilLength - 2); i++) {
            address councilMember = getCouncilMember(councilLength - 2, i);

            if (councilMember == _oldAddress) {
                councilMembers[councilLength - 1].push(_newAddress);
            } else {
                councilMembers[councilLength - 1].push(councilMember);
            }
        }
    }

    function _setProposalVars(uint256 _index, ProposalDraft memory _proposalDraft) internal {
        proposals[_index].proposalType = _proposalDraft.proposalType;
        _proposalDraft.propVarsDraft.proposer = msg.sender;
        proposals[_index].propVars = IProposalManager(VaultDirectory.ProposalManager).handlePropVars(_proposalDraft.propVarsDraft);
        proposals[_index].propVars.threshold = getDAOConfigBaseVotingThreshold();
        proposals[_index].propVars.endDate = block.timestamp + getDAOConfigVotingPeriod();
        proposals[_index].propVars.totalMembers = getNumMembers();
        proposals[_index].propVars.quorum = DAOConfig.QUORUM;
        proposals[_index].existingAddress = _proposalDraft.existingAddress;
        proposals[_index].newAddress = _proposalDraft.newAddress;
        proposals[_index].amountOrIndex = _proposalDraft.amountOrIndex;
        proposals[_index].token = _proposalDraft.token;
        proposals[_index].addressArray = _proposalDraft.addressArray;
        proposals[_index].amountArray = _proposalDraft.amountArray;
    }

    /**
     * @notice _setFundingCall
     */
    function _setFundingCall(uint256 _index) internal {
        require(_index <= getCurrentRound(), "EA30"); //Must be a previous call
        if (callScheduleStatus[_index] == CallStatus.Called) {
            revert("EA31"); //This round has already been called
        }
        fundingCallTimeTracker[_index] = block.timestamp;
        callScheduleStatus[_index] = CallStatus.Called;

        emit FundingRoundCalled(_index);
    }

    /**
     * @notice _claimreturns
     * @param _token Token address
     * @param _amount Amount claimed
     * @param _fromAddress Address claimed from
     * @param _toAddress Address claimed to, used for delegated claiming if keys lost etc
     */
    function _claimReturns(address _token, uint256 _amount, address _fromAddress, address _toAddress) private {
        IReturnsVault returnsVault = IReturnsVault(VaultDirectory.ReturnsVault);
        require(returnsVault.getPrimaryToken() == _token, "EA50"); //This token is not approved
        _updateInflation();

        // scale here
        uint256 totalUserReturns = _safeSubtract(
            (((members[_fromAddress].shares * (_safeSubtract(returnsVault.getTotalReturns(_token), kickedClaimedTracker))) / (totalShares))),
            members[_fromAddress].claimed
        );

        // scale here
        require(_amount <= totalUserReturns, "EA42"); //Cannot withdraw more than what you are owed
        require(members[_fromAddress].lastClaimed + DAOConfig.CLAIM_PERIOD <= block.timestamp, "EA43"); //Cannot claim before time period elapses

        members[_fromAddress].lastClaimed = block.timestamp;

        // Scale here
        members[_fromAddress].claimed += _amount;

        returnsVault.withdraw(_token, _toAddress, getStandardisedDecimalPrecisionDownscale(_amount, _token));

        emit Claimed(_fromAddress, _amount);
    }

    function _addTotalShares(uint256 _amount) internal {
        totalShares += _amount;
    }

    function _subtractTotalShares(uint256 _amount) internal {
        totalShares = _safeSubtract(totalShares, _amount);
    }

    /**
     * @notice changeMetadata
     * @param _metadata New metadata
     */
    function changeMetadata(string memory _metadata) external {
        _onlyMember();
        emit MemberMetadata(_metadata);
    }

    /************************ Aux *************************/
    function _pendingCommit(CommitStatus _status) internal pure {
        require(_status == CommitStatus.Pending, "EA51"); //Must be in a pending commitment state
    }

    /************************ Checks ~ Modifiers *************************/
    /* NOTE: Traditional Modifiers not used as the contract size is too large */

    function _signupsStopped() internal view {
        require(!canJoin, "EA19"); //Signups must have already stopped
    }

    function _onlyMember() internal view {
        require(members[msg.sender].status == MemberStatus.Member || members[msg.sender].status == MemberStatus.Council, "EA45"); //Not a member of the DAO
    }

    function _memberCheck(address[] memory _addresses) internal view {
        for (uint256 i = 0; i < _addresses.length; i++) {
            _nullCheck(_addresses[i]);
            require(members[_addresses[i]].status == MemberStatus.Member || members[_addresses[i]].status == MemberStatus.Council, "EA45"); //Not a member of the DAO
        }
    }

    function _tokenCheck(address _token1, address _token2) internal view {
        require(_token1 == _token2, "EA32"); //Token not approved
    }

    function _daoActive() internal view {
        require(block.timestamp <= daoEndTime, "EA47"); //DAO has ended
    }
}

File 2 of 9 : ICapitalVault.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

interface ICapitalVault {
    function initialize(address _baseToken) external;

    function getPrimaryToken() external view returns (address);

    function getWhitelistedTokens(address _token) external view returns (bool);

    function withdraw(
        address _token,
        address _recipient,
        uint256 _amount
    ) external;
}

File 3 of 9 : DAO.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IDAO.sol";

contract DAO is IDAO {
    /******************** Constants *********************/

    /******************** Public Variables *********************/
    mapping(address => bool) public whitelistedTokens; //Tokens whitelisted per vault (only stables should be used in v1 due to the shares mechanics) Sub vaults can interact with any tokens.

    uint256 public proposalIndex;

    /******************** Structs and Definitions *********************/
    mapping(uint256 => Proposal) public proposals;

    function _safeSubtract(uint256 _num1, uint256 _num2) internal pure returns (uint256) {
        if (_num2 >= _num1) {
            return 0;
        } else {
            return (_num1 - _num2);
        }
    }

    function _nullCheck(address _address) internal pure {
        require(_address != address(0), "ED0"); //This address cannot be null
    }
}

File 4 of 9 : IReturnsVault.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

interface IReturnsVault {
    function initialize(address _baseToken) external;

    function getPrimaryToken() external view returns (address);

    function getWhitelistedTokens(address _token) external view returns (bool);

    function getTotalReturns(address _token) external returns (uint256);

    function sync(address _token) external;

    function withdraw(
        address _token,
        address _recipient,
        uint256 _amount
    ) external;
}

File 5 of 9 : IOperationsVault.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

interface IOperationsVault {
    function initialize(address _baseToken) external;

    function getWhitelistedTokens(address _token) external view returns (bool);
}

File 6 of 9 : IERC20DP.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20DP {
    /**
     * @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 decimals.
     */
    function decimals() external view returns (uint8);

    /**
     * @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 7 of 9 : IProposalManager.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
import "../interfaces/IDAO.sol";

interface IProposalManager is IDAO {
    function handlePropVars(ProposalVariablesDraft calldata _propVarsDraft) external view returns (ProposalVariables memory);

    function voteProposal(address _voter, ProposalVariables calldata _propVars, Vote _vote) external view returns (ProposalVariables memory);

    function processProposalSecurity(ProposalVariables calldata _propVars) external view returns (ProposalVariables memory);
}

File 8 of 9 : IDAO.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

interface IDAO {
    event CurrentBalance(address _token, uint256 _amount, address _vault);

    enum Vote {
        Null,
        Yes,
        No
    }

    enum Status {
        Pending,
        Passed,
        Failed
    }

    enum MemberStatus {
        NonMember,
        Member,
        Council
    }

    /* 
        Aetos Proposal Types:
            0: Text vote, 
            1: Replace a single council member, 
            2: Existing member kick, 
            3: Stop signups, 
            4: Stop DAO, 
            5: New Member, 
            6: Slash member, 
            7: Pardon member, 
            8: Issue bonus shares,
            9: Nominate new council,
            10: Assume role and withdraw

        Capital Vault Proposal Types:
            0: AMM Swap,
            1: Token Whitelist,
            2: Funding
        
        Operations Vault Proposal Types:
            0: AMM Swap,
            1: Token Whitelist,
            2: Contributor

        Returns Vault Proposal Types:
            0: AMM Swap,
            1: Token Whitelist

        Sub Vault Proposal Types:
            0: Token Whitelist,
            1: Custom Txn,
            2: Close Sub Vault,
            3: Manager add,
            4: Manager remove,
            5: Manager replace,
            6: Issue Returns to main vaults
        */
    struct Proposal {
        uint256 proposalType;
        address existingAddress; // Used in proposals that require existing member addresses
        address newAddress; // Used in proposals that introduce new member addresses
        address[] addressArray;
        uint256[] amountArray;
        address amm;
        address token;
        uint256 amountOrIndex;
        bool whitelist;
        bool active;
        CustomTxn customTxn;
        ProposalVariables propVars;
    }

    struct ProposalDraft {
        uint256 proposalType;
        address existingAddress; // Used in proposals that require existing member addresses
        address newAddress; // Used in proposals that introduce new member addresses
        address[] addressArray;
        uint256[] amountArray;
        address amm;
        address token;
        uint256 amountOrIndex;
        bool whitelist;
        bool active;
        CustomTxn customTxn;
        ProposalVariablesDraft propVarsDraft;
    }

    struct CustomTxn {
        address contractAddress;
        bytes params;
    }

    struct ProposalVariables {
        address proposer;
        uint256 startDate; // When the proposal was created
        uint256 endDate; // When the voting period ends for the proposal
        uint256 closedDate; // When the proposal was finalised
        uint256 threshold /* Between 0-100, i.e. 50 = 50% */;
        uint256 quorum; // Min amount of votes required
        uint256 totalMembers; //Total members that can potentially vote for this
        string detailsURI;
        uint256 yesVotes;
        uint256 noVotes;
        Status status;
        address[] voters;
    }

    struct ProposalVariablesDraft {
        address proposer;
        string detailsURI;
    }
}

File 9 of 9 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.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);
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_vault","type":"address"}],"name":"CurrentBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"FundingRoundCalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"HonouredFundingCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_commitment","type":"uint256"}],"name":"MemberJoin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"}],"name":"MemberLeave","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_metadata","type":"string"}],"name":"MemberMetadata","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"MemberPardoned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"MemberSlashed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"enum IDAO.Status","name":"_status","type":"uint8"}],"name":"ProcessProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"components":[{"internalType":"uint256","name":"proposalType","type":"uint256"},{"internalType":"address","name":"existingAddress","type":"address"},{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"address[]","name":"addressArray","type":"address[]"},{"internalType":"uint256[]","name":"amountArray","type":"uint256[]"},{"internalType":"address","name":"amm","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountOrIndex","type":"uint256"},{"internalType":"bool","name":"whitelist","type":"bool"},{"internalType":"bool","name":"active","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"internalType":"struct IDAO.CustomTxn","name":"customTxn","type":"tuple"},{"components":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"startDate","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"uint256","name":"closedDate","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"quorum","type":"uint256"},{"internalType":"uint256","name":"totalMembers","type":"uint256"},{"internalType":"string","name":"detailsURI","type":"string"},{"internalType":"uint256","name":"yesVotes","type":"uint256"},{"internalType":"uint256","name":"noVotes","type":"uint256"},{"internalType":"enum IDAO.Status","name":"status","type":"uint8"},{"internalType":"address[]","name":"voters","type":"address[]"}],"internalType":"struct IDAO.ProposalVariables","name":"propVars","type":"tuple"}],"indexed":false,"internalType":"struct IDAO.Proposal","name":"_proposal","type":"tuple"}],"name":"ProposeProposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":true,"internalType":"enum IDAO.Vote","name":"_vote","type":"uint8"}],"name":"VoteProposal","type":"event"},{"inputs":[],"name":"DAOConfig","outputs":[{"internalType":"uint256","name":"COUNCIL_MEMBER_SIZE","type":"uint256"},{"internalType":"uint256","name":"BASE_INFLATION","type":"uint256"},{"internalType":"uint256","name":"OPERATION_INFLATION","type":"uint256"},{"internalType":"uint256","name":"BONUS_INFLATION","type":"uint256"},{"internalType":"uint256","name":"PENALTY_PERCENT","type":"uint256"},{"internalType":"uint256","name":"COUNCIL_VOTING_PERIOD","type":"uint256"},{"internalType":"uint256","name":"MIN_COMMITMENT","type":"uint256"},{"internalType":"uint256","name":"MAX_COMMITMENT","type":"uint256"},{"internalType":"uint256","name":"VOTING_PERIOD","type":"uint256"},{"internalType":"uint256","name":"BASE_VOTING_THRESHOLD","type":"uint256"},{"internalType":"uint256","name":"QUORUM","type":"uint256"},{"internalType":"uint256","name":"CLAIM_PERIOD","type":"uint256"},{"internalType":"string","name":"DAO_METADATA_URI","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VaultDirectory","outputs":[{"internalType":"address","name":"CapitalVault","type":"address"},{"internalType":"address","name":"OperationsVault","type":"address"},{"internalType":"address","name":"ReturnsVault","type":"address"},{"internalType":"address","name":"ProposalManager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusSharesUnlocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"callSchedulePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"callScheduleStatus","outputs":[{"internalType":"enum Aetos.CallStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canJoin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_metadata","type":"string"}],"name":"changeMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimReturns","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"confirmMembership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractInit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"councilMembers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoInit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"fundingCallTimeTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCallScheduleLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCanJoin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_council","type":"uint256"},{"internalType":"uint256","name":"_member","type":"uint256"}],"name":"getCouncilMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getCouncilMembers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAOConfigBaseVotingThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAOConfigCouncilMemberSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAOConfigTotalInflation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAOConfigVotingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDAOEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_member","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getMemberCommitStatus","outputs":[{"internalType":"enum Aetos.CommitStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_member","type":"address"}],"name":"getMemberStatus","outputs":[{"internalType":"enum IDAO.MemberStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNumCouncil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumCurrentCouncil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumMembers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOperationsVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOperationsVaultPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProposalManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReturnsVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_primaryToken","type":"address"}],"name":"getStandardisedDecimalPrecisionDownscale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"getStandardisedDecimalPrecisionUpscale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalCouncilLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"honourFundingCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"inflationShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"COUNCIL_MEMBER_SIZE","type":"uint256"},{"internalType":"uint256","name":"BASE_INFLATION","type":"uint256"},{"internalType":"uint256","name":"OPERATION_INFLATION","type":"uint256"},{"internalType":"uint256","name":"BONUS_INFLATION","type":"uint256"},{"internalType":"uint256","name":"PENALTY_PERCENT","type":"uint256"},{"internalType":"uint256","name":"COUNCIL_VOTING_PERIOD","type":"uint256"},{"internalType":"uint256","name":"MIN_COMMITMENT","type":"uint256"},{"internalType":"uint256","name":"MAX_COMMITMENT","type":"uint256"},{"internalType":"uint256","name":"VOTING_PERIOD","type":"uint256"},{"internalType":"uint256","name":"BASE_VOTING_THRESHOLD","type":"uint256"},{"internalType":"uint256","name":"QUORUM","type":"uint256"},{"internalType":"uint256","name":"CLAIM_PERIOD","type":"uint256"},{"internalType":"string","name":"DAO_METADATA_URI","type":"string"}],"internalType":"struct Aetos.ConfigStruct","name":"_DAOConfig","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_callSchedule","type":"uint256[]"},{"internalType":"uint256","name":"_scheduleTime","type":"uint256"},{"internalType":"address[]","name":"_council","type":"address[]"},{"internalType":"uint256[]","name":"_commitments","type":"uint256[]"},{"internalType":"uint256","name":"_daoEndSec","type":"uint256"},{"components":[{"internalType":"address","name":"CapitalVault","type":"address"},{"internalType":"address","name":"OperationsVault","type":"address"},{"internalType":"address","name":"ReturnsVault","type":"address"},{"internalType":"address","name":"ProposalManager","type":"address"}],"internalType":"struct Aetos.DirectoryStruct","name":"_vaultDirectory","type":"tuple"}],"name":"initializeDAO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"kickedClaimedTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastNominateCouncilVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdatedCouncilShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"members","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"enum IDAO.MemberStatus","name":"status","type":"uint8"},{"internalType":"uint256","name":"commited","type":"uint256"},{"internalType":"uint256","name":"claimed","type":"uint256"},{"internalType":"uint256","name":"lastClaimed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numMembers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposalIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"uint256","name":"proposalType","type":"uint256"},{"internalType":"address","name":"existingAddress","type":"address"},{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"address","name":"amm","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountOrIndex","type":"uint256"},{"internalType":"bool","name":"whitelist","type":"bool"},{"internalType":"bool","name":"active","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"internalType":"struct IDAO.CustomTxn","name":"customTxn","type":"tuple"},{"components":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"startDate","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"uint256","name":"closedDate","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"quorum","type":"uint256"},{"internalType":"uint256","name":"totalMembers","type":"uint256"},{"internalType":"string","name":"detailsURI","type":"string"},{"internalType":"uint256","name":"yesVotes","type":"uint256"},{"internalType":"uint256","name":"noVotes","type":"uint256"},{"internalType":"enum IDAO.Status","name":"status","type":"uint8"},{"internalType":"address[]","name":"voters","type":"address[]"}],"internalType":"struct IDAO.ProposalVariables","name":"propVars","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"proposalType","type":"uint256"},{"internalType":"address","name":"existingAddress","type":"address"},{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"address[]","name":"addressArray","type":"address[]"},{"internalType":"uint256[]","name":"amountArray","type":"uint256[]"},{"internalType":"address","name":"amm","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountOrIndex","type":"uint256"},{"internalType":"bool","name":"whitelist","type":"bool"},{"internalType":"bool","name":"active","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"internalType":"struct IDAO.CustomTxn","name":"customTxn","type":"tuple"},{"components":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"string","name":"detailsURI","type":"string"}],"internalType":"struct IDAO.ProposalVariablesDraft","name":"propVarsDraft","type":"tuple"}],"internalType":"struct IDAO.ProposalDraft","name":"_proposalDraft","type":"tuple"}],"name":"propose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"proposalType","type":"uint256"},{"internalType":"address","name":"existingAddress","type":"address"},{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"address[]","name":"addressArray","type":"address[]"},{"internalType":"uint256[]","name":"amountArray","type":"uint256[]"},{"internalType":"address","name":"amm","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountOrIndex","type":"uint256"},{"internalType":"bool","name":"whitelist","type":"bool"},{"internalType":"bool","name":"active","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"internalType":"struct IDAO.CustomTxn","name":"customTxn","type":"tuple"},{"components":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"string","name":"detailsURI","type":"string"}],"internalType":"struct IDAO.ProposalVariablesDraft","name":"propVarsDraft","type":"tuple"}],"internalType":"struct IDAO.ProposalDraft","name":"_proposalDraft","type":"tuple"}],"name":"proposeMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scheduleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"setFundingCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalBonusSharesUnlocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCouncilSharesGiven","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"enum IDAO.Vote","name":"_vote","type":"uint8"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040526020805462ffffff1916905534801561001c57600080fd5b50615fdc806200002d6000396000f3fe608060405234801561001057600080fd5b506004361061038d5760003560e01c80636b0e575f116101de578063b3c4547b1161010f578063dde8535f116100ad578063e92c38591161007c578063e92c3859146107c8578063f66bcac4146107db578063f80e1c89146107e4578063ffb2c479146107ec57600080fd5b8063dde8535f1461077a578063e3d27f291461079a578063e6e32ad3146107a2578063e84e0eb0146107b557600080fd5b8063c37191d4116100e9578063c37191d41461071b578063d9b6225e1461073c578063daf9c2101461074f578063dcb262321461077257600080fd5b8063b3c4547b146106eb578063b58e8f03146106f3578063b8ac3146146106fb57600080fd5b80638906994a1161017c5780639f338e77116101565780639f338e77146106ba578063a32bf597146106cd578063a86eaca4146106d5578063ac6d7816146106e257600080fd5b80638906994a1461068b578063943e82161461069e57806396dbd9e0146106b157600080fd5b8063792de97c116101b8578063792de97c14610634578063797bbfe7146106475780637f02ac54146106675780638652169d1461067a57600080fd5b80636b0e575f146106025780636eac2ccb1461060b57806374d2ea7c1461061457600080fd5b806334ce66de116102c35780634f6c488b116102615780635d97505b116102305780635d97505b146105c35780635fc9e6be146105d457806361082b3d146105dc57806369740a2a146105ef57600080fd5b80634f6c488b1461058c578063546213a2146105945780635977e0f2146105a75780635c746f82146105b057600080fd5b806340f40d321161029d57806340f40d32146105435780634698d110146105685780634c1b34f9146105715780634e3fe0fd1461058457600080fd5b806334ce66de146105155780633a98ef39146105285780633c8d1dd81461053157600080fd5b80631b48201e11610330578063289c25f41161030a578063289c25f4146104895780632e5ade11146104a0578063305104a7146104f95780633303c2691461050257600080fd5b80631b48201e1461045757806321d84c4b1461047757806326e6979b1461048057600080fd5b806308ae4b0c1161036c57806308ae4b0c146103e0578063112a502914610432578063132cd0621461043a57806317d5430a1461044f57600080fd5b80621402da14610392578063013cf08b146103ae57806304873f5d146103d7575b600080fd5b61039b60185481565b6040519081526020015b60405180910390f35b6103c16103bc366004614b22565b6107ff565b6040516103a59a99989796959493929190614cb9565b61039b60155481565b6104216103ee366004614d75565b60246020526000908152604090208054600182015460028301546004840154600590940154929360ff9092169290919085565b6040516103a5959493929190614d99565b61039b610aaa565b61044d6104483660046150e8565b610ac1565b005b60215461039b565b61046a610465366004614b22565b610f9e565b6040516103a59190615243565b61039b601e5481565b61039b60235481565b60205460ff165b60405190151581526020016103a5565b6010546011546012546013546104c6936001600160a01b03908116938116928116911684565b604080516001600160a01b03958616815293851660208501529184169183019190915290911660608201526080016103a5565b61039b601c5481565b61044d610510366004615290565b61101d565b61044d6105233660046150e8565b61103d565b61039b60195481565b60205461049090610100900460ff1681565b6011546001600160a01b03165b6040516001600160a01b0390911681526020016103a5565b61039b60215481565b61044d61057f3660046152bc565b61120b565b60055461039b565b600b5461039b565b61044d6105a236600461539c565b6113e6565b61039b60015481565b61039b6105be36600461539c565b611793565b6013546001600160a01b0316610550565b60035461039b565b61039b6105ea366004614b22565b611828565b61039b6105fd36600461539c565b61184f565b61039b601a5481565b61039b60145481565b61039b610622366004614b22565b60256020526000908152604090205481565b61039b610642366004614b22565b6118d0565b61065a610655366004615290565b6118f1565b6040516103a591906153cc565b6105506106753660046153e6565b611946565b6012546001600160a01b0316610550565b6105506106993660046153e6565b611992565b61044d6106ac366004615415565b6119d6565b61039b601d5481565b61044d6106c836600461543a565b611bbe565b61039b612234565b6020546104909060ff1681565b61039b601f5481565b60225461039b565b60155461039b565b61070e610709366004614b22565b6122b2565b6040516103a59190615542565b6107236122e6565b6040516103a59d9c9b9a99989796959493929190615556565b61044d61074a3660046155cc565b6123b3565b61049061075d366004614d75565b60006020819052908152604090205460ff1681565b60175461039b565b61078d610788366004614d75565b6123f5565b6040516103a59190615608565b600c5461039b565b6020546104909062010000900460ff1681565b61044d6107c336600461539c565b612416565b61044d6107d6366004614b22565b612acd565b61039b601b5481565b61039b612ae9565b61044d6107fa366004614b22565b612b1e565b600260208181526000928352604092839020805460018201549382015460058301546006840154600785015460088601548951808b01909a526009870180546001600160a01b039081168c52600a89018054989c9b82169b9782169a968216999590911697939660ff8085169761010090950416959490938401919061088490615615565b80601f01602080910402602001604051908101604052809291908181526020018280546108b090615615565b80156108fd5780601f106108d2576101008083540402835291602001916108fd565b820191906000526020600020905b8154815290600101906020018083116108e057829003601f168201915b5050509190925250506040805161018081018252600b850180546001600160a01b03168252600c8601546020830152600d86015492820192909252600e8501546060820152600f8501546080820152601085015460a0820152601185015460c082015260128501805494959491935060e084019161097a90615615565b80601f01602080910402602001604051908101604052809291908181526020018280546109a690615615565b80156109f35780601f106109c8576101008083540402835291602001916109f3565b820191906000526020600020905b8154815290600101906020018083116109d657829003601f168201915b50505091835250506008820154602082015260098201546040820152600a82015460609091019060ff166002811115610a2e57610a2e614b8b565b6002811115610a3f57610a3f614b8b565b8152602001600b8201805480602002602001604051908101604052809291908181526020018280548015610a9c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a7e575b50505050508152505090508a565b600454600654600091610abc91615665565b905090565b610ac9613a25565b8051600b1015610b0d5760405162461bcd60e51b8152600401610b049060208082526004908201526308a8262760e31b604082015260600190565b60405180910390fd5b6000816101600151602001515111610b4d5760405162461bcd60e51b815260206004820152600360248201526204541360ec1b6044820152606401610b04565b610b5960015482613ab7565b8051600103610bf957610b6a613d20565b610b778160400151613d5c565b60208101516001600160a01b03163314610b9057600080fd5b60408101516001600160a01b03163303610ba957600080fd5b6001610bb882604001516123f5565b6002811115610bc957610bc9614b8b565b14610bd357600080fd5b6002610bde336123f5565b6002811115610bef57610bef614b8b565b14610bf957600080fd5b8051600203610c8357610c0a613d20565b6010546040805163a775888360e01b81529051610c83926001600160a01b03169163a77588839160048083019260209291908290030181865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190615683565b8260c00151613d98565b8051600403610cae57610c94613d20565b6001546000908152600260205260409020605a600f909101555b8051600503610ce85760405162461bcd60e51b8152600401610b04906020808252600490820152634541323160e01b604082015260600190565b805160061480610cf9575080516007145b15610e1157610d06613d20565b610d138160200151613d5c565b600160178260e0015181548110610d2c57610d2c6156a0565b90600052602060002090602091828204019190069054906101000a900460ff166001811115610d5d57610d5d614b8b565b14610d6757600080fd5b60006024600083602001516001600160a01b03166001600160a01b031681526020019081526020016000206003018260e0015181548110610daa57610daa6156a0565b90600052602060002090602091828204019190069054906101000a900460ff166003811115610ddb57610ddb614b8b565b14610de557600080fd5b600b5460e08201516000908152602560205260409020544291610e0791615665565b10610e1157600080fd5b8051600803610e6457610e22613d20565b80606001515181608001515114610e645760405162461bcd60e51b8152600401610b049060208082526004908201526322a0991960e11b604082015260600190565b8051600903610efb57610e75613d20565b600854601d54610e859190615665565b4211610ebc5760405162461bcd60e51b8152600401610b04906020808252600490820152634541323360e01b604082015260600190565b60035481606001515114610efb5760405162461bcd60e51b8152600401610b04906020808252600490820152634541313360e01b604082015260600190565b8051600a03610f3e576015544211610f3e5760405162461bcd60e51b8152600401610b049060208082526004908201526308a8268760e31b604082015260600190565b6001546000818152600260205260409081902090517fc71a1e2cb91ef76d3fec5535207e4457a4bd2b772f99618204772d34df8ebb9891610f7e91615891565b60405180910390a260018054906000610f9683615996565b919050555050565b606060228281548110610fb357610fb36156a0565b9060005260206000200180548060200260200160405190810160405280929190818152602001828054801561101157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ff3575b50505050509050919050565b611025613a25565b61102d613d20565b61103982823333613de2565b5050565b80516005146110775760405162461bcd60e51b8152600401610b049060208082526004908201526308a8262760e31b604082015260600190565b60205460ff166110b25760405162461bcd60e51b8152600401610b049060208082526004908201526311504c8d60e21b604082015260600190565b60016110bd336123f5565b60028111156110ce576110ce614b8b565b1415806110f5575060026110e1336123f5565b60028111156110f2576110f2614b8b565b14155b61112a5760405162461bcd60e51b8152600401610b04906020808252600490820152634541323560e01b604082015260600190565b60095460e0820151108015906111465750600a5460e082015111155b61117b5760405162461bcd60e51b8152600401610b049060208082526004908201526322a0991b60e11b604082015260600190565b61118760015482613ab7565b6001805460009081526002602081815260408084206013018490558051848152808301808352955485529290915290912090516111ca9260169092019190614a2d565b506001546000818152600260205260409081902090517fc71a1e2cb91ef76d3fec5535207e4457a4bd2b772f99618204772d34df8ebb9891610f7e91615891565b60205462010000900460ff161561124a5760405162461bcd60e51b815260206004820152600360248201526245413760e81b6044820152606401610b04565b8060e001518160c00151106112875760405162461bcd60e51b815260206004820152600360248201526222a09960e91b6044820152606401610b04565b6064816101200151106112c25760405162461bcd60e51b815260206004820152600360248201526245413360e81b6044820152606401610b04565b6103e78160400151826060015183602001516112de9190615665565b6112e89190615665565b1061131b5760405162461bcd60e51b815260206004820152600360248201526245413560e81b6044820152606401610b04565b6032816080015111156113565760405162461bcd60e51b815260206004820152600360248201526222a09b60e91b6044820152606401610b04565b80516003908155602082015160045560408201516005556060820151600655608082015160075560a082015160085560c082015160095560e0820151600a55610100820151600b55610120820151600c55610140820151600d55610160820151600e55610180820151829190600f906113cf90826159fd565b50506020805462ff00ff1916620100011790555050565b6113ee6140e7565b6010546040805163a775888360e01b815290516001600160a01b0380851693169163a77588839160048083019260209291908290030181865afa158015611439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145d9190615683565b6001600160a01b03161461149c5760405162461bcd60e51b8152600401610b04906020808252600490820152630454135360e41b604082015260600190565b60205460ff166114d75760405162461bcd60e51b8152600401610b049060208082526004908201526311504c8d60e21b604082015260600190565b6114e44262127500615665565b6000838152600260205260409020600e01541061152c5760405162461bcd60e51b8152600401610b04906020808252600490820152634541333760e01b604082015260600190565b6000828152600260205260409020546005146115735760405162461bcd60e51b8152600401610b049060208082526004908201526308a8266760e31b604082015260600190565b600160008381526002602081905260409091206015015460ff169081111561159d5761159d614b8b565b146115d35760405162461bcd60e51b8152600401610b04906020808252600490820152634541333960e01b604082015260600190565b600082815260026020819052604090912001546001600160a01b031633146116265760405162461bcd60e51b8152600401610b04906020808252600490820152630454134360e41b604082015260600190565b60013360009081526024602052604090206001015460ff16600281111561164f5761164f614b8b565b036116855760405162461bcd60e51b8152600401610b04906020808252600490820152634541343160e01b604082015260600190565b60008281526002602081815260408084206007018054338652602484529185209182556001808301805460ff191690911790555490830181905592859052526116cd90614122565b60005b601754811015611727573360009081526024602090815260408220600301805460018101825590835291819020908204018054601f9092166101000a60ff021990911690558061171f81615996565b9150506116d0565b50611733600082612416565b6021805490600061174383615996565b9091555050336000818152602460209081526040918290206002015491519182527f6caf6186588a289956ca08d23a7cbfe2ca473d5969db8117a4cbbe45a96674d1910160405180910390a25050565b6000670de0b6b3a7640000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118009190615abc565b61180b90600a615bc3565b6118159085615bd2565b61181f9190615be9565b90505b92915050565b60006022828154811061183d5761183d6156a0565b60009182526020909120015492915050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b39190615abc565b6118be90600a615bc3565b611815670de0b6b3a764000085615bd2565b601681815481106118e057600080fd5b600091825260209091200154905081565b6001600160a01b038216600090815260246020526040812060030180548390811061191e5761191e6156a0565b90600052602060002090602091828204019190069054906101000a900460ff16905092915050565b60006022838154811061195b5761195b6156a0565b906000526020600020018281548110611976576119766156a0565b6000918252602090912001546001600160a01b03169392505050565b602282815481106119a257600080fd5b9060005260206000200181815481106119ba57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6119de613a25565b601354600083815260026020526040908190209051630836aaf960e21b81526001600160a01b03909216916320daabe491611a23913391600b01908690600401615c0b565b600060405180830381865afa158015611a40573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a689190810190615cfc565b6000838152600260209081526040918290208351600b820180546001600160a01b0319166001600160a01b0390921691909117815591840151600c82015591830151600d8301556060830151600e8301556080830151600f83015560a0830151601083015560c0830151601183015560e0830151909160120190611aec90826159fd565b5061010082015160088201556101208201516009820155610140820151600a8201805460ff19166001836002811115611b2757611b27614b8b565b02179055506101608201518051611b4891600b840191602090910190614a2d565b505050600082815260026020818152604083206016018054600181018255908452922090910180546001600160a01b031916331790558190811115611b8f57611b8f614b8b565b60405183907fc92326dacbba7a4c0f0b5ca0bab775311245300cea304ed0655a887fb568662890600090a35050565b602054610100900460ff1615611bfc5760405162461bcd60e51b815260206004820152600360248201526245413760e81b6044820152606401610b04565b8051611c0790613d5c565b611c148160200151613d5c565b611c218160400151613d5c565b611c2e8160600151613d5c565b6000805b8751811015611cc757878181518110611c4d57611c4d6156a0565b602002602001015182611c609190615665565b91506064888281518110611c7657611c766156a0565b60200260200101511115611cb55760405162461bcd60e51b8152600401610b04906020808252600490820152634541313160e01b604082015260600190565b80611cbf81615996565b915050611c32565b5080606414611d015760405162461bcd60e51b8152600401610b049060208082526004908201526322a0989960e11b604082015260600190565b6003548551148015611d1557506003548451145b611d4a5760405162461bcd60e51b8152600401610b04906020808252600490820152634541313360e01b604082015260600190565b82600003611d835760405162461bcd60e51b8152600401610b049060208082526004908201526322a0989b60e11b604082015260600190565b8651611d969060169060208a0190614a92565b50601886905542601d5560228054600101815560009081525b855181101561213357611dda868281518110611dcd57611dcd6156a0565b6020026020010151613d5c565b600260246000888481518110611df257611df26156a0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a81548160ff02191690836002811115611e3e57611e3e614b8b565b0217905550848181518110611e5557611e556156a0565b602002602001015160246000888481518110611e7357611e736156a0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060020181905550600360070154858281518110611eba57611eba6156a0565b602002602001015111158015611eee5750600360060154858281518110611ee357611ee36156a0565b602002602001015110155b611f235760405162461bcd60e51b8152600401610b04906020808252600490820152634541313760e01b604082015260600190565b848181518110611f3557611f356156a0565b602002602001015160246000888481518110611f5357611f536156a0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000181905550611fa4858281518110611f9757611f976156a0565b6020026020010151614122565b858181518110611fb657611fb66156a0565b60200260200101516001600160a01b03167f6caf6186588a289956ca08d23a7cbfe2ca473d5969db8117a4cbbe45a96674d1868381518110611ffa57611ffa6156a0565b602002602001015160405161201191815260200190565b60405180910390a260005b6016548110156120a0576024600088848151811061203c5761203c6156a0565b6020908102919091018101516001600160a01b031682528181019290925260400160009081206003018054600181018255908252908290209181049091018054601f9092166101000a60ff021990911690558061209881615996565b91505061201c565b5060226000815481106120b5576120b56156a0565b906000526020600020018682815181106120d1576120d16156a0565b6020908102919091018101518254600181018455600093845291832090910180546001600160a01b0319166001600160a01b03909216919091179055602180549161211b83615996565b9190505550808061212b90615996565b915050611daf565b5060005b875181101561219c57601780546001810182556000919091527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c1560208204018054601f9092166101000a60ff021990911690558061219481615996565b915050612137565b506121a7600061413c565b8151601080546001600160a01b039283166001600160a01b031991821617909155602084015160118054918416918316919091179055604084015160128054918416918316919091179055606084015160138054919093169116179055426014819055612215908490615665565b601555505042601c5550506020805461ff001916610100179055505050565b60185460165460009161224691615bd2565b6014546122539190615665565b42111561226857601654610abc906001614289565b601654610abc9061227b90600190615df5565b6018546016546122a390612290908390615bd2565b60145461229d9190615665565b42614289565b6122ad9190615be9565b614289565b601781815481106122c257600080fd5b9060005260206000209060209182820401919006915054906101000a900460ff1681565b60038054600454600554600654600754600854600954600a54600b54600c54600d54600e54600f80549c9d9b9c9a9b999a9899979896979596949593949293919261233090615615565b80601f016020809104026020016040519081016040528092919081815260200182805461235c90615615565b80156123a95780601f1061237e576101008083540402835291602001916123a9565b820191906000526020600020905b81548152906001019060200180831161238c57829003601f168201915b505050505090508d565b6123bb613a25565b7f39052d9341110f416317f52c8982d02e4e1c70a295435edccc09fc9c45136cad816040516123ea9190615e08565b60405180910390a150565b6001600160a01b031660009081526024602052604090206001015460ff1690565b61241e613a25565b6010546040516324d6c8d560e01b81526001600160a01b038381166004830152909116906324d6c8d590602401602060405180830381865afa158015612468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248c9190615e1b565b801561250157506011546040516324d6c8d560e01b81526001600160a01b038381166004830152909116906324d6c8d590602401602060405180830381865afa1580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190615e1b565b6125365760405162461bcd60e51b8152600401610b049060208082526004908201526322a0999960e11b604082015260600190565b60016017838154811061254b5761254b6156a0565b90600052602060002090602091828204019190069054906101000a900460ff16600181111561257c5761257c614b8b565b146125b25760405162461bcd60e51b8152600401610b049060208082526004908201526311504ccd60e21b604082015260600190565b60023360009081526024602052604090206003018054849081106125d8576125d86156a0565b90600052602060002090602091828204019190069054906101000a900460ff16600381111561260957612609614b8b565b0361263f5760405162461bcd60e51b8152600401610b04906020808252600490820152634541333560e01b604082015260600190565b6001336000908152602460205260409020600301805484908110612665576126656156a0565b90600052602060002090602091828204019190069054906101000a900460ff16600381111561269657612696614b8b565b1415806126f8575060033360009081526024602052604090206003018054849081106126c4576126c46156a0565b90600052602060002090602091828204019190069054906101000a900460ff1660038111156126f5576126f5614b8b565b14155b61272d5760405162461bcd60e51b8152600401610b049060208082526004908201526322a0999b60e11b604082015260600190565b6000606460168481548110612744576127446156a0565b6000918252602080832090910154338352602490915260409091206002015461276d9190615bd2565b6127779190615be9565b60055490915060009061278c906103e8615be9565b6127969083615be9565b905060006127a48383614289565b60115490915084906001600160a01b03808316916323b872dd913391166127cb8786611793565b6040518463ffffffff1660e01b81526004016127e993929190615e38565b6020604051808303816000875af1158015612808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282c9190615e1b565b506010546001600160a01b03808316916323b872dd9133911661284f868a611793565b6040518463ffffffff1660e01b815260040161286d93929190615e38565b6020604051808303816000875af115801561288c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b09190615e1b565b50336000908152602460205260409020600301805460029190889081106128d9576128d96156a0565b90600052602060002090602091828204019190066101000a81548160ff0219169083600381111561290c5761290c614b8b565b02179055506011546040516370a0823160e01b81526001600160a01b0391821660048201527ffbd50798349c0ef233dafbe6eea9f929785731d11f54b610aea96532af84a7fe918791908416906370a0823190602401602060405180830381865afa15801561297f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a39190615e5c565b601154604080516001600160a01b039485168152602081019390935292168183015290519081900360600190a16010546040516370a0823160e01b81526001600160a01b0391821660048201527ffbd50798349c0ef233dafbe6eea9f929785731d11f54b610aea96532af84a7fe918791908416906370a0823190602401602060405180830381865afa158015612a3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a629190615e5c565b601054604080516001600160a01b039485168152602081019390935292168183015290519081900360600190a160405186815233907fadbb1a8d997c363e82403aaac89860243ed75c64674543ae32a53b239faea5f5906020015b60405180910390a2505050505050565b612ad56140e7565b612add613a25565b612ae68161413c565b50565b6022805460009190612afd90600190615df5565b81548110612b0d57612b0d6156a0565b600091825260209091200154919050565b612b26613a25565b60135460008281526002602052604090819020905163706c869160e11b81526001600160a01b039092169163e0d90d2291612b6991600b90910190600401615e75565b600060405180830381865afa158015612b86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612bae9190810190615cfc565b6000828152600260209081526040918290208351600b820180546001600160a01b0319166001600160a01b0390921691909117815591840151600c82015591830151600d8301556060830151600e8301556080830151600f83015560a0830151601083015560c0830151601183015560e0830151909160120190612c3290826159fd565b5061010082015160088201556101208201516009820155610140820151600a8201805460ff19166001836002811115612c6d57612c6d614b8b565b02179055506101608201518051612c8e91600b840191602090910190614a2d565b5060019150612c9a9050565b60008281526002602081905260409091206015015460ff1690811115612cc257612cc2614b8b565b036139d357600081815260026020526040902054600103612d0c5760008181526002602081905260409091206001810154910154612d0c916001600160a01b0390811691166142ab565b6000818152600260208190526040909120549003612eb55760008181526002602081815260408084206001908101546001600160a01b03168552602490925290922082015460ff1690811115612d6457612d64614b8b565b1480612dae575060008181526002602081815260408084206001908101546001600160a01b0316855260249092529092209091015460ff1681811115612dac57612dac614b8b565b145b612db757600080fd5b60008181526002602081815260408084206001908101546001600160a01b0316855260249092529092209091015460ff1681811115612df857612df8614b8b565b03612e2c5760008181526002602081905260409091206001810154910154612e2c916001600160a01b0390811691166142ab565b60218054906000612e3c83615e88565b909155505060008181526002602052604090206001810154600690910154612e70916001600160a01b03908116911661446c565b6000818152600260205260408082206001015490516001600160a01b03909116917f55cacd41f8c4e378339a4015150f560d647bbc13cad0af49f50cfae4375b1d5491a25b600081815260026020526040902054600303612f4e5760205460ff16612f065760405162461bcd60e51b8152600401610b04906020808252600490820152634541313960e01b604082015260600190565b6020805460ff191690556000612f206103e86122ad610aaa565b601954612f2f906103e8615bd2565b612f399190615be9565b9050612f4781601954614289565b601a556019555b600081815260026020526040902054600403612fa057612f6c614476565b42601581905550612f9a612f95612f87601a54601b54614289565b6122ad601f54601e54614289565b6146ba565b6000601e555b60008181526002602052604090205460061480612fcb57506000818152600260205260409020546007145b1561304257600081815260026020818152604080842060018101546001600160a01b03168552602483529084209385905291905260070154600390910180546130429290811061301d5761301d6156a0565b90600052602060002090602091828204019190069054906101000a900460ff166146cc565b60008181526002602052604090205460060361321d576000818152600260208181526040808420600101546001600160a01b031684526024909152822001546007549091906103e8906130959084615bd2565b61309f9190615be9565b600084815260026020526040902060070154601680546064929081106130c7576130c76156a0565b9060005260206000200154846130dd9190615bd2565b6130e79190615be9565b6130f19190615665565b6000848152600260209081526040808320600101546001600160a01b0316835260249091529020549091506131269082614289565b6000848152600260208181526040808420600180820180546001600160a01b03908116885260248652848820989098555490961685529084209388905291905260070154600390910180549091908110613182576131826156a0565b90600052602060002090602091828204019190066101000a81548160ff021916908360038111156131b5576131b5614b8b565b02179055506131c3816146ba565b600083815260026020908152604091829020600181015460079091015492519283526001600160a01b0316917f3dddf5aaaf675b4fc02037ca34ab0ceee22e5e93d6ee558a4a9a06ff3dab5444910160405180910390a250505b6000818152600260205260409020546007036133cd576000818152600260205260408120600701546016805460649290811061325b5761325b6156a0565b600091825260208083209091015485835260028083526040808520600101546001600160a01b03168552602490935291909220015461329a9190615bd2565b6132a49190615be9565b6000838152600260209081526040808320600101546001600160a01b0316835260249091529020549091506132d99082614289565b60008381526002602081815260408084206001810180546001600160a01b039081168752602485528387209790975554909516845283209286905252600790910154600391820180549091908110613333576133336156a0565b90600052602060002090602091828204019190066101000a81548160ff0219169083600381111561336657613366614b8b565b0217905550613374816146ba565b600082815260026020908152604091829020600181015460079091015492519283526001600160a01b0316917f98c8f362811b9bac88ad292b61228ce60c629f808cce81d3a79edf7ac5fe2680910160405180910390a2505b600081815260026020526040902054600814806133f857506000818152600260205260409020546009145b1561346b57600081815260026020908152604091829020600301805483518184028101840190945280845261346b939283018282801561346157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613443575b5050505050614716565b60008181526002602052604090205460080361367f57613489614476565b6000805b60008381526002602052604090206004015481101561363257601e5460008481526002602052604090206004018054839081106134cc576134cc6156a0565b9060005260206000200154111561350e5760405162461bcd60e51b8152600401610b049060208082526004908201526308a8264760e31b604082015260600190565b6000838152600260205260409020600401805482908110613531576135316156a0565b906000526020600020015460246000600260008781526020019081526020016000206003018481548110613567576135676156a0565b60009182526020808320909101546001600160a01b031683528201929092526040019020546135969190615665565b600084815260026020526040812060030180546024929190859081106135be576135be6156a0565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181209390935585835260029091529020600401805482908110613608576136086156a0565b90600052602060002001548261361e9190615665565b91508061362a81615996565b91505061348d565b50601e5481111561366e5760405162461bcd60e51b8152600401610b04906020808252600490820152634541323960e01b604082015260600190565b61367a601e5482614289565b601e55505b6000818152600260205260409020546009036138135761369d614476565b42601d55600081815260026020526040812060228054600181018255925260030180546136ed927f61035b26e3e9eee00e0d72fd1ee8ddca6894550dca6916ea2ac6baa90d11e510019190614acd565b5060006136f960225490565b905060005b61370c6105ea600284615df5565b8110156137885760016024600061372d613727600287615df5565b85611946565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a81548160ff0219169083600281111561377157613771614b8b565b02179055508061378081615996565b9150506136fe565b5060005b61379a6105ea600284615df5565b811015613810576002602460006137b5613727600187615df5565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a81548160ff021916908360028111156137f9576137f9614b8b565b02179055508061380881615996565b91505061378c565b50505b600081815260026020526040902054600a0361399d576015546000828152600260209081526040808320600101546001600160a01b031683526024909152812060050154909111156138e0576000828152600260209081526040808320600101546001600160a01b03168352602490915281206005015490036138a55761389e601554601454614289565b90506138e0565b6015546000838152600260209081526040808320600101546001600160a01b0316835260249091529020600501546138dd9190614289565b90505b6138ee816302cfd300615665565b6000838152600260209081526040808320600101546001600160a01b031683526024909152902060050154613924904290614289565b1161395a5760405162461bcd60e51b8152600401610b04906020808252600490820152634541343960e01b604082015260600190565b6000828152600260208190526040909120600681015460078201546001830154929093015461399b936001600160a01b039283169390929081169116613de2565b505b600081815260026020526040902054600b036139d3576000818152600260205260409020600f906139d19060120182615e9f565b505b6000818152600260205260409081902060150154905182917fbdb492b15201001c44f021370ca5ea73640ddcc4b4ee020fb9791241973cc37e91613a1a9160ff1690615608565b60405180910390a250565b60013360009081526024602052604090206001015460ff166002811115613a4e57613a4e614b8b565b1480613a80575060023360009081526024602052604090206001015460ff166002811115613a7e57613a7e614b8b565b145b613ab55760405162461bcd60e51b8152600401610b04906020808252600490820152634541343560e01b604082015260600190565b565b805160008381526002602052604090819020919091556101608201805133905260135490519151633c44808d60e21b81526001600160a01b039091169163f112023491613b079190600401615f79565b600060405180830381865afa158015613b24573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613b4c9190810190615cfc565b6000838152600260209081526040918290208351600b820180546001600160a01b0319166001600160a01b0390921691909117815591840151600c82015591830151600d8301556060830151600e8301556080830151600f83015560a0830151601083015560c0830151601183015560e0830151909160120190613bd090826159fd565b5061010082015160088201556101208201516009820155610140820151600a8201805460ff19166001836002811115613c0b57613c0b614b8b565b02179055506101608201518051613c2c91600b840191602090910190614a2d565b5050600c546000848152600260205260409020600f015550600b54613c519042615665565b600083815260026020818152604092839020600d80820195909555602154601182015593546010850155848101516001850180546001600160a01b03199081166001600160a01b039384161790915593860151928501805485169382169390931790925560e0850151600785015560c085015160068501805490941692169190911790915560608301518051613cef93600301929190910190614a2d565b50608081015160008381526002602090815260409091208251613d1b9360049092019290910190614a92565b505050565b60205460ff1615613ab55760405162461bcd60e51b8152600401610b04906020808252600490820152634541313960e01b604082015260600190565b6001600160a01b038116612ae65760405162461bcd60e51b815260206004820152600360248201526204544360ec1b6044820152606401610b04565b806001600160a01b0316826001600160a01b0316146110395760405162461bcd60e51b8152600401610b049060208082526004908201526322a0999960e11b604082015260600190565b6012546040805163a775888360e01b815290516001600160a01b0392831692871691839163a7758883916004808201926020929091908290030181865afa158015613e31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e559190615683565b6001600160a01b031614613e945760405162461bcd60e51b8152600401610b04906020808252600490820152630454135360e41b604082015260600190565b613e9c614476565b601954604051635158684760e01b81526001600160a01b038781166004830152600092613f6f929091613f2191908616906351586847906024016020604051808303816000875af1158015613ef5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f199190615e5c565b602354614289565b6001600160a01b038716600090815260246020526040902054613f449190615bd2565b613f4e9190615be9565b6001600160a01b038616600090815260246020526040902060040154614289565b905080851115613faa5760405162461bcd60e51b8152600401610b049060208082526004908201526322a09a1960e11b604082015260600190565b600e546001600160a01b0385166000908152602460205260409020600501544291613fd491615665565b111561400b5760405162461bcd60e51b8152600401610b04906020808252600490820152634541343360e01b604082015260600190565b6001600160a01b0384166000908152602460205260408120426005820155600401805487929061403c908490615665565b90915550506001600160a01b03821663d9caed12878561405c8983611793565b6040518463ffffffff1660e01b815260040161407a93929190615e38565b600060405180830381600087803b15801561409457600080fd5b505af11580156140a8573d6000803e3d6000fd5b50505050836001600160a01b03167fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a86604051612abd91815260200190565b601554421115613ab55760405162461bcd60e51b8152600401610b04906020808252600490820152634541343760e01b604082015260600190565b80601960008282546141349190615665565b909155505050565b614144612234565b81111561417c5760405162461bcd60e51b8152600401610b04906020808252600490820152630454133360e41b604082015260600190565b600160178281548110614191576141916156a0565b90600052602060002090602091828204019190069054906101000a900460ff1660018111156141c2576141c2614b8b565b036141f85760405162461bcd60e51b8152600401610b04906020808252600490820152634541333160e01b604082015260600190565b6000818152602560205260409020429055601780546001919083908110614221576142216156a0565b90600052602060002090602091828204019190066101000a81548160ff0219169083600181111561425457614254614b8b565b02179055506040518181527f85c2bdfea252978e9303bab90da589a13ced20c8efce97f4d1aa7a607790237d906020016123ea565b600082821061429a57506000611822565b6142a48284615df5565b9050611822565b6142b482613d5c565b6142bd81613d5c565b60016142c8826123f5565b60028111156142d9576142d9614b8b565b146142e357600080fd5b60026142ee836123f5565b60028111156142ff576142ff614b8b565b1461430957600080fd5b614311614476565b6001600160a01b038281166000908152602460205260408082206001908101805460ff199081168317909155938516835290822081018054909316600217909255602280549092018083559181525060005b6143716105ea600284615df5565b81101561446657600061438e614388600285615df5565b83611946565b9050846001600160a01b0316816001600160a01b0316036144005760226143b6600185615df5565b815481106143c6576143c66156a0565b6000918252602080832091909101805460018101825590835291200180546001600160a01b0319166001600160a01b038616179055614453565b602261440d600185615df5565b8154811061441d5761441d6156a0565b6000918252602080832091909101805460018101825590835291200180546001600160a01b0319166001600160a01b0383161790555b508061445e81615996565b915050614363565b50505050565b611039828261482d565b601c5442116144b05760405162461bcd60e51b8152600401610b049060208082526004908201526311504d0d60e21b604082015260600190565b60155442908111156144c157506015545b601c5481116144cd5750565b60006144d7612ae9565b905060006144e783601c54614289565b6144f5601554601454614289565b614503906301e14320615bd2565b61450d9190615be9565b9050600061271061451c610aaa565b60045461452b90612710615bd2565b6145359190615be9565b61453f8486615bd2565b601a54614550906301e14320615bd2565b61455a9190615be9565b6145649190615bd2565b61456e9190615be9565b905060005b83811015614624578160246000602260016022805490506145949190615df5565b815481106145a4576145a46156a0565b9060005260206000200184815481106145bf576145bf6156a0565b60009182526020808320909101546001600160a01b03168352820192909252604001812080549091906145f3908490615665565b9250508190555081601b600082825461460c9190615665565b9091555081905061461c81615996565b915050614573565b506000612710614632610aaa565b60065461464190612710615bd2565b61464b9190615be9565b84601a546301e1432061465e9190615bd2565b6146689190615be9565b6146729190615bd2565b61467c9190615be9565b905080601e60008282546146909190615665565b9250508190555080601f60008282546146a99190615665565b909155505050601c93909355505050565b6146c660195482614289565b60195550565b60008160038111156146e0576146e0614b8b565b14612ae65760405162461bcd60e51b8152600401610b04906020808252600490820152634541353160e01b604082015260600190565b60005b815181101561103957614737828281518110611dcd57611dcd6156a0565b60016024600084848151811061474f5761474f6156a0565b6020908102919091018101516001600160a01b031682528101919091526040016000206001015460ff16600281111561478a5761478a614b8b565b14806147e657506002602460008484815181106147a9576147a96156a0565b6020908102919091018101516001600160a01b031682528101919091526040016000206001015460ff1660028111156147e4576147e4614b8b565b145b61481b5760405162461bcd60e51b8152600401610b04906020808252600490820152634541343560e01b604082015260600190565b8061482581615996565b915050614719565b6010546040805163a775888360e01b815290516001600160a01b03909216916148a7918491849163a77588839160048083019260209291908290030181865afa15801561487e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a29190615683565b613d98565b6019546010546040516370a0823160e01b81526001600160a01b03918216600482015260009261495d92909161492a918716906370a0823190602401602060405180830381865afa158015614900573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149249190615e5c565b8661184f565b6001600160a01b03871660009081526024602052604090205461494d9190615bd2565b6149579190615be9565b84611793565b6001600160a01b038516600090815260246020526040902054909150614982906146ba565b6001600160a01b038416600090815260246020526040812060018101805460ff191690558181556004015460238054919290916149c0908490615665565b9091555050604051636ce5768960e11b81526001600160a01b0383169063d9caed12906149f590869088908690600401615e38565b600060405180830381600087803b158015614a0f57600080fd5b505af1158015614a23573d6000803e3d6000fd5b5050505050505050565b828054828255906000526020600020908101928215614a82579160200282015b82811115614a8257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614a4d565b50614a8e929150614b0d565b5090565b828054828255906000526020600020908101928215614a82579160200282015b82811115614a82578251825591602001919060010190614ab2565b828054828255906000526020600020908101928215614a825760005260206000209182015b82811115614a82578254825591600101919060010190614af2565b5b80821115614a8e5760008155600101614b0e565b600060208284031215614b3457600080fd5b5035919050565b60005b83811015614b56578181015183820152602001614b3e565b50506000910152565b60008151808452614b77816020860160208601614b3b565b601f01601f19169290920160200192915050565b634e487b7160e01b600052602160045260246000fd5b60038110612ae657612ae6614b8b565b614bba81614ba1565b9052565b600081518084526020808501945080840160005b83811015614bf75781516001600160a01b031687529582019590820190600101614bd2565b509495945050505050565b80516001600160a01b0316825260006101806020830151602085015260408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e08301518160e0860152614c6782860182614b5f565b91505061010080840151818601525061012080840151818601525061014080840151614c9582870182614bb1565b50506101608084015185830382870152614caf8382614bbe565b9695505050505050565b60006101408c835260018060a01b03808d166020850152808c166040850152808b166060850152808a1660808501528860a085015287151560c085015286151560e0850152816101008501528086511682850152505060208401516040610160840152614d2a610180840182614b5f565b9050828103610120840152614d3f8185614c02565b9d9c50505050505050505050505050565b6001600160a01b0381168114612ae657600080fd5b8035614d7081614d50565b919050565b600060208284031215614d8757600080fd5b8135614d9281614d50565b9392505050565b85815260a08101614da986614ba1565b8560208301528460408301528360608301528260808301529695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614e0357614e03614dcb565b60405290565b60405161018081016001600160401b0381118282101715614e0357614e03614dcb565b6040516101a081016001600160401b0381118282101715614e0357614e03614dcb565b604051608081016001600160401b0381118282101715614e0357614e03614dcb565b604051601f8201601f191681016001600160401b0381118282101715614e9957614e99614dcb565b604052919050565b60006001600160401b03821115614eba57614eba614dcb565b5060051b60200190565b600082601f830112614ed557600080fd5b81356020614eea614ee583614ea1565b614e71565b82815260059290921b84018101918181019086841115614f0957600080fd5b8286015b84811015614f2d578035614f2081614d50565b8352918301918301614f0d565b509695505050505050565b600082601f830112614f4957600080fd5b81356020614f59614ee583614ea1565b82815260059290921b84018101918181019086841115614f7857600080fd5b8286015b84811015614f2d5780358352918301918301614f7c565b8015158114612ae657600080fd5b8035614d7081614f93565b60006001600160401b03821115614fc557614fc5614dcb565b50601f01601f191660200190565b6000614fe1614ee584614fac565b9050828152838383011115614ff557600080fd5b828260208301376000602084830101529392505050565b60006040828403121561501e57600080fd5b615026614de1565b9050813561503381614d50565b815260208201356001600160401b0381111561504e57600080fd5b8201601f8101841361505f57600080fd5b61506e84823560208401614fd3565b60208301525092915050565b600082601f83011261508b57600080fd5b61181f83833560208501614fd3565b6000604082840312156150ac57600080fd5b6150b4614de1565b905081356150c181614d50565b815260208201356001600160401b038111156150dc57600080fd5b61506e8482850161507a565b6000602082840312156150fa57600080fd5b81356001600160401b038082111561511157600080fd5b90830190610180828603121561512657600080fd5b61512e614e09565b8235815261513e60208401614d65565b602082015261514f60408401614d65565b604082015260608301358281111561516657600080fd5b61517287828601614ec4565b60608301525060808301358281111561518a57600080fd5b61519687828601614f38565b6080830152506151a860a08401614d65565b60a08201526151b960c08401614d65565b60c082015260e083013560e08201526101006151d6818501614fa1565b908201526101206151e8848201614fa1565b90820152610140838101358381111561520057600080fd5b61520c8882870161500c565b828401525050610160808401358381111561522657600080fd5b6152328882870161509a565b918301919091525095945050505050565b6020808252825182820181905260009190848201906040850190845b818110156152845783516001600160a01b03168352928401929184019160010161525f565b50909695505050505050565b600080604083850312156152a357600080fd5b82356152ae81614d50565b946020939093013593505050565b6000602082840312156152ce57600080fd5b81356001600160401b03808211156152e557600080fd5b908301906101a082860312156152fa57600080fd5b615302614e2c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e0820152610100808401358183015250610120808401358183015250610140808401358183015250610160808401358183015250610180808401358381111561539057600080fd5b6152328882870161507a565b600080604083850312156153af57600080fd5b8235915060208301356153c181614d50565b809150509250929050565b60208101600483106153e0576153e0614b8b565b91905290565b600080604083850312156153f957600080fd5b50508035926020909101359150565b60038110612ae657600080fd5b6000806040838503121561542857600080fd5b8235915060208301356153c181615408565b60008060008060008086880361012081121561545557600080fd5b87356001600160401b038082111561546c57600080fd5b6154788b838c01614f38565b985060208a0135975060408a013591508082111561549557600080fd5b6154a18b838c01614ec4565b965060608a01359150808211156154b757600080fd5b506154c48a828b01614f38565b9450506080888101359350609f19820112156154df57600080fd5b506154e8614e4f565b60a08801356154f681614d50565b815260c088013561550681614d50565b602082015260e088013561551981614d50565b604082015261010088013561552d81614d50565b80606083015250809150509295509295509295565b60208101600283106153e0576153e0614b8b565b60006101a08f83528e60208401528d60408401528c60608401528b60808401528a60a08401528960c08401528860e084015287610100840152866101208401528561014084015284610160840152806101808401526155b781840185614b5f565b9150509e9d5050505050505050505050505050565b6000602082840312156155de57600080fd5b81356001600160401b038111156155f457600080fd5b6156008482850161507a565b949350505050565b602081016153e083614ba1565b600181811c9082168061562957607f821691505b60208210810361564957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156118225761182261564f565b8051614d7081614d50565b60006020828403121561569557600080fd5b8151614d9281614d50565b634e487b7160e01b600052603260045260246000fd5b6000815480845260208085019450836000528060002060005b83811015614bf75781546001600160a01b0316875295820195600191820191016156cf565b6000815480845260208085019450836000528060002060005b83811015614bf75781548752958201956001918201910161570d565b6000815461573681615615565b808552602060018381168015615753576001811461576d5761579b565b60ff1985168884015283151560051b88018301955061579b565b866000528260002060005b858110156157935781548a8201860152908301908401615778565b890184019650505b505050505092915050565b80546001600160a01b0316825260406020830181905260009061181f90840160018401615729565b60006101806157f5846157e885546001600160a01b031690565b6001600160a01b03169052565b60018301546020850152600283015460408501526003830154606085015260048301546080850152600583015460a0850152600683015460c08501528060e085015261584681850160078501615729565b90506008830154610100850152600983015461012085015261586c600a84015460ff1690565b61587a610140860182614bb1565b5083810361016085015261560081600b85016156b6565b602081528154602082015260006158b260018401546001600160a01b031690565b6001600160a01b0390811660408401526002840154166060830152610180608083018190526158e86101a08401600386016156b6565b601f19808583030160a086015261590282600488016156f4565b915061591860058701546001600160a01b031690565b6001600160a01b0390811660c087015260068701541660e0860152600786015461010086015260088087015460ff8082161515610120890152911c161515610140860152848203810161016086015261597482600988016157a6565b91508085830301838601525061598d81600b87016157ce565b95945050505050565b6000600182016159a8576159a861564f565b5060010190565b601f821115613d1b57600081815260208120601f850160051c810160208610156159d65750805b601f850160051c820191505b818110156159f5578281556001016159e2565b505050505050565b81516001600160401b03811115615a1657615a16614dcb565b615a2a81615a248454615615565b846159af565b602080601f831160018114615a5f5760008415615a475750858301515b600019600386901b1c1916600185901b1785556159f5565b600085815260208120601f198616915b82811015615a8e57888601518255948401946001909101908401615a6f565b5085821015615aac5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215615ace57600080fd5b815160ff81168114614d9257600080fd5b600181815b80851115615b1a578160001904821115615b0057615b0061564f565b80851615615b0d57918102915b93841c9390800290615ae4565b509250929050565b600082615b3157506001611822565b81615b3e57506000611822565b8160018114615b545760028114615b5e57615b7a565b6001915050611822565b60ff841115615b6f57615b6f61564f565b50506001821b611822565b5060208310610133831016604e8410600b8410161715615b9d575081810a611822565b615ba78383615adf565b8060001904821115615bbb57615bbb61564f565b029392505050565b600061181f60ff841683615b22565b80820281158282048414176118225761182261564f565b600082615c0657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0384168152606060208201819052600090615c2f908301856157ce565b9050615c3a83614ba1565b826040830152949350505050565b600082601f830112615c5957600080fd5b8151615c67614ee582614fac565b818152846020838601011115615c7c57600080fd5b615600826020830160208701614b3b565b8051614d7081615408565b600082601f830112615ca957600080fd5b81516020615cb9614ee583614ea1565b82815260059290921b84018101918181019086841115615cd857600080fd5b8286015b84811015614f2d578051615cef81614d50565b8352918301918301615cdc565b600060208284031215615d0e57600080fd5b81516001600160401b0380821115615d2557600080fd5b908301906101808286031215615d3a57600080fd5b615d42614e09565b615d4b83615678565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015182811115615d9b57600080fd5b615da787828601615c48565b60e08301525061010083810151908201526101208084015190820152610140615dd1818501615c8d565b908201526101608381015183811115615de957600080fd5b61523288828701615c98565b818103818111156118225761182261564f565b60208152600061181f6020830184614b5f565b600060208284031215615e2d57600080fd5b8151614d9281614f93565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215615e6e57600080fd5b5051919050565b60208152600061181f60208301846157ce565b600081615e9757615e9761564f565b506000190190565b818103615eaa575050565b615eb48254615615565b6001600160401b03811115615ecb57615ecb614dcb565b615ed981615a248454615615565b6000601f821160018114615f0d5760008315615ef55750848201545b600019600385901b1c1916600184901b178455615f72565b600085815260209020601f19841690600086815260209020845b83811015615f475782860154825560019586019590910190602001615f27565b5085831015615f655781850154600019600388901b60f8161c191681555b50505060018360011b0184555b5050505050565b602080825282516001600160a01b0316828201528201516040808301526000906156006060840182614b5f56fea2646970667358221220ebe2b3d934854cfb4de9f8f6f83befbb06ba7d038f923e591869649e32382f0964736f6c63430008110033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061038d5760003560e01c80636b0e575f116101de578063b3c4547b1161010f578063dde8535f116100ad578063e92c38591161007c578063e92c3859146107c8578063f66bcac4146107db578063f80e1c89146107e4578063ffb2c479146107ec57600080fd5b8063dde8535f1461077a578063e3d27f291461079a578063e6e32ad3146107a2578063e84e0eb0146107b557600080fd5b8063c37191d4116100e9578063c37191d41461071b578063d9b6225e1461073c578063daf9c2101461074f578063dcb262321461077257600080fd5b8063b3c4547b146106eb578063b58e8f03146106f3578063b8ac3146146106fb57600080fd5b80638906994a1161017c5780639f338e77116101565780639f338e77146106ba578063a32bf597146106cd578063a86eaca4146106d5578063ac6d7816146106e257600080fd5b80638906994a1461068b578063943e82161461069e57806396dbd9e0146106b157600080fd5b8063792de97c116101b8578063792de97c14610634578063797bbfe7146106475780637f02ac54146106675780638652169d1461067a57600080fd5b80636b0e575f146106025780636eac2ccb1461060b57806374d2ea7c1461061457600080fd5b806334ce66de116102c35780634f6c488b116102615780635d97505b116102305780635d97505b146105c35780635fc9e6be146105d457806361082b3d146105dc57806369740a2a146105ef57600080fd5b80634f6c488b1461058c578063546213a2146105945780635977e0f2146105a75780635c746f82146105b057600080fd5b806340f40d321161029d57806340f40d32146105435780634698d110146105685780634c1b34f9146105715780634e3fe0fd1461058457600080fd5b806334ce66de146105155780633a98ef39146105285780633c8d1dd81461053157600080fd5b80631b48201e11610330578063289c25f41161030a578063289c25f4146104895780632e5ade11146104a0578063305104a7146104f95780633303c2691461050257600080fd5b80631b48201e1461045757806321d84c4b1461047757806326e6979b1461048057600080fd5b806308ae4b0c1161036c57806308ae4b0c146103e0578063112a502914610432578063132cd0621461043a57806317d5430a1461044f57600080fd5b80621402da14610392578063013cf08b146103ae57806304873f5d146103d7575b600080fd5b61039b60185481565b6040519081526020015b60405180910390f35b6103c16103bc366004614b22565b6107ff565b6040516103a59a99989796959493929190614cb9565b61039b60155481565b6104216103ee366004614d75565b60246020526000908152604090208054600182015460028301546004840154600590940154929360ff9092169290919085565b6040516103a5959493929190614d99565b61039b610aaa565b61044d6104483660046150e8565b610ac1565b005b60215461039b565b61046a610465366004614b22565b610f9e565b6040516103a59190615243565b61039b601e5481565b61039b60235481565b60205460ff165b60405190151581526020016103a5565b6010546011546012546013546104c6936001600160a01b03908116938116928116911684565b604080516001600160a01b03958616815293851660208501529184169183019190915290911660608201526080016103a5565b61039b601c5481565b61044d610510366004615290565b61101d565b61044d6105233660046150e8565b61103d565b61039b60195481565b60205461049090610100900460ff1681565b6011546001600160a01b03165b6040516001600160a01b0390911681526020016103a5565b61039b60215481565b61044d61057f3660046152bc565b61120b565b60055461039b565b600b5461039b565b61044d6105a236600461539c565b6113e6565b61039b60015481565b61039b6105be36600461539c565b611793565b6013546001600160a01b0316610550565b60035461039b565b61039b6105ea366004614b22565b611828565b61039b6105fd36600461539c565b61184f565b61039b601a5481565b61039b60145481565b61039b610622366004614b22565b60256020526000908152604090205481565b61039b610642366004614b22565b6118d0565b61065a610655366004615290565b6118f1565b6040516103a591906153cc565b6105506106753660046153e6565b611946565b6012546001600160a01b0316610550565b6105506106993660046153e6565b611992565b61044d6106ac366004615415565b6119d6565b61039b601d5481565b61044d6106c836600461543a565b611bbe565b61039b612234565b6020546104909060ff1681565b61039b601f5481565b60225461039b565b60155461039b565b61070e610709366004614b22565b6122b2565b6040516103a59190615542565b6107236122e6565b6040516103a59d9c9b9a99989796959493929190615556565b61044d61074a3660046155cc565b6123b3565b61049061075d366004614d75565b60006020819052908152604090205460ff1681565b60175461039b565b61078d610788366004614d75565b6123f5565b6040516103a59190615608565b600c5461039b565b6020546104909062010000900460ff1681565b61044d6107c336600461539c565b612416565b61044d6107d6366004614b22565b612acd565b61039b601b5481565b61039b612ae9565b61044d6107fa366004614b22565b612b1e565b600260208181526000928352604092839020805460018201549382015460058301546006840154600785015460088601548951808b01909a526009870180546001600160a01b039081168c52600a89018054989c9b82169b9782169a968216999590911697939660ff8085169761010090950416959490938401919061088490615615565b80601f01602080910402602001604051908101604052809291908181526020018280546108b090615615565b80156108fd5780601f106108d2576101008083540402835291602001916108fd565b820191906000526020600020905b8154815290600101906020018083116108e057829003601f168201915b5050509190925250506040805161018081018252600b850180546001600160a01b03168252600c8601546020830152600d86015492820192909252600e8501546060820152600f8501546080820152601085015460a0820152601185015460c082015260128501805494959491935060e084019161097a90615615565b80601f01602080910402602001604051908101604052809291908181526020018280546109a690615615565b80156109f35780601f106109c8576101008083540402835291602001916109f3565b820191906000526020600020905b8154815290600101906020018083116109d657829003601f168201915b50505091835250506008820154602082015260098201546040820152600a82015460609091019060ff166002811115610a2e57610a2e614b8b565b6002811115610a3f57610a3f614b8b565b8152602001600b8201805480602002602001604051908101604052809291908181526020018280548015610a9c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a7e575b50505050508152505090508a565b600454600654600091610abc91615665565b905090565b610ac9613a25565b8051600b1015610b0d5760405162461bcd60e51b8152600401610b049060208082526004908201526308a8262760e31b604082015260600190565b60405180910390fd5b6000816101600151602001515111610b4d5760405162461bcd60e51b815260206004820152600360248201526204541360ec1b6044820152606401610b04565b610b5960015482613ab7565b8051600103610bf957610b6a613d20565b610b778160400151613d5c565b60208101516001600160a01b03163314610b9057600080fd5b60408101516001600160a01b03163303610ba957600080fd5b6001610bb882604001516123f5565b6002811115610bc957610bc9614b8b565b14610bd357600080fd5b6002610bde336123f5565b6002811115610bef57610bef614b8b565b14610bf957600080fd5b8051600203610c8357610c0a613d20565b6010546040805163a775888360e01b81529051610c83926001600160a01b03169163a77588839160048083019260209291908290030181865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190615683565b8260c00151613d98565b8051600403610cae57610c94613d20565b6001546000908152600260205260409020605a600f909101555b8051600503610ce85760405162461bcd60e51b8152600401610b04906020808252600490820152634541323160e01b604082015260600190565b805160061480610cf9575080516007145b15610e1157610d06613d20565b610d138160200151613d5c565b600160178260e0015181548110610d2c57610d2c6156a0565b90600052602060002090602091828204019190069054906101000a900460ff166001811115610d5d57610d5d614b8b565b14610d6757600080fd5b60006024600083602001516001600160a01b03166001600160a01b031681526020019081526020016000206003018260e0015181548110610daa57610daa6156a0565b90600052602060002090602091828204019190069054906101000a900460ff166003811115610ddb57610ddb614b8b565b14610de557600080fd5b600b5460e08201516000908152602560205260409020544291610e0791615665565b10610e1157600080fd5b8051600803610e6457610e22613d20565b80606001515181608001515114610e645760405162461bcd60e51b8152600401610b049060208082526004908201526322a0991960e11b604082015260600190565b8051600903610efb57610e75613d20565b600854601d54610e859190615665565b4211610ebc5760405162461bcd60e51b8152600401610b04906020808252600490820152634541323360e01b604082015260600190565b60035481606001515114610efb5760405162461bcd60e51b8152600401610b04906020808252600490820152634541313360e01b604082015260600190565b8051600a03610f3e576015544211610f3e5760405162461bcd60e51b8152600401610b049060208082526004908201526308a8268760e31b604082015260600190565b6001546000818152600260205260409081902090517fc71a1e2cb91ef76d3fec5535207e4457a4bd2b772f99618204772d34df8ebb9891610f7e91615891565b60405180910390a260018054906000610f9683615996565b919050555050565b606060228281548110610fb357610fb36156a0565b9060005260206000200180548060200260200160405190810160405280929190818152602001828054801561101157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ff3575b50505050509050919050565b611025613a25565b61102d613d20565b61103982823333613de2565b5050565b80516005146110775760405162461bcd60e51b8152600401610b049060208082526004908201526308a8262760e31b604082015260600190565b60205460ff166110b25760405162461bcd60e51b8152600401610b049060208082526004908201526311504c8d60e21b604082015260600190565b60016110bd336123f5565b60028111156110ce576110ce614b8b565b1415806110f5575060026110e1336123f5565b60028111156110f2576110f2614b8b565b14155b61112a5760405162461bcd60e51b8152600401610b04906020808252600490820152634541323560e01b604082015260600190565b60095460e0820151108015906111465750600a5460e082015111155b61117b5760405162461bcd60e51b8152600401610b049060208082526004908201526322a0991b60e11b604082015260600190565b61118760015482613ab7565b6001805460009081526002602081815260408084206013018490558051848152808301808352955485529290915290912090516111ca9260169092019190614a2d565b506001546000818152600260205260409081902090517fc71a1e2cb91ef76d3fec5535207e4457a4bd2b772f99618204772d34df8ebb9891610f7e91615891565b60205462010000900460ff161561124a5760405162461bcd60e51b815260206004820152600360248201526245413760e81b6044820152606401610b04565b8060e001518160c00151106112875760405162461bcd60e51b815260206004820152600360248201526222a09960e91b6044820152606401610b04565b6064816101200151106112c25760405162461bcd60e51b815260206004820152600360248201526245413360e81b6044820152606401610b04565b6103e78160400151826060015183602001516112de9190615665565b6112e89190615665565b1061131b5760405162461bcd60e51b815260206004820152600360248201526245413560e81b6044820152606401610b04565b6032816080015111156113565760405162461bcd60e51b815260206004820152600360248201526222a09b60e91b6044820152606401610b04565b80516003908155602082015160045560408201516005556060820151600655608082015160075560a082015160085560c082015160095560e0820151600a55610100820151600b55610120820151600c55610140820151600d55610160820151600e55610180820151829190600f906113cf90826159fd565b50506020805462ff00ff1916620100011790555050565b6113ee6140e7565b6010546040805163a775888360e01b815290516001600160a01b0380851693169163a77588839160048083019260209291908290030181865afa158015611439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145d9190615683565b6001600160a01b03161461149c5760405162461bcd60e51b8152600401610b04906020808252600490820152630454135360e41b604082015260600190565b60205460ff166114d75760405162461bcd60e51b8152600401610b049060208082526004908201526311504c8d60e21b604082015260600190565b6114e44262127500615665565b6000838152600260205260409020600e01541061152c5760405162461bcd60e51b8152600401610b04906020808252600490820152634541333760e01b604082015260600190565b6000828152600260205260409020546005146115735760405162461bcd60e51b8152600401610b049060208082526004908201526308a8266760e31b604082015260600190565b600160008381526002602081905260409091206015015460ff169081111561159d5761159d614b8b565b146115d35760405162461bcd60e51b8152600401610b04906020808252600490820152634541333960e01b604082015260600190565b600082815260026020819052604090912001546001600160a01b031633146116265760405162461bcd60e51b8152600401610b04906020808252600490820152630454134360e41b604082015260600190565b60013360009081526024602052604090206001015460ff16600281111561164f5761164f614b8b565b036116855760405162461bcd60e51b8152600401610b04906020808252600490820152634541343160e01b604082015260600190565b60008281526002602081815260408084206007018054338652602484529185209182556001808301805460ff191690911790555490830181905592859052526116cd90614122565b60005b601754811015611727573360009081526024602090815260408220600301805460018101825590835291819020908204018054601f9092166101000a60ff021990911690558061171f81615996565b9150506116d0565b50611733600082612416565b6021805490600061174383615996565b9091555050336000818152602460209081526040918290206002015491519182527f6caf6186588a289956ca08d23a7cbfe2ca473d5969db8117a4cbbe45a96674d1910160405180910390a25050565b6000670de0b6b3a7640000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118009190615abc565b61180b90600a615bc3565b6118159085615bd2565b61181f9190615be9565b90505b92915050565b60006022828154811061183d5761183d6156a0565b60009182526020909120015492915050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b39190615abc565b6118be90600a615bc3565b611815670de0b6b3a764000085615bd2565b601681815481106118e057600080fd5b600091825260209091200154905081565b6001600160a01b038216600090815260246020526040812060030180548390811061191e5761191e6156a0565b90600052602060002090602091828204019190069054906101000a900460ff16905092915050565b60006022838154811061195b5761195b6156a0565b906000526020600020018281548110611976576119766156a0565b6000918252602090912001546001600160a01b03169392505050565b602282815481106119a257600080fd5b9060005260206000200181815481106119ba57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6119de613a25565b601354600083815260026020526040908190209051630836aaf960e21b81526001600160a01b03909216916320daabe491611a23913391600b01908690600401615c0b565b600060405180830381865afa158015611a40573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a689190810190615cfc565b6000838152600260209081526040918290208351600b820180546001600160a01b0319166001600160a01b0390921691909117815591840151600c82015591830151600d8301556060830151600e8301556080830151600f83015560a0830151601083015560c0830151601183015560e0830151909160120190611aec90826159fd565b5061010082015160088201556101208201516009820155610140820151600a8201805460ff19166001836002811115611b2757611b27614b8b565b02179055506101608201518051611b4891600b840191602090910190614a2d565b505050600082815260026020818152604083206016018054600181018255908452922090910180546001600160a01b031916331790558190811115611b8f57611b8f614b8b565b60405183907fc92326dacbba7a4c0f0b5ca0bab775311245300cea304ed0655a887fb568662890600090a35050565b602054610100900460ff1615611bfc5760405162461bcd60e51b815260206004820152600360248201526245413760e81b6044820152606401610b04565b8051611c0790613d5c565b611c148160200151613d5c565b611c218160400151613d5c565b611c2e8160600151613d5c565b6000805b8751811015611cc757878181518110611c4d57611c4d6156a0565b602002602001015182611c609190615665565b91506064888281518110611c7657611c766156a0565b60200260200101511115611cb55760405162461bcd60e51b8152600401610b04906020808252600490820152634541313160e01b604082015260600190565b80611cbf81615996565b915050611c32565b5080606414611d015760405162461bcd60e51b8152600401610b049060208082526004908201526322a0989960e11b604082015260600190565b6003548551148015611d1557506003548451145b611d4a5760405162461bcd60e51b8152600401610b04906020808252600490820152634541313360e01b604082015260600190565b82600003611d835760405162461bcd60e51b8152600401610b049060208082526004908201526322a0989b60e11b604082015260600190565b8651611d969060169060208a0190614a92565b50601886905542601d5560228054600101815560009081525b855181101561213357611dda868281518110611dcd57611dcd6156a0565b6020026020010151613d5c565b600260246000888481518110611df257611df26156a0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a81548160ff02191690836002811115611e3e57611e3e614b8b565b0217905550848181518110611e5557611e556156a0565b602002602001015160246000888481518110611e7357611e736156a0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060020181905550600360070154858281518110611eba57611eba6156a0565b602002602001015111158015611eee5750600360060154858281518110611ee357611ee36156a0565b602002602001015110155b611f235760405162461bcd60e51b8152600401610b04906020808252600490820152634541313760e01b604082015260600190565b848181518110611f3557611f356156a0565b602002602001015160246000888481518110611f5357611f536156a0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000181905550611fa4858281518110611f9757611f976156a0565b6020026020010151614122565b858181518110611fb657611fb66156a0565b60200260200101516001600160a01b03167f6caf6186588a289956ca08d23a7cbfe2ca473d5969db8117a4cbbe45a96674d1868381518110611ffa57611ffa6156a0565b602002602001015160405161201191815260200190565b60405180910390a260005b6016548110156120a0576024600088848151811061203c5761203c6156a0565b6020908102919091018101516001600160a01b031682528181019290925260400160009081206003018054600181018255908252908290209181049091018054601f9092166101000a60ff021990911690558061209881615996565b91505061201c565b5060226000815481106120b5576120b56156a0565b906000526020600020018682815181106120d1576120d16156a0565b6020908102919091018101518254600181018455600093845291832090910180546001600160a01b0319166001600160a01b03909216919091179055602180549161211b83615996565b9190505550808061212b90615996565b915050611daf565b5060005b875181101561219c57601780546001810182556000919091527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c1560208204018054601f9092166101000a60ff021990911690558061219481615996565b915050612137565b506121a7600061413c565b8151601080546001600160a01b039283166001600160a01b031991821617909155602084015160118054918416918316919091179055604084015160128054918416918316919091179055606084015160138054919093169116179055426014819055612215908490615665565b601555505042601c5550506020805461ff001916610100179055505050565b60185460165460009161224691615bd2565b6014546122539190615665565b42111561226857601654610abc906001614289565b601654610abc9061227b90600190615df5565b6018546016546122a390612290908390615bd2565b60145461229d9190615665565b42614289565b6122ad9190615be9565b614289565b601781815481106122c257600080fd5b9060005260206000209060209182820401919006915054906101000a900460ff1681565b60038054600454600554600654600754600854600954600a54600b54600c54600d54600e54600f80549c9d9b9c9a9b999a9899979896979596949593949293919261233090615615565b80601f016020809104026020016040519081016040528092919081815260200182805461235c90615615565b80156123a95780601f1061237e576101008083540402835291602001916123a9565b820191906000526020600020905b81548152906001019060200180831161238c57829003601f168201915b505050505090508d565b6123bb613a25565b7f39052d9341110f416317f52c8982d02e4e1c70a295435edccc09fc9c45136cad816040516123ea9190615e08565b60405180910390a150565b6001600160a01b031660009081526024602052604090206001015460ff1690565b61241e613a25565b6010546040516324d6c8d560e01b81526001600160a01b038381166004830152909116906324d6c8d590602401602060405180830381865afa158015612468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248c9190615e1b565b801561250157506011546040516324d6c8d560e01b81526001600160a01b038381166004830152909116906324d6c8d590602401602060405180830381865afa1580156124dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125019190615e1b565b6125365760405162461bcd60e51b8152600401610b049060208082526004908201526322a0999960e11b604082015260600190565b60016017838154811061254b5761254b6156a0565b90600052602060002090602091828204019190069054906101000a900460ff16600181111561257c5761257c614b8b565b146125b25760405162461bcd60e51b8152600401610b049060208082526004908201526311504ccd60e21b604082015260600190565b60023360009081526024602052604090206003018054849081106125d8576125d86156a0565b90600052602060002090602091828204019190069054906101000a900460ff16600381111561260957612609614b8b565b0361263f5760405162461bcd60e51b8152600401610b04906020808252600490820152634541333560e01b604082015260600190565b6001336000908152602460205260409020600301805484908110612665576126656156a0565b90600052602060002090602091828204019190069054906101000a900460ff16600381111561269657612696614b8b565b1415806126f8575060033360009081526024602052604090206003018054849081106126c4576126c46156a0565b90600052602060002090602091828204019190069054906101000a900460ff1660038111156126f5576126f5614b8b565b14155b61272d5760405162461bcd60e51b8152600401610b049060208082526004908201526322a0999b60e11b604082015260600190565b6000606460168481548110612744576127446156a0565b6000918252602080832090910154338352602490915260409091206002015461276d9190615bd2565b6127779190615be9565b60055490915060009061278c906103e8615be9565b6127969083615be9565b905060006127a48383614289565b60115490915084906001600160a01b03808316916323b872dd913391166127cb8786611793565b6040518463ffffffff1660e01b81526004016127e993929190615e38565b6020604051808303816000875af1158015612808573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061282c9190615e1b565b506010546001600160a01b03808316916323b872dd9133911661284f868a611793565b6040518463ffffffff1660e01b815260040161286d93929190615e38565b6020604051808303816000875af115801561288c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b09190615e1b565b50336000908152602460205260409020600301805460029190889081106128d9576128d96156a0565b90600052602060002090602091828204019190066101000a81548160ff0219169083600381111561290c5761290c614b8b565b02179055506011546040516370a0823160e01b81526001600160a01b0391821660048201527ffbd50798349c0ef233dafbe6eea9f929785731d11f54b610aea96532af84a7fe918791908416906370a0823190602401602060405180830381865afa15801561297f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129a39190615e5c565b601154604080516001600160a01b039485168152602081019390935292168183015290519081900360600190a16010546040516370a0823160e01b81526001600160a01b0391821660048201527ffbd50798349c0ef233dafbe6eea9f929785731d11f54b610aea96532af84a7fe918791908416906370a0823190602401602060405180830381865afa158015612a3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a629190615e5c565b601054604080516001600160a01b039485168152602081019390935292168183015290519081900360600190a160405186815233907fadbb1a8d997c363e82403aaac89860243ed75c64674543ae32a53b239faea5f5906020015b60405180910390a2505050505050565b612ad56140e7565b612add613a25565b612ae68161413c565b50565b6022805460009190612afd90600190615df5565b81548110612b0d57612b0d6156a0565b600091825260209091200154919050565b612b26613a25565b60135460008281526002602052604090819020905163706c869160e11b81526001600160a01b039092169163e0d90d2291612b6991600b90910190600401615e75565b600060405180830381865afa158015612b86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612bae9190810190615cfc565b6000828152600260209081526040918290208351600b820180546001600160a01b0319166001600160a01b0390921691909117815591840151600c82015591830151600d8301556060830151600e8301556080830151600f83015560a0830151601083015560c0830151601183015560e0830151909160120190612c3290826159fd565b5061010082015160088201556101208201516009820155610140820151600a8201805460ff19166001836002811115612c6d57612c6d614b8b565b02179055506101608201518051612c8e91600b840191602090910190614a2d565b5060019150612c9a9050565b60008281526002602081905260409091206015015460ff1690811115612cc257612cc2614b8b565b036139d357600081815260026020526040902054600103612d0c5760008181526002602081905260409091206001810154910154612d0c916001600160a01b0390811691166142ab565b6000818152600260208190526040909120549003612eb55760008181526002602081815260408084206001908101546001600160a01b03168552602490925290922082015460ff1690811115612d6457612d64614b8b565b1480612dae575060008181526002602081815260408084206001908101546001600160a01b0316855260249092529092209091015460ff1681811115612dac57612dac614b8b565b145b612db757600080fd5b60008181526002602081815260408084206001908101546001600160a01b0316855260249092529092209091015460ff1681811115612df857612df8614b8b565b03612e2c5760008181526002602081905260409091206001810154910154612e2c916001600160a01b0390811691166142ab565b60218054906000612e3c83615e88565b909155505060008181526002602052604090206001810154600690910154612e70916001600160a01b03908116911661446c565b6000818152600260205260408082206001015490516001600160a01b03909116917f55cacd41f8c4e378339a4015150f560d647bbc13cad0af49f50cfae4375b1d5491a25b600081815260026020526040902054600303612f4e5760205460ff16612f065760405162461bcd60e51b8152600401610b04906020808252600490820152634541313960e01b604082015260600190565b6020805460ff191690556000612f206103e86122ad610aaa565b601954612f2f906103e8615bd2565b612f399190615be9565b9050612f4781601954614289565b601a556019555b600081815260026020526040902054600403612fa057612f6c614476565b42601581905550612f9a612f95612f87601a54601b54614289565b6122ad601f54601e54614289565b6146ba565b6000601e555b60008181526002602052604090205460061480612fcb57506000818152600260205260409020546007145b1561304257600081815260026020818152604080842060018101546001600160a01b03168552602483529084209385905291905260070154600390910180546130429290811061301d5761301d6156a0565b90600052602060002090602091828204019190069054906101000a900460ff166146cc565b60008181526002602052604090205460060361321d576000818152600260208181526040808420600101546001600160a01b031684526024909152822001546007549091906103e8906130959084615bd2565b61309f9190615be9565b600084815260026020526040902060070154601680546064929081106130c7576130c76156a0565b9060005260206000200154846130dd9190615bd2565b6130e79190615be9565b6130f19190615665565b6000848152600260209081526040808320600101546001600160a01b0316835260249091529020549091506131269082614289565b6000848152600260208181526040808420600180820180546001600160a01b03908116885260248652848820989098555490961685529084209388905291905260070154600390910180549091908110613182576131826156a0565b90600052602060002090602091828204019190066101000a81548160ff021916908360038111156131b5576131b5614b8b565b02179055506131c3816146ba565b600083815260026020908152604091829020600181015460079091015492519283526001600160a01b0316917f3dddf5aaaf675b4fc02037ca34ab0ceee22e5e93d6ee558a4a9a06ff3dab5444910160405180910390a250505b6000818152600260205260409020546007036133cd576000818152600260205260408120600701546016805460649290811061325b5761325b6156a0565b600091825260208083209091015485835260028083526040808520600101546001600160a01b03168552602490935291909220015461329a9190615bd2565b6132a49190615be9565b6000838152600260209081526040808320600101546001600160a01b0316835260249091529020549091506132d99082614289565b60008381526002602081815260408084206001810180546001600160a01b039081168752602485528387209790975554909516845283209286905252600790910154600391820180549091908110613333576133336156a0565b90600052602060002090602091828204019190066101000a81548160ff0219169083600381111561336657613366614b8b565b0217905550613374816146ba565b600082815260026020908152604091829020600181015460079091015492519283526001600160a01b0316917f98c8f362811b9bac88ad292b61228ce60c629f808cce81d3a79edf7ac5fe2680910160405180910390a2505b600081815260026020526040902054600814806133f857506000818152600260205260409020546009145b1561346b57600081815260026020908152604091829020600301805483518184028101840190945280845261346b939283018282801561346157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613443575b5050505050614716565b60008181526002602052604090205460080361367f57613489614476565b6000805b60008381526002602052604090206004015481101561363257601e5460008481526002602052604090206004018054839081106134cc576134cc6156a0565b9060005260206000200154111561350e5760405162461bcd60e51b8152600401610b049060208082526004908201526308a8264760e31b604082015260600190565b6000838152600260205260409020600401805482908110613531576135316156a0565b906000526020600020015460246000600260008781526020019081526020016000206003018481548110613567576135676156a0565b60009182526020808320909101546001600160a01b031683528201929092526040019020546135969190615665565b600084815260026020526040812060030180546024929190859081106135be576135be6156a0565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181209390935585835260029091529020600401805482908110613608576136086156a0565b90600052602060002001548261361e9190615665565b91508061362a81615996565b91505061348d565b50601e5481111561366e5760405162461bcd60e51b8152600401610b04906020808252600490820152634541323960e01b604082015260600190565b61367a601e5482614289565b601e55505b6000818152600260205260409020546009036138135761369d614476565b42601d55600081815260026020526040812060228054600181018255925260030180546136ed927f61035b26e3e9eee00e0d72fd1ee8ddca6894550dca6916ea2ac6baa90d11e510019190614acd565b5060006136f960225490565b905060005b61370c6105ea600284615df5565b8110156137885760016024600061372d613727600287615df5565b85611946565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a81548160ff0219169083600281111561377157613771614b8b565b02179055508061378081615996565b9150506136fe565b5060005b61379a6105ea600284615df5565b811015613810576002602460006137b5613727600187615df5565b6001600160a01b03166001600160a01b0316815260200190815260200160002060010160006101000a81548160ff021916908360028111156137f9576137f9614b8b565b02179055508061380881615996565b91505061378c565b50505b600081815260026020526040902054600a0361399d576015546000828152600260209081526040808320600101546001600160a01b031683526024909152812060050154909111156138e0576000828152600260209081526040808320600101546001600160a01b03168352602490915281206005015490036138a55761389e601554601454614289565b90506138e0565b6015546000838152600260209081526040808320600101546001600160a01b0316835260249091529020600501546138dd9190614289565b90505b6138ee816302cfd300615665565b6000838152600260209081526040808320600101546001600160a01b031683526024909152902060050154613924904290614289565b1161395a5760405162461bcd60e51b8152600401610b04906020808252600490820152634541343960e01b604082015260600190565b6000828152600260208190526040909120600681015460078201546001830154929093015461399b936001600160a01b039283169390929081169116613de2565b505b600081815260026020526040902054600b036139d3576000818152600260205260409020600f906139d19060120182615e9f565b505b6000818152600260205260409081902060150154905182917fbdb492b15201001c44f021370ca5ea73640ddcc4b4ee020fb9791241973cc37e91613a1a9160ff1690615608565b60405180910390a250565b60013360009081526024602052604090206001015460ff166002811115613a4e57613a4e614b8b565b1480613a80575060023360009081526024602052604090206001015460ff166002811115613a7e57613a7e614b8b565b145b613ab55760405162461bcd60e51b8152600401610b04906020808252600490820152634541343560e01b604082015260600190565b565b805160008381526002602052604090819020919091556101608201805133905260135490519151633c44808d60e21b81526001600160a01b039091169163f112023491613b079190600401615f79565b600060405180830381865afa158015613b24573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613b4c9190810190615cfc565b6000838152600260209081526040918290208351600b820180546001600160a01b0319166001600160a01b0390921691909117815591840151600c82015591830151600d8301556060830151600e8301556080830151600f83015560a0830151601083015560c0830151601183015560e0830151909160120190613bd090826159fd565b5061010082015160088201556101208201516009820155610140820151600a8201805460ff19166001836002811115613c0b57613c0b614b8b565b02179055506101608201518051613c2c91600b840191602090910190614a2d565b5050600c546000848152600260205260409020600f015550600b54613c519042615665565b600083815260026020818152604092839020600d80820195909555602154601182015593546010850155848101516001850180546001600160a01b03199081166001600160a01b039384161790915593860151928501805485169382169390931790925560e0850151600785015560c085015160068501805490941692169190911790915560608301518051613cef93600301929190910190614a2d565b50608081015160008381526002602090815260409091208251613d1b9360049092019290910190614a92565b505050565b60205460ff1615613ab55760405162461bcd60e51b8152600401610b04906020808252600490820152634541313960e01b604082015260600190565b6001600160a01b038116612ae65760405162461bcd60e51b815260206004820152600360248201526204544360ec1b6044820152606401610b04565b806001600160a01b0316826001600160a01b0316146110395760405162461bcd60e51b8152600401610b049060208082526004908201526322a0999960e11b604082015260600190565b6012546040805163a775888360e01b815290516001600160a01b0392831692871691839163a7758883916004808201926020929091908290030181865afa158015613e31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e559190615683565b6001600160a01b031614613e945760405162461bcd60e51b8152600401610b04906020808252600490820152630454135360e41b604082015260600190565b613e9c614476565b601954604051635158684760e01b81526001600160a01b038781166004830152600092613f6f929091613f2191908616906351586847906024016020604051808303816000875af1158015613ef5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f199190615e5c565b602354614289565b6001600160a01b038716600090815260246020526040902054613f449190615bd2565b613f4e9190615be9565b6001600160a01b038616600090815260246020526040902060040154614289565b905080851115613faa5760405162461bcd60e51b8152600401610b049060208082526004908201526322a09a1960e11b604082015260600190565b600e546001600160a01b0385166000908152602460205260409020600501544291613fd491615665565b111561400b5760405162461bcd60e51b8152600401610b04906020808252600490820152634541343360e01b604082015260600190565b6001600160a01b0384166000908152602460205260408120426005820155600401805487929061403c908490615665565b90915550506001600160a01b03821663d9caed12878561405c8983611793565b6040518463ffffffff1660e01b815260040161407a93929190615e38565b600060405180830381600087803b15801561409457600080fd5b505af11580156140a8573d6000803e3d6000fd5b50505050836001600160a01b03167fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a86604051612abd91815260200190565b601554421115613ab55760405162461bcd60e51b8152600401610b04906020808252600490820152634541343760e01b604082015260600190565b80601960008282546141349190615665565b909155505050565b614144612234565b81111561417c5760405162461bcd60e51b8152600401610b04906020808252600490820152630454133360e41b604082015260600190565b600160178281548110614191576141916156a0565b90600052602060002090602091828204019190069054906101000a900460ff1660018111156141c2576141c2614b8b565b036141f85760405162461bcd60e51b8152600401610b04906020808252600490820152634541333160e01b604082015260600190565b6000818152602560205260409020429055601780546001919083908110614221576142216156a0565b90600052602060002090602091828204019190066101000a81548160ff0219169083600181111561425457614254614b8b565b02179055506040518181527f85c2bdfea252978e9303bab90da589a13ced20c8efce97f4d1aa7a607790237d906020016123ea565b600082821061429a57506000611822565b6142a48284615df5565b9050611822565b6142b482613d5c565b6142bd81613d5c565b60016142c8826123f5565b60028111156142d9576142d9614b8b565b146142e357600080fd5b60026142ee836123f5565b60028111156142ff576142ff614b8b565b1461430957600080fd5b614311614476565b6001600160a01b038281166000908152602460205260408082206001908101805460ff199081168317909155938516835290822081018054909316600217909255602280549092018083559181525060005b6143716105ea600284615df5565b81101561446657600061438e614388600285615df5565b83611946565b9050846001600160a01b0316816001600160a01b0316036144005760226143b6600185615df5565b815481106143c6576143c66156a0565b6000918252602080832091909101805460018101825590835291200180546001600160a01b0319166001600160a01b038616179055614453565b602261440d600185615df5565b8154811061441d5761441d6156a0565b6000918252602080832091909101805460018101825590835291200180546001600160a01b0319166001600160a01b0383161790555b508061445e81615996565b915050614363565b50505050565b611039828261482d565b601c5442116144b05760405162461bcd60e51b8152600401610b049060208082526004908201526311504d0d60e21b604082015260600190565b60155442908111156144c157506015545b601c5481116144cd5750565b60006144d7612ae9565b905060006144e783601c54614289565b6144f5601554601454614289565b614503906301e14320615bd2565b61450d9190615be9565b9050600061271061451c610aaa565b60045461452b90612710615bd2565b6145359190615be9565b61453f8486615bd2565b601a54614550906301e14320615bd2565b61455a9190615be9565b6145649190615bd2565b61456e9190615be9565b905060005b83811015614624578160246000602260016022805490506145949190615df5565b815481106145a4576145a46156a0565b9060005260206000200184815481106145bf576145bf6156a0565b60009182526020808320909101546001600160a01b03168352820192909252604001812080549091906145f3908490615665565b9250508190555081601b600082825461460c9190615665565b9091555081905061461c81615996565b915050614573565b506000612710614632610aaa565b60065461464190612710615bd2565b61464b9190615be9565b84601a546301e1432061465e9190615bd2565b6146689190615be9565b6146729190615bd2565b61467c9190615be9565b905080601e60008282546146909190615665565b9250508190555080601f60008282546146a99190615665565b909155505050601c93909355505050565b6146c660195482614289565b60195550565b60008160038111156146e0576146e0614b8b565b14612ae65760405162461bcd60e51b8152600401610b04906020808252600490820152634541353160e01b604082015260600190565b60005b815181101561103957614737828281518110611dcd57611dcd6156a0565b60016024600084848151811061474f5761474f6156a0565b6020908102919091018101516001600160a01b031682528101919091526040016000206001015460ff16600281111561478a5761478a614b8b565b14806147e657506002602460008484815181106147a9576147a96156a0565b6020908102919091018101516001600160a01b031682528101919091526040016000206001015460ff1660028111156147e4576147e4614b8b565b145b61481b5760405162461bcd60e51b8152600401610b04906020808252600490820152634541343560e01b604082015260600190565b8061482581615996565b915050614719565b6010546040805163a775888360e01b815290516001600160a01b03909216916148a7918491849163a77588839160048083019260209291908290030181865afa15801561487e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148a29190615683565b613d98565b6019546010546040516370a0823160e01b81526001600160a01b03918216600482015260009261495d92909161492a918716906370a0823190602401602060405180830381865afa158015614900573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149249190615e5c565b8661184f565b6001600160a01b03871660009081526024602052604090205461494d9190615bd2565b6149579190615be9565b84611793565b6001600160a01b038516600090815260246020526040902054909150614982906146ba565b6001600160a01b038416600090815260246020526040812060018101805460ff191690558181556004015460238054919290916149c0908490615665565b9091555050604051636ce5768960e11b81526001600160a01b0383169063d9caed12906149f590869088908690600401615e38565b600060405180830381600087803b158015614a0f57600080fd5b505af1158015614a23573d6000803e3d6000fd5b5050505050505050565b828054828255906000526020600020908101928215614a82579160200282015b82811115614a8257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614a4d565b50614a8e929150614b0d565b5090565b828054828255906000526020600020908101928215614a82579160200282015b82811115614a82578251825591602001919060010190614ab2565b828054828255906000526020600020908101928215614a825760005260206000209182015b82811115614a82578254825591600101919060010190614af2565b5b80821115614a8e5760008155600101614b0e565b600060208284031215614b3457600080fd5b5035919050565b60005b83811015614b56578181015183820152602001614b3e565b50506000910152565b60008151808452614b77816020860160208601614b3b565b601f01601f19169290920160200192915050565b634e487b7160e01b600052602160045260246000fd5b60038110612ae657612ae6614b8b565b614bba81614ba1565b9052565b600081518084526020808501945080840160005b83811015614bf75781516001600160a01b031687529582019590820190600101614bd2565b509495945050505050565b80516001600160a01b0316825260006101806020830151602085015260408301516040850152606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e08301518160e0860152614c6782860182614b5f565b91505061010080840151818601525061012080840151818601525061014080840151614c9582870182614bb1565b50506101608084015185830382870152614caf8382614bbe565b9695505050505050565b60006101408c835260018060a01b03808d166020850152808c166040850152808b166060850152808a1660808501528860a085015287151560c085015286151560e0850152816101008501528086511682850152505060208401516040610160840152614d2a610180840182614b5f565b9050828103610120840152614d3f8185614c02565b9d9c50505050505050505050505050565b6001600160a01b0381168114612ae657600080fd5b8035614d7081614d50565b919050565b600060208284031215614d8757600080fd5b8135614d9281614d50565b9392505050565b85815260a08101614da986614ba1565b8560208301528460408301528360608301528260808301529695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614e0357614e03614dcb565b60405290565b60405161018081016001600160401b0381118282101715614e0357614e03614dcb565b6040516101a081016001600160401b0381118282101715614e0357614e03614dcb565b604051608081016001600160401b0381118282101715614e0357614e03614dcb565b604051601f8201601f191681016001600160401b0381118282101715614e9957614e99614dcb565b604052919050565b60006001600160401b03821115614eba57614eba614dcb565b5060051b60200190565b600082601f830112614ed557600080fd5b81356020614eea614ee583614ea1565b614e71565b82815260059290921b84018101918181019086841115614f0957600080fd5b8286015b84811015614f2d578035614f2081614d50565b8352918301918301614f0d565b509695505050505050565b600082601f830112614f4957600080fd5b81356020614f59614ee583614ea1565b82815260059290921b84018101918181019086841115614f7857600080fd5b8286015b84811015614f2d5780358352918301918301614f7c565b8015158114612ae657600080fd5b8035614d7081614f93565b60006001600160401b03821115614fc557614fc5614dcb565b50601f01601f191660200190565b6000614fe1614ee584614fac565b9050828152838383011115614ff557600080fd5b828260208301376000602084830101529392505050565b60006040828403121561501e57600080fd5b615026614de1565b9050813561503381614d50565b815260208201356001600160401b0381111561504e57600080fd5b8201601f8101841361505f57600080fd5b61506e84823560208401614fd3565b60208301525092915050565b600082601f83011261508b57600080fd5b61181f83833560208501614fd3565b6000604082840312156150ac57600080fd5b6150b4614de1565b905081356150c181614d50565b815260208201356001600160401b038111156150dc57600080fd5b61506e8482850161507a565b6000602082840312156150fa57600080fd5b81356001600160401b038082111561511157600080fd5b90830190610180828603121561512657600080fd5b61512e614e09565b8235815261513e60208401614d65565b602082015261514f60408401614d65565b604082015260608301358281111561516657600080fd5b61517287828601614ec4565b60608301525060808301358281111561518a57600080fd5b61519687828601614f38565b6080830152506151a860a08401614d65565b60a08201526151b960c08401614d65565b60c082015260e083013560e08201526101006151d6818501614fa1565b908201526101206151e8848201614fa1565b90820152610140838101358381111561520057600080fd5b61520c8882870161500c565b828401525050610160808401358381111561522657600080fd5b6152328882870161509a565b918301919091525095945050505050565b6020808252825182820181905260009190848201906040850190845b818110156152845783516001600160a01b03168352928401929184019160010161525f565b50909695505050505050565b600080604083850312156152a357600080fd5b82356152ae81614d50565b946020939093013593505050565b6000602082840312156152ce57600080fd5b81356001600160401b03808211156152e557600080fd5b908301906101a082860312156152fa57600080fd5b615302614e2c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e0820152610100808401358183015250610120808401358183015250610140808401358183015250610160808401358183015250610180808401358381111561539057600080fd5b6152328882870161507a565b600080604083850312156153af57600080fd5b8235915060208301356153c181614d50565b809150509250929050565b60208101600483106153e0576153e0614b8b565b91905290565b600080604083850312156153f957600080fd5b50508035926020909101359150565b60038110612ae657600080fd5b6000806040838503121561542857600080fd5b8235915060208301356153c181615408565b60008060008060008086880361012081121561545557600080fd5b87356001600160401b038082111561546c57600080fd5b6154788b838c01614f38565b985060208a0135975060408a013591508082111561549557600080fd5b6154a18b838c01614ec4565b965060608a01359150808211156154b757600080fd5b506154c48a828b01614f38565b9450506080888101359350609f19820112156154df57600080fd5b506154e8614e4f565b60a08801356154f681614d50565b815260c088013561550681614d50565b602082015260e088013561551981614d50565b604082015261010088013561552d81614d50565b80606083015250809150509295509295509295565b60208101600283106153e0576153e0614b8b565b60006101a08f83528e60208401528d60408401528c60608401528b60808401528a60a08401528960c08401528860e084015287610100840152866101208401528561014084015284610160840152806101808401526155b781840185614b5f565b9150509e9d5050505050505050505050505050565b6000602082840312156155de57600080fd5b81356001600160401b038111156155f457600080fd5b6156008482850161507a565b949350505050565b602081016153e083614ba1565b600181811c9082168061562957607f821691505b60208210810361564957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156118225761182261564f565b8051614d7081614d50565b60006020828403121561569557600080fd5b8151614d9281614d50565b634e487b7160e01b600052603260045260246000fd5b6000815480845260208085019450836000528060002060005b83811015614bf75781546001600160a01b0316875295820195600191820191016156cf565b6000815480845260208085019450836000528060002060005b83811015614bf75781548752958201956001918201910161570d565b6000815461573681615615565b808552602060018381168015615753576001811461576d5761579b565b60ff1985168884015283151560051b88018301955061579b565b866000528260002060005b858110156157935781548a8201860152908301908401615778565b890184019650505b505050505092915050565b80546001600160a01b0316825260406020830181905260009061181f90840160018401615729565b60006101806157f5846157e885546001600160a01b031690565b6001600160a01b03169052565b60018301546020850152600283015460408501526003830154606085015260048301546080850152600583015460a0850152600683015460c08501528060e085015261584681850160078501615729565b90506008830154610100850152600983015461012085015261586c600a84015460ff1690565b61587a610140860182614bb1565b5083810361016085015261560081600b85016156b6565b602081528154602082015260006158b260018401546001600160a01b031690565b6001600160a01b0390811660408401526002840154166060830152610180608083018190526158e86101a08401600386016156b6565b601f19808583030160a086015261590282600488016156f4565b915061591860058701546001600160a01b031690565b6001600160a01b0390811660c087015260068701541660e0860152600786015461010086015260088087015460ff8082161515610120890152911c161515610140860152848203810161016086015261597482600988016157a6565b91508085830301838601525061598d81600b87016157ce565b95945050505050565b6000600182016159a8576159a861564f565b5060010190565b601f821115613d1b57600081815260208120601f850160051c810160208610156159d65750805b601f850160051c820191505b818110156159f5578281556001016159e2565b505050505050565b81516001600160401b03811115615a1657615a16614dcb565b615a2a81615a248454615615565b846159af565b602080601f831160018114615a5f5760008415615a475750858301515b600019600386901b1c1916600185901b1785556159f5565b600085815260208120601f198616915b82811015615a8e57888601518255948401946001909101908401615a6f565b5085821015615aac5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215615ace57600080fd5b815160ff81168114614d9257600080fd5b600181815b80851115615b1a578160001904821115615b0057615b0061564f565b80851615615b0d57918102915b93841c9390800290615ae4565b509250929050565b600082615b3157506001611822565b81615b3e57506000611822565b8160018114615b545760028114615b5e57615b7a565b6001915050611822565b60ff841115615b6f57615b6f61564f565b50506001821b611822565b5060208310610133831016604e8410600b8410161715615b9d575081810a611822565b615ba78383615adf565b8060001904821115615bbb57615bbb61564f565b029392505050565b600061181f60ff841683615b22565b80820281158282048414176118225761182261564f565b600082615c0657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b0384168152606060208201819052600090615c2f908301856157ce565b9050615c3a83614ba1565b826040830152949350505050565b600082601f830112615c5957600080fd5b8151615c67614ee582614fac565b818152846020838601011115615c7c57600080fd5b615600826020830160208701614b3b565b8051614d7081615408565b600082601f830112615ca957600080fd5b81516020615cb9614ee583614ea1565b82815260059290921b84018101918181019086841115615cd857600080fd5b8286015b84811015614f2d578051615cef81614d50565b8352918301918301615cdc565b600060208284031215615d0e57600080fd5b81516001600160401b0380821115615d2557600080fd5b908301906101808286031215615d3a57600080fd5b615d42614e09565b615d4b83615678565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015182811115615d9b57600080fd5b615da787828601615c48565b60e08301525061010083810151908201526101208084015190820152610140615dd1818501615c8d565b908201526101608381015183811115615de957600080fd5b61523288828701615c98565b818103818111156118225761182261564f565b60208152600061181f6020830184614b5f565b600060208284031215615e2d57600080fd5b8151614d9281614f93565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215615e6e57600080fd5b5051919050565b60208152600061181f60208301846157ce565b600081615e9757615e9761564f565b506000190190565b818103615eaa575050565b615eb48254615615565b6001600160401b03811115615ecb57615ecb614dcb565b615ed981615a248454615615565b6000601f821160018114615f0d5760008315615ef55750848201545b600019600385901b1c1916600184901b178455615f72565b600085815260209020601f19841690600086815260209020845b83811015615f475782860154825560019586019590910190602001615f27565b5085831015615f655781850154600019600388901b60f8161c191681555b50505060018360011b0184555b5050505050565b602080825282516001600160a01b0316828201528201516040808301526000906156006060840182614b5f56fea2646970667358221220ebe2b3d934854cfb4de9f8f6f83befbb06ba7d038f923e591869649e32382f0964736f6c63430008110033

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

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.