Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
BountyV2
Compiler Version
v0.8.11+commit.d7f03943
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only /* Bounty.sol - SKALE Manager Copyright (C) 2020-Present SKALE Labs @author Dmytro Stebaiev SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity 0.8.11; import "@skalenetwork/skale-manager-interfaces/IBountyV2.sol"; import "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol"; import "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol"; import "@skalenetwork/skale-manager-interfaces/INodes.sol"; import "./Permissions.sol"; import "./ConstantsHolder.sol"; import "./delegation/PartialDifferences.sol"; contract BountyV2 is Permissions, IBountyV2 { using PartialDifferences for PartialDifferences.Value; using PartialDifferences for PartialDifferences.Sequence; struct BountyHistory { uint month; uint bountyPaid; } // TODO: replace with an array when solidity starts supporting it uint public constant YEAR1_BOUNTY = 3850e5 * 1e18; uint public constant YEAR2_BOUNTY = 3465e5 * 1e18; uint public constant YEAR3_BOUNTY = 3080e5 * 1e18; uint public constant YEAR4_BOUNTY = 2695e5 * 1e18; uint public constant YEAR5_BOUNTY = 2310e5 * 1e18; uint public constant YEAR6_BOUNTY = 1925e5 * 1e18; uint public constant EPOCHS_PER_YEAR = 12; uint public constant SECONDS_PER_DAY = 24 * 60 * 60; uint public constant BOUNTY_WINDOW_SECONDS = 3 * SECONDS_PER_DAY; bytes32 public constant BOUNTY_REDUCTION_MANAGER_ROLE = keccak256("BOUNTY_REDUCTION_MANAGER_ROLE"); uint private _nextEpoch; uint private _epochPool; uint private _bountyWasPaidInCurrentEpoch; bool public bountyReduction; uint public nodeCreationWindowSeconds; PartialDifferences.Value private _effectiveDelegatedSum; // validatorId amount of nodes mapping (uint => uint) public nodesByValidator; // deprecated // validatorId => BountyHistory mapping (uint => BountyHistory) private _bountyHistory; modifier onlyBountyReductionManager() { require(hasRole(BOUNTY_REDUCTION_MANAGER_ROLE, msg.sender), "BOUNTY_REDUCTION_MANAGER_ROLE is required"); _; } function calculateBounty(uint nodeIndex) external override allow("SkaleManager") returns (uint) { ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder")); INodes nodes = INodes(contractManager.getContract("Nodes")); ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers")); IDelegationController delegationController = IDelegationController( contractManager.getContract("DelegationController") ); require( _getNextRewardTimestamp(nodeIndex, nodes, timeHelpers) <= block.timestamp, "Transaction is sent too early" ); uint validatorId = nodes.getValidatorId(nodeIndex); if (nodesByValidator[validatorId] > 0) { delete nodesByValidator[validatorId]; } uint currentMonth = timeHelpers.getCurrentMonth(); _refillEpochPool(currentMonth, timeHelpers, constantsHolder); _prepareBountyHistory(validatorId, currentMonth); uint bounty = _calculateMaximumBountyAmount( _epochPool, _effectiveDelegatedSum.getAndUpdateValue(currentMonth), _bountyWasPaidInCurrentEpoch, nodeIndex, _bountyHistory[validatorId].bountyPaid, delegationController.getAndUpdateEffectiveDelegatedToValidator(validatorId, currentMonth), delegationController.getAndUpdateDelegatedToValidatorNow(validatorId), constantsHolder, nodes ); _bountyHistory[validatorId].bountyPaid = _bountyHistory[validatorId].bountyPaid + bounty; bounty = _reduceBounty( bounty, nodeIndex, nodes, constantsHolder ); _epochPool = _epochPool - bounty; _bountyWasPaidInCurrentEpoch = _bountyWasPaidInCurrentEpoch + bounty; return bounty; } function enableBountyReduction() external override onlyBountyReductionManager { bountyReduction = true; emit BountyReduction(true); } function disableBountyReduction() external override onlyBountyReductionManager { bountyReduction = false; emit BountyReduction(false); } function setNodeCreationWindowSeconds(uint window) external override allow("Nodes") { emit NodeCreationWindowWasChanged(nodeCreationWindowSeconds, window); nodeCreationWindowSeconds = window; } function handleDelegationAdd( uint amount, uint month ) external override allow("DelegationController") { _effectiveDelegatedSum.addToValue(amount, month); } function handleDelegationRemoving( uint amount, uint month ) external override allow("DelegationController") { _effectiveDelegatedSum.subtractFromValue(amount, month); } function estimateBounty(uint nodeIndex) external view override returns (uint) { ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder")); INodes nodes = INodes(contractManager.getContract("Nodes")); ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers")); IDelegationController delegationController = IDelegationController( contractManager.getContract("DelegationController") ); uint currentMonth = timeHelpers.getCurrentMonth(); uint validatorId = nodes.getValidatorId(nodeIndex); uint stagePoolSize; (stagePoolSize, ) = _getEpochPool(currentMonth, timeHelpers, constantsHolder); return _calculateMaximumBountyAmount( stagePoolSize, _effectiveDelegatedSum.getValue(currentMonth), _nextEpoch == currentMonth + 1 ? _bountyWasPaidInCurrentEpoch : 0, nodeIndex, _getBountyPaid(validatorId, currentMonth), delegationController.getEffectiveDelegatedToValidator(validatorId, currentMonth), delegationController.getDelegatedToValidator(validatorId, currentMonth), constantsHolder, nodes ); } function getNextRewardTimestamp(uint nodeIndex) external view override returns (uint) { return _getNextRewardTimestamp( nodeIndex, INodes(contractManager.getContract("Nodes")), ITimeHelpers(contractManager.getContract("TimeHelpers")) ); } function getEffectiveDelegatedSum() external view override returns (uint[] memory) { return _effectiveDelegatedSum.getValues(); } function initialize(address contractManagerAddress) public override initializer { Permissions.initialize(contractManagerAddress); _nextEpoch = 0; _epochPool = 0; _bountyWasPaidInCurrentEpoch = 0; bountyReduction = false; nodeCreationWindowSeconds = 3 * SECONDS_PER_DAY; } // private function _refillEpochPool(uint currentMonth, ITimeHelpers timeHelpers, ConstantsHolder constantsHolder) private { uint epochPool; uint nextEpoch; (epochPool, nextEpoch) = _getEpochPool(currentMonth, timeHelpers, constantsHolder); if (_nextEpoch < nextEpoch) { (_epochPool, _nextEpoch) = (epochPool, nextEpoch); _bountyWasPaidInCurrentEpoch = 0; } } function _reduceBounty( uint bounty, uint nodeIndex, INodes nodes, ConstantsHolder constants ) private returns (uint reducedBounty) { if (!bountyReduction) { return bounty; } reducedBounty = bounty; if (!nodes.checkPossibilityToMaintainNode(nodes.getValidatorId(nodeIndex), nodeIndex)) { reducedBounty = reducedBounty / constants.MSR_REDUCING_COEFFICIENT(); } } function _prepareBountyHistory(uint validatorId, uint currentMonth) private { if (_bountyHistory[validatorId].month < currentMonth) { _bountyHistory[validatorId].month = currentMonth; delete _bountyHistory[validatorId].bountyPaid; } } function _calculateMaximumBountyAmount( uint epochPoolSize, uint effectiveDelegatedSum, uint bountyWasPaidInCurrentEpoch, uint nodeIndex, uint bountyPaidToTheValidator, uint effectiveDelegated, uint delegated, ConstantsHolder constantsHolder, INodes nodes ) private view returns (uint) { if (nodes.isNodeLeft(nodeIndex)) { return 0; } if (block.timestamp < constantsHolder.launchTimestamp()) { // network is not launched // bounty is turned off return 0; } if (effectiveDelegatedSum == 0) { // no delegations in the system return 0; } if (constantsHolder.msr() == 0) { return 0; } uint bounty = _calculateBountyShare( epochPoolSize + bountyWasPaidInCurrentEpoch, effectiveDelegated, effectiveDelegatedSum, delegated / constantsHolder.msr(), bountyPaidToTheValidator ); return bounty; } function _getFirstEpoch(ITimeHelpers timeHelpers, ConstantsHolder constantsHolder) private view returns (uint) { return timeHelpers.timestampToMonth(constantsHolder.launchTimestamp()); } function _getEpochPool( uint currentMonth, ITimeHelpers timeHelpers, ConstantsHolder constantsHolder ) private view returns (uint epochPool, uint nextEpoch) { epochPool = _epochPool; for (nextEpoch = _nextEpoch; nextEpoch <= currentMonth; ++nextEpoch) { epochPool = epochPool + _getEpochReward(nextEpoch, timeHelpers, constantsHolder); } } function _getEpochReward( uint epoch, ITimeHelpers timeHelpers, ConstantsHolder constantsHolder ) private view returns (uint) { uint firstEpoch = _getFirstEpoch(timeHelpers, constantsHolder); if (epoch < firstEpoch) { return 0; } uint epochIndex = epoch - firstEpoch; uint year = epochIndex / EPOCHS_PER_YEAR; if (year >= 6) { uint power = (year - 6) / 3 + 1; if (power < 256) { return YEAR6_BOUNTY / 2 ** power / EPOCHS_PER_YEAR; } else { return 0; } } else { uint[6] memory customBounties = [ YEAR1_BOUNTY, YEAR2_BOUNTY, YEAR3_BOUNTY, YEAR4_BOUNTY, YEAR5_BOUNTY, YEAR6_BOUNTY ]; return customBounties[year] / EPOCHS_PER_YEAR; } } function _getBountyPaid(uint validatorId, uint month) private view returns (uint) { require(_bountyHistory[validatorId].month <= month, "Can't get bounty paid"); if (_bountyHistory[validatorId].month == month) { return _bountyHistory[validatorId].bountyPaid; } else { return 0; } } function _getNextRewardTimestamp(uint nodeIndex, INodes nodes, ITimeHelpers timeHelpers) private view returns (uint) { uint lastRewardTimestamp = nodes.getNodeLastRewardDate(nodeIndex); uint lastRewardMonth = timeHelpers.timestampToMonth(lastRewardTimestamp); uint lastRewardMonthStart = timeHelpers.monthToTimestamp(lastRewardMonth); uint timePassedAfterMonthStart = lastRewardTimestamp - lastRewardMonthStart; uint currentMonth = timeHelpers.getCurrentMonth(); assert(lastRewardMonth <= currentMonth); if (lastRewardMonth == currentMonth) { uint nextMonthStart = timeHelpers.monthToTimestamp(currentMonth + 1); uint nextMonthFinish = timeHelpers.monthToTimestamp(lastRewardMonth + 2); if (lastRewardTimestamp < lastRewardMonthStart + nodeCreationWindowSeconds) { return nextMonthStart - BOUNTY_WINDOW_SECONDS; } else { return _min(nextMonthStart + timePassedAfterMonthStart, nextMonthFinish - BOUNTY_WINDOW_SECONDS); } } else if (lastRewardMonth + 1 == currentMonth) { uint currentMonthStart = timeHelpers.monthToTimestamp(currentMonth); uint currentMonthFinish = timeHelpers.monthToTimestamp(currentMonth + 1); return _min( currentMonthStart + _max(timePassedAfterMonthStart, nodeCreationWindowSeconds), currentMonthFinish - BOUNTY_WINDOW_SECONDS ); } else { uint currentMonthStart = timeHelpers.monthToTimestamp(currentMonth); return currentMonthStart + nodeCreationWindowSeconds; } } function _calculateBountyShare( uint monthBounty, uint effectiveDelegated, uint effectiveDelegatedSum, uint maxNodesAmount, uint paidToValidator ) private pure returns (uint) { if (maxNodesAmount > 0) { uint totalBountyShare = monthBounty * effectiveDelegated / effectiveDelegatedSum; return _min( totalBountyShare / maxNodesAmount, totalBountyShare - paidToValidator ); } else { return 0; } } function _min(uint a, uint b) private pure returns (uint) { if (a < b) { return a; } else { return b; } } function _max(uint a, uint b) private pure returns (uint) { if (a < b) { return b; } else { return a; } } }
// SPDX-License-Identifier: AGPL-3.0-only /* IBountyV2.sol - SKALE Manager Interfaces Copyright (C) 2021-Present SKALE Labs @author Artem Payvin SKALE Manager Interfaces is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager Interfaces is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager Interfaces. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IBountyV2 { /** * @dev Emitted when bounty reduction is turned on or turned off. */ event BountyReduction(bool status); /** * @dev Emitted when a node creation window was changed. */ event NodeCreationWindowWasChanged( uint oldValue, uint newValue ); function calculateBounty(uint nodeIndex) external returns (uint); function enableBountyReduction() external; function disableBountyReduction() external; function setNodeCreationWindowSeconds(uint window) external; function handleDelegationAdd(uint amount, uint month) external; function handleDelegationRemoving(uint amount, uint month) external; function estimateBounty(uint nodeIndex) external view returns (uint); function getNextRewardTimestamp(uint nodeIndex) external view returns (uint); function getEffectiveDelegatedSum() external view returns (uint[] memory); }
// SPDX-License-Identifier: AGPL-3.0-only /* IDelegationController.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IDelegationController { enum State { PROPOSED, ACCEPTED, CANCELED, REJECTED, DELEGATED, UNDELEGATION_REQUESTED, COMPLETED } struct Delegation { address holder; // address of token owner uint validatorId; uint amount; uint delegationPeriod; uint created; // time of delegation creation uint started; // month when a delegation becomes active uint finished; // first month after a delegation ends string info; } /** * @dev Emitted when validator was confiscated. */ event Confiscated( uint indexed validatorId, uint amount ); /** * @dev Emitted when validator was confiscated. */ event SlashesProcessed( address indexed holder, uint limit ); /** * @dev Emitted when a delegation is proposed to a validator. */ event DelegationProposed( uint delegationId ); /** * @dev Emitted when a delegation is accepted by a validator. */ event DelegationAccepted( uint delegationId ); /** * @dev Emitted when a delegation is cancelled by the delegator. */ event DelegationRequestCanceledByUser( uint delegationId ); /** * @dev Emitted when a delegation is requested to undelegate. */ event UndelegationRequested( uint delegationId ); function getAndUpdateDelegatedToValidatorNow(uint validatorId) external returns (uint); function getAndUpdateDelegatedAmount(address holder) external returns (uint); function getAndUpdateEffectiveDelegatedByHolderToValidator(address holder, uint validatorId, uint month) external returns (uint effectiveDelegated); function delegate( uint validatorId, uint amount, uint delegationPeriod, string calldata info ) external; function cancelPendingDelegation(uint delegationId) external; function acceptPendingDelegation(uint delegationId) external; function requestUndelegation(uint delegationId) external; function confiscate(uint validatorId, uint amount) external; function getAndUpdateEffectiveDelegatedToValidator(uint validatorId, uint month) external returns (uint); function getAndUpdateDelegatedByHolderToValidatorNow(address holder, uint validatorId) external returns (uint); function processSlashes(address holder, uint limit) external; function processAllSlashes(address holder) external; function getEffectiveDelegatedValuesByValidator(uint validatorId) external view returns (uint[] memory); function getEffectiveDelegatedToValidator(uint validatorId, uint month) external view returns (uint); function getDelegatedToValidator(uint validatorId, uint month) external view returns (uint); function getDelegation(uint delegationId) external view returns (Delegation memory); function getFirstDelegationMonth(address holder, uint validatorId) external view returns(uint); function getDelegationsByValidatorLength(uint validatorId) external view returns (uint); function getDelegationsByHolderLength(address holder) external view returns (uint); function getState(uint delegationId) external view returns (State state); function getLockedInPendingDelegations(address holder) external view returns (uint); function hasUnprocessedSlashes(address holder) external view returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-only /* ITimeHelpers.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface ITimeHelpers { function calculateProofOfUseLockEndTime(uint month, uint lockUpPeriodDays) external view returns (uint timestamp); function getCurrentMonth() external view returns (uint); function timestampToYear(uint timestamp) external view returns (uint); function timestampToMonth(uint timestamp) external view returns (uint); function monthToTimestamp(uint month) external view returns (uint timestamp); function addDays(uint fromTimestamp, uint n) external pure returns (uint); function addMonths(uint fromTimestamp, uint n) external pure returns (uint); function addYears(uint fromTimestamp, uint n) external pure returns (uint); }
// SPDX-License-Identifier: AGPL-3.0-only /* INodes.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; import "./utils/IRandom.sol"; interface INodes { // All Nodes states enum NodeStatus {Active, Leaving, Left, In_Maintenance} struct Node { string name; bytes4 ip; bytes4 publicIP; uint16 port; bytes32[2] publicKey; uint startBlock; uint lastRewardDate; uint finishTime; NodeStatus status; uint validatorId; } // struct to note which Nodes and which number of Nodes owned by user struct CreatedNodes { mapping (uint => bool) isNodeExist; uint numberOfNodes; } struct SpaceManaging { uint8 freeSpace; uint indexInSpaceMap; } struct NodeCreationParams { string name; bytes4 ip; bytes4 publicIp; uint16 port; bytes32[2] publicKey; uint16 nonce; string domainName; } /** * @dev Emitted when a node is created. */ event NodeCreated( uint nodeIndex, address owner, string name, bytes4 ip, bytes4 publicIP, uint16 port, uint16 nonce, string domainName ); /** * @dev Emitted when a node completes a network exit. */ event ExitCompleted( uint nodeIndex ); /** * @dev Emitted when a node begins to exit from the network. */ event ExitInitialized( uint nodeIndex, uint startLeavingPeriod ); /** * @dev Emitted when a node set to in compliant or compliant. */ event IncompliantNode( uint indexed nodeIndex, bool status ); /** * @dev Emitted when a node set to in maintenance or from in maintenance. */ event MaintenanceNode( uint indexed nodeIndex, bool status ); /** * @dev Emitted when a node status changed. */ event IPChanged( uint indexed nodeIndex, bytes4 previousIP, bytes4 newIP ); function removeSpaceFromNode(uint nodeIndex, uint8 space) external returns (bool); function addSpaceToNode(uint nodeIndex, uint8 space) external; function changeNodeLastRewardDate(uint nodeIndex) external; function changeNodeFinishTime(uint nodeIndex, uint time) external; function createNode(address from, NodeCreationParams calldata params) external; function initExit(uint nodeIndex) external; function completeExit(uint nodeIndex) external returns (bool); function deleteNodeForValidator(uint validatorId, uint nodeIndex) external; function checkPossibilityCreatingNode(address nodeAddress) external; function checkPossibilityToMaintainNode(uint validatorId, uint nodeIndex) external returns (bool); function setNodeInMaintenance(uint nodeIndex) external; function removeNodeFromInMaintenance(uint nodeIndex) external; function setNodeIncompliant(uint nodeIndex) external; function setNodeCompliant(uint nodeIndex) external; function setDomainName(uint nodeIndex, string memory domainName) external; function makeNodeVisible(uint nodeIndex) external; function makeNodeInvisible(uint nodeIndex) external; function changeIP(uint nodeIndex, bytes4 newIP, bytes4 newPublicIP) external; function numberOfActiveNodes() external view returns (uint); function incompliant(uint nodeIndex) external view returns (bool); function getRandomNodeWithFreeSpace( uint8 freeSpace, IRandom.RandomGenerator memory randomGenerator ) external view returns (uint); function isTimeForReward(uint nodeIndex) external view returns (bool); function getNodeIP(uint nodeIndex) external view returns (bytes4); function getNodeDomainName(uint nodeIndex) external view returns (string memory); function getNodePort(uint nodeIndex) external view returns (uint16); function getNodePublicKey(uint nodeIndex) external view returns (bytes32[2] memory); function getNodeAddress(uint nodeIndex) external view returns (address); function getNodeFinishTime(uint nodeIndex) external view returns (uint); function isNodeLeft(uint nodeIndex) external view returns (bool); function isNodeInMaintenance(uint nodeIndex) external view returns (bool); function getNodeLastRewardDate(uint nodeIndex) external view returns (uint); function getNodeNextRewardDate(uint nodeIndex) external view returns (uint); function getNumberOfNodes() external view returns (uint); function getNumberOnlineNodes() external view returns (uint); function getActiveNodeIds() external view returns (uint[] memory activeNodeIds); function getNodeStatus(uint nodeIndex) external view returns (NodeStatus); function getValidatorNodeIndexes(uint validatorId) external view returns (uint[] memory); function countNodesWithFreeSpace(uint8 freeSpace) external view returns (uint count); function getValidatorId(uint nodeIndex) external view returns (uint); function isNodeExist(address from, uint nodeIndex) external view returns (bool); function isNodeActive(uint nodeIndex) external view returns (bool); function isNodeLeaving(uint nodeIndex) external view returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-only /* Permissions.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity 0.8.11; import "@skalenetwork/skale-manager-interfaces/IContractManager.sol"; import "@skalenetwork/skale-manager-interfaces/IPermissions.sol"; import "./thirdparty/openzeppelin/AccessControlUpgradeableLegacy.sol"; /** * @title Permissions * @dev Contract is connected module for Upgradeable approach, knows ContractManager */ contract Permissions is AccessControlUpgradeableLegacy, IPermissions { using AddressUpgradeable for address; IContractManager public contractManager; /** * @dev Modifier to make a function callable only when caller is the Owner. * * Requirements: * * - The caller must be the owner. */ modifier onlyOwner() { require(_isOwner(), "Caller is not the owner"); _; } /** * @dev Modifier to make a function callable only when caller is an Admin. * * Requirements: * * - The caller must be an admin. */ modifier onlyAdmin() { require(_isAdmin(msg.sender), "Caller is not an admin"); _; } /** * @dev Modifier to make a function callable only when caller is the Owner * or `contractName` contract. * * Requirements: * * - The caller must be the owner or `contractName`. */ modifier allow(string memory contractName) { require( contractManager.getContract(contractName) == msg.sender || _isOwner(), "Message sender is invalid"); _; } /** * @dev Modifier to make a function callable only when caller is the Owner * or `contractName1` or `contractName2` contract. * * Requirements: * * - The caller must be the owner, `contractName1`, or `contractName2`. */ modifier allowTwo(string memory contractName1, string memory contractName2) { require( contractManager.getContract(contractName1) == msg.sender || contractManager.getContract(contractName2) == msg.sender || _isOwner(), "Message sender is invalid"); _; } /** * @dev Modifier to make a function callable only when caller is the Owner * or `contractName1`, `contractName2`, or `contractName3` contract. * * Requirements: * * - The caller must be the owner, `contractName1`, `contractName2`, or * `contractName3`. */ modifier allowThree(string memory contractName1, string memory contractName2, string memory contractName3) { require( contractManager.getContract(contractName1) == msg.sender || contractManager.getContract(contractName2) == msg.sender || contractManager.getContract(contractName3) == msg.sender || _isOwner(), "Message sender is invalid"); _; } function initialize(address contractManagerAddress) public virtual override initializer { AccessControlUpgradeableLegacy.__AccessControl_init(); _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setContractManager(contractManagerAddress); } function _isOwner() internal view returns (bool) { return hasRole(DEFAULT_ADMIN_ROLE, msg.sender); } function _isAdmin(address account) internal view returns (bool) { address skaleManagerAddress = contractManager.contracts(keccak256(abi.encodePacked("SkaleManager"))); if (skaleManagerAddress != address(0)) { AccessControlUpgradeableLegacy skaleManager = AccessControlUpgradeableLegacy(skaleManagerAddress); return skaleManager.hasRole(keccak256("ADMIN_ROLE"), account) || _isOwner(); } else { return _isOwner(); } } function _setContractManager(address contractManagerAddress) private { require(contractManagerAddress != address(0), "ContractManager address is not set"); require(contractManagerAddress.isContract(), "Address is not contract"); contractManager = IContractManager(contractManagerAddress); } }
// SPDX-License-Identifier: AGPL-3.0-only /* ConstantsHolder.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity 0.8.11; import "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol"; import "./Permissions.sol"; /** * @title ConstantsHolder * @dev Contract contains constants and common variables for the SKALE Network. */ contract ConstantsHolder is Permissions, IConstantsHolder { // initial price for creating Node (100 SKL) uint public constant NODE_DEPOSIT = 100 * 1e18; uint8 public constant TOTAL_SPACE_ON_NODE = 128; // part of Node for Small Skale-chain (1/128 of Node) uint8 public constant SMALL_DIVISOR = 128; // part of Node for Medium Skale-chain (1/32 of Node) uint8 public constant MEDIUM_DIVISOR = 32; // part of Node for Large Skale-chain (full Node) uint8 public constant LARGE_DIVISOR = 1; // part of Node for Medium Test Skale-chain (1/4 of Node) uint8 public constant MEDIUM_TEST_DIVISOR = 4; // typically number of Nodes for Skale-chain (16 Nodes) uint public constant NUMBER_OF_NODES_FOR_SCHAIN = 16; // number of Nodes for Test Skale-chain (2 Nodes) uint public constant NUMBER_OF_NODES_FOR_TEST_SCHAIN = 2; // number of Nodes for Test Skale-chain (4 Nodes) uint public constant NUMBER_OF_NODES_FOR_MEDIUM_TEST_SCHAIN = 4; // number of seconds in one year uint32 public constant SECONDS_TO_YEAR = 31622400; // initial number of monitors uint public constant NUMBER_OF_MONITORS = 24; uint public constant OPTIMAL_LOAD_PERCENTAGE = 80; uint public constant ADJUSTMENT_SPEED = 1000; uint public constant COOLDOWN_TIME = 60; uint public constant MIN_PRICE = 10**6; uint public constant MSR_REDUCING_COEFFICIENT = 2; uint public constant DOWNTIME_THRESHOLD_PART = 30; uint public constant BOUNTY_LOCKUP_MONTHS = 2; uint public constant ALRIGHT_DELTA = 134161; uint public constant BROADCAST_DELTA = 177490; uint public constant COMPLAINT_BAD_DATA_DELTA = 80995; uint public constant PRE_RESPONSE_DELTA = 100061; uint public constant COMPLAINT_DELTA = 104611; uint public constant RESPONSE_DELTA = 49132; // MSR - Minimum staking requirement uint public msr; // Reward period - 30 days (each 30 days Node would be granted for bounty) uint32 public rewardPeriod; // Allowable latency - 150000 ms by default uint32 public allowableLatency; /** * Delta period - 1 hour (1 hour before Reward period became Monitors need * to send Verdicts and 1 hour after Reward period became Node need to come * and get Bounty) */ uint32 public deltaPeriod; /** * Check time - 2 minutes (every 2 minutes monitors should check metrics * from checked nodes) */ uint public checkTime; //Need to add minimal allowed parameters for verdicts uint public launchTimestamp; uint public rotationDelay; uint public proofOfUseLockUpPeriodDays; uint public proofOfUseDelegationPercentage; uint public limitValidatorsPerDelegator; uint256 public firstDelegationsMonth; // deprecated // date when schains will be allowed for creation uint public schainCreationTimeStamp; uint public minimalSchainLifetime; uint public complaintTimeLimit; bytes32 public constant CONSTANTS_HOLDER_MANAGER_ROLE = keccak256("CONSTANTS_HOLDER_MANAGER_ROLE"); modifier onlyConstantsHolderManager() { require(hasRole(CONSTANTS_HOLDER_MANAGER_ROLE, msg.sender), "CONSTANTS_HOLDER_MANAGER_ROLE is required"); _; } /** * @dev Allows the Owner to set new reward and delta periods * This function is only for tests. */ function setPeriods(uint32 newRewardPeriod, uint32 newDeltaPeriod) external override onlyConstantsHolderManager { require( newRewardPeriod >= newDeltaPeriod && newRewardPeriod - newDeltaPeriod >= checkTime, "Incorrect Periods" ); emit ConstantUpdated( keccak256(abi.encodePacked("RewardPeriod")), uint(rewardPeriod), uint(newRewardPeriod) ); rewardPeriod = newRewardPeriod; emit ConstantUpdated( keccak256(abi.encodePacked("DeltaPeriod")), uint(deltaPeriod), uint(newDeltaPeriod) ); deltaPeriod = newDeltaPeriod; } /** * @dev Allows the Owner to set the new check time. * This function is only for tests. */ function setCheckTime(uint newCheckTime) external override onlyConstantsHolderManager { require(rewardPeriod - deltaPeriod >= checkTime, "Incorrect check time"); emit ConstantUpdated( keccak256(abi.encodePacked("CheckTime")), uint(checkTime), uint(newCheckTime) ); checkTime = newCheckTime; } /** * @dev Allows the Owner to set the allowable latency in milliseconds. * This function is only for testing purposes. */ function setLatency(uint32 newAllowableLatency) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("AllowableLatency")), uint(allowableLatency), uint(newAllowableLatency) ); allowableLatency = newAllowableLatency; } /** * @dev Allows the Owner to set the minimum stake requirement. */ function setMSR(uint newMSR) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("MSR")), uint(msr), uint(newMSR) ); msr = newMSR; } /** * @dev Allows the Owner to set the launch timestamp. */ function setLaunchTimestamp(uint timestamp) external override onlyConstantsHolderManager { require( block.timestamp < launchTimestamp, "Cannot set network launch timestamp because network is already launched" ); emit ConstantUpdated( keccak256(abi.encodePacked("LaunchTimestamp")), uint(launchTimestamp), uint(timestamp) ); launchTimestamp = timestamp; } /** * @dev Allows the Owner to set the node rotation delay. */ function setRotationDelay(uint newDelay) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("RotationDelay")), uint(rotationDelay), uint(newDelay) ); rotationDelay = newDelay; } /** * @dev Allows the Owner to set the proof-of-use lockup period. */ function setProofOfUseLockUpPeriod(uint periodDays) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("ProofOfUseLockUpPeriodDays")), uint(proofOfUseLockUpPeriodDays), uint(periodDays) ); proofOfUseLockUpPeriodDays = periodDays; } /** * @dev Allows the Owner to set the proof-of-use delegation percentage * requirement. */ function setProofOfUseDelegationPercentage(uint percentage) external override onlyConstantsHolderManager { require(percentage <= 100, "Percentage value is incorrect"); emit ConstantUpdated( keccak256(abi.encodePacked("ProofOfUseDelegationPercentage")), uint(proofOfUseDelegationPercentage), uint(percentage) ); proofOfUseDelegationPercentage = percentage; } /** * @dev Allows the Owner to set the maximum number of validators that a * single delegator can delegate to. */ function setLimitValidatorsPerDelegator(uint newLimit) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("LimitValidatorsPerDelegator")), uint(limitValidatorsPerDelegator), uint(newLimit) ); limitValidatorsPerDelegator = newLimit; } function setSchainCreationTimeStamp(uint timestamp) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("SchainCreationTimeStamp")), uint(schainCreationTimeStamp), uint(timestamp) ); schainCreationTimeStamp = timestamp; } function setMinimalSchainLifetime(uint lifetime) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("MinimalSchainLifetime")), uint(minimalSchainLifetime), uint(lifetime) ); minimalSchainLifetime = lifetime; } function setComplaintTimeLimit(uint timeLimit) external override onlyConstantsHolderManager { emit ConstantUpdated( keccak256(abi.encodePacked("ComplaintTimeLimit")), uint(complaintTimeLimit), uint(timeLimit) ); complaintTimeLimit = timeLimit; } function initialize(address contractsAddress) public override initializer { Permissions.initialize(contractsAddress); msr = 0; rewardPeriod = 2592000; allowableLatency = 150000; deltaPeriod = 3600; checkTime = 300; launchTimestamp = type(uint).max; rotationDelay = 12 hours; proofOfUseLockUpPeriodDays = 90; proofOfUseDelegationPercentage = 50; limitValidatorsPerDelegator = 20; firstDelegationsMonth = 0; complaintTimeLimit = 1800; } }
// SPDX-License-Identifier: AGPL-3.0-only /* PartialDifferences.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Dmytro Stebaiev SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity 0.8.11; import "../utils/MathUtils.sol"; import "../utils/FractionUtils.sol"; /** * @title Partial Differences Library * @dev This library contains functions to manage Partial Differences data * structure. Partial Differences is an array of value differences over time. * * For example: assuming an array [3, 6, 3, 1, 2], partial differences can * represent this array as [_, 3, -3, -2, 1]. * * This data structure allows adding values on an open interval with O(1) * complexity. * * For example: add +5 to [3, 6, 3, 1, 2] starting from the second element (3), * instead of performing [3, 6, 3+5, 1+5, 2+5] partial differences allows * performing [_, 3, -3+5, -2, 1]. The original array can be restored by * adding values from partial differences. */ library PartialDifferences { using MathUtils for uint; struct Sequence { // month => diff mapping (uint => uint) addDiff; // month => diff mapping (uint => uint) subtractDiff; // month => value mapping (uint => uint) value; uint firstUnprocessedMonth; uint lastChangedMonth; } struct Value { // month => diff mapping (uint => uint) addDiff; // month => diff mapping (uint => uint) subtractDiff; uint value; uint firstUnprocessedMonth; uint lastChangedMonth; } // functions for sequence function addToSequence(Sequence storage sequence, uint diff, uint month) internal { require(sequence.firstUnprocessedMonth <= month, "Cannot add to the past"); if (sequence.firstUnprocessedMonth == 0) { sequence.firstUnprocessedMonth = month; } sequence.addDiff[month] = sequence.addDiff[month] + diff; if (sequence.lastChangedMonth != month) { sequence.lastChangedMonth = month; } } function subtractFromSequence(Sequence storage sequence, uint diff, uint month) internal { require(sequence.firstUnprocessedMonth <= month, "Cannot subtract from the past"); if (sequence.firstUnprocessedMonth == 0) { sequence.firstUnprocessedMonth = month; } sequence.subtractDiff[month] = sequence.subtractDiff[month] + diff; if (sequence.lastChangedMonth != month) { sequence.lastChangedMonth = month; } } function getAndUpdateValueInSequence(Sequence storage sequence, uint month) internal returns (uint) { if (sequence.firstUnprocessedMonth == 0) { return 0; } if (sequence.firstUnprocessedMonth <= month) { for (uint i = sequence.firstUnprocessedMonth; i <= month; ++i) { uint nextValue = (sequence.value[i - 1] + sequence.addDiff[i]).boundedSub(sequence.subtractDiff[i]); if (sequence.value[i] != nextValue) { sequence.value[i] = nextValue; } if (sequence.addDiff[i] > 0) { delete sequence.addDiff[i]; } if (sequence.subtractDiff[i] > 0) { delete sequence.subtractDiff[i]; } } sequence.firstUnprocessedMonth = month + 1; } return sequence.value[month]; } function reduceSequence( Sequence storage sequence, FractionUtils.Fraction memory reducingCoefficient, uint month) internal { require(month + 1 >= sequence.firstUnprocessedMonth, "Cannot reduce value in the past"); require( reducingCoefficient.numerator <= reducingCoefficient.denominator, "Increasing of values is not implemented"); if (sequence.firstUnprocessedMonth == 0) { return; } uint value = getAndUpdateValueInSequence(sequence, month); if (value.approximatelyEqual(0)) { return; } sequence.value[month] = sequence.value[month] * reducingCoefficient.numerator / reducingCoefficient.denominator; for (uint i = month + 1; i <= sequence.lastChangedMonth; ++i) { sequence.subtractDiff[i] = sequence.subtractDiff[i] * reducingCoefficient.numerator / reducingCoefficient.denominator; } } // functions for value function addToValue(Value storage sequence, uint diff, uint month) internal { require(sequence.firstUnprocessedMonth <= month, "Cannot add to the past"); if (sequence.firstUnprocessedMonth == 0) { sequence.firstUnprocessedMonth = month; sequence.lastChangedMonth = month; } if (month > sequence.lastChangedMonth) { sequence.lastChangedMonth = month; } if (month >= sequence.firstUnprocessedMonth) { sequence.addDiff[month] = sequence.addDiff[month] + diff; } else { sequence.value = sequence.value + diff; } } function subtractFromValue(Value storage sequence, uint diff, uint month) internal { require(sequence.firstUnprocessedMonth <= month + 1, "Cannot subtract from the past"); if (sequence.firstUnprocessedMonth == 0) { sequence.firstUnprocessedMonth = month; sequence.lastChangedMonth = month; } if (month > sequence.lastChangedMonth) { sequence.lastChangedMonth = month; } if (month >= sequence.firstUnprocessedMonth) { sequence.subtractDiff[month] = sequence.subtractDiff[month] + diff; } else { sequence.value = sequence.value.boundedSub(diff); } } function getAndUpdateValue(Value storage sequence, uint month) internal returns (uint) { require( month + 1 >= sequence.firstUnprocessedMonth, "Cannot calculate value in the past"); if (sequence.firstUnprocessedMonth == 0) { return 0; } if (sequence.firstUnprocessedMonth <= month) { uint value = sequence.value; for (uint i = sequence.firstUnprocessedMonth; i <= month; ++i) { value = (value + sequence.addDiff[i]).boundedSub(sequence.subtractDiff[i]); if (sequence.addDiff[i] > 0) { delete sequence.addDiff[i]; } if (sequence.subtractDiff[i] > 0) { delete sequence.subtractDiff[i]; } } if (sequence.value != value) { sequence.value = value; } sequence.firstUnprocessedMonth = month + 1; } return sequence.value; } function reduceValue( Value storage sequence, uint amount, uint month) internal returns (FractionUtils.Fraction memory) { require(month + 1 >= sequence.firstUnprocessedMonth, "Cannot reduce value in the past"); if (sequence.firstUnprocessedMonth == 0) { return FractionUtils.createFraction(0); } uint value = getAndUpdateValue(sequence, month); if (value.approximatelyEqual(0)) { return FractionUtils.createFraction(0); } uint _amount = amount; if (value < amount) { _amount = value; } FractionUtils.Fraction memory reducingCoefficient = FractionUtils.createFraction(value.boundedSub(_amount), value); reduceValueByCoefficient(sequence, reducingCoefficient, month); return reducingCoefficient; } function reduceValueByCoefficient( Value storage sequence, FractionUtils.Fraction memory reducingCoefficient, uint month) internal { reduceValueByCoefficientAndUpdateSumIfNeeded( sequence, sequence, reducingCoefficient, month, false); } function reduceValueByCoefficientAndUpdateSum( Value storage sequence, Value storage sumSequence, FractionUtils.Fraction memory reducingCoefficient, uint month) internal { reduceValueByCoefficientAndUpdateSumIfNeeded( sequence, sumSequence, reducingCoefficient, month, true); } function reduceValueByCoefficientAndUpdateSumIfNeeded( Value storage sequence, Value storage sumSequence, FractionUtils.Fraction memory reducingCoefficient, uint month, bool hasSumSequence) internal { require(month + 1 >= sequence.firstUnprocessedMonth, "Cannot reduce value in the past"); if (hasSumSequence) { require(month + 1 >= sumSequence.firstUnprocessedMonth, "Cannot reduce value in the past"); } require( reducingCoefficient.numerator <= reducingCoefficient.denominator, "Increasing of values is not implemented"); if (sequence.firstUnprocessedMonth == 0) { return; } uint value = getAndUpdateValue(sequence, month); if (value.approximatelyEqual(0)) { return; } uint newValue = sequence.value * reducingCoefficient.numerator / reducingCoefficient.denominator; if (hasSumSequence) { subtractFromValue(sumSequence, sequence.value.boundedSub(newValue), month); } sequence.value = newValue; for (uint i = month + 1; i <= sequence.lastChangedMonth; ++i) { uint newDiff = sequence.subtractDiff[i] * reducingCoefficient.numerator / reducingCoefficient.denominator; if (hasSumSequence) { sumSequence.subtractDiff[i] = sumSequence.subtractDiff[i] .boundedSub(sequence.subtractDiff[i].boundedSub(newDiff)); } sequence.subtractDiff[i] = newDiff; } } function getValueInSequence(Sequence storage sequence, uint month) internal view returns (uint) { if (sequence.firstUnprocessedMonth == 0) { return 0; } if (sequence.firstUnprocessedMonth <= month) { uint value = sequence.value[sequence.firstUnprocessedMonth - 1]; for (uint i = sequence.firstUnprocessedMonth; i <= month; ++i) { value = value + sequence.addDiff[i] - sequence.subtractDiff[i]; } return value; } else { return sequence.value[month]; } } function getValuesInSequence(Sequence storage sequence) internal view returns (uint[] memory values) { if (sequence.firstUnprocessedMonth == 0) { return values; } uint begin = sequence.firstUnprocessedMonth - 1; uint end = sequence.lastChangedMonth + 1; if (end <= begin) { end = begin + 1; } values = new uint[](end - begin); values[0] = sequence.value[sequence.firstUnprocessedMonth - 1]; for (uint i = 0; i + 1 < values.length; ++i) { uint month = sequence.firstUnprocessedMonth + i; values[i + 1] = values[i] + sequence.addDiff[month] - sequence.subtractDiff[month]; } } function getValue(Value storage sequence, uint month) internal view returns (uint) { require( month + 1 >= sequence.firstUnprocessedMonth, "Cannot calculate value in the past"); if (sequence.firstUnprocessedMonth == 0) { return 0; } if (sequence.firstUnprocessedMonth <= month) { uint value = sequence.value; for (uint i = sequence.firstUnprocessedMonth; i <= month; ++i) { value = value + sequence.addDiff[i] - sequence.subtractDiff[i]; } return value; } else { return sequence.value; } } function getValues(Value storage sequence) internal view returns (uint[] memory values) { if (sequence.firstUnprocessedMonth == 0) { return values; } uint begin = sequence.firstUnprocessedMonth - 1; uint end = sequence.lastChangedMonth + 1; if (end <= begin) { end = begin + 1; } values = new uint[](end - begin); values[0] = sequence.value; for (uint i = 0; i + 1 < values.length; ++i) { uint month = sequence.firstUnprocessedMonth + i; values[i + 1] = values[i] + sequence.addDiff[month] - sequence.subtractDiff[month]; } } }
// SPDX-License-Identifier: AGPL-3.0-only /* IRandom.sol - SKALE Manager Interfaces Copyright (C) 2022-Present SKALE Labs @author Dmytro Stebaiev SKALE Manager Interfaces is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager Interfaces is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager Interfaces. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IRandom { struct RandomGenerator { uint seed; } }
// SPDX-License-Identifier: AGPL-3.0-only /* IContractManager.sol - SKALE Manager Interfaces Copyright (C) 2021-Present SKALE Labs @author Dmytro Stebaeiv SKALE Manager Interfaces is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager Interfaces is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager Interfaces. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IContractManager { /** * @dev Emitted when contract is upgraded. */ event ContractUpgraded(string contractsName, address contractsAddress); function initialize() external; function setContractsAddress(string calldata contractsName, address newContractsAddress) external; function contracts(bytes32 nameHash) external view returns (address); function getDelegationPeriodManager() external view returns (address); function getBounty() external view returns (address); function getValidatorService() external view returns (address); function getTimeHelpers() external view returns (address); function getConstantsHolder() external view returns (address); function getSkaleToken() external view returns (address); function getTokenState() external view returns (address); function getPunisher() external view returns (address); function getContract(string calldata name) external view returns (address); }
// SPDX-License-Identifier: AGPL-3.0-only /* IPermissions.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IPermissions { function initialize(address contractManagerAddress) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.7; import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@skalenetwork/skale-manager-interfaces/thirdparty/openzeppelin/IAccessControlUpgradeableLegacy.sol"; import "./InitializableWithGap.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, _msgSender())); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. */ abstract contract AccessControlUpgradeableLegacy is InitializableWithGap, ContextUpgradeable, IAccessControlUpgradeableLegacy { function __AccessControl_init() internal initializer { __Context_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; struct RoleData { EnumerableSetUpgradeable.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view override returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view override returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-only /* IAccessControlUpgradeableLegacy.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Artem Payvin SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IAccessControlUpgradeableLegacy { /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); function grantRole(bytes32 role, address account) external; function revokeRole(bytes32 role, address account) external; function renounceRole(bytes32 role, address account) external; function hasRole(bytes32 role, address account) external view returns (bool); function getRoleMemberCount(bytes32 role) external view returns (uint256); function getRoleMember(bytes32 role, uint256 index) external view returns (address); function getRoleAdmin(bytes32 role) external view returns (bytes32); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.7; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; contract InitializableWithGap is Initializable { uint256[50] private ______gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: AGPL-3.0-only /* IConstantsHolder.sol - SKALE Manager Interfaces Copyright (C) 2021-Present SKALE Labs @author Artem Payvin SKALE Manager Interfaces is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager Interfaces is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager Interfaces. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.6.10 <0.9.0; interface IConstantsHolder { /** * @dev Emitted when constants updated. */ event ConstantUpdated( bytes32 indexed constantHash, uint previousValue, uint newValue ); function setPeriods(uint32 newRewardPeriod, uint32 newDeltaPeriod) external; function setCheckTime(uint newCheckTime) external; function setLatency(uint32 newAllowableLatency) external; function setMSR(uint newMSR) external; function setLaunchTimestamp(uint timestamp) external; function setRotationDelay(uint newDelay) external; function setProofOfUseLockUpPeriod(uint periodDays) external; function setProofOfUseDelegationPercentage(uint percentage) external; function setLimitValidatorsPerDelegator(uint newLimit) external; function setSchainCreationTimeStamp(uint timestamp) external; function setMinimalSchainLifetime(uint lifetime) external; function setComplaintTimeLimit(uint timeLimit) external; function msr() external view returns (uint); function launchTimestamp() external view returns (uint); function rotationDelay() external view returns (uint); function limitValidatorsPerDelegator() external view returns (uint); function schainCreationTimeStamp() external view returns (uint); function minimalSchainLifetime() external view returns (uint); function complaintTimeLimit() external view returns (uint); }
// SPDX-License-Identifier: AGPL-3.0-only /* MathUtils.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Dmytro Stebaiev SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity 0.8.11; library MathUtils { uint constant private _EPS = 1e6; event UnderflowError( uint a, uint b ); function boundedSub(uint256 a, uint256 b) internal returns (uint256) { if (a >= b) { return a - b; } else { emit UnderflowError(a, b); return 0; } } function boundedSubWithoutEvent(uint256 a, uint256 b) internal pure returns (uint256) { if (a >= b) { return a - b; } else { return 0; } } function muchGreater(uint256 a, uint256 b) internal pure returns (bool) { assert(type(uint).max - _EPS > b); return a > b + _EPS; } function approximatelyEqual(uint256 a, uint256 b) internal pure returns (bool) { if (a > b) { return a - b < _EPS; } else { return b - a < _EPS; } } }
// SPDX-License-Identifier: AGPL-3.0-only /* FractionUtils.sol - SKALE Manager Copyright (C) 2018-Present SKALE Labs @author Dmytro Stebaiev SKALE Manager is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. SKALE Manager is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with SKALE Manager. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity 0.8.11; library FractionUtils { struct Fraction { uint numerator; uint denominator; } function createFraction(uint numerator, uint denominator) internal pure returns (Fraction memory) { require(denominator > 0, "Division by zero"); Fraction memory fraction = Fraction({numerator: numerator, denominator: denominator}); reduceFraction(fraction); return fraction; } function createFraction(uint value) internal pure returns (Fraction memory) { return createFraction(value, 1); } function reduceFraction(Fraction memory fraction) internal pure { uint _gcd = gcd(fraction.numerator, fraction.denominator); fraction.numerator = fraction.numerator / _gcd; fraction.denominator = fraction.denominator / _gcd; } // numerator - is limited by 7*10^27, we could multiply it numerator * numerator - it would less than 2^256-1 function multiplyFraction(Fraction memory a, Fraction memory b) internal pure returns (Fraction memory) { return createFraction(a.numerator * b.numerator, a.denominator * b.denominator); } function gcd(uint a, uint b) internal pure returns (uint) { uint _a = a; uint _b = b; if (_b > _a) { (_a, _b) = swap(_a, _b); } while (_b > 0) { _a = _a % _b; (_a, _b) = swap (_a, _b); } return _a; } function swap(uint a, uint b) internal pure returns (uint, uint) { return (b, a); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"BountyReduction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"NodeCreationWindowWasChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"BOUNTY_REDUCTION_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BOUNTY_WINDOW_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EPOCHS_PER_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_PER_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR1_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR2_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR3_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR4_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR5_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR6_BOUNTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bountyReduction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nodeIndex","type":"uint256"}],"name":"calculateBounty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractManager","outputs":[{"internalType":"contract IContractManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableBountyReduction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableBountyReduction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nodeIndex","type":"uint256"}],"name":"estimateBounty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEffectiveDelegatedSum","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nodeIndex","type":"uint256"}],"name":"getNextRewardTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"}],"name":"handleDelegationAdd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"month","type":"uint256"}],"name":"handleDelegationRemoving","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractManagerAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nodeCreationWindowSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nodesByValidator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"window","type":"uint256"}],"name":"setNodeCreationWindowSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613134806100206000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c8063775bc5251161010f578063b39e12cf116100a2578063c9e0706c11610071578063c9e0706c14610431578063ca15c87314610439578063d547741f1461044c578063e68d5f631461045f57600080fd5b8063b39e12cf146103f0578063beb4cb8614610403578063c20e9c211461040b578063c4d66de81461041e57600080fd5b80639df57f7f116100de5780639df57f7f146103bb578063a217fddf146103cd578063a43d8437146103d5578063b11eec50146103e857600080fd5b8063775bc5251461034a5780639010d07c1461036a57806391d14854146103955780639da69ccf146103a857600080fd5b80635a4adb6811610187578063663f70c311610156578063663f70c3146102fd5780636ad5a9cf1461031057806371e142951461032357806374f0314f1461034057600080fd5b80635a4adb68146102b05780635b8d992b146102c357806362c59ad4146102d857806365e9b20e146102eb57600080fd5b80632c3636d3116101c35780632c3636d3146102795780632e233788146102815780632f2ff15d1461028a57806336568abe1461029d57600080fd5b8063022d2623146101f557806304ebc43b1461020a5780630676484014610244578063248a9ca314610256575b600080fd5b610208610203366004612c33565b610471565b005b6102317fb4dfa5f0aba688c4e234bff5d34d47655ba3ad7086852346991862f4d562194d81565b6040519081526020015b60405180910390f35b6102316abf1427179aea6c4700000081565b610231610264366004612c33565b60009081526065602052604090206002015490565b61020861057f565b610231609c5481565b610208610298366004612c61565b61060b565b6102086102ab366004612c61565b610699565b6102086102be366004612c91565b610713565b6102cb6107f6565b60405161023b9190612cb3565b6102316102e6366004612c33565b610807565b6102316a9f3b75e90118af9080000081565b61023161030b366004612c33565b610c2c565b61020861031e366004612c91565b6111c5565b609b546103309060ff1681565b604051901515815260200161023b565b6102316201518081565b610231610358366004612c33565b60a26020526000908152604090205481565b61037d610378366004612c91565b6112a3565b6040516001600160a01b03909116815260200161023b565b6103306103a3366004612c61565b6112c4565b6102316b013e76ebd202315f2100000081565b6102316adeecd84634bc28fd80000081565b610231600081565b6102316103e3366004612c33565b6112dc565b6102316113c6565b60975461037d906001600160a01b031681565b6102086113d7565b6102316b011e9e3aa3685fa26a80000081565b61020861042c366004612cf7565b611458565b610231600c81565b610231610447366004612c33565b6114fd565b61020861045a366004612c61565b611514565b6102316afec58974ce8de5b400000081565b60408051808201825260058152644e6f64657360d81b60208201526097549151633581777360e01b8152909133916001600160a01b03909116906335817773906104bf908590600401612d14565b602060405180830381865afa1580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105009190612d69565b6001600160a01b031614806105185750610518611595565b61053d5760405162461bcd60e51b815260040161053490612d86565b60405180910390fd5b609c5460408051918252602082018490527fa910e8c03ed572b836d2e10cc366bc78f33a5167896a7f06a213fbb24ebb0a25910160405180910390a150609c55565b6105a97fb4dfa5f0aba688c4e234bff5d34d47655ba3ad7086852346991862f4d562194d336112c4565b6105c55760405162461bcd60e51b815260040161053490612dbd565b609b805460ff191660019081179091556040519081527f33ad725ac6f2240b9caa447aa8f4f83708ce0fc916485166bf6ea932b6ccca12906020015b60405180910390a1565b60008281526065602052604090206002015461062790336112c4565b61068b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526e0818591b5a5b881d1bc819dc985b9d608a1b6064820152608401610534565b61069582826115a1565b5050565b6001600160a01b03811633146107095760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610534565b61069582826115fa565b60408051808201825260148152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60208201526097549151633581777360e01b8152909133916001600160a01b0390911690633581777390610770908590600401612d14565b602060405180830381865afa15801561078d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b19190612d69565b6001600160a01b031614806107c957506107c9611595565b6107e55760405162461bcd60e51b815260040161053490612d86565b6107f1609d8484611653565b505050565b6060610802609d611733565b905090565b609754604051633581777360e01b815260206004820152600f60248201526e21b7b739ba30b73a39a437b63232b960891b604482015260009182916001600160a01b0390911690633581777390606401602060405180830381865afa158015610874573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108989190612d69565b609754604051633581777360e01b81529192506000916001600160a01b03909116906335817773906108cc90600401612e06565b602060405180830381865afa1580156108e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090d9190612d69565b609754604051633581777360e01b81529192506000916001600160a01b039091169063358177739061094190600401612e25565b602060405180830381865afa15801561095e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109829190612d69565b609754604051633581777360e01b81526020600482015260146024820152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60448201529192506000916001600160a01b0390911690633581777390606401602060405180830381865afa1580156109f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a199190612d69565b90506000826001600160a01b031663ddd1b67e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7f9190612e4a565b6040516310454ac560e31b8152600481018990529091506000906001600160a01b0386169063822a562890602401602060405180830381865afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190612e4a565b90506000610afd8386896118b1565b509050610c1f81610b0f609d866118ee565b610b1a866001612e79565b60985414610b29576000610b2d565b609a545b8c610b3887896119a2565b6040516311f4d6a360e31b815260048101899052602481018a90526001600160a01b038b1690638fa6b51890604401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba89190612e4a565b604051632dd8922360e11b8152600481018a9052602481018b90526001600160a01b038c1690635bb1244690604401602060405180830381865afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c189190612e4a565b8e8e611a2e565b9998505050505050505050565b604080518082018252600c81526b29b5b0b632a6b0b730b3b2b960a11b60208201526097549151633581777360e01b815260009233916001600160a01b0390911690633581777390610c82908590600401612d14565b602060405180830381865afa158015610c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc39190612d69565b6001600160a01b03161480610cdb5750610cdb611595565b610cf75760405162461bcd60e51b815260040161053490612d86565b609754604051633581777360e01b815260206004820152600f60248201526e21b7b739ba30b73a39a437b63232b960891b60448201526000916001600160a01b031690633581777390606401602060405180830381865afa158015610d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d849190612d69565b609754604051633581777360e01b81529192506000916001600160a01b0390911690633581777390610db890600401612e06565b602060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df99190612d69565b609754604051633581777360e01b81529192506000916001600160a01b0390911690633581777390610e2d90600401612e25565b602060405180830381865afa158015610e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e9190612d69565b609754604051633581777360e01b81526020600482015260146024820152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60448201529192506000916001600160a01b0390911690633581777390606401602060405180830381865afa158015610ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f059190612d69565b905042610f13888585611c25565b1115610f615760405162461bcd60e51b815260206004820152601d60248201527f5472616e73616374696f6e2069732073656e7420746f6f206561726c790000006044820152606401610534565b6040516310454ac560e31b8152600481018890526000906001600160a01b0385169063822a562890602401602060405180830381865afa158015610fa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcd9190612e4a565b600081815260a2602052604090205490915015610ff457600081815260a260205260408120555b6000836001600160a01b031663ddd1b67e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611034573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110589190612e4a565b9050611065818588612100565b61106f8282612134565b60995460009061115690611084609d85612161565b609a54600087815260a3602052604090819020600101549051630416880b60e41b815260048101899052602481018890528f91906001600160a01b038b169063416880b0906044016020604051808303816000875af11580156110eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110f9190612e4a565b604051630eb81c0960e11b8152600481018b90526001600160a01b038c1690631d703812906024016020604051808303816000875af1158015610bf4573d6000803e3d6000fd5b600084815260a36020526040902060010154909150611176908290612e79565b600084815260a36020526040902060010155611194818b888a61227f565b9050806099546111a49190612e91565b609955609a546111b5908290612e79565b609a559998505050505050505050565b60408051808201825260148152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60208201526097549151633581777360e01b8152909133916001600160a01b0390911690633581777390611222908590600401612d14565b602060405180830381865afa15801561123f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112639190612d69565b6001600160a01b0316148061127b575061127b611595565b6112975760405162461bcd60e51b815260040161053490612d86565b6107f1609d84846123ec565b60008281526065602052604081206112bb90836124ae565b90505b92915050565b60008281526065602052604081206112bb90836124ba565b609754604051633581777360e01b81526000916112be9184916001600160a01b03169063358177739061131190600401612e06565b602060405180830381865afa15801561132e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113529190612d69565b609754604051633581777360e01b81526001600160a01b039091169063358177739061138090600401612e25565b602060405180830381865afa15801561139d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c19190612d69565b611c25565b6113d4620151806003612ea8565b81565b6114017fb4dfa5f0aba688c4e234bff5d34d47655ba3ad7086852346991862f4d562194d336112c4565b61141d5760405162461bcd60e51b815260040161053490612dbd565b609b805460ff19169055604051600081527f33ad725ac6f2240b9caa447aa8f4f83708ce0fc916485166bf6ea932b6ccca1290602001610601565b600054610100900460ff166114735760005460ff1615611477565b303b155b6114935760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff161580156114b5576000805461ffff19166101011790555b6114be826124dc565b600060988190556099819055609a55609b805460ff191690556114e5620151806003612ea8565b609c558015610695576000805461ff00191690555050565b60008181526065602052604081206112be9061256a565b60008281526065602052604090206002015461153090336112c4565b6107095760405162461bcd60e51b815260206004820152603060248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526f2061646d696e20746f207265766f6b6560801b6064820152608401610534565b600061080281336112c4565b60008281526065602052604090206115b99082612574565b156106955760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60008281526065602052604090206116129082612589565b156106955760405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b61165e816001612e79565b836003015411156116b15760405162461bcd60e51b815260206004820152601d60248201527f43616e6e6f742073756274726163742066726f6d2074686520706173740000006044820152606401610534565b60038301546116c95760038301819055600483018190555b82600401548111156116dd57600483018190555b8260030154811061171a576000818152600184016020526040902054611704908390612e79565b6000828152600185016020526040902055505050565b6002830154611729908361259e565b6002840155505050565b606081600301546000141561174757919050565b60006001836003015461175a9190612e91565b905060008360040154600161176f9190612e79565b905081811161178657611783826001612e79565b90505b6117908282612e91565b67ffffffffffffffff8111156117a8576117a8612f15565b6040519080825280602002602001820160405280156117d1578160200160208202803683370190505b5092508360020154836000815181106117ec576117ec612f2b565b60200260200101818152505060005b8351611808826001612e79565b10156118a95760008186600301546118209190612e79565b6000818152600188016020908152604080832054918a9052909120548751929350909187908590811061185557611855612f2b565b60200260200101516118679190612e79565b6118719190612e91565b8561187d846001612e79565b8151811061188d5761188d612f2b565b6020908102919091010152506118a281612f41565b90506117fb565b505050919050565b6099546098545b8481116118e6576118ca8185856125f9565b6118d49083612e79565b91506118df81612f41565b90506118b8565b935093915050565b6003820154600090611901836001612e79565b101561191f5760405162461bcd60e51b815260040161053490612f5c565b6003830154611930575060006112be565b8183600301541161199757600283015460038401545b83811161198f57600081815260018601602090815260408083205491889052909120546119739084612e79565b61197d9190612e91565b915061198881612f41565b9050611946565b5090506112be565b5060028201546112be565b600082815260a360205260408120548210156119f85760405162461bcd60e51b815260206004820152601560248201527410d85b89dd0819d95d08189bdd5b9d1e481c185a59605a1b6044820152606401610534565b600083815260a36020526040902054821415611a265750600082815260a360205260409020600101546112be565b5060006112be565b604051639bcd952160e01b8152600481018790526000906001600160a01b03831690639bcd952190602401602060405180830381865afa158015611a76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9a9190612f9e565b15611aa757506000610c1f565b826001600160a01b03166365cf7c9b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ae5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b099190612e4a565b421015611b1857506000610c1f565b88611b2557506000610c1f565b826001600160a01b031663ed089aa76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b879190612e4a565b611b9357506000610c1f565b6000611c16611ba28a8d612e79565b878c876001600160a01b031663ed089aa76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611be2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c069190612e4a565b611c10908a612fc0565b8b612747565b9b9a5050505050505050505050565b604051631924374d60e31b81526004810184905260009081906001600160a01b0385169063c921ba6890602401602060405180830381865afa158015611c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c939190612e4a565b60405163bf64d84960e01b8152600481018290529091506000906001600160a01b0385169063bf64d84990602401602060405180830381865afa158015611cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d029190612e4a565b604051632b45aad960e11b8152600481018290529091506000906001600160a01b0386169063568b55b290602401602060405180830381865afa158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d719190612e4a565b90506000611d7f8285612e91565b90506000866001600160a01b031663ddd1b67e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de59190612e4a565b905080841115611df757611df7612fe2565b80841415611f5e5760006001600160a01b03881663568b55b2611e1b846001612e79565b6040518263ffffffff1660e01b8152600401611e3991815260200190565b602060405180830381865afa158015611e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7a9190612e4a565b905060006001600160a01b03891663568b55b2611e98886002612e79565b6040518263ffffffff1660e01b8152600401611eb691815260200190565b602060405180830381865afa158015611ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef79190612e4a565b9050609c5485611f079190612e79565b871015611f3457611f1c620151806003612ea8565b611f269083612e91565b9750505050505050506120f9565b611f26611f418584612e79565b611f4f620151806003612ea8565b611f599084612e91565b612794565b80611f6a856001612e79565b141561207457604051632b45aad960e11b8152600481018290526000906001600160a01b0389169063568b55b290602401602060405180830381865afa158015611fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fdc9190612e4a565b905060006001600160a01b03891663568b55b2611ffa856001612e79565b6040518263ffffffff1660e01b815260040161201891815260200190565b602060405180830381865afa158015612035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120599190612e4a565b9050611f2661206a85609c546127ac565b611f419084612e79565b604051632b45aad960e11b8152600481018290526000906001600160a01b0389169063568b55b290602401602060405180830381865afa1580156120bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e09190612e4a565b9050609c54816120f09190612e79565b96505050505050505b9392505050565b60008061210e8585856118b1565b609854919350915081111561212d57609881905560998290556000609a555b5050505050565b600082815260a3602052604090205481111561069557600091825260a36020526040822090815560010155565b6003820154600090612174836001612e79565b10156121925760405162461bcd60e51b815260040161053490612f5c565b60038301546121a3575060006112be565b8183600301541161227657600283015460038401545b83811161225057600081815260018601602090815260408083205491889052909120546121f191906121eb9085612e79565b9061259e565b60008281526020879052604090205490925015612218576000818152602086905260408120555b6000818152600186016020526040902054156122405760008181526001860160205260408120555b61224981612f41565b90506121b9565b508084600201541461226457600284018190555b61226f836001612e79565b6003850155505b50506002015490565b609b5460009060ff166122935750836123e4565b506040516310454ac560e31b81526004810184905284906001600160a01b0384169063c9e91c6690829063822a562890602401602060405180830381865afa1580156122e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123079190612e4a565b866040518363ffffffff1660e01b815260040161232e929190918252602082015260400190565b6020604051808303816000875af115801561234d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123719190612f9e565b6123e457816001600160a01b031663d9dd800d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d79190612e4a565b6123e19082612fc0565b90505b949350505050565b80836003015411156124395760405162461bcd60e51b815260206004820152601660248201527510d85b9b9bdd08185919081d1bc81d1a19481c185cdd60521b6044820152606401610534565b60038301546124515760038301819055600483018190555b826004015481111561246557600483018190555b8260030154811061249e5760008181526020849052604090205461248a908390612e79565b600082815260208590526040902055505050565b8183600201546117299190612e79565b60006112bb83836127c4565b6001600160a01b038116600090815260018301602052604081205415156112bb565b600054610100900460ff166124f75760005460ff16156124fb565b303b155b6125175760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff16158015612539576000805461ffff19166101011790555b6125416127ee565b61254c60003361068b565b61255582612870565b8015610695576000805461ff00191690555050565b60006112be825490565b60006112bb836001600160a01b03841661294a565b60006112bb836001600160a01b038416612991565b60008183106125b8576125b18284612e91565b90506112be565b60408051848152602081018490527f5b70a077a991facb623c7b2ee44cc539dc6ba345b6636552b8ea97fbbd4d5419910160405180910390a15060006112be565b6000806126068484612a84565b90508085101561261a5760009150506120f9565b60006126268287612e91565b90506000612635600c83612fc0565b9050600681106126b3576000600361264e600684612e91565b6126589190612fc0565b612663906001612e79565b90506101008110156126a657600c61267c8260026130dc565b612691906a9f3b75e90118af90800000612fc0565b61269b9190612fc0565b9450505050506120f9565b60009450505050506120f9565b6040805160c0810182526b013e76ebd202315f2100000081526b011e9e3aa3685fa26a80000060208201526afec58974ce8de5b4000000918101919091526adeecd84634bc28fd80000060608201526abf1427179aea6c4700000060808201526a9f3b75e90118af9080000060a0820152600c81836006811061273857612738612f2b565b602002015161269b9190612fc0565b600082156127875760008461275c8789612ea8565b6127669190612fc0565b905061277f6127758583612fc0565b611f598584612e91565b91505061278b565b5060005b95945050505050565b6000818310156127a55750816112be565b50806112be565b6000818310156127bd5750806112be565b50816112be565b60008260000182815481106127db576127db612f2b565b9060005260206000200154905092915050565b600054610100900460ff166128095760005460ff161561280d565b303b155b6128295760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff1615801561284b576000805461ffff19166101011790555b612853612b56565b61285b612bc3565b801561286d576000805461ff00191690555b50565b6001600160a01b0381166128d15760405162461bcd60e51b815260206004820152602260248201527f436f6e74726163744d616e616765722061646472657373206973206e6f742073604482015261195d60f21b6064820152608401610534565b6001600160a01b0381163b6129285760405162461bcd60e51b815260206004820152601760248201527f41646472657373206973206e6f7420636f6e74726163740000000000000000006044820152606401610534565b609780546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600183016020526040812054611a26575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112be565b60008181526001830160205260408120548015612a7a5760006129b5600183612e91565b85549091506000906129c990600190612e91565b9050818114612a2e5760008660000182815481106129e9576129e9612f2b565b9060005260206000200154905080876000018481548110612a0c57612a0c612f2b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a3f57612a3f6130e8565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112be565b60009150506112be565b6000826001600160a01b031663bf64d849836001600160a01b03166365cf7c9b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af79190612e4a565b6040518263ffffffff1660e01b8152600401612b1591815260200190565b602060405180830381865afa158015612b32573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190612e4a565b600054610100900460ff16612bc15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610534565b565b600054610100900460ff16612bde5760005460ff1615612be2565b303b155b612bfe5760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff1615801561285b576000805461ffff1916610101179055801561286d576000805461ff001916905550565b600060208284031215612c4557600080fd5b5035919050565b6001600160a01b038116811461286d57600080fd5b60008060408385031215612c7457600080fd5b823591506020830135612c8681612c4c565b809150509250929050565b60008060408385031215612ca457600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015612ceb57835183529284019291840191600101612ccf565b50909695505050505050565b600060208284031215612d0957600080fd5b81356120f981612c4c565b600060208083528351808285015260005b81811015612d4157858101830151858201604001528201612d25565b81811115612d53576000604083870101525b50601f01601f1916929092016040019392505050565b600060208284031215612d7b57600080fd5b81516120f981612c4c565b60208082526019908201527f4d6573736167652073656e64657220697320696e76616c696400000000000000604082015260600190565b60208082526029908201527f424f554e54595f524544554354494f4e5f4d414e414745525f524f4c45206973604082015268081c995c5d5a5c995960ba1b606082015260800190565b6020808252600590820152644e6f64657360d81b604082015260600190565b6020808252600b908201526a54696d6548656c7065727360a81b604082015260600190565b600060208284031215612e5c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115612e8c57612e8c612e63565b500190565b600082821015612ea357612ea3612e63565b500390565b6000816000190483118215151615612ec257612ec2612e63565b500290565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000600019821415612f5557612f55612e63565b5060010190565b60208082526022908201527f43616e6e6f742063616c63756c6174652076616c756520696e207468652070616040820152611cdd60f21b606082015260800190565b600060208284031215612fb057600080fd5b815180151581146120f957600080fd5b600082612fdd57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052600160045260246000fd5b600181815b8085111561303357816000190482111561301957613019612e63565b8085161561302657918102915b93841c9390800290612ffd565b509250929050565b60008261304a575060016112be565b81613057575060006112be565b816001811461306d576002811461307757613093565b60019150506112be565b60ff84111561308857613088612e63565b50506001821b6112be565b5060208310610133831016604e8410600b84101617156130b6575081810a6112be565b6130c08383612ff8565b80600019048211156130d4576130d4612e63565b029392505050565b60006112bb838361303b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a7e59f69048fe7e736bf828dd1a8ce956d67fa396202eb024c03b2465cad408f64736f6c634300080b0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c8063775bc5251161010f578063b39e12cf116100a2578063c9e0706c11610071578063c9e0706c14610431578063ca15c87314610439578063d547741f1461044c578063e68d5f631461045f57600080fd5b8063b39e12cf146103f0578063beb4cb8614610403578063c20e9c211461040b578063c4d66de81461041e57600080fd5b80639df57f7f116100de5780639df57f7f146103bb578063a217fddf146103cd578063a43d8437146103d5578063b11eec50146103e857600080fd5b8063775bc5251461034a5780639010d07c1461036a57806391d14854146103955780639da69ccf146103a857600080fd5b80635a4adb6811610187578063663f70c311610156578063663f70c3146102fd5780636ad5a9cf1461031057806371e142951461032357806374f0314f1461034057600080fd5b80635a4adb68146102b05780635b8d992b146102c357806362c59ad4146102d857806365e9b20e146102eb57600080fd5b80632c3636d3116101c35780632c3636d3146102795780632e233788146102815780632f2ff15d1461028a57806336568abe1461029d57600080fd5b8063022d2623146101f557806304ebc43b1461020a5780630676484014610244578063248a9ca314610256575b600080fd5b610208610203366004612c33565b610471565b005b6102317fb4dfa5f0aba688c4e234bff5d34d47655ba3ad7086852346991862f4d562194d81565b6040519081526020015b60405180910390f35b6102316abf1427179aea6c4700000081565b610231610264366004612c33565b60009081526065602052604090206002015490565b61020861057f565b610231609c5481565b610208610298366004612c61565b61060b565b6102086102ab366004612c61565b610699565b6102086102be366004612c91565b610713565b6102cb6107f6565b60405161023b9190612cb3565b6102316102e6366004612c33565b610807565b6102316a9f3b75e90118af9080000081565b61023161030b366004612c33565b610c2c565b61020861031e366004612c91565b6111c5565b609b546103309060ff1681565b604051901515815260200161023b565b6102316201518081565b610231610358366004612c33565b60a26020526000908152604090205481565b61037d610378366004612c91565b6112a3565b6040516001600160a01b03909116815260200161023b565b6103306103a3366004612c61565b6112c4565b6102316b013e76ebd202315f2100000081565b6102316adeecd84634bc28fd80000081565b610231600081565b6102316103e3366004612c33565b6112dc565b6102316113c6565b60975461037d906001600160a01b031681565b6102086113d7565b6102316b011e9e3aa3685fa26a80000081565b61020861042c366004612cf7565b611458565b610231600c81565b610231610447366004612c33565b6114fd565b61020861045a366004612c61565b611514565b6102316afec58974ce8de5b400000081565b60408051808201825260058152644e6f64657360d81b60208201526097549151633581777360e01b8152909133916001600160a01b03909116906335817773906104bf908590600401612d14565b602060405180830381865afa1580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105009190612d69565b6001600160a01b031614806105185750610518611595565b61053d5760405162461bcd60e51b815260040161053490612d86565b60405180910390fd5b609c5460408051918252602082018490527fa910e8c03ed572b836d2e10cc366bc78f33a5167896a7f06a213fbb24ebb0a25910160405180910390a150609c55565b6105a97fb4dfa5f0aba688c4e234bff5d34d47655ba3ad7086852346991862f4d562194d336112c4565b6105c55760405162461bcd60e51b815260040161053490612dbd565b609b805460ff191660019081179091556040519081527f33ad725ac6f2240b9caa447aa8f4f83708ce0fc916485166bf6ea932b6ccca12906020015b60405180910390a1565b60008281526065602052604090206002015461062790336112c4565b61068b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526e0818591b5a5b881d1bc819dc985b9d608a1b6064820152608401610534565b61069582826115a1565b5050565b6001600160a01b03811633146107095760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610534565b61069582826115fa565b60408051808201825260148152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60208201526097549151633581777360e01b8152909133916001600160a01b0390911690633581777390610770908590600401612d14565b602060405180830381865afa15801561078d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b19190612d69565b6001600160a01b031614806107c957506107c9611595565b6107e55760405162461bcd60e51b815260040161053490612d86565b6107f1609d8484611653565b505050565b6060610802609d611733565b905090565b609754604051633581777360e01b815260206004820152600f60248201526e21b7b739ba30b73a39a437b63232b960891b604482015260009182916001600160a01b0390911690633581777390606401602060405180830381865afa158015610874573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108989190612d69565b609754604051633581777360e01b81529192506000916001600160a01b03909116906335817773906108cc90600401612e06565b602060405180830381865afa1580156108e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090d9190612d69565b609754604051633581777360e01b81529192506000916001600160a01b039091169063358177739061094190600401612e25565b602060405180830381865afa15801561095e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109829190612d69565b609754604051633581777360e01b81526020600482015260146024820152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60448201529192506000916001600160a01b0390911690633581777390606401602060405180830381865afa1580156109f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a199190612d69565b90506000826001600160a01b031663ddd1b67e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7f9190612e4a565b6040516310454ac560e31b8152600481018990529091506000906001600160a01b0386169063822a562890602401602060405180830381865afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190612e4a565b90506000610afd8386896118b1565b509050610c1f81610b0f609d866118ee565b610b1a866001612e79565b60985414610b29576000610b2d565b609a545b8c610b3887896119a2565b6040516311f4d6a360e31b815260048101899052602481018a90526001600160a01b038b1690638fa6b51890604401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba89190612e4a565b604051632dd8922360e11b8152600481018a9052602481018b90526001600160a01b038c1690635bb1244690604401602060405180830381865afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c189190612e4a565b8e8e611a2e565b9998505050505050505050565b604080518082018252600c81526b29b5b0b632a6b0b730b3b2b960a11b60208201526097549151633581777360e01b815260009233916001600160a01b0390911690633581777390610c82908590600401612d14565b602060405180830381865afa158015610c9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc39190612d69565b6001600160a01b03161480610cdb5750610cdb611595565b610cf75760405162461bcd60e51b815260040161053490612d86565b609754604051633581777360e01b815260206004820152600f60248201526e21b7b739ba30b73a39a437b63232b960891b60448201526000916001600160a01b031690633581777390606401602060405180830381865afa158015610d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d849190612d69565b609754604051633581777360e01b81529192506000916001600160a01b0390911690633581777390610db890600401612e06565b602060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df99190612d69565b609754604051633581777360e01b81529192506000916001600160a01b0390911690633581777390610e2d90600401612e25565b602060405180830381865afa158015610e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e9190612d69565b609754604051633581777360e01b81526020600482015260146024820152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60448201529192506000916001600160a01b0390911690633581777390606401602060405180830381865afa158015610ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f059190612d69565b905042610f13888585611c25565b1115610f615760405162461bcd60e51b815260206004820152601d60248201527f5472616e73616374696f6e2069732073656e7420746f6f206561726c790000006044820152606401610534565b6040516310454ac560e31b8152600481018890526000906001600160a01b0385169063822a562890602401602060405180830381865afa158015610fa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcd9190612e4a565b600081815260a2602052604090205490915015610ff457600081815260a260205260408120555b6000836001600160a01b031663ddd1b67e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611034573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110589190612e4a565b9050611065818588612100565b61106f8282612134565b60995460009061115690611084609d85612161565b609a54600087815260a3602052604090819020600101549051630416880b60e41b815260048101899052602481018890528f91906001600160a01b038b169063416880b0906044016020604051808303816000875af11580156110eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110f9190612e4a565b604051630eb81c0960e11b8152600481018b90526001600160a01b038c1690631d703812906024016020604051808303816000875af1158015610bf4573d6000803e3d6000fd5b600084815260a36020526040902060010154909150611176908290612e79565b600084815260a36020526040902060010155611194818b888a61227f565b9050806099546111a49190612e91565b609955609a546111b5908290612e79565b609a559998505050505050505050565b60408051808201825260148152732232b632b3b0ba34b7b721b7b73a3937b63632b960611b60208201526097549151633581777360e01b8152909133916001600160a01b0390911690633581777390611222908590600401612d14565b602060405180830381865afa15801561123f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112639190612d69565b6001600160a01b0316148061127b575061127b611595565b6112975760405162461bcd60e51b815260040161053490612d86565b6107f1609d84846123ec565b60008281526065602052604081206112bb90836124ae565b90505b92915050565b60008281526065602052604081206112bb90836124ba565b609754604051633581777360e01b81526000916112be9184916001600160a01b03169063358177739061131190600401612e06565b602060405180830381865afa15801561132e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113529190612d69565b609754604051633581777360e01b81526001600160a01b039091169063358177739061138090600401612e25565b602060405180830381865afa15801561139d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c19190612d69565b611c25565b6113d4620151806003612ea8565b81565b6114017fb4dfa5f0aba688c4e234bff5d34d47655ba3ad7086852346991862f4d562194d336112c4565b61141d5760405162461bcd60e51b815260040161053490612dbd565b609b805460ff19169055604051600081527f33ad725ac6f2240b9caa447aa8f4f83708ce0fc916485166bf6ea932b6ccca1290602001610601565b600054610100900460ff166114735760005460ff1615611477565b303b155b6114935760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff161580156114b5576000805461ffff19166101011790555b6114be826124dc565b600060988190556099819055609a55609b805460ff191690556114e5620151806003612ea8565b609c558015610695576000805461ff00191690555050565b60008181526065602052604081206112be9061256a565b60008281526065602052604090206002015461153090336112c4565b6107095760405162461bcd60e51b815260206004820152603060248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526f2061646d696e20746f207265766f6b6560801b6064820152608401610534565b600061080281336112c4565b60008281526065602052604090206115b99082612574565b156106955760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60008281526065602052604090206116129082612589565b156106955760405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b61165e816001612e79565b836003015411156116b15760405162461bcd60e51b815260206004820152601d60248201527f43616e6e6f742073756274726163742066726f6d2074686520706173740000006044820152606401610534565b60038301546116c95760038301819055600483018190555b82600401548111156116dd57600483018190555b8260030154811061171a576000818152600184016020526040902054611704908390612e79565b6000828152600185016020526040902055505050565b6002830154611729908361259e565b6002840155505050565b606081600301546000141561174757919050565b60006001836003015461175a9190612e91565b905060008360040154600161176f9190612e79565b905081811161178657611783826001612e79565b90505b6117908282612e91565b67ffffffffffffffff8111156117a8576117a8612f15565b6040519080825280602002602001820160405280156117d1578160200160208202803683370190505b5092508360020154836000815181106117ec576117ec612f2b565b60200260200101818152505060005b8351611808826001612e79565b10156118a95760008186600301546118209190612e79565b6000818152600188016020908152604080832054918a9052909120548751929350909187908590811061185557611855612f2b565b60200260200101516118679190612e79565b6118719190612e91565b8561187d846001612e79565b8151811061188d5761188d612f2b565b6020908102919091010152506118a281612f41565b90506117fb565b505050919050565b6099546098545b8481116118e6576118ca8185856125f9565b6118d49083612e79565b91506118df81612f41565b90506118b8565b935093915050565b6003820154600090611901836001612e79565b101561191f5760405162461bcd60e51b815260040161053490612f5c565b6003830154611930575060006112be565b8183600301541161199757600283015460038401545b83811161198f57600081815260018601602090815260408083205491889052909120546119739084612e79565b61197d9190612e91565b915061198881612f41565b9050611946565b5090506112be565b5060028201546112be565b600082815260a360205260408120548210156119f85760405162461bcd60e51b815260206004820152601560248201527410d85b89dd0819d95d08189bdd5b9d1e481c185a59605a1b6044820152606401610534565b600083815260a36020526040902054821415611a265750600082815260a360205260409020600101546112be565b5060006112be565b604051639bcd952160e01b8152600481018790526000906001600160a01b03831690639bcd952190602401602060405180830381865afa158015611a76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9a9190612f9e565b15611aa757506000610c1f565b826001600160a01b03166365cf7c9b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ae5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b099190612e4a565b421015611b1857506000610c1f565b88611b2557506000610c1f565b826001600160a01b031663ed089aa76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b879190612e4a565b611b9357506000610c1f565b6000611c16611ba28a8d612e79565b878c876001600160a01b031663ed089aa76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611be2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c069190612e4a565b611c10908a612fc0565b8b612747565b9b9a5050505050505050505050565b604051631924374d60e31b81526004810184905260009081906001600160a01b0385169063c921ba6890602401602060405180830381865afa158015611c6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c939190612e4a565b60405163bf64d84960e01b8152600481018290529091506000906001600160a01b0385169063bf64d84990602401602060405180830381865afa158015611cde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d029190612e4a565b604051632b45aad960e11b8152600481018290529091506000906001600160a01b0386169063568b55b290602401602060405180830381865afa158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d719190612e4a565b90506000611d7f8285612e91565b90506000866001600160a01b031663ddd1b67e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dc1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de59190612e4a565b905080841115611df757611df7612fe2565b80841415611f5e5760006001600160a01b03881663568b55b2611e1b846001612e79565b6040518263ffffffff1660e01b8152600401611e3991815260200190565b602060405180830381865afa158015611e56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7a9190612e4a565b905060006001600160a01b03891663568b55b2611e98886002612e79565b6040518263ffffffff1660e01b8152600401611eb691815260200190565b602060405180830381865afa158015611ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef79190612e4a565b9050609c5485611f079190612e79565b871015611f3457611f1c620151806003612ea8565b611f269083612e91565b9750505050505050506120f9565b611f26611f418584612e79565b611f4f620151806003612ea8565b611f599084612e91565b612794565b80611f6a856001612e79565b141561207457604051632b45aad960e11b8152600481018290526000906001600160a01b0389169063568b55b290602401602060405180830381865afa158015611fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fdc9190612e4a565b905060006001600160a01b03891663568b55b2611ffa856001612e79565b6040518263ffffffff1660e01b815260040161201891815260200190565b602060405180830381865afa158015612035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120599190612e4a565b9050611f2661206a85609c546127ac565b611f419084612e79565b604051632b45aad960e11b8152600481018290526000906001600160a01b0389169063568b55b290602401602060405180830381865afa1580156120bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e09190612e4a565b9050609c54816120f09190612e79565b96505050505050505b9392505050565b60008061210e8585856118b1565b609854919350915081111561212d57609881905560998290556000609a555b5050505050565b600082815260a3602052604090205481111561069557600091825260a36020526040822090815560010155565b6003820154600090612174836001612e79565b10156121925760405162461bcd60e51b815260040161053490612f5c565b60038301546121a3575060006112be565b8183600301541161227657600283015460038401545b83811161225057600081815260018601602090815260408083205491889052909120546121f191906121eb9085612e79565b9061259e565b60008281526020879052604090205490925015612218576000818152602086905260408120555b6000818152600186016020526040902054156122405760008181526001860160205260408120555b61224981612f41565b90506121b9565b508084600201541461226457600284018190555b61226f836001612e79565b6003850155505b50506002015490565b609b5460009060ff166122935750836123e4565b506040516310454ac560e31b81526004810184905284906001600160a01b0384169063c9e91c6690829063822a562890602401602060405180830381865afa1580156122e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123079190612e4a565b866040518363ffffffff1660e01b815260040161232e929190918252602082015260400190565b6020604051808303816000875af115801561234d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123719190612f9e565b6123e457816001600160a01b031663d9dd800d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d79190612e4a565b6123e19082612fc0565b90505b949350505050565b80836003015411156124395760405162461bcd60e51b815260206004820152601660248201527510d85b9b9bdd08185919081d1bc81d1a19481c185cdd60521b6044820152606401610534565b60038301546124515760038301819055600483018190555b826004015481111561246557600483018190555b8260030154811061249e5760008181526020849052604090205461248a908390612e79565b600082815260208590526040902055505050565b8183600201546117299190612e79565b60006112bb83836127c4565b6001600160a01b038116600090815260018301602052604081205415156112bb565b600054610100900460ff166124f75760005460ff16156124fb565b303b155b6125175760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff16158015612539576000805461ffff19166101011790555b6125416127ee565b61254c60003361068b565b61255582612870565b8015610695576000805461ff00191690555050565b60006112be825490565b60006112bb836001600160a01b03841661294a565b60006112bb836001600160a01b038416612991565b60008183106125b8576125b18284612e91565b90506112be565b60408051848152602081018490527f5b70a077a991facb623c7b2ee44cc539dc6ba345b6636552b8ea97fbbd4d5419910160405180910390a15060006112be565b6000806126068484612a84565b90508085101561261a5760009150506120f9565b60006126268287612e91565b90506000612635600c83612fc0565b9050600681106126b3576000600361264e600684612e91565b6126589190612fc0565b612663906001612e79565b90506101008110156126a657600c61267c8260026130dc565b612691906a9f3b75e90118af90800000612fc0565b61269b9190612fc0565b9450505050506120f9565b60009450505050506120f9565b6040805160c0810182526b013e76ebd202315f2100000081526b011e9e3aa3685fa26a80000060208201526afec58974ce8de5b4000000918101919091526adeecd84634bc28fd80000060608201526abf1427179aea6c4700000060808201526a9f3b75e90118af9080000060a0820152600c81836006811061273857612738612f2b565b602002015161269b9190612fc0565b600082156127875760008461275c8789612ea8565b6127669190612fc0565b905061277f6127758583612fc0565b611f598584612e91565b91505061278b565b5060005b95945050505050565b6000818310156127a55750816112be565b50806112be565b6000818310156127bd5750806112be565b50816112be565b60008260000182815481106127db576127db612f2b565b9060005260206000200154905092915050565b600054610100900460ff166128095760005460ff161561280d565b303b155b6128295760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff1615801561284b576000805461ffff19166101011790555b612853612b56565b61285b612bc3565b801561286d576000805461ff00191690555b50565b6001600160a01b0381166128d15760405162461bcd60e51b815260206004820152602260248201527f436f6e74726163744d616e616765722061646472657373206973206e6f742073604482015261195d60f21b6064820152608401610534565b6001600160a01b0381163b6129285760405162461bcd60e51b815260206004820152601760248201527f41646472657373206973206e6f7420636f6e74726163740000000000000000006044820152606401610534565b609780546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600183016020526040812054611a26575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112be565b60008181526001830160205260408120548015612a7a5760006129b5600183612e91565b85549091506000906129c990600190612e91565b9050818114612a2e5760008660000182815481106129e9576129e9612f2b565b9060005260206000200154905080876000018481548110612a0c57612a0c612f2b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612a3f57612a3f6130e8565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112be565b60009150506112be565b6000826001600160a01b031663bf64d849836001600160a01b03166365cf7c9b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af79190612e4a565b6040518263ffffffff1660e01b8152600401612b1591815260200190565b602060405180830381865afa158015612b32573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112bb9190612e4a565b600054610100900460ff16612bc15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610534565b565b600054610100900460ff16612bde5760005460ff1615612be2565b303b155b612bfe5760405162461bcd60e51b815260040161053490612ec7565b600054610100900460ff1615801561285b576000805461ffff1916610101179055801561286d576000805461ff001916905550565b600060208284031215612c4557600080fd5b5035919050565b6001600160a01b038116811461286d57600080fd5b60008060408385031215612c7457600080fd5b823591506020830135612c8681612c4c565b809150509250929050565b60008060408385031215612ca457600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015612ceb57835183529284019291840191600101612ccf565b50909695505050505050565b600060208284031215612d0957600080fd5b81356120f981612c4c565b600060208083528351808285015260005b81811015612d4157858101830151858201604001528201612d25565b81811115612d53576000604083870101525b50601f01601f1916929092016040019392505050565b600060208284031215612d7b57600080fd5b81516120f981612c4c565b60208082526019908201527f4d6573736167652073656e64657220697320696e76616c696400000000000000604082015260600190565b60208082526029908201527f424f554e54595f524544554354494f4e5f4d414e414745525f524f4c45206973604082015268081c995c5d5a5c995960ba1b606082015260800190565b6020808252600590820152644e6f64657360d81b604082015260600190565b6020808252600b908201526a54696d6548656c7065727360a81b604082015260600190565b600060208284031215612e5c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115612e8c57612e8c612e63565b500190565b600082821015612ea357612ea3612e63565b500390565b6000816000190483118215151615612ec257612ec2612e63565b500290565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000600019821415612f5557612f55612e63565b5060010190565b60208082526022908201527f43616e6e6f742063616c63756c6174652076616c756520696e207468652070616040820152611cdd60f21b606082015260800190565b600060208284031215612fb057600080fd5b815180151581146120f957600080fd5b600082612fdd57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052600160045260246000fd5b600181815b8085111561303357816000190482111561301957613019612e63565b8085161561302657918102915b93841c9390800290612ffd565b509250929050565b60008261304a575060016112be565b81613057575060006112be565b816001811461306d576002811461307757613093565b60019150506112be565b60ff84111561308857613088612e63565b50506001821b6112be565b5060208310610133831016604e8410600b84101617156130b6575081810a6112be565b6130c08383612ff8565b80600019048211156130d4576130d4612e63565b029392505050565b60006112bb838361303b565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a7e59f69048fe7e736bf828dd1a8ce956d67fa396202eb024c03b2465cad408f64736f6c634300080b0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.