false
true
0

Contract Address Details

0xf3E82f4123d4262a2baEC25b03652f3932A91739

Contract Name
TimeDeposit
Creator
0xc6eda6–db69f1 at 0xee7e5c–31415b
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
2,220 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
26093968
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
TimeDeposit




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




Optimization runs
200
EVM Version
default




Verified at
2023-09-29T08:55:25.823906Z

Constructor Arguments

0x000000000000000000000000faac6a85c3e123ab2cf7669b1024f146cfef0b38000000000000000000000000486fea20ea242456b450b005ed7d019e3e984f28

Arg [0] (address) : 0xfaac6a85c3e123ab2cf7669b1024f146cfef0b38
Arg [1] (address) : 0x486fea20ea242456b450b005ed7d019e3e984f28

              

Contract source code

// File: MAINNET/PulseDAO-main (8)/PulseDAO-main/contracts/interface/IVoting.sol


// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity >=0.7.0 <0.9.0;

interface IVoting {
    event AddCredit(address indexed depositor, uint256 amount);
    event BurnCredit(address burnFrom, uint256 amount, uint256 forId);
    event SetCreditingContract(address _contract, bool setting);
    event SetDeductingContract(address _contract, bool setting);

    function addCredit(uint256 amount, address _beneficiary) external;

    function airdropContract() external view returns (address);

    function airdropContractLocked() external view returns (address);

    function airdropVotingCredit(uint256 amount, address beneficiary) external;

    function burnCredit(uint256 amount, uint256 _forId) external;

    function burnedForId(uint256) external view returns (uint256);

    function creditingContract(address) external view returns (bool);

    function creditingContractCount() external view returns (uint256);

    function deductCredit(address from, uint256 amount) external returns (bool);

    function deductingContract(address) external view returns (bool);

    function deductingContractCount() external view returns (uint256);

    function depositCredit(uint256 amount) external;

    function masterchef() external view returns (address);

    function modifyCreditingContract(address _contract, bool setting) external;

    function modifyDeductingContract(address _contract, bool setting) external;

    function owner() external view returns (address);

    function redeemGovernor() external;

    function token() external view returns (address);

    function updateChef() external;

    function userCredit(address) external view returns (uint256);
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"contract IDTX","name":"_token","type":"address"},{"internalType":"contract IMasterChef","name":"_masterchef","type":"address"},{"internalType":"address","name":"_airdropContract","type":"address"},{"internalType":"address","name":"_airdropContractLocked","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddCredit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"burnFrom","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"forId","type":"uint256"}],"name":"BurnCredit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_contract","type":"address"},{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"SetCreditingContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_contract","type":"address"},{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"SetDeductingContract","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"addCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"airdropContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropContractLocked","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"airdropVotingCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_forId","type":"uint256"}],"name":"burnCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"burnedForId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"creditingContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creditingContractCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deductCredit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deductingContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deductingContractCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"masterchef","outputs":[{"internalType":"contract IMasterChef","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"bool","name":"setting","type":"bool"}],"name":"modifyCreditingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"bool","name":"setting","type":"bool"}],"name":"modifyDeductingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeemGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IDTX","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateChef","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userCredit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
*/

// File: MAINNET/PulseDAO-main (8)/PulseDAO-main/contracts/interface/IGovernor.sol


// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity >=0.7.0 <0.9.0;

interface IGovernor {
    event EnforceGovernor(address _newGovernor, address indexed enforcer);
    event GiveRolloverBonus(
        address recipient,
        uint256 amount,
        address poolInto
    );
    event Harvest(address indexed sender, uint256 callFee);
    event Multisig(
        address signer,
        address newGovernor,
        bool sign,
        uint256 idToVoteFor
    );
    event SetInflation(uint256 rewardPerBlock);
    event TransferOwner(address newOwner, uint256 timestamp);

    function acPool1() external view returns (address);

    function acPool1ID() external view returns (uint256);

    function acPool2() external view returns (address);

    function acPool2ID() external view returns (uint256);

    function acPool3() external view returns (address);

    function acPool3ID() external view returns (uint256);

    function acPool4() external view returns (address);

    function acPool4ID() external view returns (uint256);

    function acPool5() external view returns (address);

    function acPool5ID() external view returns (uint256);

    function acPool6() external view returns (address);

    function acPool6ID() external view returns (uint256);

    function allocationPercentages(uint256) external view returns (uint256);

    function basicContract() external view returns (address);

    function beginMintingPhase() external;

    function burnTokens(uint256 amount) external;

    function changeGovernorActivated() external view returns (bool);

    function changeGovernorForSecurityPriorMintingBegins(address _newGovernor)
        external;

    function consensusContract() external view returns (address);

    function costToVote() external view returns (uint256);

    function creditContract() external view returns (address);

    function delayBeforeEnforce() external view returns (uint256);

    function eligibleNewGovernor() external view returns (address);

    function enforceGovernor() external;

    function eventFibonacceningActive() external view returns (bool);

    function farmContract() external view returns (address);

    function fibonacceningContract() external view returns (address);

    function getRollBonus(address _bonusForPool)
        external
        view
        returns (uint256);

    function governorRejected() external;

    function harvest() external;

    function hexVault() external view returns (address);

    function incVault() external view returns (address);

    function isInflationStatic() external view returns (bool);

    function lastHarvestedTime() external view returns (uint256);

    function lastRegularReward() external view returns (uint256);

    function masterchef() external view returns (address);

    function maxDelay() external view returns (uint256);

    function minDelay() external view returns (uint256);

    function mintingPhaseLaunchDate() external view returns (uint256);

    function newGovernorBlockDelay() external view returns (uint256);

    function newGovernorRequestBlock() external view returns (uint256);

    function nftAllocationContract() external view returns (address);

    function nftStakingContract() external view returns (address);

    function nftStakingPoolID() external view returns (uint256);

    function nftWallet() external view returns (address);

    function pendingHarvestRewards() external view returns (uint256);

    function plsVault() external view returns (address);

    function plsxVault() external view returns (address);

    function postGrandFibIncreaseCount() external;

    function rebalancePools() external;

    function referralBonus() external view returns (uint256);

    function rememberReward() external;

    function rewardContract() external view returns (address);

    function senateContract() external view returns (address);

    function setActivateFibonaccening(bool _arg) external;

    function setCallFee(address _acPool, uint256 _newCallFee) external;

    function setGovernorTax(uint256 _amount) external;

    function setInflation(uint256 rewardPerBlock) external;

    function setNewGovernor(address beneficiary) external;

    function setPool(
        uint256 _pid,
        uint256 _allocPoint,
        bool _withUpdate
    ) external;

    function setThresholdFibonaccening(uint256 newThreshold) external;

    function stakeRolloverBonus(
        address _toAddress,
        address _depositToPool,
        uint256 _bonusToPay,
        uint256 _stakeID
    ) external;

    function thresholdFibonaccening() external view returns (uint256);

    function token() external view returns (address);

    function tokenDistributionContract() external view returns (address);

    function tokenDistributionContractExtraPenalty()
        external
        view
        returns (address);

    function tokensSentForReferralRewards() external view returns (uint256);

    function totalFibonacciEventsAfterGrand() external view returns (uint256);

    function transferCollectedFees(address _tokenContract) external;

    function transferRewardBoostThreshold() external;

    function transferToReferralContract() external;

    function transferToTreasury(uint256 amount) external;

    function treasuryRequest(
        address _tokenAddr,
        address _recipient,
        uint256 _amountToSend
    ) external;

    function treasuryWallet() external view returns (address);

    function tshareVault() external view returns (address);

    function updateCostToVote(uint256 newCostToVote) external;

    function updateDelayBeforeEnforce(uint256 newDelay) external;

    function updateDelayBetweenEvents(uint256 _amount) external;

    function updateGrandEventLength(uint256 _amount) external;

    function updateRolloverBonus(address _forPool, uint256 _bonus) external;

    function updateVault(uint256 _type, uint256 _amount) external;
}

// File: MAINNET/PulseDAO-main (8)/PulseDAO-main/contracts/interface/IacPool.sol


// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity >=0.7.0 <0.9.0;

interface IacPool {
    event AddAndExtendStake(
        address indexed sender,
        address indexed recipient,
        uint256 amount,
        uint256 stakeID,
        uint256 shares,
        uint256 lastDepositedTime
    );
    event AddVotes(address indexed voter, uint256 proposalID, uint256 change);
    event Deposit(
        address indexed sender,
        uint256 amount,
        uint256 shares,
        uint256 lastDepositedTime
    );
    event GiftDeposit(
        address indexed sender,
        address indexed recipient,
        uint256 amount,
        uint256 shares,
        uint256 lastDepositedTime
    );
    event HopDeposit(
        address indexed recipient,
        uint256 amount,
        uint256 shares,
        uint256 previousLastDepositedTime,
        uint256 mandatoryTime
    );
    event HopPool(
        address indexed sender,
        uint256 DTXamount,
        uint256 shares,
        address indexed newPool
    );
    event MigrateStake(
        address indexed goodSamaritan,
        uint256 DTXamount,
        uint256 shares,
        address indexed recipient
    );
    event RemoveVotes(
        address indexed voter,
        uint256 proposalID,
        uint256 change
    );
    event SetDelegate(address userDelegating, address delegatee);
    event StakeAllowanceRevoke(
        address owner,
        address spender,
        uint256 allowanceID
    );
    event StakeApproval(
        address owner,
        address spender,
        uint256 allowanceID,
        uint256 shareAllowance,
        uint256 lastDeposit,
        uint256 mandatoryTime
    );
    event TransferStake(
        address indexed sender,
        address indexed recipient,
        uint256 shares,
        uint256 stakeID
    );
    event TransferStakeFrom(
        address _from,
        address _to,
        uint256 _stakeID,
        uint256 _allowanceID
    );
    event TrustedPool(address contractAddress, bool setting);
    event TrustedSender(address contractAddress, bool setting);
    event Withdraw(
        address indexed sender,
        uint256 amount,
        uint256 penalty,
        uint256 shares
    );

    function addAndExtendStake(
        address _recipientAddr,
        uint256 _amount,
        uint256 _stakeID,
        uint256 _lockUpTokensInSeconds
    ) external;

    function admin() external view returns (address);

    function allowOrigin() external view returns (bool);

    function allowStakeTransfer() external view returns (bool);

    function allowStakeTransferFrom() external view returns (bool);

    function allowTxOrigin(bool _setting) external;

    function balanceOf() external view returns (uint256);

    function calculateHarvestDTXRewards() external view returns (uint256);

    function calculateTotalPendingDTXRewards() external view returns (uint256);

    function callFee() external view returns (uint256);

    function delegateeVote(address[] memory votingAddress, uint256 proposalID)
        external;

    function deposit(uint256 _amount) external;

    function enableDisableStakeTransfer(bool _setting) external;

    function enableDisableStakeTransferFrom(bool _setting) external;

    function getNrOfStakes(address _user) external view returns (uint256);

    function getPricePerFullShare() external view returns (uint256);

    function getUserShares(address _wallet, uint256 _stakeID)
        external
        view
        returns (uint256);

    function getUserTotalShares(address _user) external view returns (uint256);

    function giftDeposit(
        uint256 _amount,
        address _toAddress,
        uint256 _minToServeInSecs
    ) external;

    function giveStakeAllowance(address spender, uint256 _stakeID) external;

    function gracePeriod() external view returns (uint256);

    function hopDeposit(
        uint256 _amount,
        address _recipientAddress,
        uint256 previousLastDepositedTime,
        uint256 _mandatoryTime
    ) external;

    function hopStakeToAnotherPool(
        uint256 _shares,
        uint256 _stakeID,
        address _poolAddress
    ) external;

    function masterchef() external view returns (address);

    function migrateAllStakes(address _staker) external;

    function migrateStake(address _staker, uint256 _stakeID) external;

    function migrationPool() external view returns (address);

    function minimumGift() external view returns (uint256);

    function modifyPartialTransfers(bool _decision) external;

    function modifyPartialWithdrawals(bool _decision) external;

    function nrOfstakeAllowances(address owner, address spender)
        external
        view
        returns (uint256);

    function partialTransfers() external view returns (bool);

    function partialWithdrawals() external view returns (bool);

    function poolID() external view returns (uint256);

    function revokeStakeAllowance(address spender, uint256 allowanceID)
        external;

    function setAdmin() external;

    function setCallFee(uint256 _callFee) external;

    function setDelegate(address _delegate, bool asProxy) external;

    function setMasterChefAddress(address _masterchef, uint256 _newPoolID)
        external;

    function setMigrationPool(address _newPool) external;

    function setMinimumGiftDeposit(uint256 _amount, bool _setting) external;

    function setTrustedPool(address[] memory _pool, bool _setting) external;

    function setTrustedSender(address[] memory _sender, bool _setting) external;

    function stakeAllowances(
        address owner,
        address spender,
        uint256 allowanceID
    )
        external
        view
        returns (
            uint256,
            uint256,
            uint256
        );

    function stakeRollover(address _poolInto, uint256 _stakeID) external;

    function token() external view returns (address);

    function totalShares() external view returns (uint256);

    function totalVotesForID(uint256) external view returns (uint256);

    function transferStakeFrom(
        address _from,
        uint256 _stakeID,
        uint256 allowanceID,
        address _to
    ) external returns (bool);

    function transferStakeToAnotherWallet(
        uint256 _shares,
        uint256 _stakeID,
        address _recipientAddress
    ) external;

    function treasury() external view returns (address);

    function trustedPool(address) external view returns (bool);

    function trustedPoolCount() external view returns (uint256);

    function trustedSender(address) external view returns (bool);

    function trustedSenderCount() external view returns (uint256);

    function updateMinGiftGovernor() external view returns (bool);

    function updateMinimumGift() external;

    function userDelegate(address) external view returns (address);

    function userInfo(address, uint256)
        external
        view
        returns (
            uint256 shares,
            uint256 lastDepositedTime,
            uint256 dtxAtLastUserAction,
            uint256 lastUserActionTime,
            uint256 mandatoryTimeToServe
        );

    function userVote(address) external view returns (uint256);

    function voteForProposal(uint256 proposalID, bool asProxy) external;

    function votingCredit(uint256 _shares, uint256 _stakeID) external;

    function votingCreditAddress() external view returns (address);

    function withdraw(uint256 _shares, uint256 _stakeID) external;

    function withdrawAll(uint256 _stakeID) external;

    function withdrawFeePeriod() external view returns (uint256);

    function withdrawStuckTokens(address _tokenAddress) external;
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"contract IDTX","name":"_token","type":"address"},{"internalType":"contract IMasterChef","name":"_masterchef","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastDepositedTime","type":"uint256"}],"name":"AddAndExtendStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"change","type":"uint256"}],"name":"AddVotes","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastDepositedTime","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastDepositedTime","type":"uint256"}],"name":"GiftDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"previousLastDepositedTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mandatoryTime","type":"uint256"}],"name":"HopDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"DTXamount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"address","name":"newPool","type":"address"}],"name":"HopPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"goodSamaritan","type":"address"},{"indexed":false,"internalType":"uint256","name":"DTXamount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"MigrateStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"change","type":"uint256"}],"name":"RemoveVotes","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userDelegating","type":"address"},{"indexed":false,"internalType":"address","name":"delegatee","type":"address"}],"name":"SetDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"allowanceID","type":"uint256"}],"name":"StakeAllowanceRevoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"allowanceID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shareAllowance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastDeposit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mandatoryTime","type":"uint256"}],"name":"StakeApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeID","type":"uint256"}],"name":"TransferStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_stakeID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_allowanceID","type":"uint256"}],"name":"TransferStakeFrom","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"TrustedPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"TrustedSender","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"address","name":"_recipientAddr","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_stakeID","type":"uint256"},{"internalType":"uint256","name":"_lockUpTokensInSeconds","type":"uint256"}],"name":"addAndExtendStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowOrigin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowStakeTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowStakeTransferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"allowTxOrigin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateHarvestDTXRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateTotalPendingDTXRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"votingAddress","type":"address[]"},{"internalType":"uint256","name":"proposalID","type":"uint256"}],"name":"delegateeVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"enableDisableStakeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_setting","type":"bool"}],"name":"enableDisableStakeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getNrOfStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPricePerFullShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"getUserShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserTotalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_toAddress","type":"address"},{"internalType":"uint256","name":"_minToServeInSecs","type":"uint256"}],"name":"giftDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"giveStakeAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gracePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_recipientAddress","type":"address"},{"internalType":"uint256","name":"previousLastDepositedTime","type":"uint256"},{"internalType":"uint256","name":"_mandatoryTime","type":"uint256"}],"name":"hopDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_stakeID","type":"uint256"},{"internalType":"address","name":"_poolAddress","type":"address"}],"name":"hopStakeToAnotherPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"masterchef","outputs":[{"internalType":"contract IMasterChef","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"migrateAllStakes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"migrateStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumGift","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_decision","type":"bool"}],"name":"modifyPartialTransfers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_decision","type":"bool"}],"name":"modifyPartialWithdrawals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"nrOfstakeAllowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"partialTransfers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"partialWithdrawals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowanceID","type":"uint256"}],"name":"revokeStakeAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_callFee","type":"uint256"}],"name":"setCallFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"},{"internalType":"bool","name":"asProxy","type":"bool"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMasterChef","name":"_masterchef","type":"address"},{"internalType":"uint256","name":"_newPoolID","type":"uint256"}],"name":"setMasterChefAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPool","type":"address"}],"name":"setMigrationPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_setting","type":"bool"}],"name":"setMinimumGiftDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pool","type":"address[]"},{"internalType":"bool","name":"_setting","type":"bool"}],"name":"setTrustedPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_sender","type":"address[]"},{"internalType":"bool","name":"_setting","type":"bool"}],"name":"setTrustedSender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowanceID","type":"uint256"}],"name":"stakeAllowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_poolInto","type":"address"},{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"stakeRollover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IDTX","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalVotesForID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_stakeID","type":"uint256"},{"internalType":"uint256","name":"allowanceID","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"transferStakeFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_stakeID","type":"uint256"},{"internalType":"address","name":"_recipientAddress","type":"address"}],"name":"transferStakeToAnotherWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"trustedPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trustedPoolCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"trustedSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trustedSenderCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateMinGiftGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateMinimumGift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userDelegate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"lastDepositedTime","type":"uint256"},{"internalType":"uint256","name":"dtxAtLastUserAction","type":"uint256"},{"internalType":"uint256","name":"lastUserActionTime","type":"uint256"},{"internalType":"uint256","name":"mandatoryTimeToServe","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalID","type":"uint256"},{"internalType":"bool","name":"asProxy","type":"bool"}],"name":"voteForProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"votingCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"votingCreditAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakeID","type":"uint256"}],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFeePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"withdrawStuckTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
*/

// File: MAINNET/PulseDAO-main (8)/PulseDAO-main/contracts/interface/IMasterChef.sol


// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity ^0.8.20;

interface IMasterChef {
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
    event TransferCredit(address from, address to, uint256 amount);
    event TrustedContract(address contractAddress, bool setting);
    event UpdateEmissions(address indexed user, uint256 newEmissions);

    function DTXPerBlock() external view returns (uint256);

    function add(
        uint256 _allocPoint,
        address _participant,
        bool _withUpdate
    ) external;

    function burn(address _from, uint256 _amount) external returns (bool);

    function credit(address) external view returns (uint256);

    function dev(address _devaddr) external;

    function devaddr() external view returns (address);

    function dtx() external view returns (address);

    function existingParticipant(address) external view returns (bool);

    function fairMintSenate() external;

    function fairTokensPublishedToSenate() external view returns (uint256);

    function feeAddress() external view returns (address);

    function governorFee() external view returns (uint256);

    function massAdd(
        uint256[] memory _allocPoint,
        address[] memory _participant,
        bool[] memory _withUpdate
    ) external;

    function massUpdatePools() external;

    function owner() external view returns (address);

    function pendingDtx(uint256 _pid) external view returns (uint256);

    function poolInfo(uint256)
        external
        view
        returns (
            uint256 allocPoint,
            uint256 lastRewardBlock,
            address participant
        );

    function poolLength() external view returns (uint256);

    function publishTokens(address _to, uint256 _amount) external;

    function renounceOwnership() external;

    function renounceRewards() external;

    function rewardSenators(bool _e) external;

    function senatorRewards() external view returns (bool);

    function set(
        uint256 _pid,
        uint256 _allocPoint,
        bool _withUpdate
    ) external;

    function setFeeAddress(address _feeAddress) external;

    function setGovernorFee(uint256 _amount) external;

    function setTrustedContract(address _contractAddress, bool _setting)
        external;

    function startBlock() external view returns (uint256);

    function startPublishing(
        uint256 _pid,
        address _participant,
        uint256 _alloc
    ) external;

    function stopPublishing(uint256 _pid) external;

    function tokenChangeOwnership(address _newOwner) external;

    function totalAllocPoint() external view returns (uint256);

    function totalCreditRewards() external view returns (uint256);

    function totalCreditRewardsAtLastFairMint() external view returns (uint256);

    function totalPrincipalBurned() external view returns (uint256);

    function totalPublished() external view returns (uint256);

    function transferCredit(address _to, uint256 _amount) external;

    function transferOwnership(address newOwner) external;

    function trustedContract(address) external view returns (bool);

    function trustedContractCount() external view returns (uint256);

    function updateEmissionRate(uint256 _DTXPerBlock) external;

    function updatePool(uint256 _pid) external;

    function updateStartBlock(uint256 _startBlock) external;

    function virtualTotalSupply() external view returns (uint256);
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"contract IDTX","name":"_DTX","type":"address"},{"internalType":"address","name":"_airdropFull","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferCredit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"setting","type":"bool"}],"name":"TrustedContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"newEmissions","type":"uint256"}],"name":"UpdateEmissions","type":"event"},{"inputs":[],"name":"DTXPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"address","name":"_participant","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"credit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_devaddr","type":"address"}],"name":"dev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devaddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dtx","outputs":[{"internalType":"contract IDTX","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"existingParticipant","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fairMintSenate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fairTokensPublishedToSenate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governorFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_allocPoint","type":"uint256[]"},{"internalType":"address[]","name":"_participant","type":"address[]"},{"internalType":"bool[]","name":"_withUpdate","type":"bool[]"}],"name":"massAdd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"pendingDtx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"address","name":"participant","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"publishTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_e","type":"bool"}],"name":"rewardSenators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"senatorRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddress","type":"address"}],"name":"setFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setGovernorFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddress","type":"address"},{"internalType":"bool","name":"_setting","type":"bool"}],"name":"setTrustedContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_participant","type":"address"},{"internalType":"uint256","name":"_alloc","type":"uint256"}],"name":"startPublishing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"stopPublishing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"tokenChangeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCreditRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCreditRewardsAtLastFairMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPrincipalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalPublished","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"trustedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trustedContractCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_DTXPerBlock","type":"uint256"}],"name":"updateEmissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startBlock","type":"uint256"}],"name":"updateStartBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"virtualTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
*/

// File: MAINNET/PulseDAO-main (8)/PulseDAO-main/contracts/interface/IDTX.sol


// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity ^0.8.20;

interface IDTX {
    error ERC20InsufficientAllowance(
        address spender,
        uint256 allowance,
        uint256 needed
    );
    error ERC20InsufficientBalance(
        address sender,
        uint256 balance,
        uint256 needed
    );
    error ERC20InvalidApprover(address approver);
    error ERC20InvalidReceiver(address receiver);
    error ERC20InvalidSender(address sender);
    error ERC20InvalidSpender(address spender);
    error OwnableInvalidOwner(address owner);
    error OwnableUnauthorizedAccount(address account);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function MAX_SUPPLY() external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function balanceOf(address account) external view returns (uint256);

    function burn(uint256 value) external;

    function burnFrom(address account, uint256 value) external;

    function burnToken(address account, uint256 amount) external returns (bool);

    function decimals() external view returns (uint8);

    function governor() external view returns (address);

    function masterchefAddress() external view returns (address);

    function mint(address to, uint256 amount) external;

    function name() external view returns (string memory);

    function owner() external view returns (address);

    function rebrandName(string memory _newName) external;

    function rebrandSymbol(string memory _newSymbol) external;

    function renounceOwnership() external;

    function symbol() external view returns (string memory);

    function totalSupply() external view returns (uint256);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function transferOwnership(address newOwner) external;
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterchefAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_newName","type":"string"}],"name":"rebrandName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newSymbol","type":"string"}],"name":"rebrandSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
*/

// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

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

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

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: MAINNET/PulseDAO-main (8)/PulseDAO-main/contracts/mining/5year.sol



pragma solidity >= 0.8.0;










/**
 * DTX time-locked deposit
 * Auto-compounding pool
 * !!! Warning: !!! Copyrighted. 
 */
contract TimeDeposit is ReentrancyGuard {
    using SafeMath for uint256;

    struct UserInfo {
        uint256 shares; // number of shares for a user
        uint256 lastDepositedTime; // keeps track of deposited time for potential penalty
        uint256 dtxAtLastUserAction; // keeps track of DTX deposited at the last user action
        uint256 lastUserActionTime; // keeps track of the last user action time
        uint256 mandatoryTimeToServe; // optional: disables early withdraw
    }
	//allows stakes to be transferred, similar to token transfers
	struct StakeTransfer {
		uint256 shares; // ALLOWANCE of shares
        uint256 lastDepositedTime;
        uint256 mandatoryTimeToServe; 
	}

    IDTX public immutable token; // DTX token

    IMasterChef public masterchef;  
    
	// the secret formula they don't want you to know
    // 5 years = 5 * 365 = 1825 + 1(leap year every 4 years) = 1826
    // 1337 + 420 + 69 = 1826 ... 1826 days = exactly 5 years
    uint256 public immutable withdrawFeePeriod = 1826 days; 
    uint256 public immutable gracePeriod = 21 days;

    mapping(address => UserInfo[]) public userInfo;
    mapping(address => uint256) public userVote; //the ID the user is voting for
    mapping(uint256 => uint256) public totalVotesForID; //total votes for a given ID
	mapping(address => address) public userDelegate; //user can delegate their voting to another wallet
	
	mapping(address => bool) public trustedSender; //Pools with shorter lockup duration(trustedSender(contracts) can transfer into this pool)
	mapping(address => bool) public trustedPool; //Pools with longer lockup duration(can transfer from this pool into trustedPool(contracts))
	
	mapping(address => mapping(address => StakeTransfer[])) private _stakeAllowances; 
	//similar to token allowances, difference being it's not for amount of tokens, but for a specific stake defined by shares, latdeposittime and mandatorytime

	uint256 public poolID; 
    uint256 public totalShares;
    address public admin; //admin = governing contract!
    address public treasury; //penalties go to this address
    address public migrationPool; //if pools are to change

	
	uint256 public minimumGift = 1000 * 1e18;
	bool public updateMinGiftGovernor = true; //allows automatic update by anybody to costToVote from governing contract
    
    uint256 public callFee = 5; // call fee paid for rebalancing pools
	
	bool public allowStakeTransfer = true; //enable/disable transferring of stakes to another wallet
	bool public allowStakeTransferFrom = false; //allow third party transfers(disabled initially)
	
	bool public partialWithdrawals = true; //partial withdrawals from stakes
	bool public partialTransfers = true; //allows transferring a portion of  a stake
	
	bool public allowOrigin = true; //(dis)allows tx.origin for voting
	//safe to use tx.origin IMO. Can be disabled and use msg.sender instead
	//it allows the voting and delegating in a single transaction for all pools through a proxy contract
	
	// Easier to verify (opposed to checking event logs)
	uint256 public trustedSenderCount;
	uint256 public trustedPoolCount;

    event Deposit(address indexed sender, uint256 amount, uint256 shares, uint256 lastDepositedTime);
    event GiftDeposit(
        address indexed sender, 
        address indexed recipient, 
        uint256 amount, 
        uint256 shares, 
        uint256 lastDepositedTime
    );
    event AddAndExtendStake(
        address indexed sender, 
        address indexed recipient, 
        uint256 amount, 
        uint256 stakeID, 
        uint256 shares, 
        uint256 lastDepositedTime
    );
    event Withdraw(address indexed sender, uint256 amount, uint256 penalty, uint256 shares);
    
	event TransferStake(address indexed sender, address indexed recipient, uint256 shares, uint256 stakeID);
    event HopPool(address indexed sender, uint256 DTXamount, uint256 shares, address indexed newPool);
    event MigrateStake(address indexed goodSamaritan, uint256 DTXamount, uint256 shares, address indexed recipient);
   
    event HopDeposit(
        address indexed recipient, 
        uint256 amount, 
        uint256 shares, 
        uint256 previousLastDepositedTime, 
        uint256 mandatoryTime
    );
	
    event RemoveVotes(address indexed voter, uint256 proposalID, uint256 change);
    event AddVotes(address indexed voter, uint256 proposalID, uint256 change);
	
	event TrustedSender(address contractAddress, bool setting);
	event TrustedPool(address contractAddress, bool setting);
	
	event StakeApproval(
        address owner, 
        address spender, 
        uint256 allowanceID, 
        uint256 shareAllowance, 
        uint256 lastDeposit, 
        uint256 mandatoryTime
    );
	event StakeAllowanceRevoke(address owner, address spender, uint256 allowanceID);
	event TransferStakeFrom(address _from, address _to, uint256 _stakeID, uint256 _allowanceID);
	
	event SetDelegate(address userDelegating, address delegatee);

    /**
     * @notice Constructor
     * @param _token: DTX token contract
     * @param _masterchef: MasterChef contract
     */
    constructor(
        IDTX _token,
        IMasterChef _masterchef
    ) {
        token = _token;
        masterchef = _masterchef;
        admin = msg.sender;
        poolID = 5;
    }
    
    /**
     * @notice Checks if the msg.sender is the admin
     */
    modifier decentralizedVoting() {
        require(msg.sender == admin, "admin: wut?");
        _;
    }
	
    /**
     * @notice Deposits funds into the DTX time-locked vault
     * @param _amount: number of tokens to deposit (in DTX
     * 
     * Creates a NEW stake
     */
    function deposit(uint256 _amount) external nonReentrant {
    	require(_amount > 0, "Nothing to deposit");
	
        uint256 pool = balanceOf();
        require(masterchef.burn(msg.sender, _amount), "token burn failed");
        uint256 currentShares = 0;
        if (totalShares != 0) {
            currentShares = (_amount.mul(totalShares)).div(pool);
        } else {
            currentShares = _amount;
        }
        
        totalShares = totalShares.add(currentShares);
        
        userInfo[msg.sender].push(
                UserInfo(currentShares, block.timestamp, _amount, block.timestamp, 0)
            );
        
		uint256 votingFor = userVote[msg.sender];
        if(votingFor != 0) {
            _updateVotingAddDiff(msg.sender, votingFor, currentShares);
        }

        emit Deposit(msg.sender, _amount, currentShares, block.timestamp);
    }

    /**
     * Equivalent to Deposit
     * Instead of crediting the msg.sender, it credits custom recipient
     * A mechanism to gift a time-locked stake to another wallet
     * Users can withdraw at any time(but will pay a penalty)
     * Optionally stake can be irreversibly locked for a minimum period of time(minToServe)
     */
    function giftDeposit(uint256 _amount, address _toAddress, uint256 _minToServeInSecs) external nonReentrant {
        require(_amount >= minimumGift, "Below Minimum Gift");

        uint256 pool = balanceOf();
        require(masterchef.burn(msg.sender, _amount), "token burn failed");
        uint256 currentShares = 0;
        if (totalShares != 0) {
            currentShares = (_amount.mul(totalShares)).div(pool);
        } else {
            currentShares = _amount;
        }
        
        totalShares = totalShares.add(currentShares);
        
        userInfo[_toAddress].push(
                UserInfo(currentShares, block.timestamp, _amount, block.timestamp, _minToServeInSecs)
            );
			
        uint256 votingFor = userVote[_toAddress];
        if(votingFor != 0) {
            _updateVotingAddDiff(_toAddress, votingFor, currentShares);
        }

        emit GiftDeposit(msg.sender, _toAddress, _amount, currentShares, block.timestamp);
    }
    
    /**
     * @notice Deposits funds into the DTX time-locked vault
     * @param _amount: number of tokens to deposit (in DTX
     * 
     * Deposits into existing stake, effectively extending the stake
     * It's used for rolling over stakes by the governor(admin) as well
     * Mandatory Lock Up period can only be Increased
	 * It can be Decreased if stake is being extended(after it matures)
     */
    function addAndExtendStake(address _recipientAddr, uint256 _amount, uint256 _stakeID, uint256 _lockUpTokensInSeconds) external nonReentrant {
        require(_amount > 0, "Nothing to deposit");
        require(userInfo[_recipientAddr].length > _stakeID, "wrong Stake ID");
        
        if(msg.sender != admin) { require(_recipientAddr == msg.sender, "can only extend your own stake"); }

        uint256 pool = balanceOf();
        require(masterchef.burn(msg.sender, _amount), "token burn failed");
        uint256 currentShares = 0;
        if (totalShares != 0) {
            currentShares = (_amount.mul(totalShares)).div(pool);
        } else {
            currentShares = _amount;
        }
        UserInfo storage user = userInfo[_recipientAddr][_stakeID];

        user.shares = user.shares.add(currentShares);
        totalShares = totalShares.add(currentShares);
        
        if(_lockUpTokensInSeconds > user.mandatoryTimeToServe || 
				block.timestamp > user.lastDepositedTime.add(withdrawFeePeriod)) { 
			user.mandatoryTimeToServe = _lockUpTokensInSeconds; 
		}
		
        user.dtxAtLastUserAction = user.shares.mul(balanceOf()).div(totalShares);
        user.lastUserActionTime = block.timestamp;
		user.lastDepositedTime = block.timestamp;
        
		uint256 votingFor = userVote[_recipientAddr];
        if(votingFor != 0) {
            _updateVotingAddDiff(_recipientAddr, votingFor, currentShares);
        }

        emit AddAndExtendStake(msg.sender, _recipientAddr, _amount, _stakeID, currentShares, block.timestamp);
    }
 

    function withdrawAll(uint256 _stakeID) external {
        withdraw(userInfo[msg.sender][_stakeID].shares, _stakeID);
    }

    
    /**
     * @notice Sets admin address and treasury
     * If new governor is set, anyone can pay the gas to update the addresses
	 * Masterchef owns the token, the governor owns the Masterchef
	 * Treasury is feeAddress from masterchef(which collects fees from deposits into masterchef)
	 * Currently all penalties are going to fee address(currently governing contract)
	 * Alternatively, fee address can be set as a separate contract, which would re-distribute
	 * The tokens back into pool(so honest stakers would directly receive penalties from prematurely ended stakes)
	 * Alternatively could also split: a portion to honest stakers, a portion into governing contract. 
	 * With initial setting, all penalties are going towards governing contract
     */
    function setAdmin() external {
        admin = IMasterChef(masterchef).owner();
        treasury = IMasterChef(masterchef).feeAddress();
    }
	
	//updates minimum gift to costToVote from Governing contract
	function updateMinimumGift() external {
		require(updateMinGiftGovernor, "automatic update disabled");
		minimumGift = IGovernor(admin).costToVote();
	}

    /**
     * @notice Withdraws from funds from the DTX time-locked vault
     * @param _shares: Number of shares to withdraw
     */
    function withdraw(uint256 _shares, uint256 _stakeID) public {
        require(_stakeID < userInfo[msg.sender].length, "invalid stake ID");
        UserInfo storage user = userInfo[msg.sender][_stakeID];
        require(_shares > 0, "Nothing to withdraw");
        require(_shares <= user.shares, "Withdraw amount exceeds balance");
        require(block.timestamp > user.lastDepositedTime.add(user.mandatoryTimeToServe), "must serve mandatory time");
        if(!partialWithdrawals) { require(_shares == user.shares, "must transfer full stake"); }

        uint256 currentAmount = (balanceOf().mul(_shares)).div(totalShares);
        user.shares = user.shares.sub(_shares);
        totalShares = totalShares.sub(_shares);

        uint256 currentWithdrawFee = 0;
        
        if (block.timestamp < user.lastDepositedTime.add(withdrawFeePeriod)) {
            uint256 withdrawFee = uint256(8200).sub(((block.timestamp - user.lastDepositedTime).div(86400)).mul(4269).div(1000));
            currentWithdrawFee = currentAmount.mul(withdrawFee).div(10000);
            IMasterChef(masterchef).publishTokens(treasury, currentWithdrawFee); 
            currentAmount = currentAmount.sub(currentWithdrawFee);
        } else if(block.timestamp > user.lastDepositedTime.add(withdrawFeePeriod).add(gracePeriod)) {
            uint256 withdrawFee = block.timestamp.sub(user.lastDepositedTime.add(withdrawFeePeriod)).div(86400).mul(4269).div(1000);
            if(withdrawFee > 8200) { withdrawFee = 8200; }
            currentWithdrawFee = currentAmount.mul(withdrawFee).div(10000);
            IMasterChef(masterchef).publishTokens(treasury, currentWithdrawFee); 
            currentAmount = currentAmount.sub(currentWithdrawFee);
        }

        if (user.shares > 0) {
            user.dtxAtLastUserAction = user.shares.mul(balanceOf().sub(currentAmount)).div(totalShares);
            user.lastUserActionTime = block.timestamp;
        } else {
            _removeStake(msg.sender, _stakeID); //delete the stake
        }
        
		uint256 votingFor = userVote[msg.sender];
        if(votingFor != 0) {
            _updateVotingSubDiff(msg.sender, votingFor, _shares);
        }

		emit Withdraw(msg.sender, currentAmount, currentWithdrawFee, _shares);
		
        IMasterChef(masterchef).publishTokens(msg.sender, currentAmount);
    } 
    
    /**
     * Users can transfer their stake to another pool
     * Can only transfer to pool with longer lock-up period(trusted pools)
     * Equivalent to withdrawing, but it deposits the stake into another pool as hopDeposit
     * Users can transfer stake without penalty
     * Time served gets transferred 
     * The pool is "registered" as a "trustedSender" to another pool
     */
    function hopStakeToAnotherPool(uint256 _shares, uint256 _stakeID, address _poolAddress) public {
        require(_shares > 0, "Nothing to withdraw");
		require(_stakeID < userInfo[msg.sender].length, "wrong stake ID");
		
        UserInfo storage user = userInfo[msg.sender][_stakeID];
		require(_shares <= user.shares, "Withdraw amount exceeds balance");
        if(!partialWithdrawals) { require(_shares == user.shares, "must transfer full stake"); } 
        
		uint256 _lastDepositedTime = user.lastDepositedTime;
        if(trustedPool[_poolAddress]) { 
			if(block.timestamp > _lastDepositedTime.add(withdrawFeePeriod).add(gracePeriod)) {
				_lastDepositedTime = block.timestamp; //if after grace period, resets timer
			}
        } else { 
			//can only hop into trusted Pools or into trusted sender(lower pool) after time has been served within grace period
			//only meant for stakeRollover. After hop, stake is extended and timer reset
            require(trustedSender[_poolAddress] && block.timestamp > _lastDepositedTime.add(withdrawFeePeriod) &&
                                block.timestamp < _lastDepositedTime.add(withdrawFeePeriod).add(gracePeriod),
                                        "can only hop into pre-set Pools");
		}

        uint256 currentAmount = (balanceOf().mul(_shares)).div(totalShares);
        user.shares = user.shares.sub(_shares);
        totalShares = totalShares.sub(_shares);
		
		uint256 votingFor = userVote[msg.sender];
        if(votingFor != 0) {
            _updateVotingSubDiff(msg.sender, votingFor, _shares);
        }
		
		IacPool(_poolAddress).hopDeposit(currentAmount, msg.sender, _lastDepositedTime, user.mandatoryTimeToServe);
		IMasterChef(masterchef).transferCredit(_poolAddress, currentAmount);

        if (user.shares > 0) {
            user.dtxAtLastUserAction = user.shares.mul(balanceOf()).div(totalShares);
            user.lastUserActionTime = block.timestamp;
        } else {
            _removeStake(msg.sender, _stakeID); //delete the stake
        }
        
        emit HopPool(msg.sender, currentAmount, _shares, _poolAddress);
    }

    
    /**
     * hopDeposit is equivalent to gift deposit, exception being that the time served can be passed
     * The msg.sender can only be a trusted contract
     * The checks are already made in the hopStakeToAnotherPool function
     * msg sender can only be trusted senders
     */
     
    function hopDeposit(uint256 _amount, address _recipientAddress, uint256 previousLastDepositedTime, uint256 _mandatoryTime) external {
        require(trustedSender[msg.sender] || trustedPool[msg.sender], "only trusted senders(other pools)");
		//only trustedSenders allowed. TrustedPools are under condition that the stake has matured(hopStake checks condition)
        
        uint256 pool = balanceOf();
        
        uint256 currentShares = 0;
        if (totalShares != 0) {
            currentShares = (_amount.mul(totalShares)).div(pool);
        } else {
            currentShares = _amount;
        }
        
        totalShares = totalShares.add(currentShares);
        
        userInfo[_recipientAddress].push(
                UserInfo(currentShares, previousLastDepositedTime, _amount,
                    block.timestamp, _mandatoryTime)
            );

		uint256 votingFor = userVote[_recipientAddress];
        if(votingFor != 0) {
            _updateVotingAddDiff(_recipientAddress, votingFor, currentShares);
        }

        emit HopDeposit(_recipientAddress, _amount, currentShares, previousLastDepositedTime, _mandatoryTime);
    }
	
    /**
     * Users are encouraged to keep staking
     * Governor pays bonuses to re-commit and roll over your stake
     * Higher bonuses available for hopping into pools with longer lockup period
     */
    function stakeRollover(address _poolInto, uint256 _stakeID) external {
        require(userInfo[msg.sender].length > _stakeID, "invalid stake ID");
        
        UserInfo storage user = userInfo[msg.sender][_stakeID];
        
        require(block.timestamp > user.lastDepositedTime.add(withdrawFeePeriod), "stake not yet mature");
        
        uint256 currentAmount = (balanceOf().mul(user.shares)).div(totalShares); 
        uint256 toPay = currentAmount.mul(IGovernor(admin).getRollBonus(_poolInto)).div(10000);

        require(IDTX(token).balanceOf(admin) >= toPay, "governor reserves are currently insufficient");
        
        if(_poolInto == address(this)) {
            IGovernor(admin).stakeRolloverBonus(msg.sender, _poolInto, toPay, _stakeID); //gov sends tokens to extend the stake
        } else {
			hopStakeToAnotherPool(user.shares, _stakeID, _poolInto); //will revert if pool is wrong
			IGovernor(admin).stakeRolloverBonus(msg.sender, _poolInto, toPay, IacPool(_poolInto).getNrOfStakes(msg.sender) - 1); //extends latest stake
        }
    }
    
    /**
     * Transfer stake to another account(another wallet address)
     */
    function transferStakeToAnotherWallet(uint256 _shares, uint256 _stakeID, address _recipientAddress) external {
        require(allowStakeTransfer, "transfers disabled");
		require(_recipientAddress != msg.sender, "can't transfer to self");
        require(_stakeID < userInfo[msg.sender].length, "wrong stake ID");
        UserInfo storage user = userInfo[msg.sender][_stakeID];
		uint256 _tokensTransferred = _shares.mul(balanceOf()).div(totalShares);
        require(_tokensTransferred >= minimumGift, "Below minimum threshold");
        require(_shares <= user.shares, "Withdraw amount exceeds balance");
        if(!partialTransfers) { require(_shares == user.shares, "must transfer full stake"); }
        
        user.shares = user.shares.sub(_shares);

		uint256 votingFor = userVote[msg.sender];
        if(votingFor != 0) {
            _updateVotingSubDiff(msg.sender, votingFor, _shares);
        }
		votingFor = userVote[_recipientAddress];
        if(votingFor != 0) {
            _updateVotingAddDiff(_recipientAddress, votingFor, _shares);
        }
        
        userInfo[_recipientAddress].push(
                UserInfo(_shares, user.lastDepositedTime, _tokensTransferred, block.timestamp, user.mandatoryTimeToServe)
            );

        if (user.shares > 0) {
            user.dtxAtLastUserAction = user.shares.mul(balanceOf()).div(totalShares);
            user.lastUserActionTime = block.timestamp;
        } else {
            _removeStake(msg.sender, _stakeID); //delete the stake
        }

        emit TransferStake(msg.sender, _recipientAddress, _shares, _stakeID);
    }

    /**
     * user delegates their shares to cast a vote on a proposal
     * casting to proposal ID = 0 is basically neutral position (not voting)
	 * Is origin is allowed, proxy contract can be used to vote in all pools in a single tx
     */
    function voteForProposal(uint256 proposalID, bool asProxy) external {
        address _wallet;
		(allowOrigin && asProxy) ? _wallet = tx.origin : _wallet = msg.sender;
        uint256 votingFor = userVote[_wallet]; //the ID the user is voting for(before change)
		
        if(proposalID != votingFor) { // do nothing if false(already voting for that ID)
	
			uint256 userTotalShares = getUserTotalShares(_wallet);
			if(userTotalShares > 0) { //if false, no shares, thus just assign proposal ID to userVote
				if(proposalID != 0) { // Allocates vote to an ID
					if(votingFor == 0) { //starts voting, adds votes
						_updateVotingAddDiff(_wallet, proposalID, userTotalShares);
					} else { //removes from previous vote, adds to new
						_updateVotingSubDiff(_wallet, votingFor, userTotalShares);
						_updateVotingAddDiff(_wallet, proposalID, userTotalShares);
					}
				} else { //stops voting (previously voted, now going into neutral (=0)
					_updateVotingSubDiff(_wallet, votingFor, userTotalShares);
				}
			}
			userVote[_wallet] = proposalID;
		}
    }
	
	/*
	* delegatee can vote with shares of another user
	*/
    function delegateeVote(address[] calldata votingAddress, uint256 proposalID) external {
        for(uint256 i = 0; i < votingAddress.length; i++) {
			if(userDelegate[votingAddress[i]] == msg.sender) {
				uint256 votingFor = userVote[votingAddress[i]]; //the ID the user is voting for(before change)
				
				if(proposalID != votingFor){
				
					uint256 userTotalShares = getUserTotalShares(votingAddress[i]);
					if(userTotalShares > 0) {
						if(proposalID != 0) { 
							if(votingFor == 0) {
								_updateVotingAddDiff(votingAddress[i], proposalID, userTotalShares);
							} else {
								_updateVotingSubDiff(votingAddress[i], votingFor, userTotalShares);
								_updateVotingAddDiff(votingAddress[i], proposalID, userTotalShares);
							}
						} else {
							_updateVotingSubDiff(votingAddress[i], votingFor, userTotalShares);
						}
					}
					userVote[votingAddress[i]] = proposalID;
				}
			}
		}
    }
	
     /**
     * Users can delegate their shares
     */
    function setDelegate(address _delegate, bool asProxy) external {
        address _wallet;
		(allowOrigin && asProxy) ? _wallet=tx.origin : _wallet=msg.sender;
        userDelegate[_wallet] = _delegate;
        
		emit SetDelegate(_wallet, _delegate);
    }
	
	// allows third party stake transfer(stake IDs can be changed, 
	// so instead of being identified through ID, it's identified by shares, lastdeposit and mandatory time
    function giveStakeAllowance(address spender, uint256 _stakeID) external {
		UserInfo storage user = userInfo[msg.sender][_stakeID];
		require(user.shares.mul(balanceOf()).div(totalShares) >= minimumGift, "below minimum threshold");
		
		uint256 _allowanceID = _stakeAllowances[msg.sender][spender].length;

		_stakeAllowances[msg.sender][spender].push(
			StakeTransfer(user.shares, user.lastDepositedTime, user.mandatoryTimeToServe)
		);
		
		emit StakeApproval(msg.sender, spender, _allowanceID, user.shares, user.lastDepositedTime, user.mandatoryTimeToServe);
    }
	
    //Note: allowanceID (and not ID of the stake!)
	function revokeStakeAllowance(address spender, uint256 allowanceID) external {
		StakeTransfer[] storage allowances = _stakeAllowances[msg.sender][spender];
        uint256 lastAllowanceID = allowances.length.sub(1);
        
        if(allowanceID != lastAllowanceID) {
            allowances[allowanceID] = allowances[lastAllowanceID];
        }
        
        allowances.pop();
		
		emit StakeAllowanceRevoke(msg.sender, spender, allowanceID);
	}
	
    /**
     * A third party can transfer the stake(allowance required)
	 * Allows smart contract inter-operability similar to how regular tokens work
	 * Can only transfer full stake (You can split the stake through other methods)
	 * Bad: makes illiquid stakes liquid
	 * I think best is to have the option, but leave it unavailable unless desired
     */
    function transferStakeFrom(address _from, uint256 _stakeID, uint256 allowanceID, address _to) external returns (bool) {
        require(allowStakeTransferFrom, "third party stake transfers disabled");
		
		require(_from != _to, "can't transfer to self");
        require(_stakeID < userInfo[_from].length, "wrong stake ID");
        UserInfo storage user = userInfo[_from][_stakeID];
		
		(uint256 _shares, uint256 _lastDeposit, uint256 _mandatoryTime) = stakeAllowances(_from, msg.sender, allowanceID);

		//since stake ID can change, the stake to transfer is identified through number of shares, last deposit and mandatory time
		//checks if stake allowance(for allowanceID) matches the actual stake of a user
		require(_shares == user.shares, "incorrect stake or allowance");
		require(_lastDeposit == user.lastDepositedTime, "incorrect stake or allowance");
		require(_mandatoryTime == user.mandatoryTimeToServe, "incorrect stake or allowance");
     
		uint256 votingFor = userVote[_from];
        if(votingFor != 0) {
            _updateVotingSubDiff(_from, votingFor, _shares);
        }
		votingFor = userVote[_to];
        if(votingFor != 0) {
            _updateVotingAddDiff(_to, votingFor, _shares);
        }

        _removeStake(_from, _stakeID); //transfer from must transfer full stake
		_revokeStakeAllowance(_from, allowanceID);
		
        userInfo[_to].push(
                UserInfo(_shares, _lastDeposit, _shares.mul(balanceOf()).div(totalShares),
                    block.timestamp, _mandatoryTime)
            );

        emit TransferStakeFrom(_from, _to, _stakeID, allowanceID);
		
		return true;
    }
	
	/**
     * Ability to withdraw tokens from the stake, and add voting credit
     * At the time of launch there is no option(voting with credit), but can be added later on
    */
	function votingCredit(uint256 _shares, uint256 _stakeID) public {
        require(votingCreditAddress() != address(0), "disabled");
        require(_stakeID < userInfo[msg.sender].length, "invalid stake ID");
        UserInfo storage user = userInfo[msg.sender][_stakeID];
        require(_shares > 0, "Nothing to withdraw");
        require(_shares <= user.shares, "Withdraw amount exceeds balance");

        uint256 currentAmount = (balanceOf().mul(_shares)).div(totalShares);
        user.shares = user.shares.sub(_shares);
        totalShares = totalShares.sub(_shares);

        if (user.shares > 0) {
            user.dtxAtLastUserAction = user.shares.mul(balanceOf().sub(currentAmount)).div(totalShares);
            user.lastUserActionTime = block.timestamp;
        } else {
            _removeStake(msg.sender, _stakeID); //delete the stake
        }

		uint256 votingFor = userVote[msg.sender];
        if(votingFor != 0) {
            _updateVotingSubDiff(msg.sender, votingFor, _shares);
        }

		emit Withdraw(treasury, currentAmount, 0, _shares);
		
        IMasterChef(masterchef).publishTokens(treasury, currentAmount);
		IVoting(votingCreditAddress()).addCredit(currentAmount, msg.sender); 
    } 
	
    /**
	 * Allows the pools to be changed to new contracts
     * if migration Pool is set
     * anyone can be a "good Samaritan"
     * and transfer the stake of another user to the new pool
     */
    function migrateStake(address _staker, uint256 _stakeID) public {
        require(migrationPool != address(0), "migration not activated");
        require(_stakeID < userInfo[_staker].length, "invalid stake ID");
        UserInfo storage user = userInfo[_staker][_stakeID];
		require(user.shares > 0, "no balance");
        
        uint256 currentAmount = (balanceOf().mul(user.shares)).div(totalShares);
        totalShares = totalShares.sub(user.shares);
		
        user.shares = 0; // equivalent to deleting the stake. Pools are no longer to be used,
						//setting user shares to 0 is sufficient
		
		IacPool(migrationPool).hopDeposit(currentAmount, _staker, user.lastDepositedTime, user.mandatoryTimeToServe);
		IMasterChef(masterchef).transferCredit(migrationPool, currentAmount);

        emit MigrateStake(msg.sender, currentAmount, user.shares, _staker);
    }

    /**
     * loop and migrate all user stakes
     * could run out of gas if too many stakes
     */
    function migrateAllStakes(address _staker) external {
        UserInfo[] storage user = userInfo[_staker];
        uint256 userStakes = user.length;
        
        for(uint256 i=0; i < userStakes; i++) {
            migrateStake(_staker, i);
        }
    }
    
	//enables or disables ability to draw stake from another wallet(allowance required)
	function enableDisableStakeTransferFrom(bool _setting) external decentralizedVoting {
		allowStakeTransferFrom = _setting;
	}

    /**
     * @notice Sets call fee 
     * @dev Only callable by the contract admin.
     */
    function setCallFee(uint256 _callFee) external decentralizedVoting {
        callFee = _callFee;
    }

     /*
     * set trusted senders, other pools that we can receive from (that can hopDeposit)
     * guaranteed to be trusted (they rely lastDepositTime)
     */
    function setTrustedSender(address[] calldata _sender, bool _setting) external decentralizedVoting {
        for(uint i=0; i < _sender.length; i++) {
		if(trustedSender[_sender[i]] != _setting) {
				trustedSender[_sender[i]] = _setting;

				_setting ? trustedSenderCount++ : trustedSenderCount--;

				emit TrustedSender(_sender[i], _setting);
			}
		}
    }
    
     /**
     * set trusted pools, the smart contracts that we can send the tokens to without penalty
	 * NOTICE: new pool must be set as trusted contract(to be able to draw balance without allowance)
     */
    function setTrustedPool(address[] calldata _pool, bool _setting) external decentralizedVoting {
        for(uint i=0; i < _pool.length; i++) {
		if(trustedPool[_pool[i]] != _setting) {
			trustedPool[_pool[i]] = _setting;
			
			_setting ? trustedPoolCount++ : trustedPoolCount--;

			emit TrustedPool(_pool[i], _setting);
		}
	}
    }


     /**
     * set address of new pool that we can migrate into
	 * !!! NOTICE !!!
     *  new pool must be set as trusted contract in the token contract by the governor(to be able to draw balance without allowance)
     */
    function setMigrationPool(address _newPool) external decentralizedVoting {
		migrationPool = _newPool;
    }
    
     /**
     * Enable or disable partial withdrawals from stakes
     */
    function modifyPartialWithdrawals(bool _decision) external decentralizedVoting {
        partialWithdrawals = _decision;
    }
	function modifyPartialTransfers(bool _decision) external decentralizedVoting {
        partialTransfers = _decision;
    }
	
	function enableDisableStakeTransfer(bool _setting) external decentralizedVoting {
		allowStakeTransfer = _setting;
	}

	
	/*
	 * Unlikely, but Masterchef can be changed if needed to be used without changing pools
	 * masterchef = IMasterChef(token.owner());
	 * Must stop earning first(withdraw tokens from old chef)
	*/
	function setMasterChefAddress(IMasterChef _masterchef, uint256 _newPoolID) external decentralizedVoting {
		masterchef = _masterchef;
		poolID = _newPoolID; //in case pool ID changes
	}
	
	
	function allowTxOrigin(bool _setting) external decentralizedVoting {
		allowOrigin = _setting;
	}
	
	//sets minimum amount(for sending gift, transferring to another wallet,...)
	//if setting is enabled, minimumGift can be auto-updated to costToVote from governor by anybody
	function setMinimumGiftDeposit(uint256 _amount, bool _setting) external decentralizedVoting {
		minimumGift = _amount;
		updateMinGiftGovernor = _setting;
	}

	/**
     * Returns number of stakes for a user
     */
    function getNrOfStakes(address _user) external view returns (uint256) {
        return userInfo[_user].length;
    }
	
    /**
     * @notice Calculates the expected harvest reward from third party
     * @return Expected reward to collect in DTX
     */
    function calculateHarvestDTXRewards() external view returns (uint256) {
        uint256 amount = IMasterChef(masterchef).pendingDtx(poolID);
        uint256 currentCallFee = amount.mul(callFee).div(10000);

        return currentCallFee;
    }

    /**
     * @return Returns total pending dtx rewards
     */
    function calculateTotalPendingDTXRewards() external view returns (uint256) {
        uint256 amount = IMasterChef(masterchef).pendingDtx(poolID);

        return amount;
    }

    /**
     * @notice Calculates the price per share
     */
    function getPricePerFullShare() external view returns (uint256) {
        return totalShares == 0 ? 1e18 : balanceOf().mul(1e18).div(totalShares);
    }

	/**
     * Returns all shares for a user
     */
    function getUserTotalShares(address _user) public view returns (uint256) {
        UserInfo[] storage _stake = userInfo[_user];
        uint256 nrOfUserStakes = _stake.length;

		uint256 countShares = 0;
		
		for(uint256 i=0; i < nrOfUserStakes; i++) {
			countShares += _stake[i].shares;
		}
		
		return countShares;
    }
    
    /**
     * @notice returns number of shares for a certain stake of an user
     */
    function getUserShares(address _wallet, uint256 _stakeID) public view returns (uint256) {
        return userInfo[_wallet][_stakeID].shares;
    }
	
    /**
     * @notice Calculates the total underlying tokens
     * @dev It includes tokens held by the contract and held in MasterChef
     */
    function balanceOf() public view returns (uint256) {
        uint256 amount = IMasterChef(masterchef).pendingDtx(poolID); 
		uint256 _credit = IMasterChef(masterchef).credit(address(this));
        return amount.add(_credit); 
    }
    
    function votingCreditAddress() public view returns (address) {
    	return IGovernor(admin).creditContract();
    }

	function nrOfstakeAllowances(address owner, address spender) public view returns (uint256) {
        return _stakeAllowances[owner][spender].length;
    }
	
    function stakeAllowances(address owner, address spender, uint256 allowanceID) public view returns (uint256, uint256, uint256) {
        StakeTransfer storage stakeStore = _stakeAllowances[owner][spender][allowanceID];
        return (stakeStore.shares, stakeStore.lastDepositedTime, stakeStore.mandatoryTimeToServe);
    }
	
    //Note: allowanceID (and not ID of the stake!)
	function _revokeStakeAllowance(address owner, uint256 allowanceID) private {
		StakeTransfer[] storage allowances = _stakeAllowances[owner][msg.sender];
        uint256 lastAllowanceID = allowances.length.sub(1);
        
        if(allowanceID != lastAllowanceID) {
            allowances[allowanceID] = allowances[lastAllowanceID];
        }
        
        allowances.pop();
		
		emit StakeAllowanceRevoke(owner, msg.sender, allowanceID);
	}
	
    /**
     * updates votes(whenever there is transfer of funds)
     */
    function _updateVotingAddDiff(address voter, uint256 proposalID, uint256 diff) private {
        totalVotesForID[proposalID] = totalVotesForID[proposalID].add(diff);
        
        emit AddVotes(voter, proposalID, diff);
    }
    function _updateVotingSubDiff(address voter, uint256 proposalID, uint256 diff) private {
        totalVotesForID[proposalID] = totalVotesForID[proposalID].sub(diff);
        
        emit RemoveVotes(voter, proposalID, diff);
    }
    
    /**
     * removes the stake
     */
    function _removeStake(address _staker, uint256 _stakeID) private {
        UserInfo[] storage stakes = userInfo[_staker];
        uint256 lastStakeID = stakes.length - 1;
        
        if(_stakeID != lastStakeID) {
            stakes[_stakeID] = stakes[lastStakeID];
        }
        
        stakes.pop();
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_token","internalType":"contract IDTX"},{"type":"address","name":"_masterchef","internalType":"contract IMasterChef"}]},{"type":"event","name":"AddAndExtendStake","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"stakeID","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"uint256","name":"lastDepositedTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AddVotes","inputs":[{"type":"address","name":"voter","internalType":"address","indexed":true},{"type":"uint256","name":"proposalID","internalType":"uint256","indexed":false},{"type":"uint256","name":"change","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Deposit","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"uint256","name":"lastDepositedTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"GiftDeposit","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"uint256","name":"lastDepositedTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"HopDeposit","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"uint256","name":"previousLastDepositedTime","internalType":"uint256","indexed":false},{"type":"uint256","name":"mandatoryTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"HopPool","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"uint256","name":"DTXamount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"address","name":"newPool","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"MigrateStake","inputs":[{"type":"address","name":"goodSamaritan","internalType":"address","indexed":true},{"type":"uint256","name":"DTXamount","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"address","name":"recipient","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RemoveVotes","inputs":[{"type":"address","name":"voter","internalType":"address","indexed":true},{"type":"uint256","name":"proposalID","internalType":"uint256","indexed":false},{"type":"uint256","name":"change","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetDelegate","inputs":[{"type":"address","name":"userDelegating","internalType":"address","indexed":false},{"type":"address","name":"delegatee","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"StakeAllowanceRevoke","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"address","name":"spender","internalType":"address","indexed":false},{"type":"uint256","name":"allowanceID","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"StakeApproval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"address","name":"spender","internalType":"address","indexed":false},{"type":"uint256","name":"allowanceID","internalType":"uint256","indexed":false},{"type":"uint256","name":"shareAllowance","internalType":"uint256","indexed":false},{"type":"uint256","name":"lastDeposit","internalType":"uint256","indexed":false},{"type":"uint256","name":"mandatoryTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferStake","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false},{"type":"uint256","name":"stakeID","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferStakeFrom","inputs":[{"type":"address","name":"_from","internalType":"address","indexed":false},{"type":"address","name":"_to","internalType":"address","indexed":false},{"type":"uint256","name":"_stakeID","internalType":"uint256","indexed":false},{"type":"uint256","name":"_allowanceID","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TrustedPool","inputs":[{"type":"address","name":"contractAddress","internalType":"address","indexed":false},{"type":"bool","name":"setting","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"TrustedSender","inputs":[{"type":"address","name":"contractAddress","internalType":"address","indexed":false},{"type":"bool","name":"setting","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"Withdraw","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"penalty","internalType":"uint256","indexed":false},{"type":"uint256","name":"shares","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addAndExtendStake","inputs":[{"type":"address","name":"_recipientAddr","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint256","name":"_stakeID","internalType":"uint256"},{"type":"uint256","name":"_lockUpTokensInSeconds","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"admin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"allowOrigin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"allowStakeTransfer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"allowStakeTransferFrom","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"allowTxOrigin","inputs":[{"type":"bool","name":"_setting","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"calculateHarvestDTXRewards","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"calculateTotalPendingDTXRewards","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"callFee","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"delegateeVote","inputs":[{"type":"address[]","name":"votingAddress","internalType":"address[]"},{"type":"uint256","name":"proposalID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deposit","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableDisableStakeTransfer","inputs":[{"type":"bool","name":"_setting","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableDisableStakeTransferFrom","inputs":[{"type":"bool","name":"_setting","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNrOfStakes","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getPricePerFullShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getUserShares","inputs":[{"type":"address","name":"_wallet","internalType":"address"},{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getUserTotalShares","inputs":[{"type":"address","name":"_user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"giftDeposit","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_toAddress","internalType":"address"},{"type":"uint256","name":"_minToServeInSecs","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"giveStakeAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gracePeriod","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"hopDeposit","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"address","name":"_recipientAddress","internalType":"address"},{"type":"uint256","name":"previousLastDepositedTime","internalType":"uint256"},{"type":"uint256","name":"_mandatoryTime","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"hopStakeToAnotherPool","inputs":[{"type":"uint256","name":"_shares","internalType":"uint256"},{"type":"uint256","name":"_stakeID","internalType":"uint256"},{"type":"address","name":"_poolAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IMasterChef"}],"name":"masterchef","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"migrateAllStakes","inputs":[{"type":"address","name":"_staker","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"migrateStake","inputs":[{"type":"address","name":"_staker","internalType":"address"},{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"migrationPool","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minimumGift","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"modifyPartialTransfers","inputs":[{"type":"bool","name":"_decision","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"modifyPartialWithdrawals","inputs":[{"type":"bool","name":"_decision","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nrOfstakeAllowances","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"partialTransfers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"partialWithdrawals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"poolID","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeStakeAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"allowanceID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAdmin","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCallFee","inputs":[{"type":"uint256","name":"_callFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDelegate","inputs":[{"type":"address","name":"_delegate","internalType":"address"},{"type":"bool","name":"asProxy","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMasterChefAddress","inputs":[{"type":"address","name":"_masterchef","internalType":"contract IMasterChef"},{"type":"uint256","name":"_newPoolID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMigrationPool","inputs":[{"type":"address","name":"_newPool","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinimumGiftDeposit","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"bool","name":"_setting","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTrustedPool","inputs":[{"type":"address[]","name":"_pool","internalType":"address[]"},{"type":"bool","name":"_setting","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTrustedSender","inputs":[{"type":"address[]","name":"_sender","internalType":"address[]"},{"type":"bool","name":"_setting","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakeAllowances","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"allowanceID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stakeRollover","inputs":[{"type":"address","name":"_poolInto","internalType":"address"},{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IDTX"}],"name":"token","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalShares","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalVotesForID","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferStakeFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_stakeID","internalType":"uint256"},{"type":"uint256","name":"allowanceID","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferStakeToAnotherWallet","inputs":[{"type":"uint256","name":"_shares","internalType":"uint256"},{"type":"uint256","name":"_stakeID","internalType":"uint256"},{"type":"address","name":"_recipientAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"treasury","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"trustedPool","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"trustedPoolCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"trustedSender","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"trustedSenderCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"updateMinGiftGovernor","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateMinimumGift","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"userDelegate","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"shares","internalType":"uint256"},{"type":"uint256","name":"lastDepositedTime","internalType":"uint256"},{"type":"uint256","name":"dtxAtLastUserAction","internalType":"uint256"},{"type":"uint256","name":"lastUserActionTime","internalType":"uint256"},{"type":"uint256","name":"mandatoryTimeToServe","internalType":"uint256"}],"name":"userInfo","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"userVote","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"voteForProposal","inputs":[{"type":"uint256","name":"proposalID","internalType":"uint256"},{"type":"bool","name":"asProxy","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"votingCredit","inputs":[{"type":"uint256","name":"_shares","internalType":"uint256"},{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"votingCreditAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_shares","internalType":"uint256"},{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawAll","inputs":[{"type":"uint256","name":"_stakeID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawFeePeriod","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x60e0604052630967530060a052621baf8060c052683635c9adc5dea00000600e55600f805460ff1916600117905560056010556011805464010101000164ffffffffff1990911617905534801562000055575f80fd5b5060405162004696380380620046968339810160408190526200007891620000d0565b60015f8190556001600160a01b039283166080528054919092166001600160a01b031991821617909155600b80549091163317905560056009556200010d565b6001600160a01b0381168114620000cd575f80fd5b50565b5f8060408385031215620000e2575f80fd5b8251620000ef81620000b8565b60208401519092506200010281620000b8565b809150509250929050565b60805160a05160c05161450a6200018c5f395f81816106be01528181610a4801528181610b01015261161301525f818161087301528181610a6d01528181610ace01528181610b2601528181611521015281816116370152818161168c01528181612a4c0152612d9b01525f81816109260152612ed3015261450a5ff3fe608060405234801561000f575f80fd5b50600436106103d5575f3560e01c8063859f267f11610200578063be50baa91161011f578063ddd9d045116100b4578063e5ea69ff11610084578063e5ea69ff146108b4578063f5ba1c87146108dc578063f851a440146108fb578063fb1db2781461090e578063fc0c546a14610921575f80fd5b8063ddd9d04514610853578063ded6275e14610866578063df10b4e61461086e578063e56d607d14610895575f80fd5b8063d693f834116100ef578063d693f83414610807578063d6d3774b1461081a578063d6fe34051461082d578063d71a4bc214610840575f80fd5b8063be50baa91461079f578063c721308f146107cd578063cc7c7dec146107e1578063d0afa9dd146107f4575f80fd5b8063aaa9603a11610195578063b7cdbed311610165578063b7cdbed314610753578063b949103b14610766578063ba17978714610779578063bdcd9c801461078c575f80fd5b8063aaa9603a146106f2578063b330fc5314610705578063b3f5f6551461072d578063b6b55f2514610740575f80fd5b8063958e2d31116101d0578063958e2d31146106935780639f6a9283146106a6578063a06db7dc146106b9578063a56924bd146106e0575f80fd5b8063859f267f1461065b5780638d9344851461066e57806390321e1a14610677578063955afa6c14610680575f80fd5b80633b500bcb116102f757806361d027b31161028c578063722713f71161025c578063722713f71461061d57806377c7b8fc1461062557806378e6e38a1461062d578063800b2f34146106355780638482b20214610648575f80fd5b806361d027b3146105b757806362671897146105e257806364f5c072146105f55780636505e8e81461060a575f80fd5b80634a994eef116102c75780634a994eef14610576578063527cc2f11461058957806352d816471461059c578063607214d3146105af575f80fd5b80633b500bcb1461051b5780633f6ba4151461052e578063441a3e701461055057806347be531114610563575f80fd5b8063221665e51161036d5780632e8ba0391161033d5780632e8ba039146104e9578063341d609f146104f6578063343d927e146105095780633a98ef3914610512575f80fd5b8063221665e5146104bd57806325c6ea1f146104c557806326465826146104ce5780632cae2096146104e1575f80fd5b8063174628d1116103a8578063174628d114610430578063182c1da1146104625780631de8e5921461046f57806321ce919d14610482575f80fd5b8063062d5ed4146103d95780630b799acf146103ee5780630cf57ace146104015780631718e21114610414575b5f80fd5b6103ec6103e7366004613ed2565b610948565b005b6103ec6103fc366004613f15565b610d51565b6103ec61040f366004613f30565b610d9b565b61041d600e5481565b6040519081526020015b60405180910390f35b61045261043e366004613f30565b60076020525f908152604090205460ff1681565b6040519015158152602001610427565b6011546104529060ff1681565b6103ec61047d366004613f4b565b610de1565b610495610490366004613f79565b610e24565b604080519586526020860194909452928401919091526060830152608082015260a001610427565b6103ec610e6e565b61041d60135481565b6103ec6104dc366004613fa3565b610f39565b6103ec610f68565b600f546104529060ff1681565b61041d610504366004613fba565b61107e565b61041d60125481565b61041d600a5481565b610452610529366004613fe6565b6110aa565b61045261053c366004613f30565b60066020525f908152604090205460ff1681565b6103ec61055e36600461402d565b6113b4565b6103ec610571366004614095565b611870565b6103ec6105843660046140dd565b6119f5565b6103ec610597366004613f79565b611a8a565b6103ec6105aa366004613f15565b611ba6565b61041d611bee565b600c546105ca906001600160a01b031681565b6040516001600160a01b039091168152602001610427565b6103ec6105f0366004614109565b611c66565b60115461045290640100000000900460ff1681565b6103ec610618366004613f4b565b611e22565b61041d611eda565b61041d611fd4565b61041d61200a565b6103ec610643366004613f79565b6120a7565b6103ec610656366004613f79565b61220a565b6103ec610669366004614143565b61225a565b61041d60095481565b61041d60105481565b600d546105ca906001600160a01b031681565b6103ec6106a1366004613fa3565b612476565b6103ec6106b4366004613f15565b6124b3565b61041d7f000000000000000000000000000000000000000000000000000000000000000081565b60115461045290610100900460ff1681565b6103ec610700366004613ed2565b6124f9565b6105ca610713366004613f30565b60056020525f90815260409020546001600160a01b031681565b6103ec61073b366004614178565b612803565b6103ec61074e366004613fa3565b612b3a565b6103ec610761366004613f79565b612d3b565b6011546104529062010000900460ff1681565b6103ec6107873660046141b0565b613100565b6103ec61079a366004613f79565b6132d5565b6107b26107ad3660046141f8565b613530565b60408051938452602084019290925290820152606001610427565b601154610452906301000000900460ff1681565b6103ec6107ef366004613f15565b61359a565b6103ec610802366004614095565b6135de565b6103ec610815366004613f30565b613763565b6103ec61082836600461402d565b6137af565b6103ec61083b366004613f15565b613a0d565b61041d61084e366004613f30565b613a4a565b61041d610861366004613f79565b613ab7565b6105ca613af7565b61041d7f000000000000000000000000000000000000000000000000000000000000000081565b61041d6108a3366004613fa3565b60046020525f908152604090205481565b61041d6108c2366004613f30565b6001600160a01b03165f9081526002602052604090205490565b61041d6108ea366004613f30565b60036020525f908152604090205481565b600b546105ca906001600160a01b031681565b6001546105ca906001600160a01b031681565b6105ca7f000000000000000000000000000000000000000000000000000000000000000081565b5f83116109705760405162461bcd60e51b815260040161096790614225565b60405180910390fd5b335f90815260026020526040902054821061099d5760405162461bcd60e51b815260040161096790614252565b335f9081526002602052604081208054849081106109bd576109bd61427a565b905f5260205f2090600502019050805f01548411156109ee5760405162461bcd60e51b81526004016109679061428e565b60115462010000900460ff16610a1e5780548414610a1e5760405162461bcd60e51b8152600401610967906142c5565b60018101546001600160a01b0383165f9081526007602052604090205460ff1615610aa657610a977f0000000000000000000000000000000000000000000000000000000000000000610a91837f0000000000000000000000000000000000000000000000000000000000000000613b62565b90613b62565b421115610aa15750425b610b99565b6001600160a01b0383165f9081526006602052604090205460ff168015610af55750610af2817f0000000000000000000000000000000000000000000000000000000000000000613b62565b42115b8015610b4d5750610b4a7f0000000000000000000000000000000000000000000000000000000000000000610a91837f0000000000000000000000000000000000000000000000000000000000000000613b62565b42105b610b995760405162461bcd60e51b815260206004820152601f60248201527f63616e206f6e6c7920686f7020696e746f207072652d73657420506f6f6c73006044820152606401610967565b5f610bb8600a54610bb288610bac611eda565b90613b6d565b90613b78565b8354909150610bc79087613b83565b8355600a54610bd69087613b83565b600a55335f908152600360205260409020548015610bf957610bf9338289613b8e565b600484810154604051636267189760e01b81529182018490523360248301526044820185905260648201526001600160a01b038616906362671897906084015f604051808303815f87803b158015610c4f575f80fd5b505af1158015610c61573d5f803e3d5ffd5b505060015460405163cc58a6bb60e01b81526001600160a01b03898116600483015260248201879052909116925063cc58a6bb91506044015f604051808303815f87803b158015610cb0575f80fd5b505af1158015610cc2573d5f803e3d5ffd5b50508554159150610cf8905057610ce8600a54610bb2610ce0611eda565b875490613b6d565b6002850155426003850155610d02565b610d023387613c02565b60408051838152602081018990526001600160a01b0387169133917f2391574aca0f6cc92f9588562ee00a7c2d33f83d17d01d8fa177ba4423740f44910160405180910390a350505050505050565b600b546001600160a01b03163314610d7b5760405162461bcd60e51b8152600401610967906142fc565b601180549115156401000000000264ff0000000019909216919091179055565b6001600160a01b0381165f908152600260205260408120805490915b81811015610ddb57610dc984826132d5565b80610dd381614335565b915050610db7565b50505050565b600b546001600160a01b03163314610e0b5760405162461bcd60e51b8152600401610967906142fc565b600e91909155600f805460ff1916911515919091179055565b6002602052815f5260405f208181548110610e3d575f80fd5b5f91825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b600f5460ff16610ec05760405162461bcd60e51b815260206004820152601960248201527f6175746f6d61746963207570646174652064697361626c6564000000000000006044820152606401610967565b600b5f9054906101000a90046001600160a01b03166001600160a01b03166351a41dec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f10573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f34919061434d565b600e55565b600b546001600160a01b03163314610f635760405162461bcd60e51b8152600401610967906142fc565b601055565b60015f9054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fdc9190614364565b600b80546001600160a01b0319166001600160a01b0392831617905560015460408051630824ea6b60e31b81529051919092169163412753589160048083019260209291908290030181865afa158015611038573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061105c9190614364565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038083165f908152600860209081526040808320938516835292905220545b92915050565b6011545f90610100900460ff1661110f5760405162461bcd60e51b8152602060048201526024808201527f7468697264207061727479207374616b65207472616e73666572732064697361604482015263189b195960e21b6064820152608401610967565b816001600160a01b0316856001600160a01b0316036111695760405162461bcd60e51b815260206004820152601660248201527531b0b713ba103a3930b739b332b9103a379039b2b63360511b6044820152606401610967565b6001600160a01b0385165f90815260026020526040902054841061119f5760405162461bcd60e51b815260040161096790614252565b6001600160a01b0385165f9081526002602052604081208054869081106111c8576111c861427a565b905f5260205f20906005020190505f805f6111e4893389613530565b925092509250835f0154831461120c5760405162461bcd60e51b81526004016109679061437f565b8360010154821461122f5760405162461bcd60e51b81526004016109679061437f565b836004015481146112525760405162461bcd60e51b81526004016109679061437f565b6001600160a01b0389165f90815260036020526040902054801561127b5761127b8a8286613b8e565b506001600160a01b0386165f9081526003602052604090205480156112a5576112a5878286613cea565b6112af8a8a613c02565b6112b98a89613d55565b60025f886001600160a01b03166001600160a01b031681526020019081526020015f206040518060a0016040528086815260200185815260200161130b600a54610bb2611304611eda565b8a90613b6d565b81524260208083019190915260409182018690528354600181810186555f958652948290208451600590920201908155908301519381019390935581810151600284015560608201516003840155608090910151600490920191909155517f017cb7d605aa3dcd304a9eb2a4df6075576ccc4a5dc2fe0b518c558e8f75338d9061139c908c908a908d908d906143b6565b60405180910390a15060019998505050505050505050565b335f9081526002602052604090205481106113e15760405162461bcd60e51b8152600401610967906143df565b335f9081526002602052604081208054839081106114015761140161427a565b905f5260205f20906005020190505f831161142e5760405162461bcd60e51b815260040161096790614225565b805483111561144f5760405162461bcd60e51b81526004016109679061428e565b6004810154600182015461146291613b62565b42116114b05760405162461bcd60e51b815260206004820152601960248201527f6d757374207365727665206d616e6461746f72792074696d65000000000000006044820152606401610967565b60115462010000900460ff166114e057805483146114e05760405162461bcd60e51b8152600401610967906142c5565b5f6114f3600a54610bb286610bac611eda565b82549091506115029085613b83565b8255600a546115119085613b83565b600a5560018201545f90611545907f0000000000000000000000000000000000000000000000000000000000000000613b62565b42101561160e575f61157c6115736103e8610bb26110ad610bac620151808a6001015442610bb29190614409565b61200890613b83565b905061158e612710610bb28584613b6d565b600154600c54604051632a98027560e01b81526001600160a01b039182166004820152602481018490529294501690632a980275906044015f604051808303815f87803b1580156115dd575f80fd5b505af11580156115ef573d5f803e3d5ffd5b505050506116068284613b8390919063ffffffff16565b925050611762565b6116697f0000000000000000000000000000000000000000000000000000000000000000610a917f00000000000000000000000000000000000000000000000000000000000000008660010154613b6290919063ffffffff16565b421115611762575f6116c56103e8610bb26110ad610bac62015180610bb26116be7f00000000000000000000000000000000000000000000000000000000000000008c60010154613b6290919063ffffffff16565b4290613b83565b90506120088111156116d657506120085b6116e6612710610bb28584613b6d565b600154600c54604051632a98027560e01b81526001600160a01b039182166004820152602481018490529294501690632a980275906044015f604051808303815f87803b158015611735575f80fd5b505af1158015611747573d5f803e3d5ffd5b5050505061175e8284613b8390919063ffffffff16565b9250505b82541561179c5761178c600a54610bb26117848561177e611eda565b90613b83565b865490613b6d565b60028401554260038401556117a6565b6117a63385613c02565b335f9081526003602052604090205480156117c6576117c6338288613b8e565b604080518481526020810184905290810187905233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949060600160405180910390a2600154604051632a98027560e01b8152336004820152602481018590526001600160a01b0390911690632a980275906044015f604051808303815f87803b158015611852575f80fd5b505af1158015611864573d5f803e3d5ffd5b50505050505050505050565b600b546001600160a01b0316331461189a5760405162461bcd60e51b8152600401610967906142fc565b5f5b82811015610ddb5781151560075f8686858181106118bc576118bc61427a565b90506020020160208101906118d19190613f30565b6001600160a01b0316815260208101919091526040015f205460ff161515146119e3578160075f86868581811061190a5761190a61427a565b905060200201602081019061191f9190613f30565b6001600160a01b0316815260208101919091526040015f20805460ff1916911515919091179055816119635760138054905f61195a8361441c565b91905055611977565b60138054905f61197283614335565b919050555b507f808293acec1c44217eccd857d5abb88ff31456d23bf3a000d2f5aee5f92f4c198484838181106119ab576119ab61427a565b90506020020160208101906119c09190613f30565b604080516001600160a01b03909216825284151560208301520160405180910390a15b806119ed81614335565b91505061189c565b6011545f90640100000000900460ff168015611a0e5750815b611a1a57503380611a1e565b5032805b506001600160a01b038181165f8181526005602090815260409182902080546001600160a01b031916948816948517905581519283528201929092527fbeebfeebc9d1af8057ca45af36b2171fea34cb5b251e394f0bc5fcabde119d7f910160405180910390a1505050565b335f9081526008602090815260408083206001600160a01b038616845290915281208054909190611abc906001613b83565b9050808314611b1d57818181548110611ad757611ad761427a565b905f5260205f209060030201828481548110611af557611af561427a565b5f91825260209091208254600390920201908155600180830154908201556002918201549101555b81805480611b2d57611b2d614431565b5f828152602080822060035f19949094019384020182815560018101839055600201919091559155604080513381526001600160a01b0387169281019290925281018490527f29fbfeb988fb99326ac41d70606334081c6be7e8518f6caa5b7b1bcbe7872a1e906060015b60405180910390a150505050565b600b546001600160a01b03163314611bd05760405162461bcd60e51b8152600401610967906142fc565b6011805491151563010000000263ff00000019909216919091179055565b60015460095460405163b6ec056160e01b81525f9283926001600160a01b039091169163b6ec056191611c279160040190815260200190565b602060405180830381865afa158015611c42573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a4919061434d565b335f9081526006602052604090205460ff1680611c915750335f9081526007602052604090205460ff165b611ce75760405162461bcd60e51b815260206004820152602160248201527f6f6e6c7920747275737465642073656e64657273286f7468657220706f6f6c736044820152602960f81b6064820152608401610967565b5f611cf0611eda565b90505f600a545f14611d1c57611d1582610bb2600a5489613b6d90919063ffffffff16565b9050611d1f565b50845b600a54611d2c9082613b62565b600a556001600160a01b0385165f818152600260208181526040808420815160a0810183528781528084018b81528184018e81524260608401908152608084018d8152855460018181018855968b52888b20955160059091029095019485559251948401949094555195820195909555905160038083019190915593516004909101559383525220548015611dc657611dc6868284613cea565b6040805188815260208101849052908101869052606081018590526001600160a01b038716907fb66a80ae2ebf4737952b9c2b57a9d34ef56806ab937f481b75197ae991d81afb9060800160405180910390a250505050505050565b6011545f90640100000000900460ff168015611e3b5750815b611e4757503380611e4b565b5032805b506001600160a01b0381165f90815260036020526040902054838114610ddb575f611e7583613a4a565b90508015611ebb578415611eb057815f03611e9a57611e95838683613cea565b611ebb565b611ea5838383613b8e565b611e95838683613cea565b611ebb838383613b8e565b50506001600160a01b03165f9081526003602052604090209190915550565b60015460095460405163b6ec056160e01b81525f9283926001600160a01b039091169163b6ec056191611f139160040190815260200190565b602060405180830381865afa158015611f2e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f52919061434d565b6001546040516301aba89b60e71b81523060048201529192505f916001600160a01b039091169063d5d44d8090602401602060405180830381865afa158015611f9d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc1919061434d565b9050611fcd8282613b62565b9250505090565b5f600a545f14611ffd57611ff8600a54610bb2670de0b6b3a7640000610bac611eda565b905090565b50670de0b6b3a764000090565b60015460095460405163b6ec056160e01b81525f9283926001600160a01b039091169163b6ec0561916120439160040190815260200190565b602060405180830381865afa15801561205e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612082919061434d565b90505f6120a0612710610bb260105485613b6d90919063ffffffff16565b9392505050565b335f9081526002602052604081208054839081106120c7576120c761427a565b905f5260205f2090600502019050600e546120f1600a54610bb26120e9611eda565b855490613b6d565b101561213f5760405162461bcd60e51b815260206004820152601760248201527f62656c6f77206d696e696d756d207468726573686f6c640000000000000000006044820152606401610967565b335f8181526008602090815260408083206001600160a01b0388168085529083528184208054835160608082018652895482526001808b018054848a0190815260048d018054868b019081528488018955978c529a8a90209451600387029095019485555191840191909155935160029092019190915588549254965485519889529588019390935292860183905290850152608084019290925260a0830152907f13356b03fc409456fbfbc8b432cb402b7841b3114d1d159625eb0f3d4e3a46819060c001611b98565b600b546001600160a01b031633146122345760405162461bcd60e51b8152600401610967906142fc565b600180546001600160a01b0319166001600160a01b039390931692909217909155600955565b612262613e67565b600e548310156122a95760405162461bcd60e51b815260206004820152601260248201527110995b1bddc8135a5b9a5b5d5b4811da599d60721b6044820152606401610967565b5f6122b2611eda565b600154604051632770a7eb60e21b8152336004820152602481018790529192506001600160a01b031690639dc29fac906044016020604051808303815f875af1158015612301573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123259190614445565b6123415760405162461bcd60e51b815260040161096790614460565b5f600a545f1461236b5761236482610bb2600a5488613b6d90919063ffffffff16565b905061236e565b50835b600a5461237b9082613b62565b600a556001600160a01b0384165f818152600260208181526040808420815160a081018352878152428185018181528285018e815260608401928352608084018d8152855460018181018855968b52888b209551600590910290950194855591519484019490945592519582019590955593516003808601919091559051600490940193909355938352522054801561241957612419858284613cea565b6040805187815260208101849052428183015290516001600160a01b0387169133917f190f4e47df17911728b041870d3cd75008c166bb9d8cde694aaa68f73ad415829181900360600190a350505061247160015f55565b505050565b335f90815260026020526040902080546124b091908390811061249b5761249b61427a565b905f5260205f2090600502015f0154826113b4565b50565b600b546001600160a01b031633146124dd5760405162461bcd60e51b8152600401610967906142fc565b60118054911515620100000262ff000019909216919091179055565b60115460ff166125405760405162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c9cc8191a5cd8589b195960721b6044820152606401610967565b336001600160a01b038216036125915760405162461bcd60e51b815260206004820152601660248201527531b0b713ba103a3930b739b332b9103a379039b2b63360511b6044820152606401610967565b335f9081526002602052604090205482106125be5760405162461bcd60e51b815260040161096790614252565b335f9081526002602052604081208054849081106125de576125de61427a565b905f5260205f20906005020190505f612605600a54610bb26125fe611eda565b8890613b6d565b9050600e548110156126595760405162461bcd60e51b815260206004820152601760248201527f42656c6f77206d696e696d756d207468726573686f6c640000000000000000006044820152606401610967565b815485111561267a5760405162461bcd60e51b81526004016109679061428e565b6011546301000000900460ff166126ab57815485146126ab5760405162461bcd60e51b8152600401610967906142c5565b81546126b79086613b83565b8255335f9081526003602052604090205480156126d9576126d9338288613b8e565b506001600160a01b0383165f90815260036020526040902054801561270357612703848288613cea565b6001600160a01b0384165f908152600260208181526040808420815160a0810183528b81526001808a015482860190815293820189815242606084019081526004808d01546080860190815286548086018855968b529790992093516005909502909301938455935190830155915193810193909355516003830155519101558254156127ab5761279b600a54610bb2611784611eda565b60028401554260038401556127b5565b6127b53386613c02565b60408051878152602081018790526001600160a01b0386169133917ff3f8af030ee2cfc3c3c4ea260e6bcdd578eb1558b6eb3d79f7d0617ddbdc5b78910160405180910390a3505050505050565b61280b613e67565b5f831161284f5760405162461bcd60e51b8152602060048201526012602482015271139bdd1a1a5b99c81d1bc819195c1bdcda5d60721b6044820152606401610967565b6001600160a01b0384165f9081526002602052604090205482106128a65760405162461bcd60e51b815260206004820152600e60248201526d1ddc9bdb99c814dd185ad948125160921b6044820152606401610967565b600b546001600160a01b03163314612910576001600160a01b03841633146129105760405162461bcd60e51b815260206004820152601e60248201527f63616e206f6e6c7920657874656e6420796f7572206f776e207374616b6500006044820152606401610967565b5f612919611eda565b600154604051632770a7eb60e21b8152336004820152602481018790529192506001600160a01b031690639dc29fac906044016020604051808303815f875af1158015612968573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061298c9190614445565b6129a85760405162461bcd60e51b815260040161096790614460565b5f600a545f146129d2576129cb82610bb2600a5488613b6d90919063ffffffff16565b90506129d5565b50835b6001600160a01b0386165f9081526002602052604081208054869081106129fe576129fe61427a565b905f5260205f2090600502019050612a2282825f0154613b6290919063ffffffff16565b8155600a54612a319083613b62565b600a556004810154841180612a7357506001810154612a70907f0000000000000000000000000000000000000000000000000000000000000000613b62565b42115b15612a8057600481018490555b612a99600a54610bb2612a91611eda565b845490613b6d565b600282015542600380830182905560018301919091556001600160a01b0388165f90815260209190915260409020548015612ad957612ad9888285613cea565b60408051888152602081018890529081018490524260608201526001600160a01b0389169033907f7f65dfb94bab62e0708845150044cf7ad9c77fbfe6ba9e3c8c1f210e15aa953d9060800160405180910390a350505050610ddb60015f55565b612b42613e67565b5f8111612b865760405162461bcd60e51b8152602060048201526012602482015271139bdd1a1a5b99c81d1bc819195c1bdcda5d60721b6044820152606401610967565b5f612b8f611eda565b600154604051632770a7eb60e21b8152336004820152602481018590529192506001600160a01b031690639dc29fac906044016020604051808303815f875af1158015612bde573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c029190614445565b612c1e5760405162461bcd60e51b815260040161096790614460565b5f600a545f14612c4857612c4182610bb2600a5486613b6d90919063ffffffff16565b9050612c4b565b50815b600a54612c589082613b62565b600a55335f818152600260208181526040808420815160a081018352878152428185018181528285018c81526060840192835260808401898152855460018181018855968b52888b2095516005909102909501948555915194840194909455925195820195909555935160038086019190915590516004909401939093559383525220548015612ced57612ced338284613cea565b60408051858152602081018490524281830152905133917f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e919081900360600190a25050506124b060015f55565b335f908152600260205260409020548110612d685760405162461bcd60e51b8152600401610967906143df565b335f908152600260205260408120805483908110612d8857612d8861427a565b905f5260205f2090600502019050612dcd7f00000000000000000000000000000000000000000000000000000000000000008260010154613b6290919063ffffffff16565b4211612e125760405162461bcd60e51b81526020600482015260146024820152737374616b65206e6f7420796574206d617475726560601b6044820152606401610967565b5f612e28600a54610bb2845f0154610bac611eda565b600b5460405163ded6e1c960e01b81526001600160a01b0387811660048301529293505f92612eac9261271092610bb2929091169063ded6e1c990602401602060405180830381865afa158015612e81573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ea5919061434d565b8590613b6d565b600b546040516370a0823160e01b81526001600160a01b03918216600482015291925082917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015612f1a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f3e919061434d565b1015612fa15760405162461bcd60e51b815260206004820152602c60248201527f676f7665726e6f72207265736572766573206172652063757272656e746c792060448201526b1a5b9cdd59999a58da595b9d60a21b6064820152608401610967565b306001600160a01b0386160361301957600b5460405163e5f59bc160e01b81526001600160a01b039091169063e5f59bc190612fe7903390899086908a906004016143b6565b5f604051808303815f87803b158015612ffe575f80fd5b505af1158015613010573d5f803e3d5ffd5b505050506130f9565b8254613026908587610948565b600b5460405163e5ea69ff60e01b815233600482018190526001600160a01b039283169263e5f59bc1928991869160019184169063e5ea69ff90602401602060405180830381865afa15801561307e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a2919061434d565b6130ac9190614409565b6040518563ffffffff1660e01b81526004016130cb94939291906143b6565b5f604051808303815f87803b1580156130e2575f80fd5b505af11580156130f4573d5f803e3d5ffd5b505050505b5050505050565b5f5b82811015610ddb573360055f8686858181106131205761312061427a565b90506020020160208101906131359190613f30565b6001600160a01b03908116825260208201929092526040015f205416036132c3575f60035f86868581811061316c5761316c61427a565b90506020020160208101906131819190613f30565b6001600160a01b03166001600160a01b031681526020019081526020015f205490508083146132c1575f6131d58686858181106131c0576131c061427a565b905060200201602081019061084e9190613f30565b9050801561327b57831561326657815f036132205761321b8686858181106131ff576131ff61427a565b90506020020160208101906132149190613f30565b8583613cea565b61327b565b6132518686858181106132355761323561427a565b905060200201602081019061324a9190613f30565b8383613b8e565b61321b8686858181106131ff576131ff61427a565b61327b8686858181106132355761323561427a565b8360035f8888878181106132915761329161427a565b90506020020160208101906132a69190613f30565b6001600160a01b0316815260208101919091526040015f2055505b505b806132cd81614335565b915050613102565b600d546001600160a01b031661332d5760405162461bcd60e51b815260206004820152601760248201527f6d6967726174696f6e206e6f74206163746976617465640000000000000000006044820152606401610967565b6001600160a01b0382165f9081526002602052604090205481106133635760405162461bcd60e51b8152600401610967906143df565b6001600160a01b0382165f90815260026020526040812080548390811061338c5761338c61427a565b905f5260205f20906005020190505f815f0154116133d95760405162461bcd60e51b815260206004820152600a6024820152696e6f2062616c616e636560b01b6044820152606401610967565b5f6133ef600a54610bb2845f0154610bac611eda565b8254600a549192506134019190613b83565b600a555f8255600d546001830154600480850154604051636267189760e01b81529182018590526001600160a01b038881166024840152604483019390935260648201529116906362671897906084015f604051808303815f87803b158015613468575f80fd5b505af115801561347a573d5f803e3d5ffd5b5050600154600d5460405163cc58a6bb60e01b81526001600160a01b039182166004820152602481018690529116925063cc58a6bb91506044015f604051808303815f87803b1580156134cb575f80fd5b505af11580156134dd573d5f803e3d5ffd5b505083546040805185815260208101929092526001600160a01b03881693503392507fe28c7cce19d5f22ab16a04ca1bb768f7533bf719280b5e40718b41c2641ac309910160405180910390a350505050565b6001600160a01b038084165f90815260086020908152604080832093861683529290529081208054829182918291908690811061356f5761356f61427a565b5f91825260209091206003909102018054600182015460029092015490999198509650945050505050565b600b546001600160a01b031633146135c45760405162461bcd60e51b8152600401610967906142fc565b601180549115156101000261ff0019909216919091179055565b600b546001600160a01b031633146136085760405162461bcd60e51b8152600401610967906142fc565b5f5b82811015610ddb5781151560065f86868581811061362a5761362a61427a565b905060200201602081019061363f9190613f30565b6001600160a01b0316815260208101919091526040015f205460ff16151514613751578160065f8686858181106136785761367861427a565b905060200201602081019061368d9190613f30565b6001600160a01b0316815260208101919091526040015f20805460ff1916911515919091179055816136d15760128054905f6136c88361441c565b919050556136e5565b60128054905f6136e083614335565b919050555b507f68e0e16e4195f1bb5436073ae329e02686b513fd39cd623585b36d74785b21c18484838181106137195761371961427a565b905060200201602081019061372e9190613f30565b604080516001600160a01b03909216825284151560208301520160405180910390a15b8061375b81614335565b91505061360a565b600b546001600160a01b0316331461378d5760405162461bcd60e51b8152600401610967906142fc565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6137b8613af7565b6001600160a01b0316036137f95760405162461bcd60e51b8152602060048201526008602482015267191a5cd8589b195960c21b6044820152606401610967565b335f9081526002602052604090205481106138265760405162461bcd60e51b8152600401610967906143df565b335f9081526002602052604081208054839081106138465761384661427a565b905f5260205f20906005020190505f83116138735760405162461bcd60e51b815260040161096790614225565b80548311156138945760405162461bcd60e51b81526004016109679061428e565b5f6138a7600a54610bb286610bac611eda565b82549091506138b69085613b83565b8255600a546138c59085613b83565b600a558154156138f4576138e4600a54610bb26120e98461177e611eda565b60028301554260038301556138fe565b6138fe3384613c02565b335f90815260036020526040902054801561391e5761391e338287613b8e565b600c54604080518481525f60208201529081018790526001600160a01b03909116907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949060600160405180910390a2600154600c54604051632a98027560e01b81526001600160a01b03918216600482015260248101859052911690632a980275906044015f604051808303815f87803b1580156139ba575f80fd5b505af11580156139cc573d5f803e3d5ffd5b505050506139d8613af7565b60405163364c781560e01b8152600481018490523360248201526001600160a01b03919091169063364c7815906044016130cb565b600b546001600160a01b03163314613a375760405162461bcd60e51b8152600401610967906142fc565b6011805460ff1916911515919091179055565b6001600160a01b0381165f908152600260205260408120805482805b82811015613aae57838181548110613a8057613a8061427a565b905f5260205f2090600502015f015482613a9a919061448b565b915080613aa681614335565b915050613a66565b50949350505050565b6001600160a01b0382165f908152600260205260408120805483908110613ae057613ae061427a565b905f5260205f2090600502015f0154905092915050565b600b546040805163c24375cf60e01b815290515f926001600160a01b03169163c24375cf9160048083019260209291908290030181865afa158015613b3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ff89190614364565b5f6120a0828461448b565b5f6120a0828461449e565b5f6120a082846144b5565b5f6120a08284614409565b5f82815260046020526040902054613ba69082613b83565b5f838152600460209081526040918290209290925580518481529182018390526001600160a01b038516917f65b0f2fb4228364e2ac61c432687ae942c732095fc217265116bec6cc441683491015b60405180910390a2505050565b6001600160a01b0382165f9081526002602052604081208054909190613c2a90600190614409565b9050808314613ca357818181548110613c4557613c4561427a565b905f5260205f209060050201828481548110613c6357613c6361427a565b905f5260205f2090600502015f820154815f0155600182015481600101556002820154816002015560038201548160030155600482015481600401559050505b81805480613cb357613cb3614431565b5f8281526020812060055f199093019283020181815560018101829055600281018290556003810182905560040155905550505050565b5f82815260046020526040902054613d029082613b62565b5f838152600460209081526040918290209290925580518481529182018390526001600160a01b038516917fdb8549181d0331885cbb0e0d1e36bdd89e38e53990069f6f07a4090a15f74e5d9101613bf5565b6001600160a01b0382165f90815260086020908152604080832033845290915281208054909190613d87906001613b83565b9050808314613de857818181548110613da257613da261427a565b905f5260205f209060030201828481548110613dc057613dc061427a565b5f91825260209091208254600390920201908155600180830154908201556002918201549101555b81805480613df857613df8614431565b5f828152602080822060035f19949094019384020182815560018101839055600201919091559155604080516001600160a01b0387168152339281019290925281018490527f29fbfeb988fb99326ac41d70606334081c6be7e8518f6caa5b7b1bcbe7872a1e90606001611b98565b60025f5403613eb85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610967565b60025f55565b6001600160a01b03811681146124b0575f80fd5b5f805f60608486031215613ee4575f80fd5b83359250602084013591506040840135613efd81613ebe565b809150509250925092565b80151581146124b0575f80fd5b5f60208284031215613f25575f80fd5b81356120a081613f08565b5f60208284031215613f40575f80fd5b81356120a081613ebe565b5f8060408385031215613f5c575f80fd5b823591506020830135613f6e81613f08565b809150509250929050565b5f8060408385031215613f8a575f80fd5b8235613f9581613ebe565b946020939093013593505050565b5f60208284031215613fb3575f80fd5b5035919050565b5f8060408385031215613fcb575f80fd5b8235613fd681613ebe565b91506020830135613f6e81613ebe565b5f805f8060808587031215613ff9575f80fd5b843561400481613ebe565b93506020850135925060408501359150606085013561402281613ebe565b939692955090935050565b5f806040838503121561403e575f80fd5b50508035926020909101359150565b5f8083601f84011261405d575f80fd5b50813567ffffffffffffffff811115614074575f80fd5b6020830191508360208260051b850101111561408e575f80fd5b9250929050565b5f805f604084860312156140a7575f80fd5b833567ffffffffffffffff8111156140bd575f80fd5b6140c98682870161404d565b9094509250506020840135613efd81613f08565b5f80604083850312156140ee575f80fd5b82356140f981613ebe565b91506020830135613f6e81613f08565b5f805f806080858703121561411c575f80fd5b84359350602085013561412e81613ebe565b93969395505050506040820135916060013590565b5f805f60608486031215614155575f80fd5b83359250602084013561416781613ebe565b929592945050506040919091013590565b5f805f806080858703121561418b575f80fd5b843561419681613ebe565b966020860135965060408601359560600135945092505050565b5f805f604084860312156141c2575f80fd5b833567ffffffffffffffff8111156141d8575f80fd5b6141e48682870161404d565b909790965060209590950135949350505050565b5f805f6060848603121561420a575f80fd5b833561421581613ebe565b9250602084013561416781613ebe565b6020808252601390820152724e6f7468696e6720746f20776974686472617760681b604082015260600190565b6020808252600e908201526d1ddc9bdb99c81cdd185ad948125160921b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252601f908201527f576974686472617720616d6f756e7420657863656564732062616c616e636500604082015260600190565b60208082526018908201527f6d757374207472616e736665722066756c6c207374616b650000000000000000604082015260600190565b6020808252600b908201526a61646d696e3a207775743f60a81b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161434657614346614321565b5060010190565b5f6020828403121561435d575f80fd5b5051919050565b5f60208284031215614374575f80fd5b81516120a081613ebe565b6020808252601c908201527f696e636f7272656374207374616b65206f7220616c6c6f77616e636500000000604082015260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b60208082526010908201526f1a5b9d985b1a59081cdd185ad948125160821b604082015260600190565b818103818111156110a4576110a4614321565b5f8161442a5761442a614321565b505f190190565b634e487b7160e01b5f52603160045260245ffd5b5f60208284031215614455575f80fd5b81516120a081613f08565b6020808252601190820152701d1bdad95b88189d5c9b8819985a5b1959607a1b604082015260600190565b808201808211156110a4576110a4614321565b80820281158282048414176110a4576110a4614321565b5f826144cf57634e487b7160e01b5f52601260045260245ffd5b50049056fea264697066735822122083e3da79046bf3aaa8a2695c4d81c28741b0bae652e2fa651245426441a8cc5064736f6c63430008140033000000000000000000000000faac6a85c3e123ab2cf7669b1024f146cfef0b38000000000000000000000000486fea20ea242456b450b005ed7d019e3e984f28

Deployed ByteCode

0x608060405234801561000f575f80fd5b50600436106103d5575f3560e01c8063859f267f11610200578063be50baa91161011f578063ddd9d045116100b4578063e5ea69ff11610084578063e5ea69ff146108b4578063f5ba1c87146108dc578063f851a440146108fb578063fb1db2781461090e578063fc0c546a14610921575f80fd5b8063ddd9d04514610853578063ded6275e14610866578063df10b4e61461086e578063e56d607d14610895575f80fd5b8063d693f834116100ef578063d693f83414610807578063d6d3774b1461081a578063d6fe34051461082d578063d71a4bc214610840575f80fd5b8063be50baa91461079f578063c721308f146107cd578063cc7c7dec146107e1578063d0afa9dd146107f4575f80fd5b8063aaa9603a11610195578063b7cdbed311610165578063b7cdbed314610753578063b949103b14610766578063ba17978714610779578063bdcd9c801461078c575f80fd5b8063aaa9603a146106f2578063b330fc5314610705578063b3f5f6551461072d578063b6b55f2514610740575f80fd5b8063958e2d31116101d0578063958e2d31146106935780639f6a9283146106a6578063a06db7dc146106b9578063a56924bd146106e0575f80fd5b8063859f267f1461065b5780638d9344851461066e57806390321e1a14610677578063955afa6c14610680575f80fd5b80633b500bcb116102f757806361d027b31161028c578063722713f71161025c578063722713f71461061d57806377c7b8fc1461062557806378e6e38a1461062d578063800b2f34146106355780638482b20214610648575f80fd5b806361d027b3146105b757806362671897146105e257806364f5c072146105f55780636505e8e81461060a575f80fd5b80634a994eef116102c75780634a994eef14610576578063527cc2f11461058957806352d816471461059c578063607214d3146105af575f80fd5b80633b500bcb1461051b5780633f6ba4151461052e578063441a3e701461055057806347be531114610563575f80fd5b8063221665e51161036d5780632e8ba0391161033d5780632e8ba039146104e9578063341d609f146104f6578063343d927e146105095780633a98ef3914610512575f80fd5b8063221665e5146104bd57806325c6ea1f146104c557806326465826146104ce5780632cae2096146104e1575f80fd5b8063174628d1116103a8578063174628d114610430578063182c1da1146104625780631de8e5921461046f57806321ce919d14610482575f80fd5b8063062d5ed4146103d95780630b799acf146103ee5780630cf57ace146104015780631718e21114610414575b5f80fd5b6103ec6103e7366004613ed2565b610948565b005b6103ec6103fc366004613f15565b610d51565b6103ec61040f366004613f30565b610d9b565b61041d600e5481565b6040519081526020015b60405180910390f35b61045261043e366004613f30565b60076020525f908152604090205460ff1681565b6040519015158152602001610427565b6011546104529060ff1681565b6103ec61047d366004613f4b565b610de1565b610495610490366004613f79565b610e24565b604080519586526020860194909452928401919091526060830152608082015260a001610427565b6103ec610e6e565b61041d60135481565b6103ec6104dc366004613fa3565b610f39565b6103ec610f68565b600f546104529060ff1681565b61041d610504366004613fba565b61107e565b61041d60125481565b61041d600a5481565b610452610529366004613fe6565b6110aa565b61045261053c366004613f30565b60066020525f908152604090205460ff1681565b6103ec61055e36600461402d565b6113b4565b6103ec610571366004614095565b611870565b6103ec6105843660046140dd565b6119f5565b6103ec610597366004613f79565b611a8a565b6103ec6105aa366004613f15565b611ba6565b61041d611bee565b600c546105ca906001600160a01b031681565b6040516001600160a01b039091168152602001610427565b6103ec6105f0366004614109565b611c66565b60115461045290640100000000900460ff1681565b6103ec610618366004613f4b565b611e22565b61041d611eda565b61041d611fd4565b61041d61200a565b6103ec610643366004613f79565b6120a7565b6103ec610656366004613f79565b61220a565b6103ec610669366004614143565b61225a565b61041d60095481565b61041d60105481565b600d546105ca906001600160a01b031681565b6103ec6106a1366004613fa3565b612476565b6103ec6106b4366004613f15565b6124b3565b61041d7f00000000000000000000000000000000000000000000000000000000001baf8081565b60115461045290610100900460ff1681565b6103ec610700366004613ed2565b6124f9565b6105ca610713366004613f30565b60056020525f90815260409020546001600160a01b031681565b6103ec61073b366004614178565b612803565b6103ec61074e366004613fa3565b612b3a565b6103ec610761366004613f79565b612d3b565b6011546104529062010000900460ff1681565b6103ec6107873660046141b0565b613100565b6103ec61079a366004613f79565b6132d5565b6107b26107ad3660046141f8565b613530565b60408051938452602084019290925290820152606001610427565b601154610452906301000000900460ff1681565b6103ec6107ef366004613f15565b61359a565b6103ec610802366004614095565b6135de565b6103ec610815366004613f30565b613763565b6103ec61082836600461402d565b6137af565b6103ec61083b366004613f15565b613a0d565b61041d61084e366004613f30565b613a4a565b61041d610861366004613f79565b613ab7565b6105ca613af7565b61041d7f000000000000000000000000000000000000000000000000000000000967530081565b61041d6108a3366004613fa3565b60046020525f908152604090205481565b61041d6108c2366004613f30565b6001600160a01b03165f9081526002602052604090205490565b61041d6108ea366004613f30565b60036020525f908152604090205481565b600b546105ca906001600160a01b031681565b6001546105ca906001600160a01b031681565b6105ca7f000000000000000000000000faac6a85c3e123ab2cf7669b1024f146cfef0b3881565b5f83116109705760405162461bcd60e51b815260040161096790614225565b60405180910390fd5b335f90815260026020526040902054821061099d5760405162461bcd60e51b815260040161096790614252565b335f9081526002602052604081208054849081106109bd576109bd61427a565b905f5260205f2090600502019050805f01548411156109ee5760405162461bcd60e51b81526004016109679061428e565b60115462010000900460ff16610a1e5780548414610a1e5760405162461bcd60e51b8152600401610967906142c5565b60018101546001600160a01b0383165f9081526007602052604090205460ff1615610aa657610a977f00000000000000000000000000000000000000000000000000000000001baf80610a91837f0000000000000000000000000000000000000000000000000000000009675300613b62565b90613b62565b421115610aa15750425b610b99565b6001600160a01b0383165f9081526006602052604090205460ff168015610af55750610af2817f0000000000000000000000000000000000000000000000000000000009675300613b62565b42115b8015610b4d5750610b4a7f00000000000000000000000000000000000000000000000000000000001baf80610a91837f0000000000000000000000000000000000000000000000000000000009675300613b62565b42105b610b995760405162461bcd60e51b815260206004820152601f60248201527f63616e206f6e6c7920686f7020696e746f207072652d73657420506f6f6c73006044820152606401610967565b5f610bb8600a54610bb288610bac611eda565b90613b6d565b90613b78565b8354909150610bc79087613b83565b8355600a54610bd69087613b83565b600a55335f908152600360205260409020548015610bf957610bf9338289613b8e565b600484810154604051636267189760e01b81529182018490523360248301526044820185905260648201526001600160a01b038616906362671897906084015f604051808303815f87803b158015610c4f575f80fd5b505af1158015610c61573d5f803e3d5ffd5b505060015460405163cc58a6bb60e01b81526001600160a01b03898116600483015260248201879052909116925063cc58a6bb91506044015f604051808303815f87803b158015610cb0575f80fd5b505af1158015610cc2573d5f803e3d5ffd5b50508554159150610cf8905057610ce8600a54610bb2610ce0611eda565b875490613b6d565b6002850155426003850155610d02565b610d023387613c02565b60408051838152602081018990526001600160a01b0387169133917f2391574aca0f6cc92f9588562ee00a7c2d33f83d17d01d8fa177ba4423740f44910160405180910390a350505050505050565b600b546001600160a01b03163314610d7b5760405162461bcd60e51b8152600401610967906142fc565b601180549115156401000000000264ff0000000019909216919091179055565b6001600160a01b0381165f908152600260205260408120805490915b81811015610ddb57610dc984826132d5565b80610dd381614335565b915050610db7565b50505050565b600b546001600160a01b03163314610e0b5760405162461bcd60e51b8152600401610967906142fc565b600e91909155600f805460ff1916911515919091179055565b6002602052815f5260405f208181548110610e3d575f80fd5b5f91825260209091206005909102018054600182015460028301546003840154600490940154929550909350919085565b600f5460ff16610ec05760405162461bcd60e51b815260206004820152601960248201527f6175746f6d61746963207570646174652064697361626c6564000000000000006044820152606401610967565b600b5f9054906101000a90046001600160a01b03166001600160a01b03166351a41dec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f10573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f34919061434d565b600e55565b600b546001600160a01b03163314610f635760405162461bcd60e51b8152600401610967906142fc565b601055565b60015f9054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fb8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fdc9190614364565b600b80546001600160a01b0319166001600160a01b0392831617905560015460408051630824ea6b60e31b81529051919092169163412753589160048083019260209291908290030181865afa158015611038573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061105c9190614364565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038083165f908152600860209081526040808320938516835292905220545b92915050565b6011545f90610100900460ff1661110f5760405162461bcd60e51b8152602060048201526024808201527f7468697264207061727479207374616b65207472616e73666572732064697361604482015263189b195960e21b6064820152608401610967565b816001600160a01b0316856001600160a01b0316036111695760405162461bcd60e51b815260206004820152601660248201527531b0b713ba103a3930b739b332b9103a379039b2b63360511b6044820152606401610967565b6001600160a01b0385165f90815260026020526040902054841061119f5760405162461bcd60e51b815260040161096790614252565b6001600160a01b0385165f9081526002602052604081208054869081106111c8576111c861427a565b905f5260205f20906005020190505f805f6111e4893389613530565b925092509250835f0154831461120c5760405162461bcd60e51b81526004016109679061437f565b8360010154821461122f5760405162461bcd60e51b81526004016109679061437f565b836004015481146112525760405162461bcd60e51b81526004016109679061437f565b6001600160a01b0389165f90815260036020526040902054801561127b5761127b8a8286613b8e565b506001600160a01b0386165f9081526003602052604090205480156112a5576112a5878286613cea565b6112af8a8a613c02565b6112b98a89613d55565b60025f886001600160a01b03166001600160a01b031681526020019081526020015f206040518060a0016040528086815260200185815260200161130b600a54610bb2611304611eda565b8a90613b6d565b81524260208083019190915260409182018690528354600181810186555f958652948290208451600590920201908155908301519381019390935581810151600284015560608201516003840155608090910151600490920191909155517f017cb7d605aa3dcd304a9eb2a4df6075576ccc4a5dc2fe0b518c558e8f75338d9061139c908c908a908d908d906143b6565b60405180910390a15060019998505050505050505050565b335f9081526002602052604090205481106113e15760405162461bcd60e51b8152600401610967906143df565b335f9081526002602052604081208054839081106114015761140161427a565b905f5260205f20906005020190505f831161142e5760405162461bcd60e51b815260040161096790614225565b805483111561144f5760405162461bcd60e51b81526004016109679061428e565b6004810154600182015461146291613b62565b42116114b05760405162461bcd60e51b815260206004820152601960248201527f6d757374207365727665206d616e6461746f72792074696d65000000000000006044820152606401610967565b60115462010000900460ff166114e057805483146114e05760405162461bcd60e51b8152600401610967906142c5565b5f6114f3600a54610bb286610bac611eda565b82549091506115029085613b83565b8255600a546115119085613b83565b600a5560018201545f90611545907f0000000000000000000000000000000000000000000000000000000009675300613b62565b42101561160e575f61157c6115736103e8610bb26110ad610bac620151808a6001015442610bb29190614409565b61200890613b83565b905061158e612710610bb28584613b6d565b600154600c54604051632a98027560e01b81526001600160a01b039182166004820152602481018490529294501690632a980275906044015f604051808303815f87803b1580156115dd575f80fd5b505af11580156115ef573d5f803e3d5ffd5b505050506116068284613b8390919063ffffffff16565b925050611762565b6116697f00000000000000000000000000000000000000000000000000000000001baf80610a917f00000000000000000000000000000000000000000000000000000000096753008660010154613b6290919063ffffffff16565b421115611762575f6116c56103e8610bb26110ad610bac62015180610bb26116be7f00000000000000000000000000000000000000000000000000000000096753008c60010154613b6290919063ffffffff16565b4290613b83565b90506120088111156116d657506120085b6116e6612710610bb28584613b6d565b600154600c54604051632a98027560e01b81526001600160a01b039182166004820152602481018490529294501690632a980275906044015f604051808303815f87803b158015611735575f80fd5b505af1158015611747573d5f803e3d5ffd5b5050505061175e8284613b8390919063ffffffff16565b9250505b82541561179c5761178c600a54610bb26117848561177e611eda565b90613b83565b865490613b6d565b60028401554260038401556117a6565b6117a63385613c02565b335f9081526003602052604090205480156117c6576117c6338288613b8e565b604080518481526020810184905290810187905233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949060600160405180910390a2600154604051632a98027560e01b8152336004820152602481018590526001600160a01b0390911690632a980275906044015f604051808303815f87803b158015611852575f80fd5b505af1158015611864573d5f803e3d5ffd5b50505050505050505050565b600b546001600160a01b0316331461189a5760405162461bcd60e51b8152600401610967906142fc565b5f5b82811015610ddb5781151560075f8686858181106118bc576118bc61427a565b90506020020160208101906118d19190613f30565b6001600160a01b0316815260208101919091526040015f205460ff161515146119e3578160075f86868581811061190a5761190a61427a565b905060200201602081019061191f9190613f30565b6001600160a01b0316815260208101919091526040015f20805460ff1916911515919091179055816119635760138054905f61195a8361441c565b91905055611977565b60138054905f61197283614335565b919050555b507f808293acec1c44217eccd857d5abb88ff31456d23bf3a000d2f5aee5f92f4c198484838181106119ab576119ab61427a565b90506020020160208101906119c09190613f30565b604080516001600160a01b03909216825284151560208301520160405180910390a15b806119ed81614335565b91505061189c565b6011545f90640100000000900460ff168015611a0e5750815b611a1a57503380611a1e565b5032805b506001600160a01b038181165f8181526005602090815260409182902080546001600160a01b031916948816948517905581519283528201929092527fbeebfeebc9d1af8057ca45af36b2171fea34cb5b251e394f0bc5fcabde119d7f910160405180910390a1505050565b335f9081526008602090815260408083206001600160a01b038616845290915281208054909190611abc906001613b83565b9050808314611b1d57818181548110611ad757611ad761427a565b905f5260205f209060030201828481548110611af557611af561427a565b5f91825260209091208254600390920201908155600180830154908201556002918201549101555b81805480611b2d57611b2d614431565b5f828152602080822060035f19949094019384020182815560018101839055600201919091559155604080513381526001600160a01b0387169281019290925281018490527f29fbfeb988fb99326ac41d70606334081c6be7e8518f6caa5b7b1bcbe7872a1e906060015b60405180910390a150505050565b600b546001600160a01b03163314611bd05760405162461bcd60e51b8152600401610967906142fc565b6011805491151563010000000263ff00000019909216919091179055565b60015460095460405163b6ec056160e01b81525f9283926001600160a01b039091169163b6ec056191611c279160040190815260200190565b602060405180830381865afa158015611c42573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a4919061434d565b335f9081526006602052604090205460ff1680611c915750335f9081526007602052604090205460ff165b611ce75760405162461bcd60e51b815260206004820152602160248201527f6f6e6c7920747275737465642073656e64657273286f7468657220706f6f6c736044820152602960f81b6064820152608401610967565b5f611cf0611eda565b90505f600a545f14611d1c57611d1582610bb2600a5489613b6d90919063ffffffff16565b9050611d1f565b50845b600a54611d2c9082613b62565b600a556001600160a01b0385165f818152600260208181526040808420815160a0810183528781528084018b81528184018e81524260608401908152608084018d8152855460018181018855968b52888b20955160059091029095019485559251948401949094555195820195909555905160038083019190915593516004909101559383525220548015611dc657611dc6868284613cea565b6040805188815260208101849052908101869052606081018590526001600160a01b038716907fb66a80ae2ebf4737952b9c2b57a9d34ef56806ab937f481b75197ae991d81afb9060800160405180910390a250505050505050565b6011545f90640100000000900460ff168015611e3b5750815b611e4757503380611e4b565b5032805b506001600160a01b0381165f90815260036020526040902054838114610ddb575f611e7583613a4a565b90508015611ebb578415611eb057815f03611e9a57611e95838683613cea565b611ebb565b611ea5838383613b8e565b611e95838683613cea565b611ebb838383613b8e565b50506001600160a01b03165f9081526003602052604090209190915550565b60015460095460405163b6ec056160e01b81525f9283926001600160a01b039091169163b6ec056191611f139160040190815260200190565b602060405180830381865afa158015611f2e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f52919061434d565b6001546040516301aba89b60e71b81523060048201529192505f916001600160a01b039091169063d5d44d8090602401602060405180830381865afa158015611f9d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc1919061434d565b9050611fcd8282613b62565b9250505090565b5f600a545f14611ffd57611ff8600a54610bb2670de0b6b3a7640000610bac611eda565b905090565b50670de0b6b3a764000090565b60015460095460405163b6ec056160e01b81525f9283926001600160a01b039091169163b6ec0561916120439160040190815260200190565b602060405180830381865afa15801561205e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612082919061434d565b90505f6120a0612710610bb260105485613b6d90919063ffffffff16565b9392505050565b335f9081526002602052604081208054839081106120c7576120c761427a565b905f5260205f2090600502019050600e546120f1600a54610bb26120e9611eda565b855490613b6d565b101561213f5760405162461bcd60e51b815260206004820152601760248201527f62656c6f77206d696e696d756d207468726573686f6c640000000000000000006044820152606401610967565b335f8181526008602090815260408083206001600160a01b0388168085529083528184208054835160608082018652895482526001808b018054848a0190815260048d018054868b019081528488018955978c529a8a90209451600387029095019485555191840191909155935160029092019190915588549254965485519889529588019390935292860183905290850152608084019290925260a0830152907f13356b03fc409456fbfbc8b432cb402b7841b3114d1d159625eb0f3d4e3a46819060c001611b98565b600b546001600160a01b031633146122345760405162461bcd60e51b8152600401610967906142fc565b600180546001600160a01b0319166001600160a01b039390931692909217909155600955565b612262613e67565b600e548310156122a95760405162461bcd60e51b815260206004820152601260248201527110995b1bddc8135a5b9a5b5d5b4811da599d60721b6044820152606401610967565b5f6122b2611eda565b600154604051632770a7eb60e21b8152336004820152602481018790529192506001600160a01b031690639dc29fac906044016020604051808303815f875af1158015612301573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123259190614445565b6123415760405162461bcd60e51b815260040161096790614460565b5f600a545f1461236b5761236482610bb2600a5488613b6d90919063ffffffff16565b905061236e565b50835b600a5461237b9082613b62565b600a556001600160a01b0384165f818152600260208181526040808420815160a081018352878152428185018181528285018e815260608401928352608084018d8152855460018181018855968b52888b209551600590910290950194855591519484019490945592519582019590955593516003808601919091559051600490940193909355938352522054801561241957612419858284613cea565b6040805187815260208101849052428183015290516001600160a01b0387169133917f190f4e47df17911728b041870d3cd75008c166bb9d8cde694aaa68f73ad415829181900360600190a350505061247160015f55565b505050565b335f90815260026020526040902080546124b091908390811061249b5761249b61427a565b905f5260205f2090600502015f0154826113b4565b50565b600b546001600160a01b031633146124dd5760405162461bcd60e51b8152600401610967906142fc565b60118054911515620100000262ff000019909216919091179055565b60115460ff166125405760405162461bcd60e51b81526020600482015260126024820152711d1c985b9cd9995c9cc8191a5cd8589b195960721b6044820152606401610967565b336001600160a01b038216036125915760405162461bcd60e51b815260206004820152601660248201527531b0b713ba103a3930b739b332b9103a379039b2b63360511b6044820152606401610967565b335f9081526002602052604090205482106125be5760405162461bcd60e51b815260040161096790614252565b335f9081526002602052604081208054849081106125de576125de61427a565b905f5260205f20906005020190505f612605600a54610bb26125fe611eda565b8890613b6d565b9050600e548110156126595760405162461bcd60e51b815260206004820152601760248201527f42656c6f77206d696e696d756d207468726573686f6c640000000000000000006044820152606401610967565b815485111561267a5760405162461bcd60e51b81526004016109679061428e565b6011546301000000900460ff166126ab57815485146126ab5760405162461bcd60e51b8152600401610967906142c5565b81546126b79086613b83565b8255335f9081526003602052604090205480156126d9576126d9338288613b8e565b506001600160a01b0383165f90815260036020526040902054801561270357612703848288613cea565b6001600160a01b0384165f908152600260208181526040808420815160a0810183528b81526001808a015482860190815293820189815242606084019081526004808d01546080860190815286548086018855968b529790992093516005909502909301938455935190830155915193810193909355516003830155519101558254156127ab5761279b600a54610bb2611784611eda565b60028401554260038401556127b5565b6127b53386613c02565b60408051878152602081018790526001600160a01b0386169133917ff3f8af030ee2cfc3c3c4ea260e6bcdd578eb1558b6eb3d79f7d0617ddbdc5b78910160405180910390a3505050505050565b61280b613e67565b5f831161284f5760405162461bcd60e51b8152602060048201526012602482015271139bdd1a1a5b99c81d1bc819195c1bdcda5d60721b6044820152606401610967565b6001600160a01b0384165f9081526002602052604090205482106128a65760405162461bcd60e51b815260206004820152600e60248201526d1ddc9bdb99c814dd185ad948125160921b6044820152606401610967565b600b546001600160a01b03163314612910576001600160a01b03841633146129105760405162461bcd60e51b815260206004820152601e60248201527f63616e206f6e6c7920657874656e6420796f7572206f776e207374616b6500006044820152606401610967565b5f612919611eda565b600154604051632770a7eb60e21b8152336004820152602481018790529192506001600160a01b031690639dc29fac906044016020604051808303815f875af1158015612968573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061298c9190614445565b6129a85760405162461bcd60e51b815260040161096790614460565b5f600a545f146129d2576129cb82610bb2600a5488613b6d90919063ffffffff16565b90506129d5565b50835b6001600160a01b0386165f9081526002602052604081208054869081106129fe576129fe61427a565b905f5260205f2090600502019050612a2282825f0154613b6290919063ffffffff16565b8155600a54612a319083613b62565b600a556004810154841180612a7357506001810154612a70907f0000000000000000000000000000000000000000000000000000000009675300613b62565b42115b15612a8057600481018490555b612a99600a54610bb2612a91611eda565b845490613b6d565b600282015542600380830182905560018301919091556001600160a01b0388165f90815260209190915260409020548015612ad957612ad9888285613cea565b60408051888152602081018890529081018490524260608201526001600160a01b0389169033907f7f65dfb94bab62e0708845150044cf7ad9c77fbfe6ba9e3c8c1f210e15aa953d9060800160405180910390a350505050610ddb60015f55565b612b42613e67565b5f8111612b865760405162461bcd60e51b8152602060048201526012602482015271139bdd1a1a5b99c81d1bc819195c1bdcda5d60721b6044820152606401610967565b5f612b8f611eda565b600154604051632770a7eb60e21b8152336004820152602481018590529192506001600160a01b031690639dc29fac906044016020604051808303815f875af1158015612bde573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c029190614445565b612c1e5760405162461bcd60e51b815260040161096790614460565b5f600a545f14612c4857612c4182610bb2600a5486613b6d90919063ffffffff16565b9050612c4b565b50815b600a54612c589082613b62565b600a55335f818152600260208181526040808420815160a081018352878152428185018181528285018c81526060840192835260808401898152855460018181018855968b52888b2095516005909102909501948555915194840194909455925195820195909555935160038086019190915590516004909401939093559383525220548015612ced57612ced338284613cea565b60408051858152602081018490524281830152905133917f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e919081900360600190a25050506124b060015f55565b335f908152600260205260409020548110612d685760405162461bcd60e51b8152600401610967906143df565b335f908152600260205260408120805483908110612d8857612d8861427a565b905f5260205f2090600502019050612dcd7f00000000000000000000000000000000000000000000000000000000096753008260010154613b6290919063ffffffff16565b4211612e125760405162461bcd60e51b81526020600482015260146024820152737374616b65206e6f7420796574206d617475726560601b6044820152606401610967565b5f612e28600a54610bb2845f0154610bac611eda565b600b5460405163ded6e1c960e01b81526001600160a01b0387811660048301529293505f92612eac9261271092610bb2929091169063ded6e1c990602401602060405180830381865afa158015612e81573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ea5919061434d565b8590613b6d565b600b546040516370a0823160e01b81526001600160a01b03918216600482015291925082917f000000000000000000000000faac6a85c3e123ab2cf7669b1024f146cfef0b38909116906370a0823190602401602060405180830381865afa158015612f1a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f3e919061434d565b1015612fa15760405162461bcd60e51b815260206004820152602c60248201527f676f7665726e6f72207265736572766573206172652063757272656e746c792060448201526b1a5b9cdd59999a58da595b9d60a21b6064820152608401610967565b306001600160a01b0386160361301957600b5460405163e5f59bc160e01b81526001600160a01b039091169063e5f59bc190612fe7903390899086908a906004016143b6565b5f604051808303815f87803b158015612ffe575f80fd5b505af1158015613010573d5f803e3d5ffd5b505050506130f9565b8254613026908587610948565b600b5460405163e5ea69ff60e01b815233600482018190526001600160a01b039283169263e5f59bc1928991869160019184169063e5ea69ff90602401602060405180830381865afa15801561307e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a2919061434d565b6130ac9190614409565b6040518563ffffffff1660e01b81526004016130cb94939291906143b6565b5f604051808303815f87803b1580156130e2575f80fd5b505af11580156130f4573d5f803e3d5ffd5b505050505b5050505050565b5f5b82811015610ddb573360055f8686858181106131205761312061427a565b90506020020160208101906131359190613f30565b6001600160a01b03908116825260208201929092526040015f205416036132c3575f60035f86868581811061316c5761316c61427a565b90506020020160208101906131819190613f30565b6001600160a01b03166001600160a01b031681526020019081526020015f205490508083146132c1575f6131d58686858181106131c0576131c061427a565b905060200201602081019061084e9190613f30565b9050801561327b57831561326657815f036132205761321b8686858181106131ff576131ff61427a565b90506020020160208101906132149190613f30565b8583613cea565b61327b565b6132518686858181106132355761323561427a565b905060200201602081019061324a9190613f30565b8383613b8e565b61321b8686858181106131ff576131ff61427a565b61327b8686858181106132355761323561427a565b8360035f8888878181106132915761329161427a565b90506020020160208101906132a69190613f30565b6001600160a01b0316815260208101919091526040015f2055505b505b806132cd81614335565b915050613102565b600d546001600160a01b031661332d5760405162461bcd60e51b815260206004820152601760248201527f6d6967726174696f6e206e6f74206163746976617465640000000000000000006044820152606401610967565b6001600160a01b0382165f9081526002602052604090205481106133635760405162461bcd60e51b8152600401610967906143df565b6001600160a01b0382165f90815260026020526040812080548390811061338c5761338c61427a565b905f5260205f20906005020190505f815f0154116133d95760405162461bcd60e51b815260206004820152600a6024820152696e6f2062616c616e636560b01b6044820152606401610967565b5f6133ef600a54610bb2845f0154610bac611eda565b8254600a549192506134019190613b83565b600a555f8255600d546001830154600480850154604051636267189760e01b81529182018590526001600160a01b038881166024840152604483019390935260648201529116906362671897906084015f604051808303815f87803b158015613468575f80fd5b505af115801561347a573d5f803e3d5ffd5b5050600154600d5460405163cc58a6bb60e01b81526001600160a01b039182166004820152602481018690529116925063cc58a6bb91506044015f604051808303815f87803b1580156134cb575f80fd5b505af11580156134dd573d5f803e3d5ffd5b505083546040805185815260208101929092526001600160a01b03881693503392507fe28c7cce19d5f22ab16a04ca1bb768f7533bf719280b5e40718b41c2641ac309910160405180910390a350505050565b6001600160a01b038084165f90815260086020908152604080832093861683529290529081208054829182918291908690811061356f5761356f61427a565b5f91825260209091206003909102018054600182015460029092015490999198509650945050505050565b600b546001600160a01b031633146135c45760405162461bcd60e51b8152600401610967906142fc565b601180549115156101000261ff0019909216919091179055565b600b546001600160a01b031633146136085760405162461bcd60e51b8152600401610967906142fc565b5f5b82811015610ddb5781151560065f86868581811061362a5761362a61427a565b905060200201602081019061363f9190613f30565b6001600160a01b0316815260208101919091526040015f205460ff16151514613751578160065f8686858181106136785761367861427a565b905060200201602081019061368d9190613f30565b6001600160a01b0316815260208101919091526040015f20805460ff1916911515919091179055816136d15760128054905f6136c88361441c565b919050556136e5565b60128054905f6136e083614335565b919050555b507f68e0e16e4195f1bb5436073ae329e02686b513fd39cd623585b36d74785b21c18484838181106137195761371961427a565b905060200201602081019061372e9190613f30565b604080516001600160a01b03909216825284151560208301520160405180910390a15b8061375b81614335565b91505061360a565b600b546001600160a01b0316331461378d5760405162461bcd60e51b8152600401610967906142fc565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6137b8613af7565b6001600160a01b0316036137f95760405162461bcd60e51b8152602060048201526008602482015267191a5cd8589b195960c21b6044820152606401610967565b335f9081526002602052604090205481106138265760405162461bcd60e51b8152600401610967906143df565b335f9081526002602052604081208054839081106138465761384661427a565b905f5260205f20906005020190505f83116138735760405162461bcd60e51b815260040161096790614225565b80548311156138945760405162461bcd60e51b81526004016109679061428e565b5f6138a7600a54610bb286610bac611eda565b82549091506138b69085613b83565b8255600a546138c59085613b83565b600a558154156138f4576138e4600a54610bb26120e98461177e611eda565b60028301554260038301556138fe565b6138fe3384613c02565b335f90815260036020526040902054801561391e5761391e338287613b8e565b600c54604080518481525f60208201529081018790526001600160a01b03909116907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949060600160405180910390a2600154600c54604051632a98027560e01b81526001600160a01b03918216600482015260248101859052911690632a980275906044015f604051808303815f87803b1580156139ba575f80fd5b505af11580156139cc573d5f803e3d5ffd5b505050506139d8613af7565b60405163364c781560e01b8152600481018490523360248201526001600160a01b03919091169063364c7815906044016130cb565b600b546001600160a01b03163314613a375760405162461bcd60e51b8152600401610967906142fc565b6011805460ff1916911515919091179055565b6001600160a01b0381165f908152600260205260408120805482805b82811015613aae57838181548110613a8057613a8061427a565b905f5260205f2090600502015f015482613a9a919061448b565b915080613aa681614335565b915050613a66565b50949350505050565b6001600160a01b0382165f908152600260205260408120805483908110613ae057613ae061427a565b905f5260205f2090600502015f0154905092915050565b600b546040805163c24375cf60e01b815290515f926001600160a01b03169163c24375cf9160048083019260209291908290030181865afa158015613b3e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ff89190614364565b5f6120a0828461448b565b5f6120a0828461449e565b5f6120a082846144b5565b5f6120a08284614409565b5f82815260046020526040902054613ba69082613b83565b5f838152600460209081526040918290209290925580518481529182018390526001600160a01b038516917f65b0f2fb4228364e2ac61c432687ae942c732095fc217265116bec6cc441683491015b60405180910390a2505050565b6001600160a01b0382165f9081526002602052604081208054909190613c2a90600190614409565b9050808314613ca357818181548110613c4557613c4561427a565b905f5260205f209060050201828481548110613c6357613c6361427a565b905f5260205f2090600502015f820154815f0155600182015481600101556002820154816002015560038201548160030155600482015481600401559050505b81805480613cb357613cb3614431565b5f8281526020812060055f199093019283020181815560018101829055600281018290556003810182905560040155905550505050565b5f82815260046020526040902054613d029082613b62565b5f838152600460209081526040918290209290925580518481529182018390526001600160a01b038516917fdb8549181d0331885cbb0e0d1e36bdd89e38e53990069f6f07a4090a15f74e5d9101613bf5565b6001600160a01b0382165f90815260086020908152604080832033845290915281208054909190613d87906001613b83565b9050808314613de857818181548110613da257613da261427a565b905f5260205f209060030201828481548110613dc057613dc061427a565b5f91825260209091208254600390920201908155600180830154908201556002918201549101555b81805480613df857613df8614431565b5f828152602080822060035f19949094019384020182815560018101839055600201919091559155604080516001600160a01b0387168152339281019290925281018490527f29fbfeb988fb99326ac41d70606334081c6be7e8518f6caa5b7b1bcbe7872a1e90606001611b98565b60025f5403613eb85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610967565b60025f55565b6001600160a01b03811681146124b0575f80fd5b5f805f60608486031215613ee4575f80fd5b83359250602084013591506040840135613efd81613ebe565b809150509250925092565b80151581146124b0575f80fd5b5f60208284031215613f25575f80fd5b81356120a081613f08565b5f60208284031215613f40575f80fd5b81356120a081613ebe565b5f8060408385031215613f5c575f80fd5b823591506020830135613f6e81613f08565b809150509250929050565b5f8060408385031215613f8a575f80fd5b8235613f9581613ebe565b946020939093013593505050565b5f60208284031215613fb3575f80fd5b5035919050565b5f8060408385031215613fcb575f80fd5b8235613fd681613ebe565b91506020830135613f6e81613ebe565b5f805f8060808587031215613ff9575f80fd5b843561400481613ebe565b93506020850135925060408501359150606085013561402281613ebe565b939692955090935050565b5f806040838503121561403e575f80fd5b50508035926020909101359150565b5f8083601f84011261405d575f80fd5b50813567ffffffffffffffff811115614074575f80fd5b6020830191508360208260051b850101111561408e575f80fd5b9250929050565b5f805f604084860312156140a7575f80fd5b833567ffffffffffffffff8111156140bd575f80fd5b6140c98682870161404d565b9094509250506020840135613efd81613f08565b5f80604083850312156140ee575f80fd5b82356140f981613ebe565b91506020830135613f6e81613f08565b5f805f806080858703121561411c575f80fd5b84359350602085013561412e81613ebe565b93969395505050506040820135916060013590565b5f805f60608486031215614155575f80fd5b83359250602084013561416781613ebe565b929592945050506040919091013590565b5f805f806080858703121561418b575f80fd5b843561419681613ebe565b966020860135965060408601359560600135945092505050565b5f805f604084860312156141c2575f80fd5b833567ffffffffffffffff8111156141d8575f80fd5b6141e48682870161404d565b909790965060209590950135949350505050565b5f805f6060848603121561420a575f80fd5b833561421581613ebe565b9250602084013561416781613ebe565b6020808252601390820152724e6f7468696e6720746f20776974686472617760681b604082015260600190565b6020808252600e908201526d1ddc9bdb99c81cdd185ad948125160921b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252601f908201527f576974686472617720616d6f756e7420657863656564732062616c616e636500604082015260600190565b60208082526018908201527f6d757374207472616e736665722066756c6c207374616b650000000000000000604082015260600190565b6020808252600b908201526a61646d696e3a207775743f60a81b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161434657614346614321565b5060010190565b5f6020828403121561435d575f80fd5b5051919050565b5f60208284031215614374575f80fd5b81516120a081613ebe565b6020808252601c908201527f696e636f7272656374207374616b65206f7220616c6c6f77616e636500000000604082015260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b60208082526010908201526f1a5b9d985b1a59081cdd185ad948125160821b604082015260600190565b818103818111156110a4576110a4614321565b5f8161442a5761442a614321565b505f190190565b634e487b7160e01b5f52603160045260245ffd5b5f60208284031215614455575f80fd5b81516120a081613f08565b6020808252601190820152701d1bdad95b88189d5c9b8819985a5b1959607a1b604082015260600190565b808201808211156110a4576110a4614321565b80820281158282048414176110a4576110a4614321565b5f826144cf57634e487b7160e01b5f52601260045260245ffd5b50049056fea264697066735822122083e3da79046bf3aaa8a2695c4d81c28741b0bae652e2fa651245426441a8cc5064736f6c63430008140033