diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 386b7dfec..ac4e42776 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -1,4 +1,7 @@
/* eslint-env node */
+
+// cspell:words venv
+
module.exports = {
"extends": [
"eslint:recommended",
@@ -6,7 +9,8 @@ module.exports = {
],
"ignorePatterns": [
"coverage/**",
- "typechain-types/**"
+ "typechain-types/**",
+ "venv/**"
],
"env": {
"node": true
diff --git a/.solhint.json b/.solhint.json
index 0c8a32ead..862c85182 100644
--- a/.solhint.json
+++ b/.solhint.json
@@ -3,10 +3,11 @@
"rules": {
"not-rely-on-time": "off",
+ "compiler-version": ["warn","0.8.26"],
+
"avoid-tx-origin": "error",
"check-send-result": "error",
"code-complexity": "error",
- "compiler-version": ["error","0.8.17"],
"comprehensive-interface": "error",
"contract-name-camelcase": "error",
"explicit-types": "error",
@@ -14,6 +15,7 @@
"func-named-parameters": "error",
"func-visibility": ["error", {"ignoreConstructors": true}],
"function-max-lines": "error",
+ "max-line-length": ["error", 100],
"max-states-count": ["error", 20],
"no-empty-blocks": "error",
"no-global-import": "error",
diff --git a/contracts/BountyV2.sol b/contracts/BountyV2.sol
index 1bcd16110..0a7486f83 100644
--- a/contracts/BountyV2.sol
+++ b/contracts/BountyV2.sol
@@ -22,7 +22,9 @@
pragma solidity 0.8.17;
import { IBountyV2 } from "@skalenetwork/skale-manager-interfaces/IBountyV2.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
import { ITimeHelpers } from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
import { INodes } from "@skalenetwork/skale-manager-interfaces/INodes.sol";
@@ -51,7 +53,8 @@ contract BountyV2 is Permissions, IBountyV2 {
uint256 public constant SECONDS_PER_DAY = 24 * 60 * 60;
uint256 public constant BOUNTY_WINDOW_SECONDS = 3 * SECONDS_PER_DAY;
- bytes32 public constant BOUNTY_REDUCTION_MANAGER_ROLE = keccak256("BOUNTY_REDUCTION_MANAGER_ROLE");
+ bytes32 public constant BOUNTY_REDUCTION_MANAGER_ROLE =
+ keccak256("BOUNTY_REDUCTION_MANAGER_ROLE");
uint256 private _nextEpoch;
uint256 private _epochPool;
@@ -67,7 +70,10 @@ contract BountyV2 is Permissions, IBountyV2 {
mapping (uint256 => BountyHistory) private _bountyHistory;
modifier onlyBountyReductionManager() {
- require(hasRole(BOUNTY_REDUCTION_MANAGER_ROLE, msg.sender), "BOUNTY_REDUCTION_MANAGER_ROLE is required");
+ require(
+ hasRole(BOUNTY_REDUCTION_MANAGER_ROLE, msg.sender),
+ "BOUNTY_REDUCTION_MANAGER_ROLE is required"
+ );
_;
}
@@ -86,12 +92,12 @@ contract BountyV2 is Permissions, IBountyV2 {
allow("SkaleManager")
returns (uint256 bounty)
{
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
+ ConstantsHolder constantsHolder =
+ ConstantsHolder(contractManager.getContract("ConstantsHolder"));
INodes nodes = INodes(contractManager.getContract("Nodes"));
ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
- IDelegationController delegationController = IDelegationController(
- contractManager.getContract("DelegationController")
- );
+ IDelegationController delegationController =
+ IDelegationController(contractManager.getContract("DelegationController"));
require(
_getNextRewardTimestamp(nodeIndex, nodes, timeHelpers) <= block.timestamp,
@@ -171,7 +177,8 @@ contract BountyV2 is Permissions, IBountyV2 {
}
function estimateBounty(uint256 nodeIndex) external view override returns (uint256 bounty) {
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
+ ConstantsHolder constantsHolder =
+ ConstantsHolder(contractManager.getContract("ConstantsHolder"));
INodes nodes = INodes(contractManager.getContract("Nodes"));
ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
IDelegationController delegationController = IDelegationController(
@@ -187,17 +194,28 @@ contract BountyV2 is Permissions, IBountyV2 {
return _calculateMaximumBountyAmount({
epochPoolSize: stagePoolSize,
effectiveDelegatedSum: _effectiveDelegatedSum.getValue(currentMonth),
- bountyWasPaidInCurrentEpoch: _nextEpoch == currentMonth + 1 ? _bountyWasPaidInCurrentEpoch : 0,
+ bountyWasPaidInCurrentEpoch: _nextEpoch == currentMonth + 1 ?
+ _bountyWasPaidInCurrentEpoch :
+ 0,
nodeIndex: nodeIndex,
bountyPaidToTheValidator: _getBountyPaid(validatorId, currentMonth),
- effectiveDelegated: delegationController.getEffectiveDelegatedToValidator(validatorId, currentMonth),
+ effectiveDelegated: delegationController.getEffectiveDelegatedToValidator(
+ validatorId, currentMonth
+ ),
delegated: delegationController.getDelegatedToValidator(validatorId, currentMonth),
constantsHolder: constantsHolder,
nodes: nodes
});
}
- function getNextRewardTimestamp(uint256 nodeIndex) external view override returns (uint256 timestamp) {
+ function getNextRewardTimestamp(
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (uint256 timestamp)
+ {
return _getNextRewardTimestamp(
nodeIndex,
INodes(contractManager.getContract("Nodes")),
@@ -211,7 +229,13 @@ contract BountyV2 is Permissions, IBountyV2 {
// private
- function _refillEpochPool(uint256 currentMonth, ITimeHelpers timeHelpers, ConstantsHolder constantsHolder) private {
+ function _refillEpochPool(
+ uint256 currentMonth,
+ ITimeHelpers timeHelpers,
+ ConstantsHolder constantsHolder
+ )
+ private
+ {
uint256 epochPool;
uint256 nextEpoch;
(epochPool, nextEpoch) = _getEpochPool(currentMonth, timeHelpers, constantsHolder);
@@ -354,7 +378,14 @@ contract BountyV2 is Permissions, IBountyV2 {
}
}
- function _getBountyPaid(uint256 validatorId, uint256 month) private view returns (uint256 amount) {
+ function _getBountyPaid(
+ uint256 validatorId,
+ uint256 month
+ )
+ private
+ view
+ returns (uint256 amount)
+ {
require(_bountyHistory[validatorId].month <= month, "Can't get bounty paid");
if (_bountyHistory[validatorId].month == month) {
return _bountyHistory[validatorId].bountyPaid;
@@ -381,7 +412,10 @@ contract BountyV2 is Permissions, IBountyV2 {
if (lastRewardTimestamp < lastRewardMonthStart + nodeCreationWindowSeconds) {
return nextMonthStart - BOUNTY_WINDOW_SECONDS;
} else {
- return _min(nextMonthStart + timePassedAfterMonthStart, nextMonthFinish - BOUNTY_WINDOW_SECONDS);
+ return _min(
+ nextMonthStart + timePassedAfterMonthStart,
+ nextMonthFinish - BOUNTY_WINDOW_SECONDS
+ );
}
} else if (lastRewardMonth + 1 == currentMonth) {
uint256 currentMonthStart = timeHelpers.monthToTimestamp(currentMonth);
diff --git a/contracts/CommonErrors.sol b/contracts/CommonErrors.sol
new file mode 100644
index 000000000..cedccd39a
--- /dev/null
+++ b/contracts/CommonErrors.sol
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: AGPL-3.0-only
+
+/*
+ CommonErrors.sol - SKALE Manager
+ Copyright (C) 2024-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 .
+*/
+
+pragma solidity ^0.8.17;
+
+
+error AddressIsNotSet();
+error GroupIndexIsInvalid(uint256 index);
+error IsNotContract(address account);
+error NotEnoughFunds();
+error RoleRequired(bytes32 role);
diff --git a/contracts/ConstantsHolder.sol b/contracts/ConstantsHolder.sol
index 745084653..25e706691 100644
--- a/contracts/ConstantsHolder.sol
+++ b/contracts/ConstantsHolder.sol
@@ -33,12 +33,12 @@ import { Permissions } from "./Permissions.sol";
contract ConstantsHolder is Permissions, IConstantsHolder {
// initial price for creating Node (100 SKL)
- uint256 public constant NODE_DEPOSIT = 100 * 1e18;
+ uint256 public constant override NODE_DEPOSIT = 100 * 1e18;
- uint8 public constant TOTAL_SPACE_ON_NODE = 128;
+ uint8 public constant override TOTAL_SPACE_ON_NODE = 128;
// part of Node for Small Skale-chain (1/128 of Node)
- uint8 public constant SMALL_DIVISOR = 128;
+ uint8 public constant override SMALL_DIVISOR = 128;
// part of Node for Medium Skale-chain (1/32 of Node)
uint8 public constant MEDIUM_DIVISOR = 32;
@@ -59,7 +59,7 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
uint256 public constant NUMBER_OF_NODES_FOR_MEDIUM_TEST_SCHAIN = 4;
// number of seconds in one year
- uint32 public constant SECONDS_TO_YEAR = 31622400;
+ uint32 public constant override SECONDS_TO_YEAR = 31622400;
// initial number of monitors
uint256 public constant NUMBER_OF_MONITORS = 24;
@@ -130,10 +130,14 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
uint256 public minNodeBalance;
- bytes32 public constant CONSTANTS_HOLDER_MANAGER_ROLE = keccak256("CONSTANTS_HOLDER_MANAGER_ROLE");
+ 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");
+ require(
+ hasRole(CONSTANTS_HOLDER_MANAGER_ROLE, msg.sender),
+ "CONSTANTS_HOLDER_MANAGER_ROLE is required"
+ );
_;
}
@@ -159,7 +163,14 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
* @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 {
+ function setPeriods(
+ uint32 newRewardPeriod,
+ uint32 newDeltaPeriod
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
require(
newRewardPeriod >= newDeltaPeriod && newRewardPeriod - newDeltaPeriod >= checkTime,
"Incorrect Periods"
@@ -248,7 +259,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
/**
* @dev Allows the Owner to set the proof-of-use lockup period.
*/
- function setProofOfUseLockUpPeriod(uint256 periodDays) external override onlyConstantsHolderManager {
+ function setProofOfUseLockUpPeriod(
+ uint256 periodDays
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
emit ConstantUpdated(
keccak256(abi.encodePacked("ProofOfUseLockUpPeriodDays")),
uint(proofOfUseLockUpPeriodDays),
@@ -261,7 +278,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
* @dev Allows the Owner to set the proof-of-use delegation percentage
* requirement.
*/
- function setProofOfUseDelegationPercentage(uint256 percentage) external override onlyConstantsHolderManager {
+ function setProofOfUseDelegationPercentage(
+ uint256 percentage
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
require(percentage <= 100, "Percentage value is incorrect");
emit ConstantUpdated(
keccak256(abi.encodePacked("ProofOfUseDelegationPercentage")),
@@ -275,7 +298,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
* @dev Allows the Owner to set the maximum number of validators that a
* single delegator can delegate to.
*/
- function setLimitValidatorsPerDelegator(uint256 newLimit) external override onlyConstantsHolderManager {
+ function setLimitValidatorsPerDelegator(
+ uint256 newLimit
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
emit ConstantUpdated(
keccak256(abi.encodePacked("LimitValidatorsPerDelegator")),
uint(limitValidatorsPerDelegator),
@@ -284,7 +313,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
limitValidatorsPerDelegator = newLimit;
}
- function setSchainCreationTimeStamp(uint256 timestamp) external override onlyConstantsHolderManager {
+ function setSchainCreationTimeStamp(
+ uint256 timestamp
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
emit ConstantUpdated(
keccak256(abi.encodePacked("SchainCreationTimeStamp")),
uint(schainCreationTimeStamp),
@@ -293,7 +328,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
schainCreationTimeStamp = timestamp;
}
- function setMinimalSchainLifetime(uint256 lifetime) external override onlyConstantsHolderManager {
+ function setMinimalSchainLifetime(
+ uint256 lifetime
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
emit ConstantUpdated(
keccak256(abi.encodePacked("MinimalSchainLifetime")),
uint(minimalSchainLifetime),
@@ -302,7 +343,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
minimalSchainLifetime = lifetime;
}
- function setComplaintTimeLimit(uint256 timeLimit) external override onlyConstantsHolderManager {
+ function setComplaintTimeLimit(
+ uint256 timeLimit
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
emit ConstantUpdated(
keccak256(abi.encodePacked("ComplaintTimeLimit")),
uint(complaintTimeLimit),
@@ -311,7 +358,13 @@ contract ConstantsHolder is Permissions, IConstantsHolder {
complaintTimeLimit = timeLimit;
}
- function setMinNodeBalance(uint256 newMinNodeBalance) external override onlyConstantsHolderManager {
+ function setMinNodeBalance(
+ uint256 newMinNodeBalance
+ )
+ external
+ override
+ onlyConstantsHolderManager
+ {
emit ConstantUpdated(
keccak256(abi.encodePacked("MinNodeBalance")),
uint(minNodeBalance),
diff --git a/contracts/ContractManager.sol b/contracts/ContractManager.sol
index 2faa006b3..3f836f84a 100644
--- a/contracts/ContractManager.sol
+++ b/contracts/ContractManager.sol
@@ -21,8 +21,12 @@
pragma solidity 0.8.17;
-import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
-import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
+import {
+ OwnableUpgradeable
+} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
+import {
+ AddressUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
import { StringUtils } from "./utils/StringUtils.sol";
@@ -91,7 +95,12 @@ contract ContractManager is InitializableWithGap, OwnableUpgradeable, IContractM
*
* - Contract must exist.
*/
- function getDelegationPeriodManager() external view override returns (address delegationPeriodManager) {
+ function getDelegationPeriodManager()
+ external
+ view
+ override
+ returns (address delegationPeriodManager)
+ {
return getContract(DELEGATION_PERIOD_MANAGER);
}
@@ -123,7 +132,14 @@ contract ContractManager is InitializableWithGap, OwnableUpgradeable, IContractM
return getContract(PUNISHER);
}
- function getContract(string memory name) public view override returns (address contractAddress) {
+ function getContract(
+ string memory name
+ )
+ public
+ view
+ override
+ returns (address contractAddress)
+ {
contractAddress = contracts[keccak256(abi.encodePacked(name))];
if (contractAddress == address(0)) {
revert(name.strConcat(" contract has not been found"));
diff --git a/contracts/Decryption.sol b/contracts/Decryption.sol
index 77e17f6c1..d526ed8d0 100644
--- a/contracts/Decryption.sol
+++ b/contracts/Decryption.sol
@@ -34,14 +34,30 @@ contract Decryption is IDecryption {
/**
* @dev Returns an encrypted text given a secret and a key.
*/
- function encrypt(uint256 secretNumber, bytes32 key) external pure override returns (bytes32 cipherText) {
+ function encrypt(
+ uint256 secretNumber,
+ bytes32 key
+ )
+ external
+ pure
+ override
+ returns (bytes32 cipherText)
+ {
return bytes32(secretNumber) ^ key;
}
/**
* @dev Returns a secret given an encrypted text and a key.
*/
- function decrypt(bytes32 cipherText, bytes32 key) external pure override returns (uint256 secretNumber) {
+ function decrypt(
+ bytes32 cipherText,
+ bytes32 key
+ )
+ external
+ pure
+ override
+ returns (uint256 secretNumber)
+ {
return uint256(cipherText ^ key);
}
}
diff --git a/contracts/KeyStorage.sol b/contracts/KeyStorage.sol
index b4837396e..16139eb14 100644
--- a/contracts/KeyStorage.sol
+++ b/contracts/KeyStorage.sol
@@ -21,12 +21,12 @@
pragma solidity 0.8.17;
-import { IKeyStorage } from "@skalenetwork/skale-manager-interfaces/IKeyStorage.sol";
-import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
+import {IKeyStorage} from "@skalenetwork/skale-manager-interfaces/IKeyStorage.sol";
+import {ISkaleDKG} from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
-import { Permissions } from "./Permissions.sol";
-import { Fp2Operations } from "./utils/fieldOperations/Fp2Operations.sol";
-import { G2Operations } from "./utils/fieldOperations/G2Operations.sol";
+import {Permissions} from "./Permissions.sol";
+import {Fp2Operations} from "./utils/fieldOperations/Fp2Operations.sol";
+import {G2Operations} from "./utils/fieldOperations/G2Operations.sol";
contract KeyStorage is Permissions, IKeyStorage {
using Fp2Operations for ISkaleDKG.Fp2Point;
@@ -55,24 +55,37 @@ contract KeyStorage is Permissions, IKeyStorage {
}
function deleteKey(bytes32 schainHash) external override allow("SkaleDKG") {
- _previousSchainsPublicKeys[schainHash].push(_schainsPublicKeys[schainHash]);
+ _previousSchainsPublicKeys[schainHash].push(
+ _schainsPublicKeys[schainHash]
+ );
delete _schainsPublicKeys[schainHash];
delete _data[schainHash][0];
delete _schainsNodesPublicKeys[schainHash];
}
- function initPublicKeyInProgress(bytes32 schainHash) external override allow("SkaleDKG") {
+ function initPublicKeyInProgress(
+ bytes32 schainHash
+ ) external override allow("SkaleDKG") {
_publicKeysInProgress[schainHash] = G2Operations.getG2Zero();
}
- function adding(bytes32 schainHash, ISkaleDKG.G2Point memory value) external override allow("SkaleDKG") {
+ function adding(
+ bytes32 schainHash,
+ ISkaleDKG.G2Point memory value
+ ) external override allow("SkaleDKG") {
require(value.isG2(), "Incorrect g2 point");
- _publicKeysInProgress[schainHash] = value.addG2(_publicKeysInProgress[schainHash]);
+ _publicKeysInProgress[schainHash] = value.addG2(
+ _publicKeysInProgress[schainHash]
+ );
}
- function finalizePublicKey(bytes32 schainHash) external override allow("SkaleDKG") {
+ function finalizePublicKey(
+ bytes32 schainHash
+ ) external override allow("SkaleDKG") {
if (!_isSchainsPublicKeyZero(schainHash)) {
- _previousSchainsPublicKeys[schainHash].push(_schainsPublicKeys[schainHash]);
+ _previousSchainsPublicKeys[schainHash].push(
+ _schainsPublicKeys[schainHash]
+ );
}
_schainsPublicKeys[schainHash] = _publicKeysInProgress[schainHash];
delete _publicKeysInProgress[schainHash];
@@ -80,12 +93,7 @@ contract KeyStorage is Permissions, IKeyStorage {
function getCommonPublicKey(
bytes32 schainHash
- )
- external
- view
- override
- returns (ISkaleDKG.G2Point memory publicKey)
- {
+ ) external view override returns (ISkaleDKG.G2Point memory publicKey) {
return _schainsPublicKeys[schainHash];
}
@@ -115,8 +123,11 @@ contract KeyStorage is Permissions, IKeyStorage {
return _previousSchainsPublicKeys[schainHash];
}
- function _isSchainsPublicKeyZero(bytes32 schainHash) private view returns (bool zero) {
- return _schainsPublicKeys[schainHash].x.a == 0 &&
+ function _isSchainsPublicKeyZero(
+ bytes32 schainHash
+ ) private view returns (bool zero) {
+ return
+ _schainsPublicKeys[schainHash].x.a == 0 &&
_schainsPublicKeys[schainHash].x.b == 0 &&
_schainsPublicKeys[schainHash].y.a == 0 &&
_schainsPublicKeys[schainHash].y.b == 0;
diff --git a/contracts/NodeRotation.sol b/contracts/NodeRotation.sol
index 2a1360085..3362512a8 100644
--- a/contracts/NodeRotation.sol
+++ b/contracts/NodeRotation.sol
@@ -100,7 +100,8 @@ contract NodeRotation is Permissions, INodeRotation {
allow("SkaleManager")
returns (bool contains, bool successful)
{
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
bytes32 schainHash = schainsInternal.getActiveSchain(nodeIndex);
if (schainHash == bytes32(0)) {
return (true, false);
@@ -144,7 +145,14 @@ contract NodeRotation is Permissions, INodeRotation {
/**
* @dev Returns rotation details for a given schain.
*/
- function getRotation(bytes32 schainHash) external view override returns (INodeRotation.Rotation memory rotation) {
+ function getRotation(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (INodeRotation.Rotation memory rotation)
+ {
return Rotation({
nodeIndex: _rotations[schainHash].nodeIndex,
newNodeIndex: _rotations[schainHash].newNodeIndex,
@@ -167,7 +175,14 @@ contract NodeRotation is Permissions, INodeRotation {
return leavingHistory[nodeIndex];
}
- function isRotationInProgress(bytes32 schainHash) external view override returns (bool inProgress) {
+ function isRotationInProgress(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (bool inProgress)
+ {
bool foundNewNode = isNewNodeFound(schainHash);
return foundNewNode ?
leavingHistory[_rotations[schainHash].nodeIndex][
@@ -181,7 +196,15 @@ contract NodeRotation is Permissions, INodeRotation {
* If there is no previous node for given node would return an error:
* "No previous node"
*/
- function getPreviousNode(bytes32 schainHash, uint256 nodeIndex) external view override returns (uint256 node) {
+ function getPreviousNode(
+ bytes32 schainHash,
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (uint256 node)
+ {
require(_rotations[schainHash].newNodeIndexes.contains(nodeIndex), "No previous node");
return _rotations[schainHash].previousNodes[nodeIndex];
}
@@ -201,7 +224,8 @@ contract NodeRotation is Permissions, INodeRotation {
allowThree("SkaleDKG", "SkaleManager", "Schains")
returns (uint256 newNode)
{
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
schainsInternal.removeNodeFromSchain(nodeIndex, schainHash);
if (!isBadNode) {
schainsInternal.removeNodeFromExceptions(schainHash, nodeIndex);
@@ -226,7 +250,8 @@ contract NodeRotation is Permissions, INodeRotation {
allowThree("SkaleManager", "Schains", "SkaleDKG")
returns (uint256 nodeIndex)
{
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
INodes nodes = INodes(contractManager.getContract("Nodes"));
require(schainsInternal.isSchainActive(schainHash), "Group is not active");
uint8 space = schainsInternal.getSchainsPartOfNode(schainHash);
@@ -236,7 +261,10 @@ contract NodeRotation is Permissions, INodeRotation {
abi.encodePacked(uint256(blockhash(block.number - 1)), schainHash)
);
nodeIndex = nodes.getRandomNodeWithFreeSpace(space, randomGenerator);
- require(nodes.removeSpaceFromNode(nodeIndex, space), "Could not remove space from nodeIndex");
+ require(
+ nodes.removeSpaceFromNode(nodeIndex, space),
+ "Could not remove space from nodeIndex"
+ );
schainsInternal.makeSchainNodesVisible(schainHash);
schainsInternal.addSchainForNode(nodes, nodeIndex, schainHash);
schainsInternal.setException(schainHash, nodeIndex);
@@ -244,9 +272,11 @@ contract NodeRotation is Permissions, INodeRotation {
}
function isNewNodeFound(bytes32 schainHash) public view override returns (bool found) {
- return _rotations[schainHash].newNodeIndexes.contains(_rotations[schainHash].newNodeIndex) &&
- _rotations[schainHash].previousNodes[_rotations[schainHash].newNodeIndex] ==
- _rotations[schainHash].nodeIndex;
+ return _rotations[schainHash]
+ .newNodeIndexes.contains(_rotations[schainHash].newNodeIndex) &&
+ _rotations[schainHash]
+ .previousNodes[_rotations[schainHash].newNodeIndex] ==
+ _rotations[schainHash].nodeIndex;
}
@@ -259,7 +289,8 @@ contract NodeRotation is Permissions, INodeRotation {
}
function _startWaiting(bytes32 schainHash, uint256 nodeIndex) private {
- IConstantsHolder constants = IConstantsHolder(contractManager.getContract("ConstantsHolder"));
+ IConstantsHolder constants =
+ IConstantsHolder(contractManager.getContract("ConstantsHolder"));
_rotations[schainHash].nodeIndex = nodeIndex;
_rotations[schainHash].freezeUntil = block.timestamp + constants.rotationDelay();
}
@@ -277,16 +308,20 @@ contract NodeRotation is Permissions, INodeRotation {
// During skaled config generation skale-admin relies on a fact that
// for each pair of nodes swaps (rotations) the more new swap has bigger finish_ts value.
- // Also skale-admin supposes that if the different between finish_ts is minimum possible (1 second)
+ // Also skale-admin supposes that
+ // if the different between finish_ts is minimum possible (1 second)
// the corresponding swap was cased by failed DKG and no proper keys were generated.
uint256 finishTimestamp;
if (shouldDelay) {
finishTimestamp = block.timestamp +
- IConstantsHolder(contractManager.getContract("ConstantsHolder")).rotationDelay();
+ IConstantsHolder(
+ contractManager.getContract("ConstantsHolder")
+ ).rotationDelay();
} else {
if(_rotations[schainHash].rotationCounter > 0) {
- uint256 previousRotatedNode = _rotations[schainHash].previousNodes[_rotations[schainHash].newNodeIndex];
+ uint256 previousRotatedNode =
+ _rotations[schainHash].previousNodes[_rotations[schainHash].newNodeIndex];
uint256 previousRotationTimestamp = leavingHistory[previousRotatedNode][
_rotations[schainHash].indexInLeavingHistory[previousRotatedNode]
].finishedRotation;
@@ -295,13 +330,20 @@ contract NodeRotation is Permissions, INodeRotation {
finishTimestamp = block.timestamp;
}
}
- leavingHistory[nodeIndex].push(LeavingHistory({schainHash: schainHash, finishedRotation: finishTimestamp}));
- require(_rotations[schainHash].newNodeIndexes.add(newNodeIndex), "New node was already added");
+ leavingHistory[nodeIndex].push(LeavingHistory({
+ schainHash: schainHash,
+ finishedRotation: finishTimestamp
+ }));
+ require(
+ _rotations[schainHash].newNodeIndexes.add(newNodeIndex),
+ "New node was already added"
+ );
_rotations[schainHash].nodeIndex = nodeIndex;
_rotations[schainHash].newNodeIndex = newNodeIndex;
_rotations[schainHash].rotationCounter++;
_rotations[schainHash].previousNodes[newNodeIndex] = nodeIndex;
- _rotations[schainHash].indexInLeavingHistory[nodeIndex] = leavingHistory[nodeIndex].length - 1;
+ _rotations[schainHash].indexInLeavingHistory[nodeIndex] =
+ leavingHistory[nodeIndex].length - 1;
delete waitForNewNode[schainHash];
ISkaleDKG(contractManager.getContract("SkaleDKG")).openChannel(schainHash);
}
@@ -314,7 +356,10 @@ contract NodeRotation is Permissions, INodeRotation {
if (_rotations[schainHash].freezeUntil < block.timestamp) {
_startWaiting(schainHash, nodeIndex);
} else {
- require(_rotations[schainHash].nodeIndex == nodeIndex, "Occupied by rotation on Schain");
+ require(
+ _rotations[schainHash].nodeIndex == nodeIndex,
+ "Occupied by rotation on Schain"
+ );
}
}
}
diff --git a/contracts/Nodes.sol b/contracts/Nodes.sol
index a4240a254..c5fe28d23 100644
--- a/contracts/Nodes.sol
+++ b/contracts/Nodes.sol
@@ -21,21 +21,32 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity 0.8.26;
-import { SafeCastUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
+import {
+ SafeCastUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
import { INodes } from "@skalenetwork/skale-manager-interfaces/INodes.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
import { IBountyV2 } from "@skalenetwork/skale-manager-interfaces/IBountyV2.sol";
+import {
+ IPaymasterController
+} from "@skalenetwork/skale-manager-interfaces/IPaymasterController.sol";
+import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+import { INodeRotation } from "@skalenetwork/skale-manager-interfaces/INodeRotation.sol";
import { Permissions } from "./Permissions.sol";
-import { ConstantsHolder } from "./ConstantsHolder.sol";
+
import { IRandom, Random } from "./utils/Random.sol";
+import { RoleRequired } from "./CommonErrors.sol";
import { SegmentTree } from "./utils/SegmentTree.sol";
-
-import { NodeRotation } from "./NodeRotation.sol";
+import { ValidatorDoesNotExist, ValidatorIsNotAuthorized } from "./delegation/ValidatorService.sol";
/**
@@ -94,6 +105,20 @@ contract Nodes is Permissions, INodes {
mapping(uint256 => NodeExtras) public nodeExtras;
+ error IpIsNotAvailable(bytes4 ip);
+ error NameIsAlreadyRegistered(string name);
+ error PortIsNotSet();
+ error PublicKeyIsIncorrect(bytes32[2] key);
+ error NodeNotFound();
+ error NodeDoesNotExist(uint256 nodeId);
+ error NodeIsNotActive(uint256 nodeId);
+ error NodeIsNotLeaving(uint256 nodeId);
+ error NodeIsNotInMaintenance(uint256 nodeId);
+ error MinimumStakingRequirementIsNotMet();
+ error NodeDoesNotExistForValidator(uint256 validatorId, uint256 nodeId);
+ error IpAndPublicIpIsDifferent(bytes4 ip, bytes4 publicIp);
+ error SenderIsNotPermitted(address sender);
+
modifier checkNodeExists(uint256 nodeIndex) {
_checkNodeIndex(nodeIndex);
_;
@@ -105,12 +130,16 @@ contract Nodes is Permissions, INodes {
}
modifier onlyCompliance() {
- require(hasRole(COMPLIANCE_ROLE, msg.sender), "COMPLIANCE_ROLE is required");
+ if (!hasRole(COMPLIANCE_ROLE, msg.sender)) {
+ revert RoleRequired(COMPLIANCE_ROLE);
+ }
_;
}
modifier nonZeroIP(bytes4 ip) {
- require(ip != 0x0 && !nodesIPCheck[ip], "IP address is zero or is not available");
+ if (ip == 0x0 || nodesIPCheck[ip]) {
+ revert IpIsNotAvailable(ip);
+ }
_;
}
@@ -214,38 +243,22 @@ contract Nodes is Permissions, INodes {
nonZeroIP(params.ip)
{
// checks that Node has correct data
- require(!nodesNameCheck[keccak256(abi.encodePacked(params.name))], "Name is already registered");
- require(params.port > 0, "Port is zero");
- require(from == _publicKeyToAddress(params.publicKey), "Public Key is incorrect");
+ if (nodesNameCheck[keccak256(abi.encodePacked(params.name))]) {
+ revert NameIsAlreadyRegistered(params.name);
+ }
+ if (params.port == 0) {
+ revert PortIsNotSet();
+ }
+ if (from != _publicKeyToAddress(params.publicKey)) {
+ revert PublicKeyIsIncorrect(params.publicKey);
+ }
+
uint256 validatorId = IValidatorService(
contractManager.getContract("ValidatorService")).getValidatorIdByNodeAddress(from);
- uint8 totalSpace = ConstantsHolder(contractManager.getContract("ConstantsHolder")).TOTAL_SPACE_ON_NODE();
- nodes.push(Node({
- name: params.name,
- ip: params.ip,
- publicIP: params.publicIp,
- port: params.port,
- publicKey: params.publicKey,
- startBlock: block.number,
- lastRewardDate: block.timestamp,
- finishTime: 0,
- status: NodeStatus.Active,
- validatorId: validatorId
- }));
- uint256 nodeIndex = nodes.length - 1;
- validatorToNodeIndexes[validatorId].push(nodeIndex);
- bytes32 nodeHashName = keccak256(abi.encodePacked(params.name));
- nodesIPCheck[params.ip] = true;
- nodesNameCheck[nodeHashName] = true;
- nodesNameToIndex[nodeHashName] = nodeIndex;
- nodeIndexes[from].isNodeExist[nodeIndex] = true;
- nodeIndexes[from].numberOfNodes++;
- domainNames[nodeIndex] = params.domainName;
- spaceOfNodes.push(SpaceManaging({
- freeSpace: totalSpace,
- indexInSpaceMap: spaceToNodes[totalSpace].length
- }));
+
+ uint256 nodeIndex = _addNode(validatorId, from, params);
_setNodeActive(nodeIndex);
+
emit NodeCreated({
nodeIndex: nodeIndex,
owner: from,
@@ -256,6 +269,10 @@ contract Nodes is Permissions, INodes {
nonce: params.nonce,
domainName: params.domainName
});
+
+ IPaymasterController paymasterController =
+ IPaymasterController(contractManager.getContract("PaymasterController"));
+ paymasterController.setNodesAmount(validatorId, validatorToNodeIndexes[validatorId].length);
}
/**
@@ -270,10 +287,14 @@ contract Nodes is Permissions, INodes {
override
checkNodeExists(nodeIndex)
{
- require(hasRole(NODE_MANAGER_ROLE, msg.sender), "NODE_MANAGER_ROLE is required");
- require(isNodeActive(nodeIndex), "Node should be Active");
+ if (!hasRole(NODE_MANAGER_ROLE, msg.sender)) {
+ revert RoleRequired(NODE_MANAGER_ROLE);
+ }
+ if (!isNodeActive(nodeIndex)) {
+ revert NodeIsNotActive(nodeIndex);
+ }
_setNodeLeaving(nodeIndex);
- NodeRotation(contractManager.getContract("NodeRotation")).freezeSchains(nodeIndex);
+ INodeRotation(contractManager.getContract("NodeRotation")).freezeSchains(nodeIndex);
emit ExitInitialized(nodeIndex, block.timestamp);
}
@@ -295,7 +316,9 @@ contract Nodes is Permissions, INodes {
allow("SkaleManager")
returns (bool successful)
{
- require(isNodeLeaving(nodeIndex), "Node is not Leaving");
+ if (!isNodeLeaving(nodeIndex)) {
+ revert NodeIsNotLeaving(nodeIndex);
+ }
_setNodeLeft(nodeIndex);
@@ -316,8 +339,11 @@ contract Nodes is Permissions, INodes {
checkNodeExists(nodeIndex)
allow("SkaleManager")
{
- IValidatorService validatorService = IValidatorService(contractManager.getValidatorService());
- require(validatorService.validatorExists(validatorId), "Validator ID does not exist");
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getValidatorService());
+ if (!validatorService.validatorExists(validatorId)) {
+ revert ValidatorDoesNotExist(validatorId);
+ }
uint256[] memory validatorNodes = validatorToNodeIndexes[validatorId];
uint256 position = _findNode(validatorNodes, nodeIndex);
if (position < validatorNodes.length) {
@@ -326,7 +352,8 @@ contract Nodes is Permissions, INodes {
}
validatorToNodeIndexes[validatorId].pop();
address nodeOwner = _publicKeyToAddress(nodes[nodeIndex].publicKey);
- uint256 validatorIdByNode = validatorService.getValidatorIdByNodeAddressWithoutRevert(nodeOwner);
+ uint256 validatorIdByNode =
+ validatorService.getValidatorIdByNodeAddressWithoutRevert(nodeOwner);
if (validatorIdByNode == validatorId || validatorIdByNode == 0) {
if (nodeIndexes[nodeOwner].numberOfNodes == 1 &&
!validatorService.validatorAddressExists(nodeOwner) &&
@@ -337,6 +364,12 @@ contract Nodes is Permissions, INodes {
nodeIndexes[nodeOwner].isNodeExist[nodeIndex] = false;
nodeIndexes[nodeOwner].numberOfNodes--;
}
+
+ IPaymasterController paymasterController =
+ IPaymasterController(contractManager.getContract("PaymasterController"));
+ // in order to do not read validatorToNodeIndexes.length
+ // we use validatorNodes but it's length is 1 more.
+ paymasterController.setNodesAmount(validatorId, validatorNodes.length - 1);
}
/**
@@ -348,13 +381,25 @@ contract Nodes is Permissions, INodes {
* - Validator must be included on trusted list if trusted list is enabled.
* - Validator must have sufficient stake to operate an additional node.
*/
- function checkPossibilityCreatingNode(address nodeAddress) external override allow("SkaleManager") {
- IValidatorService validatorService = IValidatorService(contractManager.getValidatorService());
+ function checkPossibilityCreatingNode(
+ address nodeAddress
+ )
+ external
+ override
+ allow("SkaleManager")
+ {
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getValidatorService());
uint256 validatorId = validatorService.getValidatorIdByNodeAddress(nodeAddress);
- require(validatorService.isAuthorizedValidator(validatorId), "Validator is not authorized to create a node");
- require(
- _checkValidatorPositionToMaintainNode(validatorId, validatorToNodeIndexes[validatorId].length),
- "Validator must meet the Minimum Staking Requirement");
+ if (!validatorService.isAuthorizedValidator(validatorId)) {
+ revert ValidatorIsNotAuthorized(validatorId);
+ }
+ if (!_checkValidatorPositionToMaintainNode(
+ validatorId,
+ validatorToNodeIndexes[validatorId].length
+ )) {
+ revert MinimumStakingRequirementIsNotMet();
+ }
}
/**
@@ -377,11 +422,16 @@ contract Nodes is Permissions, INodes {
allow("Bounty")
returns (bool successful)
{
- IValidatorService validatorService = IValidatorService(contractManager.getValidatorService());
- require(validatorService.validatorExists(validatorId), "Validator ID does not exist");
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getValidatorService());
+ if (!validatorService.validatorExists(validatorId)) {
+ revert ValidatorDoesNotExist(validatorId);
+ }
uint256[] memory validatorNodes = validatorToNodeIndexes[validatorId];
uint256 position = _findNode(validatorNodes, nodeIndex);
- require(position < validatorNodes.length, "Node does not exist for this Validator");
+ if (position >= validatorNodes.length) {
+ revert NodeDoesNotExistForValidator(validatorId, nodeIndex);
+ }
return _checkValidatorPositionToMaintainNode(validatorId, position);
}
@@ -393,8 +443,16 @@ contract Nodes is Permissions, INodes {
* - Node must already be Active.
* - `msg.sender` must be owner of Node, validator, or SkaleManager.
*/
- function setNodeInMaintenance(uint256 nodeIndex) external override onlyNodeOrNodeManager(nodeIndex) {
- require(nodes[nodeIndex].status == NodeStatus.Active, "Node is not Active");
+ function setNodeInMaintenance(
+ uint256 nodeIndex
+ )
+ external
+ override
+ onlyNodeOrNodeManager(nodeIndex)
+ {
+ if (!(nodes[nodeIndex].status == NodeStatus.Active)) {
+ revert NodeIsNotActive(nodeIndex);
+ }
_setNodeInMaintenance(nodeIndex);
emit MaintenanceNode(nodeIndex, true);
}
@@ -407,8 +465,16 @@ contract Nodes is Permissions, INodes {
* - Node must already be In Maintenance.
* - `msg.sender` must be owner of Node, validator, or SkaleManager.
*/
- function removeNodeFromInMaintenance(uint256 nodeIndex) external override onlyNodeOrNodeManager(nodeIndex) {
- require(nodes[nodeIndex].status == NodeStatus.In_Maintenance, "Node is not In Maintenance");
+ function removeNodeFromInMaintenance(
+ uint256 nodeIndex
+ )
+ external
+ override
+ onlyNodeOrNodeManager(nodeIndex)
+ {
+ if (!(nodes[nodeIndex].status == NodeStatus.In_Maintenance)) {
+ revert NodeIsNotInMaintenance(nodeIndex);
+ }
_setNodeActive(nodeIndex);
emit MaintenanceNode(nodeIndex, false);
}
@@ -417,7 +483,14 @@ contract Nodes is Permissions, INodes {
* @dev Marks the node as incompliant
*
*/
- function setNodeIncompliant(uint256 nodeIndex) external override onlyCompliance checkNodeExists(nodeIndex) {
+ function setNodeIncompliant(
+ uint256 nodeIndex
+ )
+ external
+ override
+ onlyCompliance
+ checkNodeExists(nodeIndex)
+ {
if (!incompliant[nodeIndex]) {
incompliant[nodeIndex] = true;
_makeNodeInvisible(nodeIndex);
@@ -429,7 +502,14 @@ contract Nodes is Permissions, INodes {
* @dev Marks the node as compliant
*
*/
- function setNodeCompliant(uint256 nodeIndex) external override onlyCompliance checkNodeExists(nodeIndex) {
+ function setNodeCompliant(
+ uint256 nodeIndex
+ )
+ external
+ override
+ onlyCompliance
+ checkNodeExists(nodeIndex)
+ {
if (incompliant[nodeIndex]) {
incompliant[nodeIndex] = false;
_tryToMakeNodeVisible(nodeIndex);
@@ -465,7 +545,9 @@ contract Nodes is Permissions, INodes {
nonZeroIP(newIP)
{
if (newPublicIP != 0x0) {
- require(newIP == newPublicIP, "IP address is not the same");
+ if (newIP != newPublicIP) {
+ revert IpAndPublicIpIsDifferent(newIP, newPublicIP);
+ }
nodes[nodeIndex].publicIP = newPublicIP;
}
nodesIPCheck[nodes[nodeIndex].ip] = false;
@@ -488,7 +570,9 @@ contract Nodes is Permissions, INodes {
freeSpace == 0 ? 1 : freeSpace,
randomGenerator
).toUint8();
- require(place > 0, "Node not found");
+ if (place == 0) {
+ revert NodeNotFound();
+ }
return spaceToNodes[place][randomGenerator.random(spaceToNodes[place].length)];
}
@@ -502,7 +586,9 @@ contract Nodes is Permissions, INodes {
checkNodeExists(nodeIndex)
returns (bool timeForReward)
{
- return IBountyV2(contractManager.getBounty()).getNextRewardTimestamp(nodeIndex) <= block.timestamp;
+ return IBountyV2(
+ contractManager.getBounty()
+ ).getNextRewardTimestamp(nodeIndex) <= block.timestamp;
}
/**
@@ -519,7 +605,6 @@ contract Nodes is Permissions, INodes {
checkNodeExists(nodeIndex)
returns (bytes4 ip)
{
- require(nodeIndex < nodes.length, "Node does not exist");
return nodes[nodeIndex].ip;
}
@@ -668,7 +753,8 @@ contract Nodes is Permissions, INodes {
function getActiveNodeIds() external view override returns (uint256[] memory activeNodeIds) {
activeNodeIds = new uint256[](numberOfActiveNodes);
uint256 indexOfActiveNodeIds = 0;
- for (uint256 indexOfNodes = 0; indexOfNodes < nodes.length; indexOfNodes++) {
+ uint256 nodesLength = nodes.length;
+ for (uint256 indexOfNodes = 0; indexOfNodes < nodesLength; indexOfNodes++) {
if (isNodeActive(indexOfNodes)) {
activeNodeIds[indexOfActiveNodeIds] = indexOfNodes;
indexOfActiveNodeIds++;
@@ -704,15 +790,25 @@ contract Nodes is Permissions, INodes {
override
returns (uint256[] memory validatorNodes)
{
- IValidatorService validatorService = IValidatorService(contractManager.getValidatorService());
- require(validatorService.validatorExists(validatorId), "Validator ID does not exist");
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getValidatorService());
+ if (!validatorService.validatorExists(validatorId)) {
+ revert ValidatorDoesNotExist(validatorId);
+ }
return validatorToNodeIndexes[validatorId];
}
/**
* @dev Returns number of nodes with available space.
*/
- function countNodesWithFreeSpace(uint8 freeSpace) external view override returns (uint256 count) {
+ function countNodesWithFreeSpace(
+ uint8 freeSpace
+ )
+ external
+ view
+ override
+ returns (uint256 count)
+ {
if (freeSpace == 0) {
return _nodesAmountBySpace.sumFromPlaceToLast(1);
}
@@ -932,24 +1028,69 @@ contract Nodes is Permissions, INodes {
IDelegationController delegationController = IDelegationController(
contractManager.getContract("DelegationController")
);
- uint256 delegationsTotal = delegationController.getAndUpdateDelegatedToValidatorNow(validatorId);
- uint256 msr = ConstantsHolder(contractManager.getConstantsHolder()).msr();
+ uint256 delegationsTotal =
+ delegationController.getAndUpdateDelegatedToValidatorNow(validatorId);
+ uint256 msr = IConstantsHolder(contractManager.getConstantsHolder()).msr();
return (position + 1) * msr <= delegationsTotal;
}
+ function _addNode(
+ uint256 validatorId,
+ address nodeAddress,
+ NodeCreationParams calldata params
+ )
+ private
+ returns (uint256 nodeIndex)
+ {
+ nodes.push(Node({
+ name: params.name,
+ ip: params.ip,
+ publicIP: params.publicIp,
+ port: params.port,
+ publicKey: params.publicKey,
+ startBlock: block.number,
+ lastRewardDate: block.timestamp,
+ finishTime: 0,
+ status: NodeStatus.Active,
+ validatorId: validatorId
+ }));
+
+ uint8 totalSpace = IConstantsHolder(
+ contractManager.getContract("ConstantsHolder")
+ ).TOTAL_SPACE_ON_NODE();
+
+ nodeIndex = nodes.length - 1;
+ validatorToNodeIndexes[validatorId].push(nodeIndex);
+ bytes32 nodeHashName = keccak256(abi.encodePacked(params.name));
+ nodesIPCheck[params.ip] = true;
+ nodesNameCheck[nodeHashName] = true;
+ nodesNameToIndex[nodeHashName] = nodeIndex;
+ nodeIndexes[nodeAddress].isNodeExist[nodeIndex] = true;
+ nodeIndexes[nodeAddress].numberOfNodes++;
+ domainNames[nodeIndex] = params.domainName;
+ spaceOfNodes.push(SpaceManaging({
+ freeSpace: totalSpace,
+ indexInSpaceMap: spaceToNodes[totalSpace].length
+ }));
+ }
+
function _checkNodeIndex(uint256 nodeIndex) private view {
- require(nodeIndex < nodes.length, "Node with such index does not exist");
+ if (nodeIndex >= nodes.length) {
+ revert NodeDoesNotExist(nodeIndex);
+ }
}
function _checkNodeOrNodeManager(uint256 nodeIndex, address sender) private view {
- IValidatorService validatorService = IValidatorService(contractManager.getValidatorService());
-
- require(
- isNodeExist(sender, nodeIndex) ||
- hasRole(NODE_MANAGER_ROLE, msg.sender) ||
- getValidatorId(nodeIndex) == validatorService.getValidatorId(sender),
- "Sender is not permitted to call this function"
- );
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getValidatorService());
+
+ if (
+ !isNodeExist(sender, nodeIndex) &&
+ !hasRole(NODE_MANAGER_ROLE, msg.sender) &&
+ !(getValidatorId(nodeIndex) == validatorService.getValidatorId(sender))
+ ) {
+ revert SenderIsNotPermitted(sender);
+ }
}
function _canBeVisible(uint256 nodeIndex) private view returns (bool can) {
@@ -959,7 +1100,14 @@ contract Nodes is Permissions, INodes {
/**
* @dev Returns the index of a given node within the validator's node index.
*/
- function _findNode(uint256[] memory validatorNodeIndexes, uint256 nodeIndex) private pure returns (uint256 node) {
+ function _findNode(
+ uint256[] memory validatorNodeIndexes,
+ uint256 nodeIndex
+ )
+ private
+ pure
+ returns (uint256 node)
+ {
uint256 i;
for (i = 0; i < validatorNodeIndexes.length; i++) {
if (validatorNodeIndexes[i] == nodeIndex) {
@@ -969,7 +1117,13 @@ contract Nodes is Permissions, INodes {
return validatorNodeIndexes.length;
}
- function _publicKeyToAddress(bytes32[2] memory pubKey) private pure returns (address nodeAddress) {
+ function _publicKeyToAddress(
+ bytes32[2] memory pubKey
+ )
+ private
+ pure
+ returns (address nodeAddress)
+ {
bytes32 hash = keccak256(abi.encodePacked(pubKey[0], pubKey[1]));
bytes20 addr;
for (uint8 i = 12; i < 32; i++) {
diff --git a/contracts/PaymasterController.sol b/contracts/PaymasterController.sol
new file mode 100644
index 000000000..030d4885f
--- /dev/null
+++ b/contracts/PaymasterController.sol
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: AGPL-3.0-only
+
+/*
+ PaymasterController.sol - SKALE Manager
+ Copyright (C) 2024-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 .
+*/
+
+pragma solidity 0.8.26;
+
+import {
+ AddressUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
+import { Encoder } from "@skalenetwork/marionette-interfaces/Encoder.sol";
+import {
+ IMessageProxyForMainnet
+} from "@skalenetwork/ima-interfaces/mainnet/IMessageProxyForMainnet.sol";
+import { IMarionette } from "@skalenetwork/marionette-interfaces/IMarionette.sol";
+import { IPaymaster } from "@skalenetwork/paymaster-interfaces/IPaymaster.sol";
+import {
+ IPaymasterController
+} from "@skalenetwork/skale-manager-interfaces/IPaymasterController.sol";
+
+import { IsNotContract, RoleRequired } from "./CommonErrors.sol";
+import { Permissions } from "./Permissions.sol";
+
+
+/**
+ * @title PaymasterController
+ * @dev This contract serves to interact with Paymaster contract
+ * on Europa chain.
+ *
+ */
+contract PaymasterController is IPaymasterController, Permissions {
+ using AddressUpgradeable for address;
+ using AddressUpgradeable for address payable;
+
+ bytes32 public constant PAYMASTER_SETTER_ROLE = keccak256("PAYMASTER_SETTER_ROLE");
+
+ IMessageProxyForMainnet public ima;
+ IMarionette public marionette;
+ IPaymaster public paymaster;
+ bytes32 public paymasterChainHash;
+
+ error MessageProxyForMainnetAddressIsNotSet();
+ error MarionetteAddressIsNotSet();
+ error PaymasterAddressIsNotSet();
+ error EuropaChainHashIsNotSet();
+
+ modifier whenConfigured() {
+ if (address(ima) == address(0)) {
+ revert MessageProxyForMainnetAddressIsNotSet();
+ }
+ if (address(marionette) == address(0)) {
+ revert MarionetteAddressIsNotSet();
+ }
+ if (address(paymaster) == address(0)) {
+ revert PaymasterAddressIsNotSet();
+ }
+ if (paymasterChainHash == 0) {
+ revert EuropaChainHashIsNotSet();
+ }
+ _;
+ }
+
+ modifier onlyPaymasterSetter() {
+ if (!hasRole(PAYMASTER_SETTER_ROLE, msg.sender)) {
+ revert RoleRequired(PAYMASTER_SETTER_ROLE);
+ }
+ _;
+ }
+
+ function initialize(address contractManagerAddress) public override initializer {
+ Permissions.initialize(contractManagerAddress);
+ _setupRole(PAYMASTER_SETTER_ROLE, msg.sender);
+ }
+
+ function setImaAddress(address imaAddress) external override onlyPaymasterSetter {
+ if (!imaAddress.isContract()) {
+ revert IsNotContract(imaAddress);
+ }
+ ima = IMessageProxyForMainnet(imaAddress);
+ }
+
+ function setMarionetteAddress(
+ address payable marionetteAddress
+ )
+ external
+ override
+ onlyPaymasterSetter
+ {
+ if (!marionetteAddress.isContract()) {
+ revert IsNotContract(marionetteAddress);
+ }
+ marionette = IMarionette(marionetteAddress);
+ }
+
+ function setPaymasterAddress(address paymasterAddress) external override onlyPaymasterSetter {
+ if (!paymasterAddress.isContract()) {
+ revert IsNotContract(paymasterAddress);
+ }
+ paymaster = IPaymaster(paymasterAddress);
+ }
+
+ function setPaymasterChainHash(bytes32 chainHash) external override onlyPaymasterSetter {
+ paymasterChainHash = chainHash;
+ }
+
+ function addSchain(string calldata name) external override allow("Schains") {
+ _callPaymaster(abi.encodeWithSelector(
+ paymaster.addSchain.selector,
+ name
+ ));
+ }
+
+ function removeSchain(bytes32 schainHash) external override allow("Schains") {
+ _callPaymaster(abi.encodeWithSelector(
+ paymaster.removeSchain.selector,
+ schainHash
+ ));
+ }
+
+ function addValidator(
+ uint256 validatorId,
+ address validatorAddress
+ )
+ external
+ override
+ allow("ValidatorService")
+ {
+ _callPaymaster(abi.encodeWithSelector(
+ paymaster.addValidator.selector,
+ validatorId,
+ validatorAddress
+ ));
+ }
+
+ function setValidatorAddress(
+ uint256 validatorId,
+ address validatorAddress
+ )
+ external
+ override
+ allow("ValidatorService")
+ {
+ _callPaymaster(abi.encodeWithSelector(
+ paymaster.setValidatorAddress.selector,
+ validatorId,
+ validatorAddress
+ ));
+ }
+
+ function setNodesAmount(
+ uint256 validatorId,
+ uint256 nodesAmount
+ )
+ external
+ override
+ allow("Nodes")
+ {
+ _callPaymaster(abi.encodeWithSelector(
+ paymaster.setNodesAmount.selector,
+ validatorId,
+ nodesAmount
+ ));
+ }
+
+ function _callPaymaster(bytes memory data) private whenConfigured {
+ ima.postOutgoingMessage(
+ paymasterChainHash,
+ address(marionette),
+ Encoder.encodeFunctionCall(
+ address(paymaster),
+ 0,
+ data
+ )
+ );
+ }
+}
diff --git a/contracts/Permissions.sol b/contracts/Permissions.sol
index b6fd25bde..688bc9f01 100644
--- a/contracts/Permissions.sol
+++ b/contracts/Permissions.sol
@@ -19,13 +19,17 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity ^0.8.17;
-import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
+import {
+ AddressUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
import { IPermissions } from "@skalenetwork/skale-manager-interfaces/IPermissions.sol";
-import { AccessControlUpgradeableLegacy } from "./thirdparty/openzeppelin/AccessControlUpgradeableLegacy.sol";
+import {
+ AccessControlUpgradeableLegacy
+} from "./thirdparty/openzeppelin/AccessControlUpgradeableLegacy.sol";
/**
@@ -102,7 +106,12 @@ contract Permissions is AccessControlUpgradeableLegacy, IPermissions {
* - The caller must be the owner, `contractName1`, `contractName2`, or
* `contractName3`.
*/
- modifier allowThree(string memory contractName1, string memory contractName2, string memory contractName3) {
+ modifier allowThree(
+ string memory contractName1,
+ string memory contractName2,
+ string memory contractName3
+ )
+ {
require(
contractManager.getContract(contractName1) == msg.sender ||
contractManager.getContract(contractName2) == msg.sender ||
@@ -123,9 +132,11 @@ contract Permissions is AccessControlUpgradeableLegacy, IPermissions {
}
function _isAdmin(address account) internal view returns (bool admin) {
- address skaleManagerAddress = contractManager.contracts(keccak256(abi.encodePacked("SkaleManager")));
+ address skaleManagerAddress =
+ contractManager.contracts(keccak256(abi.encodePacked("SkaleManager")));
if (skaleManagerAddress != address(0)) {
- AccessControlUpgradeableLegacy skaleManager = AccessControlUpgradeableLegacy(skaleManagerAddress);
+ AccessControlUpgradeableLegacy skaleManager =
+ AccessControlUpgradeableLegacy(skaleManagerAddress);
return skaleManager.hasRole(keccak256("ADMIN_ROLE"), account) || _isOwner();
} else {
return _isOwner();
diff --git a/contracts/Pricing.sol b/contracts/Pricing.sol
deleted file mode 100644
index 3434a629f..000000000
--- a/contracts/Pricing.sol
+++ /dev/null
@@ -1,142 +0,0 @@
-// SPDX-License-Identifier: AGPL-3.0-only
-
-/*
- Pricing.sol - SKALE Manager
- Copyright (C) 2018-Present SKALE Labs
- @author Artem Payvin
- @author Vadim Yavorsky
-
- 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 .
-*/
-
-pragma solidity 0.8.17;
-
-import { IPricing } from "@skalenetwork/skale-manager-interfaces/IPricing.sol";
-import { ISchainsInternal } from "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol";
-import { INodes } from "@skalenetwork/skale-manager-interfaces/INodes.sol";
-
-import { Permissions } from "./Permissions.sol";
-import { ConstantsHolder } from "./ConstantsHolder.sol";
-
-/**
- * @title Pricing
- * @dev Contains pricing operations for SKALE network.
- */
-contract Pricing is Permissions, IPricing {
-
- uint256 public constant INITIAL_PRICE = 5 * 10**6;
-
- uint256 public price;
- uint256 public totalNodes;
- uint256 public lastUpdated;
-
- function initialize(address newContractsAddress) public override initializer {
- Permissions.initialize(newContractsAddress);
- lastUpdated = block.timestamp;
- price = INITIAL_PRICE;
- }
-
- function initNodes() external override {
- INodes nodes = INodes(contractManager.getContract("Nodes"));
- totalNodes = nodes.getNumberOnlineNodes();
- }
-
- /**
- * @dev Adjust the schain price based on network capacity and demand.
- *
- * Requirements:
- *
- * - Cooldown time has exceeded.
- */
- function adjustPrice() external override {
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
- require(
- block.timestamp > lastUpdated + constantsHolder.COOLDOWN_TIME(),
- "It's not a time to update a price"
- );
- checkAllNodes();
- uint256 load = _getTotalLoad();
- uint256 capacity = _getTotalCapacity();
-
- bool networkIsOverloaded = load * 100 > constantsHolder.OPTIMAL_LOAD_PERCENTAGE() * capacity;
- uint256 loadDiff;
- if (networkIsOverloaded) {
- loadDiff = load * 100 - constantsHolder.OPTIMAL_LOAD_PERCENTAGE() * capacity;
- } else {
- loadDiff = constantsHolder.OPTIMAL_LOAD_PERCENTAGE() * capacity - load * 100;
- }
-
- uint256 priceChangeSpeedMultipliedByCapacityAndMinPrice =
- constantsHolder.ADJUSTMENT_SPEED() * loadDiff * price;
-
- uint256 timeSkipped = block.timestamp - lastUpdated;
-
- uint256 priceChange = priceChangeSpeedMultipliedByCapacityAndMinPrice
- * timeSkipped
- / constantsHolder.COOLDOWN_TIME()
- / capacity
- / constantsHolder.MIN_PRICE();
-
- if (networkIsOverloaded) {
- assert(priceChange > 0);
- price = price + priceChange;
- } else {
- if (priceChange > price) {
- price = constantsHolder.MIN_PRICE();
- } else {
- price = price - priceChange;
- if (price < constantsHolder.MIN_PRICE()) {
- price = constantsHolder.MIN_PRICE();
- }
- }
- }
- lastUpdated = block.timestamp;
- }
-
- /**
- * @dev Returns the total load percentage.
- */
- function getTotalLoadPercentage() external view override returns (uint256 load) {
- return _getTotalLoad() * 100 / _getTotalCapacity();
- }
-
- function checkAllNodes() public override {
- INodes nodes = INodes(contractManager.getContract("Nodes"));
- uint256 numberOfActiveNodes = nodes.getNumberOnlineNodes();
-
- require(totalNodes != numberOfActiveNodes, "No changes to node supply");
- totalNodes = numberOfActiveNodes;
- }
-
- function _getTotalLoad() private view returns (uint256 load) {
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
-
- load = 0;
- uint256 numberOfSchains = schainsInternal.numberOfSchains();
- for (uint256 i = 0; i < numberOfSchains; i++) {
- bytes32 schain = schainsInternal.schainsAtSystem(i);
- uint256 numberOfNodesInSchain = schainsInternal.getNumberOfNodesInGroup(schain);
- uint256 part = schainsInternal.getSchainsPartOfNode(schain);
- load = load + numberOfNodesInSchain * part;
- }
- return load;
- }
-
- function _getTotalCapacity() private view returns (uint256 capacity) {
- INodes nodes = INodes(contractManager.getContract("Nodes"));
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
-
- return nodes.getNumberOnlineNodes() * constantsHolder.TOTAL_SPACE_ON_NODE();
- }
-}
diff --git a/contracts/Schains.sol b/contracts/Schains.sol
index 8bd3e2764..1f15aff92 100644
--- a/contracts/Schains.sol
+++ b/contracts/Schains.sol
@@ -19,11 +19,14 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity 0.8.26;
-import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
+import {
+ AddressUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import { EnumerableSetUpgradeable }
from "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";
+import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
import { ISchains } from "@skalenetwork/skale-manager-interfaces/ISchains.sol";
import { ISkaleVerifier } from "@skalenetwork/skale-manager-interfaces/ISkaleVerifier.sol";
import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
@@ -32,9 +35,10 @@ import { IKeyStorage } from "@skalenetwork/skale-manager-interfaces/IKeyStorage.
import { INodeRotation } from "@skalenetwork/skale-manager-interfaces/INodeRotation.sol";
import { IWallets } from "@skalenetwork/skale-manager-interfaces/IWallets.sol";
-import { Permissions } from "./Permissions.sol";
-import { ConstantsHolder } from "./ConstantsHolder.sol";
import { G2Operations } from "./utils/fieldOperations/G2Operations.sol";
+import { NotEnoughFunds, RoleRequired } from "./CommonErrors.sol";
+import { PaymasterController } from "./PaymasterController.sol";
+import { Permissions } from "./Permissions.sol";
/**
@@ -62,8 +66,24 @@ contract Schains is Permissions, ISchains {
bytes32 public constant SCHAIN_CREATOR_ROLE = keccak256("SCHAIN_CREATOR_ROLE");
+ error SchainDoesNotExist(bytes32 schainHash);
+ error SchainIsCreatedTooEarly();
+ error SchainLifetimeIsTooSmall();
+ error SenderIsNotTheOwnerOfTheSchain();
+ error DkgWasNotFailed();
+ error NoFreeNodes();
+ error SchainNameIsNotAvailable(string schainName);
+ error OriginatorIsAContract(address originator);
+ error OriginatorIsNotProvided();
+ error NodeDoesNotContainGivenSchain(uint256 node, bytes32 schain);
+ error OptionIsAlreadySet(string optionName);
+ error OptionRemovingError(bytes32 optionHash);
+ error OptionIsNotSet(bytes32 schainHash, bytes32 optionHash);
+
modifier schainExists(ISchainsInternal schainsInternal, bytes32 schainHash) {
- require(schainsInternal.isSchainExist(schainHash), "The schain does not exist");
+ if(!schainsInternal.isSchainExist(schainHash)) {
+ revert SchainDoesNotExist(schainHash);
+ }
_;
}
@@ -82,19 +102,28 @@ contract Schains is Permissions, ISchains {
* - There is sufficient deposit to create type of schain.
* - If from is a smart contract originator must be specified
*/
- function addSchain(address from, uint256 deposit, bytes calldata data) external override allow("SkaleManager") {
+ function addSchain(
+ address from,
+ uint256 deposit,
+ bytes calldata data
+ )
+ external
+ override
+ allow("SkaleManager")
+ {
SchainParameters memory schainParameters = abi.decode(data, (SchainParameters));
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getConstantsHolder());
+ IConstantsHolder constantsHolder = IConstantsHolder(contractManager.getConstantsHolder());
uint256 schainCreationTimeStamp = constantsHolder.schainCreationTimeStamp();
uint256 minSchainLifetime = constantsHolder.minimalSchainLifetime();
- require(block.timestamp >= schainCreationTimeStamp, "It is not a time for creating Schain");
- require(
- schainParameters.lifetime >= minSchainLifetime,
- "Minimal schain lifetime should be satisfied"
- );
- require(
- getSchainPrice(schainParameters.typeOfSchain, schainParameters.lifetime) <= deposit,
- "Not enough money to create Schain");
+ if(block.timestamp < schainCreationTimeStamp) {
+ revert SchainIsCreatedTooEarly();
+ }
+ if (schainParameters.lifetime < minSchainLifetime) {
+ revert SchainLifetimeIsTooSmall();
+ }
+ if (deposit < getSchainPrice(schainParameters.typeOfSchain, schainParameters.lifetime)) {
+ revert NotEnoughFunds();
+ }
_addSchain(from, deposit, schainParameters);
}
@@ -122,7 +151,9 @@ contract Schains is Permissions, ISchains {
payable
override
{
- require(hasRole(SCHAIN_CREATOR_ROLE, msg.sender), "Sender is not authorized to create schain");
+ if (!hasRole(SCHAIN_CREATOR_ROLE, msg.sender)) {
+ revert RoleRequired(SCHAIN_CREATOR_ROLE);
+ }
SchainParameters memory schainParameters = SchainParameters({
lifetime: lifetime,
@@ -142,7 +173,9 @@ contract Schains is Permissions, ISchains {
_addSchain(_schainOwner, 0, schainParameters);
bytes32 schainHash = keccak256(abi.encodePacked(name));
- IWallets(payable(contractManager.getContract("Wallets"))).rechargeSchainWallet{value: msg.value}(schainHash);
+ IWallets(
+ payable(contractManager.getContract("Wallets"))
+ ).rechargeSchainWallet{value: msg.value}(schainHash);
}
/**
@@ -155,13 +188,20 @@ contract Schains is Permissions, ISchains {
*
* - Executed by schain owner.
*/
- function deleteSchain(address from, string calldata name) external override allow("SkaleManager") {
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ function deleteSchain(
+ address from,
+ string calldata name
+ )
+ external
+ override
+ allow("SkaleManager")
+ {
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
bytes32 schainHash = keccak256(abi.encodePacked(name));
- require(
- schainsInternal.isOwnerAddress(from, schainHash),
- "Message sender is not the owner of the Schain"
- );
+ if (!schainsInternal.isOwnerAddress(from, schainHash)) {
+ revert SenderIsNotTheOwnerOfTheSchain();
+ }
_deleteSchain(name, schainsInternal);
}
@@ -196,10 +236,14 @@ contract Schains is Permissions, ISchains {
INodeRotation nodeRotation = INodeRotation(contractManager.getContract("NodeRotation"));
bytes32 schainHash = keccak256(abi.encodePacked(name));
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
- require(!skaleDKG.isLastDKGSuccessful(schainHash), "DKG success");
+ if (skaleDKG.isLastDKGSuccessful(schainHash)) {
+ revert DkgWasNotFailed();
+ }
ISchainsInternal schainsInternal = ISchainsInternal(
contractManager.getContract("SchainsInternal"));
- require(schainsInternal.isAnyFreeNode(schainHash), "No free Nodes for new group formation");
+ if (!schainsInternal.isAnyFreeNode(schainHash)) {
+ revert NoFreeNodes();
+ }
uint256 newNodeIndex = nodeRotation.rotateNode(
skaleDKG.pendingToBeReplaced(schainHash),
schainHash,
@@ -234,7 +278,9 @@ contract Schains is Permissions, ISchains {
bytes32 schainHash = keccak256(abi.encodePacked(schainName));
if (
INodeRotation(contractManager.getContract("NodeRotation")).isNewNodeFound(schainHash) &&
- INodeRotation(contractManager.getContract("NodeRotation")).isRotationInProgress(schainHash) &&
+ INodeRotation(
+ contractManager.getContract("NodeRotation")
+ ).isRotationInProgress(schainHash) &&
ISkaleDKG(contractManager.getContract("SkaleDKG")).isLastDKGSuccessful(schainHash)
) {
publicKey = IKeyStorage(
@@ -277,7 +323,14 @@ contract Schains is Permissions, ISchains {
return _getOption(schainHash, optionHash, schainsInternal);
}
- function getOptions(bytes32 schainHash) external view override returns (SchainOption[] memory option) {
+ function getOptions(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (SchainOption[] memory option)
+ {
SchainOption[] memory options = new SchainOption[](_optionsIndex[schainHash].length());
for (uint256 i = 0; i < options.length; ++i) {
options[i] = _options[schainHash][_optionsIndex[schainHash].at(i)];
@@ -288,9 +341,18 @@ contract Schains is Permissions, ISchains {
/**
* @dev Returns the current price in SKL tokens for given Schain type and lifetime.
*/
- function getSchainPrice(uint256 typeOfSchain, uint256 lifetime) public view override returns (uint256 price) {
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getConstantsHolder());
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ function getSchainPrice(
+ uint256 typeOfSchain,
+ uint256 lifetime
+ )
+ public
+ view
+ override
+ returns (uint256 price)
+ {
+ IConstantsHolder constantsHolder = IConstantsHolder(contractManager.getConstantsHolder());
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
uint256 nodeDeposit = constantsHolder.NODE_DEPOSIT();
uint256 numberOfNodes;
uint8 divisor;
@@ -327,7 +389,9 @@ contract Schains is Permissions, ISchains {
)
private
{
- require(schainsInternal.isSchainNameAvailable(name), "Schain name is not available");
+ if (!schainsInternal.isSchainNameAvailable(name)) {
+ revert SchainNameIsNotAvailable(name);
+ }
bytes32 schainHash = keccak256(abi.encodePacked(name));
for (uint256 i = 0; i < options.length; ++i) {
@@ -358,7 +422,11 @@ contract Schains is Permissions, ISchains {
)
private
{
- uint256[] memory nodesInGroup = schainsInternal.createGroupForSchain(schainHash, numberOfNodes, partOfNode);
+ uint256[] memory nodesInGroup = schainsInternal.createGroupForSchain(
+ schainHash,
+ numberOfNodes,
+ partOfNode
+ );
ISkaleDKG(contractManager.getContract("SkaleDKG")).openChannel(schainHash);
emit SchainNodes(
@@ -376,17 +444,18 @@ contract Schains is Permissions, ISchains {
*
* - Schain type must be valid.
*/
- function _addSchain(address from, uint256 deposit, SchainParameters memory schainParameters) private {
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
-
- require(!schainParameters.originator.isContract(), "Originator address must be not a contract");
- if (from.isContract()) {
- require(schainParameters.originator != address(0), "Originator address is not provided");
- } else {
- schainParameters.originator = address(0);
- }
+ function _addSchain(
+ address from,
+ uint256 deposit,
+ SchainParameters memory schainParameters
+ )
+ private
+ {
+ _checkOriginator(from, schainParameters);
//initialize Schain
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
_initializeSchainInSchainsInternal({
name: schainParameters.name,
from: from,
@@ -420,13 +489,16 @@ contract Schains is Permissions, ISchains {
nonce: schainParameters.nonce,
schainHash: keccak256(abi.encodePacked(schainParameters.name))
});
+
+ PaymasterController paymasterController =
+ PaymasterController(contractManager.getContract("PaymasterController"));
+ paymasterController.addSchain(schainParameters.name);
}
function _deleteSchain(string calldata name, ISchainsInternal schainsInternal) private {
INodeRotation nodeRotation = INodeRotation(contractManager.getContract("NodeRotation"));
bytes32 schainHash = keccak256(abi.encodePacked(name));
- require(schainsInternal.isSchainExist(schainHash), "Schain does not exist");
_deleteOptions(schainHash, schainsInternal);
@@ -435,10 +507,9 @@ contract Schains is Permissions, ISchains {
if (schainsInternal.checkHoleForSchain(schainHash, i)) {
continue;
}
- require(
- schainsInternal.checkSchainOnNode(nodesInGroup[i], schainHash),
- "Some Node does not contain given Schain"
- );
+ if (!schainsInternal.checkSchainOnNode(nodesInGroup[i], schainHash)) {
+ revert NodeDoesNotContainGivenSchain(nodesInGroup[i], schainHash);
+ }
schainsInternal.removeNodeFromSchain(nodesInGroup[i], schainHash);
}
schainsInternal.removeAllNodesFromSchainExceptions(schainHash);
@@ -451,6 +522,10 @@ contract Schains is Permissions, ISchains {
payable(contractManager.getContract("Wallets"))
).withdrawFundsFromSchainWallet(payable(from), schainHash);
emit SchainDeleted(from, name, schainHash);
+
+ PaymasterController paymasterController =
+ PaymasterController(contractManager.getContract("PaymasterController"));
+ paymasterController.removeSchain(schainHash);
}
function _setOption(
@@ -461,7 +536,9 @@ contract Schains is Permissions, ISchains {
{
bytes32 optionHash = keccak256(abi.encodePacked(option.name));
_options[schainHash][optionHash] = option;
- require(_optionsIndex[schainHash].add(optionHash), "The option has been set already");
+ if (!_optionsIndex[schainHash].add(optionHash)) {
+ revert OptionIsAlreadySet(option.name);
+ }
}
function _deleteOptions(
@@ -474,7 +551,9 @@ contract Schains is Permissions, ISchains {
while (_optionsIndex[schainHash].length() > 0) {
bytes32 optionHash = _optionsIndex[schainHash].at(0);
delete _options[schainHash][optionHash];
- require(_optionsIndex[schainHash].remove(optionHash), "Removing error");
+ if (!_optionsIndex[schainHash].remove(optionHash)) {
+ revert OptionRemovingError(optionHash);
+ }
}
}
@@ -488,7 +567,22 @@ contract Schains is Permissions, ISchains {
schainExists(schainsInternal, schainHash)
returns (bytes memory option)
{
- require(_optionsIndex[schainHash].contains(optionHash), "Option is not set");
+ if (!_optionsIndex[schainHash].contains(optionHash)) {
+ revert OptionIsNotSet(schainHash, optionHash);
+ }
return _options[schainHash][optionHash].value;
}
+
+ function _checkOriginator(address from, SchainParameters memory schainParameters) private view {
+ if (schainParameters.originator.isContract()) {
+ revert OriginatorIsAContract(schainParameters.originator);
+ }
+ if (from.isContract()) {
+ if (schainParameters.originator == address(0)) {
+ revert OriginatorIsNotProvided();
+ }
+ } else {
+ schainParameters.originator = address(0);
+ }
+ }
}
diff --git a/contracts/SchainsInternal.sol b/contracts/SchainsInternal.sol
index 1e609bee7..9a0c62d0f 100644
--- a/contracts/SchainsInternal.sol
+++ b/contracts/SchainsInternal.sol
@@ -91,7 +91,10 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
bytes32 public constant GENERATION_MANAGER_ROLE = keccak256("GENERATION_MANAGER_ROLE");
modifier onlySchainTypeManager() {
- require(hasRole(SCHAIN_TYPE_MANAGER_ROLE, msg.sender), "SCHAIN_TYPE_MANAGER_ROLE is required");
+ require(
+ hasRole(SCHAIN_TYPE_MANAGER_ROLE, msg.sender),
+ "SCHAIN_TYPE_MANAGER_ROLE is required"
+ );
_;
}
@@ -101,7 +104,10 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
}
modifier onlyGenerationManager() {
- require(hasRole(GENERATION_MANAGER_ROLE, msg.sender), "GENERATION_MANAGER_ROLE is required");
+ require(
+ hasRole(GENERATION_MANAGER_ROLE, msg.sender),
+ "GENERATION_MANAGER_ROLE is required"
+ );
_;
}
@@ -173,7 +179,8 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
schainExists(schainHash)
returns (uint256[] memory group)
{
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
+ ConstantsHolder constantsHolder =
+ ConstantsHolder(contractManager.getContract("ConstantsHolder"));
schains[schainHash].partOfNode = partOfNode;
if (partOfNode > 0) {
sumOfSchainsResources = sumOfSchainsResources +
@@ -270,7 +277,8 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
schainsGroups[schainHash].pop();
} else {
delete schainsGroups[schainHash][indexOfNode];
- if (holesForSchains[schainHash].length > 0 && holesForSchains[schainHash][0] > indexOfNode) {
+ if (holesForSchains[schainHash].length > 0
+ && holesForSchains[schainHash][0] > indexOfNode) {
uint256 hole = holesForSchains[schainHash][0];
holesForSchains[schainHash][0] = indexOfNode;
holesForSchains[schainHash].push(hole);
@@ -282,7 +290,10 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
removeSchainForNode(nodeIndex, placeOfSchainOnNode[schainHash][nodeIndex] - 1);
delete placeOfSchainOnNode[schainHash][nodeIndex];
INodes nodes = INodes(contractManager.getContract("Nodes"));
- require(_removeAddressFromSchain(schainHash, nodes.getNodeAddress(nodeIndex)), "Incorrect node address");
+ require(
+ _removeAddressFromSchain(schainHash, nodes.getNodeAddress(nodeIndex)),
+ "Incorrect node address"
+ );
nodes.addSpaceToNode(nodeIndex, schains[schainHash].partOfNode);
}
@@ -294,7 +305,14 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
* - Message sender is Schains smart contract
* - Schain must exist
*/
- function deleteGroup(bytes32 schainHash) external override allow("Schains") schainExists(schainHash) {
+ function deleteGroup(
+ bytes32 schainHash
+ )
+ external
+ override
+ allow("Schains")
+ schainExists(schainHash)
+ {
// delete channel
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
delete schainsGroups[schainHash];
@@ -371,14 +389,28 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
* - Message sender is Schains smart contract
* - Schain must exist
*/
- function removeHolesForSchain(bytes32 schainHash) external override allow("Schains") schainExists(schainHash) {
+ function removeHolesForSchain(
+ bytes32 schainHash
+ )
+ external
+ override
+ allow("Schains")
+ schainExists(schainHash)
+ {
delete holesForSchains[schainHash];
}
/**
* @dev Allows Admin to add schain type
*/
- function addSchainType(uint8 partOfNode, uint256 numberOfNodes) external override onlySchainTypeManager {
+ function addSchainType(
+ uint8 partOfNode,
+ uint256 numberOfNodes
+ )
+ external
+ override
+ onlySchainTypeManager
+ {
require(_keysOfSchainTypes.add(numberOfSchainTypes + 1), "Schain type is already added");
schainTypes[numberOfSchainTypes + 1].partOfNode = partOfNode;
schainTypes[numberOfSchainTypes + 1].numberOfNodes = numberOfNodes;
@@ -399,11 +431,23 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
/**
* @dev Allows Admin to set number of schain types
*/
- function setNumberOfSchainTypes(uint256 newNumberOfSchainTypes) external override onlySchainTypeManager {
+ function setNumberOfSchainTypes(
+ uint256 newNumberOfSchainTypes
+ )
+ external
+ override
+ onlySchainTypeManager
+ {
numberOfSchainTypes = newNumberOfSchainTypes;
}
- function removeNodeFromAllExceptionSchains(uint256 nodeIndex) external override allow("SkaleManager") {
+ function removeNodeFromAllExceptionSchains(
+ uint256 nodeIndex
+ )
+ external
+ override
+ allow("SkaleManager")
+ {
uint256 len = _nodeToLockedSchains[nodeIndex].length;
for (uint256 i = len; i > 0; i--) {
removeNodeFromExceptions(_nodeToLockedSchains[nodeIndex][i - 1], nodeIndex);
@@ -413,7 +457,13 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
/**
* @dev Clear list of nodes that can't be chosen to schain with id {schainHash}
*/
- function removeAllNodesFromSchainExceptions(bytes32 schainHash) external override allow("Schains") {
+ function removeAllNodesFromSchainExceptions(
+ bytes32 schainHash
+ )
+ external
+ override
+ allow("Schains")
+ {
uint256 nodesAmount = _schainToExceptionNodes[schainHash].length;
for (uint256 i = nodesAmount; i > 0; --i) {
removeNodeFromExceptions(schainHash, _schainToExceptionNodes[schainHash][i - 1]);
@@ -532,14 +582,28 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
/**
* @dev Returns hashes of schain names by schain owner.
*/
- function getSchainHashesByAddress(address from) external view override returns (bytes32[] memory schainsByOwner) {
+ function getSchainHashesByAddress(
+ address from
+ )
+ external
+ view
+ override
+ returns (bytes32[] memory schainsByOwner)
+ {
return schainIndexes[from];
}
/**
* @dev Returns hashes of schain names running on a node.
*/
- function getSchainHashesForNode(uint256 nodeIndex) external view override returns (bytes32[] memory nodeSchains) {
+ function getSchainHashesForNode(
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (bytes32[] memory nodeSchains)
+ {
return schainsForNodes[nodeIndex];
}
@@ -584,7 +648,14 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
* @dev Checks whether schain name is available.
* TODO Need to delete - copy of web3.utils.soliditySha3
*/
- function isSchainNameAvailable(string calldata name) external view override returns (bool available) {
+ function isSchainNameAvailable(
+ string calldata name
+ )
+ external
+ view
+ override
+ returns (bool available)
+ {
bytes32 schainHash = keccak256(abi.encodePacked(name));
return schains[schainHash].owner == address(0) &&
!usedSchainNames[schainHash] &&
@@ -599,7 +670,15 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
*
* - Schain must exist
*/
- function isTimeExpired(bytes32 schainHash) external view override schainExists(schainHash) returns (bool expired) {
+ function isTimeExpired(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ schainExists(schainHash)
+ returns (bool expired)
+ {
return uint(schains[schainHash].startDate) + schains[schainHash].lifetime < block.timestamp;
}
@@ -654,7 +733,14 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
/**
* @dev Returns active schains of a node.
*/
- function getActiveSchains(uint256 nodeIndex) external view override returns (bytes32[] memory activeSchains) {
+ function getActiveSchains(
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (bytes32[] memory activeSchains)
+ {
uint256 activeAmount = schainsForNodes[nodeIndex].length - holesForNodes[nodeIndex].length;
uint256 cursor = 0;
@@ -754,7 +840,15 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
*
* - Schain must exist
*/
- function isAnyFreeNode(bytes32 schainHash) external view override schainExists(schainHash) returns (bool free) {
+ function isAnyFreeNode(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ schainExists(schainHash)
+ returns (bool free)
+ {
// TODO:
// Move this function to Nodes?
INodes nodes = INodes(contractManager.getContract("Nodes"));
@@ -831,7 +925,14 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
return placeOfSchainOnNode[schainHash][nodeIndex] != 0;
}
- function getSchainType(uint256 typeOfSchain) external view override returns(uint8 partOfNode, uint256 schainType) {
+ function getSchainType(
+ uint256 typeOfSchain
+ )
+ external
+ view
+ override
+ returns(uint8 partOfNode, uint256 schainType)
+ {
require(_keysOfSchainTypes.contains(typeOfSchain), "Invalid type of schain");
return (schainTypes[typeOfSchain].partOfNode, schainTypes[typeOfSchain].numberOfNodes);
}
@@ -882,7 +983,10 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
placeOfSchainOnNode[schainHash][nodeIndex] = lastHoleOfNode + 1;
holesForNodes[nodeIndex].pop();
}
- require(_addAddressToSchain(schainHash, nodes.getNodeAddress(nodeIndex)), "Node address already exist");
+ require(
+ _addAddressToSchain(schainHash, nodes.getNodeAddress(nodeIndex)),
+ "Node address already exist"
+ );
}
/**
@@ -928,7 +1032,8 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
for (uint256 i = len; i > 0; i--) {
if (_nodeToLockedSchains[nodeIndex][i - 1] == schainHash) {
if (i != len) {
- _nodeToLockedSchains[nodeIndex][i - 1] = _nodeToLockedSchains[nodeIndex][len - 1];
+ _nodeToLockedSchains[nodeIndex][i - 1] =
+ _nodeToLockedSchains[nodeIndex][len - 1];
}
_nodeToLockedSchains[nodeIndex].pop();
break;
@@ -938,7 +1043,8 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
for (uint256 i = len; i > 0; i--) {
if (_schainToExceptionNodes[schainHash][i - 1] == nodeIndex) {
if (i != len) {
- _schainToExceptionNodes[schainHash][i - 1] = _schainToExceptionNodes[schainHash][len - 1];
+ _schainToExceptionNodes[schainHash][i - 1] =
+ _schainToExceptionNodes[schainHash][len - 1];
}
_schainToExceptionNodes[schainHash].pop();
break;
@@ -953,7 +1059,14 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
return bytes(schains[schainHash].name).length != 0;
}
- function _addAddressToSchain(bytes32 schainHash, address nodeAddress) internal virtual returns (bool successful) {
+ function _addAddressToSchain(
+ bytes32 schainHash,
+ address nodeAddress
+ )
+ internal
+ virtual
+ returns (bool successful)
+ {
return _nodeAddressInSchain[schainHash].add(nodeAddress);
}
@@ -987,12 +1100,21 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
/**
* @dev Generates schain group using a pseudo-random generator.
*/
- function _generateGroup(bytes32 schainHash, uint256 numberOfNodes) private returns (uint256[] memory nodesInGroup) {
+ function _generateGroup(
+ bytes32 schainHash,
+ uint256 numberOfNodes
+ )
+ private
+ returns (uint256[] memory nodesInGroup)
+ {
INodes nodes = INodes(contractManager.getContract("Nodes"));
uint8 space = schains[schainHash].partOfNode;
nodesInGroup = new uint256[](numberOfNodes);
- require(nodes.countNodesWithFreeSpace(space) >= nodesInGroup.length, "Not enough nodes to create Schain");
+ require(
+ nodes.countNodesWithFreeSpace(space) >= nodesInGroup.length,
+ "Not enough nodes to create Schain"
+ );
IRandom.RandomGenerator memory randomGenerator = Random.createFromEntropy(
abi.encodePacked(uint256(blockhash(block.number - 1)), schainHash)
);
@@ -1001,7 +1123,11 @@ contract SchainsInternal is Permissions, IPruningSchainsInternal {
nodesInGroup[i] = node;
_setException(schainHash, node);
addSchainForNode(nodes, node, schainHash);
+ // The function makeNodeInvisible does not do external calls
+ //slither-disable-next-line reentrancy-benign
nodes.makeNodeInvisible(node);
+ // The function removeSpaceFromNode does not do external calls
+ //slither-disable-next-line reentrancy-benign
require(nodes.removeSpaceFromNode(node, space), "Could not remove space from Node");
}
// set generated group
diff --git a/contracts/SkaleDKG.sol b/contracts/SkaleDKG.sol
index 38f28b1da..3d68ba1b5 100644
--- a/contracts/SkaleDKG.sol
+++ b/contracts/SkaleDKG.sol
@@ -185,7 +185,8 @@ contract SkaleDKG is Permissions, ISkaleDKG {
schainHash,
Context({
isDebt: true,
- delta: ConstantsHolder(contractManager.getConstantsHolder()).COMPLAINT_BAD_DATA_DELTA(),
+ delta: ConstantsHolder(contractManager.getConstantsHolder())
+ .COMPLAINT_BAD_DATA_DELTA(),
dkgFunction: DkgFunction.ComplaintBadData
}))
correctGroupWithoutRevert(schainHash)
@@ -326,7 +327,14 @@ contract SkaleDKG is Permissions, ISkaleDKG {
delete pendingToBeReplaced[schainHash];
}
- function finalizeSlashing(bytes32 schainHash, uint256 badNode) external override allow("SkaleDKG") {
+ function finalizeSlashing(
+ bytes32 schainHash,
+ uint256 badNode
+ )
+ external
+ override
+ allow("SkaleDKG")
+ {
INodeRotation nodeRotation = INodeRotation(contractManager.getContract("NodeRotation"));
ISchainsInternal schainsInternal = ISchainsInternal(
contractManager.getContract("SchainsInternal")
@@ -353,23 +361,58 @@ contract SkaleDKG is Permissions, ISkaleDKG {
);
}
- function getChannelStartedTime(bytes32 schainHash) external view override returns (uint256 timestamp) {
+ function getChannelStartedTime(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 timestamp)
+ {
return channels[schainHash].startedBlockTimestamp;
}
- function getChannelStartedBlock(bytes32 schainHash) external view override returns (uint256 blockNumber) {
+ function getChannelStartedBlock(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 blockNumber)
+ {
return channels[schainHash].startedBlock;
}
- function getNumberOfBroadcasted(bytes32 schainHash) external view override returns (uint256 amount) {
+ function getNumberOfBroadcasted(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 amount)
+ {
return dkgProcess[schainHash].numberOfBroadcasted;
}
- function getNumberOfCompleted(bytes32 schainHash) external view override returns (uint256 amount) {
+ function getNumberOfCompleted(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 amount)
+ {
return dkgProcess[schainHash].numberOfCompleted;
}
- function getTimeOfLastSuccessfulDKG(bytes32 schainHash) external view override returns (uint256 timestamp) {
+ function getTimeOfLastSuccessfulDKG(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 timestamp)
+ {
return lastSuccessfulDKG[schainHash];
}
@@ -384,11 +427,25 @@ contract SkaleDKG is Permissions, ISkaleDKG {
return (complaints[schainHash].fromNodeToComplaint, complaints[schainHash].nodeToComplaint);
}
- function getComplaintStartedTime(bytes32 schainHash) external view override returns (uint256 timestamp) {
+ function getComplaintStartedTime(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 timestamp)
+ {
return complaints[schainHash].startComplaintBlockTimestamp;
}
- function getAlrightStartedTime(bytes32 schainHash) external view override returns (uint256 timestamp) {
+ function getAlrightStartedTime(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (uint256 timestamp)
+ {
return startAlrightTimestamp[schainHash];
}
@@ -399,19 +456,35 @@ contract SkaleDKG is Permissions, ISkaleDKG {
return channels[schainHash].active;
}
- function isLastDKGSuccessful(bytes32 schainHash) external view override returns (bool successful) {
+ function isLastDKGSuccessful(
+ bytes32 schainHash
+ )
+ external
+ view
+ override
+ returns (bool successful)
+ {
return channels[schainHash].startedBlockTimestamp <= lastSuccessfulDKG[schainHash];
}
/**
* @dev Checks whether broadcast is possible.
*/
- function isBroadcastPossible(bytes32 schainHash, uint256 nodeIndex) external view override returns (bool possible) {
+ function isBroadcastPossible(
+ bytes32 schainHash,
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (bool possible)
+ {
(uint256 index, bool check) = checkAndReturnIndexInGroup(schainHash, nodeIndex, false);
return channels[schainHash].active &&
check &&
_isNodeOwnedByMessageSender(nodeIndex, msg.sender) &&
- channels[schainHash].startedBlockTimestamp + _getComplaintTimeLimit() > block.timestamp &&
+ channels[schainHash].startedBlockTimestamp + _getComplaintTimeLimit()
+ > block.timestamp &&
!dkgProcess[schainHash].broadcasted[index];
}
@@ -428,8 +501,16 @@ contract SkaleDKG is Permissions, ISkaleDKG {
override
returns (bool possible)
{
- (uint256 indexFrom, bool checkFrom) = checkAndReturnIndexInGroup(schainHash, fromNodeIndex, false);
- (uint256 indexTo, bool checkTo) = checkAndReturnIndexInGroup(schainHash, toNodeIndex, false);
+ (uint256 indexFrom, bool checkFrom) = checkAndReturnIndexInGroup(
+ schainHash,
+ fromNodeIndex,
+ false
+ );
+ (uint256 indexTo, bool checkTo) = checkAndReturnIndexInGroup(
+ schainHash,
+ toNodeIndex,
+ false
+ );
if (!checkFrom || !checkTo)
return false;
bool complaintSending = (
@@ -439,13 +520,15 @@ contract SkaleDKG is Permissions, ISkaleDKG {
) ||
(
dkgProcess[schainHash].broadcasted[indexTo] &&
- complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit() <= block.timestamp &&
+ complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit()
+ <= block.timestamp &&
complaints[schainHash].nodeToComplaint == toNodeIndex
) ||
(
!dkgProcess[schainHash].broadcasted[indexTo] &&
complaints[schainHash].nodeToComplaint == type(uint256).max &&
- channels[schainHash].startedBlockTimestamp + _getComplaintTimeLimit() <= block.timestamp
+ channels[schainHash].startedBlockTimestamp + _getComplaintTimeLimit()
+ <= block.timestamp
) ||
(
complaints[schainHash].nodeToComplaint == type(uint256).max &&
@@ -463,7 +546,15 @@ contract SkaleDKG is Permissions, ISkaleDKG {
/**
* @dev Checks whether sending Alright response is possible.
*/
- function isAlrightPossible(bytes32 schainHash, uint256 nodeIndex) external view override returns (bool possible) {
+ function isAlrightPossible(
+ bytes32 schainHash,
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (bool possible)
+ {
(uint256 index, bool check) = checkAndReturnIndexInGroup(schainHash, nodeIndex, false);
return channels[schainHash].active &&
check &&
@@ -492,20 +583,30 @@ contract SkaleDKG is Permissions, ISkaleDKG {
check &&
_isNodeOwnedByMessageSender(nodeIndex, msg.sender) &&
complaints[schainHash].nodeToComplaint == nodeIndex &&
- complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit() > block.timestamp &&
+ complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit()
+ > block.timestamp &&
!complaints[schainHash].isResponse;
}
/**
* @dev Checks whether sending a response is possible.
*/
- function isResponsePossible(bytes32 schainHash, uint256 nodeIndex) external view override returns (bool possible) {
+ function isResponsePossible(
+ bytes32 schainHash,
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (bool possible)
+ {
(, bool check) = checkAndReturnIndexInGroup(schainHash, nodeIndex, false);
return channels[schainHash].active &&
check &&
_isNodeOwnedByMessageSender(nodeIndex, msg.sender) &&
complaints[schainHash].nodeToComplaint == nodeIndex &&
- complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit() > block.timestamp &&
+ complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit()
+ > block.timestamp &&
complaints[schainHash].isResponse;
}
@@ -525,7 +626,15 @@ contract SkaleDKG is Permissions, ISkaleDKG {
/**
* @dev Checks whether all data has been received by node.
*/
- function isAllDataReceived(bytes32 schainHash, uint256 nodeIndex) external view override returns (bool received) {
+ function isAllDataReceived(
+ bytes32 schainHash,
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (bool received)
+ {
(uint256 index, bool check) = checkAndReturnIndexInGroup(schainHash, nodeIndex, false);
return check && dkgProcess[schainHash].completed[index];
}
@@ -541,7 +650,11 @@ contract SkaleDKG is Permissions, ISkaleDKG {
{
bytes memory data;
for (uint256 i = 0; i < secretKeyContribution.length; i++) {
- data = abi.encodePacked(data, secretKeyContribution[i].publicKey, secretKeyContribution[i].share);
+ data = abi.encodePacked(
+ data,
+ secretKeyContribution[i].publicKey,
+ secretKeyContribution[i].share
+ );
}
for (uint256 i = 0; i < verificationVector.length; i++) {
// Named arguments cannot be used for functions that take arbitrary parameters
@@ -575,32 +688,60 @@ contract SkaleDKG is Permissions, ISkaleDKG {
return (index, index < channels[schainHash].n);
}
- function isEveryoneBroadcasted(bytes32 schainHash) public view override returns (bool broadcasted) {
+ function isEveryoneBroadcasted(
+ bytes32 schainHash
+ )
+ public
+ view
+ override
+ returns (bool broadcasted)
+ {
return channels[schainHash].n == dkgProcess[schainHash].numberOfBroadcasted;
}
- function _refundGasBySchain(bytes32 schainHash, uint256 gasTotal, Context memory context) private {
+ function _refundGasBySchain(
+ bytes32 schainHash,
+ uint256 gasTotal,
+ Context memory context
+ )
+ private
+ {
IWallets wallets = IWallets(payable(contractManager.getContract("Wallets")));
bool isLastNode = channels[schainHash].n == dkgProcess[schainHash].numberOfCompleted;
if (context.dkgFunction == DkgFunction.Alright && isLastNode) {
wallets.refundGasBySchain(
- schainHash, payable(msg.sender), gasTotal - gasleft() + context.delta - 74800, context.isDebt
+ schainHash,
+ payable(msg.sender),
+ gasTotal - gasleft() + context.delta - 74800,
+ context.isDebt
);
} else if (context.dkgFunction == DkgFunction.Complaint && gasTotal - gasleft() > 14e5) {
wallets.refundGasBySchain(
- schainHash, payable(msg.sender), gasTotal - gasleft() + context.delta - 341979, context.isDebt
+ schainHash,
+ payable(msg.sender),
+ gasTotal - gasleft() + context.delta - 341979,
+ context.isDebt
);
} else if (context.dkgFunction == DkgFunction.Complaint && gasTotal - gasleft() > 7e5) {
wallets.refundGasBySchain(
- schainHash, payable(msg.sender), gasTotal - gasleft() + context.delta - 152214, context.isDebt
+ schainHash,
+ payable(msg.sender),
+ gasTotal - gasleft() + context.delta - 152214,
+ context.isDebt
);
} else if (context.dkgFunction == DkgFunction.Response){
wallets.refundGasBySchain(
- schainHash, payable(msg.sender), gasTotal - gasleft() + context.delta, context.isDebt
+ schainHash,
+ payable(msg.sender),
+ gasTotal - gasleft() + context.delta,
+ context.isDebt
);
} else {
wallets.refundGasBySchain(
- schainHash, payable(msg.sender), gasTotal - gasleft() + context.delta, context.isDebt
+ schainHash,
+ payable(msg.sender),
+ gasTotal - gasleft() + context.delta,
+ context.isDebt
);
}
}
@@ -637,12 +778,22 @@ contract SkaleDKG is Permissions, ISkaleDKG {
emit ChannelOpened(schainHash);
}
- function _isNodeOwnedByMessageSender(uint256 nodeIndex, address from) private view returns (bool owned) {
+ function _isNodeOwnedByMessageSender(
+ uint256 nodeIndex,
+ address from
+ )
+ private
+ view
+ returns (bool owned)
+ {
return INodes(contractManager.getContract("Nodes")).isNodeExist(from, nodeIndex);
}
function _checkMsgSenderIsNodeOwner(uint256 nodeIndex) private view {
- require(_isNodeOwnedByMessageSender(nodeIndex, msg.sender), "Node does not exist for message sender");
+ require(
+ _isNodeOwnedByMessageSender(nodeIndex, msg.sender),
+ "Node does not exist for message sender"
+ );
}
function _getComplaintTimeLimit() private view returns (uint256 timeLimit) {
diff --git a/contracts/SkaleManager.sol b/contracts/SkaleManager.sol
index 4406c13a1..0bbf5c605 100644
--- a/contracts/SkaleManager.sol
+++ b/contracts/SkaleManager.sol
@@ -28,7 +28,9 @@ import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Re
import { ISkaleManager } from "@skalenetwork/skale-manager-interfaces/ISkaleManager.sol";
import { IMintableToken } from "@skalenetwork/skale-manager-interfaces/IMintableToken.sol";
import { IDistributor } from "@skalenetwork/skale-manager-interfaces/delegation/IDistributor.sol";
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
import { IBountyV2 } from "@skalenetwork/skale-manager-interfaces/IBountyV2.sol";
import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
import { INodeRotation } from "@skalenetwork/skale-manager-interfaces/INodeRotation.sol";
@@ -62,7 +64,11 @@ contract SkaleManager is IERC777Recipient, ISkaleManager, Permissions {
function initialize(address newContractsAddress) public override initializer {
Permissions.initialize(newContractsAddress);
_erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
- _erc1820.setInterfaceImplementer(address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, address(this));
+ _erc1820.setInterfaceImplementer(
+ address(this),
+ _TOKENS_RECIPIENT_INTERFACE_HASH,
+ address(this)
+ );
}
function tokensReceived(
@@ -115,7 +121,8 @@ contract SkaleManager is IERC777Recipient, ISkaleManager, Permissions {
function nodeExit(uint256 nodeIndex) external override {
uint256 gasLimit = _getGasLimit();
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getContract("ValidatorService"));
INodeRotation nodeRotation = INodeRotation(contractManager.getContract("NodeRotation"));
INodes nodes = INodes(contractManager.getContract("Nodes"));
uint256 validatorId = nodes.getValidatorId(nodeIndex);
@@ -135,7 +142,8 @@ contract SkaleManager is IERC777Recipient, ISkaleManager, Permissions {
nodeIndex,
block.timestamp + (
isSchains ?
- IConstantsHolder(contractManager.getContract("ConstantsHolder")).rotationDelay() :
+ IConstantsHolder(contractManager.getContract("ConstantsHolder"))
+ .rotationDelay() :
0
)
);
@@ -195,12 +203,23 @@ contract SkaleManager is IERC777Recipient, ISkaleManager, Permissions {
IDistributor distributor = IDistributor(contractManager.getContract("Distributor"));
require(
- IMintableToken(address(skaleToken)).mint(address(distributor), bounty, abi.encode(validatorId), ""),
+ IMintableToken(address(skaleToken)).mint(
+ address(distributor),
+ bounty,
+ abi.encode(validatorId),
+ ""
+ ),
"Token was not minted"
);
}
- function _refundGasByValidator(uint256 validatorId, address payable spender, uint256 gasLimit) private {
+ function _refundGasByValidator(
+ uint256 validatorId,
+ address payable spender,
+ uint256 gasLimit
+ )
+ private
+ {
IWallets(payable(contractManager.getContract("Wallets")))
.refundGasByValidator(validatorId, spender, gasLimit);
}
diff --git a/contracts/SkaleToken.sol b/contracts/SkaleToken.sol
index 5e25bb66b..23ec89fd6 100644
--- a/contracts/SkaleToken.sol
+++ b/contracts/SkaleToken.sol
@@ -23,10 +23,18 @@ pragma solidity 0.8.17;
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
-import { ContextUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
-import { IDelegatableToken } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegatableToken.sol";
-import { IMintableToken } from "@skalenetwork/skale-manager-interfaces/IMintableToken.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {
+ ContextUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
+import {
+ IDelegatableToken
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegatableToken.sol";
+import {
+ IMintableToken
+} from "@skalenetwork/skale-manager-interfaces/IMintableToken.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
import { ILocker } from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
import { Context, ERC777 } from "./thirdparty/openzeppelin/ERC777.sol";
@@ -48,7 +56,8 @@ contract SkaleToken is ERC777, Permissions, ReentrancyGuard, IDelegatableToken,
uint256 public constant DECIMALS = 18;
- uint256 public constant CAP = 7 * 1e9 * (10 ** DECIMALS); // the maximum amount of tokens that can ever be created
+ // the maximum amount of tokens that can ever be created
+ uint256 public constant CAP = 7 * 1e9 * (10 ** DECIMALS);
constructor(address contractsAddress, address[] memory defOps)
ERC777("SKALE", "SKL", defOps)
@@ -92,7 +101,13 @@ contract SkaleToken is ERC777, Permissions, ReentrancyGuard, IDelegatableToken,
/**
* @dev See {IDelegatableToken-getAndUpdateDelegatedAmount}.
*/
- function getAndUpdateDelegatedAmount(address wallet) external override returns (uint256 amount) {
+ function getAndUpdateDelegatedAmount(
+ address wallet
+ )
+ external
+ override
+ returns (uint256 amount)
+ {
return IDelegationController(contractManager.getContract("DelegationController"))
.getAndUpdateDelegatedAmount(wallet);
}
@@ -122,7 +137,10 @@ contract SkaleToken is ERC777, Permissions, ReentrancyGuard, IDelegatableToken,
{
uint256 locked = getAndUpdateLockedAmount(from);
if (locked > 0) {
- require(balanceOf(from) >= locked.add(tokenId), "Token should be unlocked for transferring");
+ require(
+ balanceOf(from) >= locked.add(tokenId),
+ "Token should be unlocked for transferring"
+ );
}
}
@@ -164,13 +182,24 @@ contract SkaleToken is ERC777, Permissions, ReentrancyGuard, IDelegatableToken,
});
}
- // we have to override _msgData() and _msgSender() functions because of collision in Context and ContextUpgradeable
+ // we have to override _msgData() and _msgSender() functions
+ // because of collision in Context and ContextUpgradeable
- function _msgData() internal view override(Context, ContextUpgradeable) returns (bytes calldata msgData) {
+ function _msgData()
+ internal
+ view
+ override(Context, ContextUpgradeable)
+ returns (bytes calldata msgData)
+ {
return Context._msgData();
}
- function _msgSender() internal view override(Context, ContextUpgradeable) returns (address sender) {
+ function _msgSender()
+ internal
+ view
+ override(Context, ContextUpgradeable)
+ returns (address sender)
+ {
return Context._msgSender();
}
}
diff --git a/contracts/SkaleVerifier.sol b/contracts/SkaleVerifier.sol
index 7bdb6f33d..54e1f14c5 100644
--- a/contracts/SkaleVerifier.sol
+++ b/contracts/SkaleVerifier.sol
@@ -124,7 +124,9 @@ contract SkaleVerifier is Permissions, ISkaleVerifier {
3,
Fp2Operations.P
);
- if (hashB < Fp2Operations.P / 2 || mulmod(hashB, hashB, Fp2Operations.P) != ySquared || xCoord != hashA) {
+ if (hashB < Fp2Operations.P / 2
+ || mulmod(hashB, hashB, Fp2Operations.P) != ySquared
+ || xCoord != hashA) {
return false;
}
diff --git a/contracts/SyncManager.sol b/contracts/SyncManager.sol
index 1571a82f1..09363fef1 100644
--- a/contracts/SyncManager.sol
+++ b/contracts/SyncManager.sol
@@ -47,8 +47,19 @@ contract SyncManager is Permissions, ISyncManager {
Permissions.initialize(contractManagerAddress);
}
- function addIPRange(string memory name, bytes4 startIP, bytes4 endIP) external override onlySyncManager {
- require(startIP <= endIP && startIP != bytes4(0) && endIP != bytes4(0), "Invalid IP ranges provided");
+ function addIPRange(
+ string memory name,
+ bytes4 startIP,
+ bytes4 endIP
+ )
+ external
+ override
+ onlySyncManager
+ {
+ require(
+ startIP <= endIP && startIP != bytes4(0) && endIP != bytes4(0),
+ "Invalid IP ranges provided"
+ );
bytes32 ipRangeNameHash = keccak256(abi.encodePacked(name));
require(_ipRangeNames.add(ipRangeNameHash), "IP range name is already taken");
ipRanges[ipRangeNameHash] = IPRange(startIP, endIP);
@@ -66,12 +77,26 @@ contract SyncManager is Permissions, ISyncManager {
return _ipRangeNames.length();
}
- function getIPRangeByIndex(uint256 index) external view override returns (IPRange memory range) {
+ function getIPRangeByIndex(
+ uint256 index
+ )
+ external
+ view
+ override
+ returns (IPRange memory range)
+ {
bytes32 ipRangeNameHash = _ipRangeNames.at(index);
return ipRanges[ipRangeNameHash];
}
- function getIPRangeByName(string memory name) external view override returns (IPRange memory range) {
+ function getIPRangeByName(
+ string memory name
+ )
+ external
+ view
+ override
+ returns (IPRange memory range)
+ {
bytes32 ipRangeNameHash = keccak256(abi.encodePacked(name));
return ipRanges[ipRangeNameHash];
}
diff --git a/contracts/Wallets.sol b/contracts/Wallets.sol
index 38dec0fa0..ab76cfd9f 100644
--- a/contracts/Wallets.sol
+++ b/contracts/Wallets.sol
@@ -23,10 +23,14 @@
pragma solidity 0.8.17;
-import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
+import {
+ AddressUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import { IWallets } from "@skalenetwork/skale-manager-interfaces/IWallets.sol";
import { ISchainsInternal } from "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol";
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
@@ -98,8 +102,10 @@ contract Wallets is Permissions, IWallets {
* so validator or schain owner can use usual transfer ether to recharge wallet.
*/
receive() external payable override {
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getContract("ValidatorService"));
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
bytes32[] memory schainHashes = schainsInternal.getSchainHashesByAddress(msg.sender);
if (schainHashes.length == 1) {
rechargeSchainWallet(schainHashes[0]);
@@ -131,10 +137,14 @@ contract Wallets is Permissions, IWallets {
{
require(spender != address(0), "Spender must be specified");
require(validatorId != 0, "ValidatorId could not be zero");
- uint256 minNodeBalance = IConstantsHolder(contractManager.getContract("ConstantsHolder")).minNodeBalance();
+ uint256 minNodeBalance = IConstantsHolder(contractManager.getContract("ConstantsHolder"))
+ .minNodeBalance();
uint256 actualSpenderBalance = spender.balance + gasLimit * tx.gasprice;
if (minNodeBalance > actualSpenderBalance) {
- uint256 amount = Math.min(_validatorWallets[validatorId], minNodeBalance - actualSpenderBalance);
+ uint256 amount = Math.min(
+ _validatorWallets[validatorId],
+ minNodeBalance - actualSpenderBalance
+ );
_validatorWallets[validatorId] -= amount;
emit NodeRefundedByValidator(spender, validatorId, amount);
spender.transfer(amount);
@@ -149,7 +159,14 @@ contract Wallets is Permissions, IWallets {
* Emits a {ReturnDebtFromValidator} event.
*
*/
- function refundGasByValidatorToSchain(uint256 validatorId, bytes32 schainHash) external override allow("SkaleDKG") {
+ function refundGasByValidatorToSchain(
+ uint256 validatorId,
+ bytes32 schainHash
+ )
+ external
+ override
+ allow("SkaleDKG")
+ {
uint256 debtAmount = _schainDebts[schainHash];
uint256 validatorWallet = _validatorWallets[validatorId];
if (debtAmount <= validatorWallet) {
@@ -223,7 +240,8 @@ contract Wallets is Permissions, IWallets {
* - `msg.sender` should be a validator address
*/
function withdrawFundsFromValidatorWallet(uint256 amount) external override {
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getContract("ValidatorService"));
uint256 validatorId = validatorService.getValidatorId(msg.sender);
require(amount <= _validatorWallets[validatorId], "Balance is too low");
_validatorWallets[validatorId] = _validatorWallets[validatorId] - amount;
@@ -241,7 +259,14 @@ contract Wallets is Permissions, IWallets {
/**
* @dev Returns validator eth balance.
*/
- function getValidatorBalance(uint256 validatorId) external view override returns (uint256 balance) {
+ function getValidatorBalance(
+ uint256 validatorId
+ )
+ external
+ view
+ override
+ returns (uint256 balance)
+ {
return _validatorWallets[validatorId];
}
@@ -254,7 +279,8 @@ contract Wallets is Permissions, IWallets {
* - Given validator must exist
*/
function rechargeValidatorWallet(uint256 validatorId) public payable override {
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
+ IValidatorService validatorService =
+ IValidatorService(contractManager.getContract("ValidatorService"));
require(validatorService.validatorExists(validatorId), "Validator does not exists");
_validatorWallets[validatorId] = _validatorWallets[validatorId] + msg.value;
emit ValidatorWalletRecharged(msg.sender, msg.value, validatorId);
@@ -269,8 +295,12 @@ contract Wallets is Permissions, IWallets {
* - Given schain must be created
*/
function rechargeSchainWallet(bytes32 schainHash) public payable override {
- ISchainsInternal schainsInternal = ISchainsInternal(contractManager.getContract("SchainsInternal"));
- require(schainsInternal.isSchainActive(schainHash), "Schain should be active for recharging");
+ ISchainsInternal schainsInternal =
+ ISchainsInternal(contractManager.getContract("SchainsInternal"));
+ require(
+ schainsInternal.isSchainActive(schainHash),
+ "Schain should be active for recharging"
+ );
_schainWallets[schainHash] = _schainWallets[schainHash] + msg.value;
emit SchainWalletRecharged(msg.sender, msg.value, schainHash);
}
diff --git a/contracts/delegation/DelegationController.sol b/contracts/delegation/DelegationController.sol
index a34c48b98..3d6384508 100644
--- a/contracts/delegation/DelegationController.sol
+++ b/contracts/delegation/DelegationController.sol
@@ -22,22 +22,27 @@
pragma solidity 0.8.17;
-import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
-
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
-import { IDelegationPeriodManager }
-from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationPeriodManager.sol";
-import { IPunisher } from "@skalenetwork/skale-manager-interfaces/delegation/IPunisher.sol";
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
-import { ILocker } from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
-import { ITimeHelpers } from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
-import { IBountyV2 } from "@skalenetwork/skale-manager-interfaces/IBountyV2.sol";
-import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
-
-import { Permissions } from "../Permissions.sol";
-import { FractionUtils } from "../utils/FractionUtils.sol";
-import { MathUtils } from "../utils/MathUtils.sol";
-import { PartialDifferences } from "./PartialDifferences.sol";
+import {IERC777} from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
+
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {
+ IDelegationPeriodManager
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationPeriodManager.sol";
+import {IPunisher} from "@skalenetwork/skale-manager-interfaces/delegation/IPunisher.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {ILocker} from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
+import {ITimeHelpers} from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
+import {IBountyV2} from "@skalenetwork/skale-manager-interfaces/IBountyV2.sol";
+import {IConstantsHolder} from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+
+import {Permissions} from "../Permissions.sol";
+import {FractionUtils} from "../utils/FractionUtils.sol";
+import {MathUtils} from "../utils/MathUtils.sol";
+import {PartialDifferences} from "./PartialDifferences.sol";
/**
* @title Delegation Controller
@@ -54,7 +59,8 @@ import { PartialDifferences } from "./PartialDifferences.sol";
*
* - PROPOSED: token holder proposes tokens to delegate to a validator.
* - ACCEPTED: token delegations are accepted by a validator and are locked-by-delegation.
- * - CANCELED: token holder cancels delegation proposal. Only allowed before the proposal is accepted by the validator.
+ * - CANCELED: token holder cancels delegation proposal.
+ * Only allowed before the proposal is accepted by the validator.
* - REJECTED: token proposal expires at the UTC start of the next month.
* - DELEGATED: accepted delegations are delegated at the UTC start of the month.
* - UNDELEGATION_REQUESTED: token holder requests delegations to undelegate from the validator.
@@ -73,7 +79,7 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
struct SlashingLog {
// month => slashing event
- mapping (uint256 => SlashingLogEvent) slashes;
+ mapping(uint256 => SlashingLogEvent) slashes;
uint256 firstMonth;
uint256 lastMonth;
}
@@ -102,57 +108,61 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
// month
uint256 value;
//validatorId => month
- mapping (uint256 => uint256) byValidator;
+ mapping(uint256 => uint256) byValidator;
}
struct ValidatorsStatistics {
// number of validators
uint256 number;
//validatorId => amount of delegations
- mapping (uint256 => uint256) delegated;
+ mapping(uint256 => uint256) delegated;
}
- uint256 public constant UNDELEGATION_PROHIBITION_WINDOW_SECONDS = 3 * 24 * 60 * 60;
+ uint256 public constant UNDELEGATION_PROHIBITION_WINDOW_SECONDS =
+ 3 * 24 * 60 * 60;
/// @dev delegations will never be deleted to index in this array may be used like delegation id
Delegation[] public delegations;
// validatorId => delegationId[]
- mapping (uint256 => uint256[]) public delegationsByValidator;
+ mapping(uint256 => uint256[]) public delegationsByValidator;
// holder => delegationId[]
- mapping (address => uint256[]) public delegationsByHolder;
+ mapping(address => uint256[]) public delegationsByHolder;
// delegationId => extras
mapping(uint256 => DelegationExtras) private _delegationExtras;
// validatorId => sequence
- mapping (uint256 => PartialDifferences.Value) private _delegatedToValidator;
+ mapping(uint256 => PartialDifferences.Value) private _delegatedToValidator;
// validatorId => sequence
- mapping (uint256 => PartialDifferences.Sequence) private _effectiveDelegatedToValidator;
+ mapping(uint256 => PartialDifferences.Sequence)
+ private _effectiveDelegatedToValidator;
// validatorId => slashing log
- mapping (uint256 => SlashingLog) private _slashesOfValidator;
+ mapping(uint256 => SlashingLog) private _slashesOfValidator;
// holder => sequence
- mapping (address => PartialDifferences.Value) private _delegatedByHolder;
+ mapping(address => PartialDifferences.Value) private _delegatedByHolder;
// holder => validatorId => sequence
- mapping (address => mapping (uint256 => PartialDifferences.Value)) private _delegatedByHolderToValidator;
+ mapping(address => mapping(uint256 => PartialDifferences.Value))
+ private _delegatedByHolderToValidator;
// holder => validatorId => sequence
- mapping (address => mapping (uint256 => PartialDifferences.Sequence))
- private _effectiveDelegatedByHolderToValidator;
+ mapping(address => mapping(uint256 => PartialDifferences.Sequence))
+ private _effectiveDelegatedByHolderToValidator;
SlashingEvent[] private _slashes;
// holder => index in _slashes;
- mapping (address => uint256) private _firstUnprocessedSlashByHolder;
+ mapping(address => uint256) private _firstUnprocessedSlashByHolder;
// holder => validatorId => month
- mapping (address => FirstDelegationMonth) private _firstDelegationMonth;
+ mapping(address => FirstDelegationMonth) private _firstDelegationMonth;
// holder => locked in pending
- mapping (address => LockedInPending) private _lockedInPendingDelegations;
+ mapping(address => LockedInPending) private _lockedInPendingDelegations;
- mapping (address => ValidatorsStatistics) private _numberOfValidatorsPerDelegator;
+ mapping(address => ValidatorsStatistics)
+ private _numberOfValidatorsPerDelegator;
/**
* @dev Modifier to make a function callable only if delegation exists.
@@ -169,14 +179,19 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
/**
* @dev Update and return a validator's delegations.
*/
- function getAndUpdateDelegatedToValidatorNow(uint256 validatorId) external override returns (uint256 amount) {
- return _getAndUpdateDelegatedToValidator(validatorId, _getCurrentMonth());
+ function getAndUpdateDelegatedToValidatorNow(
+ uint256 validatorId
+ ) external override returns (uint256 amount) {
+ return
+ _getAndUpdateDelegatedToValidator(validatorId, _getCurrentMonth());
}
/**
* @dev Update and return the amount delegated.
*/
- function getAndUpdateDelegatedAmount(address holder) external override returns (uint256 amount) {
+ function getAndUpdateDelegatedAmount(
+ address holder
+ ) external override returns (uint256 amount) {
return _getAndUpdateDelegatedByHolder(holder);
}
@@ -184,15 +199,21 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* @dev Update and return the effective amount delegated (minus slash) for
* the given month.
*/
- function getAndUpdateEffectiveDelegatedByHolderToValidator(address holder, uint256 validatorId, uint256 month)
+ function getAndUpdateEffectiveDelegatedByHolderToValidator(
+ address holder,
+ uint256 validatorId,
+ uint256 month
+ )
external
override
allow("Distributor")
returns (uint256 effectiveDelegated)
{
- SlashingSignal[] memory slashingSignals = _processAllSlashesWithoutSignals(holder);
- effectiveDelegated = _effectiveDelegatedByHolderToValidator[holder][validatorId]
- .getAndUpdateValueInSequence(month);
+ SlashingSignal[]
+ memory slashingSignals = _processAllSlashesWithoutSignals(holder);
+ effectiveDelegated = _effectiveDelegatedByHolderToValidator[holder][
+ validatorId
+ ].getAndUpdateValueInSequence(month);
_sendSlashingSignals(slashingSignals);
}
@@ -219,17 +240,23 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
uint256 amount,
uint256 delegationPeriod,
string calldata info
- )
- external
- override
- {
+ ) external override {
require(
- _getDelegationPeriodManager().isDelegationPeriodAllowed(delegationPeriod),
- "This delegation period is not allowed");
- _getValidatorService().checkValidatorCanReceiveDelegation(validatorId, amount);
+ _getDelegationPeriodManager().isDelegationPeriodAllowed(
+ delegationPeriod
+ ),
+ "This delegation period is not allowed"
+ );
+ _getValidatorService().checkValidatorCanReceiveDelegation(
+ validatorId,
+ amount
+ );
_checkIfDelegationIsAllowed(msg.sender, validatorId);
- SlashingSignal[] memory slashingSignals = _processAllSlashesWithoutSignals(msg.sender);
+ SlashingSignal[]
+ memory slashingSignals = _processAllSlashesWithoutSignals(
+ msg.sender
+ );
uint256 delegationId = _addDelegation({
holder: msg.sender,
@@ -240,10 +267,15 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
});
// check that there is enough money
- uint256 holderBalance = IERC777(contractManager.getSkaleToken()).balanceOf(msg.sender);
- uint256 forbiddenForDelegation = ILocker(contractManager.getTokenState())
- .getAndUpdateForbiddenForDelegationAmount(msg.sender);
- require(holderBalance >= forbiddenForDelegation, "Token holder does not have enough tokens to delegate");
+ uint256 holderBalance = IERC777(contractManager.getSkaleToken())
+ .balanceOf(msg.sender);
+ uint256 forbiddenForDelegation = ILocker(
+ contractManager.getTokenState()
+ ).getAndUpdateForbiddenForDelegationAmount(msg.sender);
+ require(
+ holderBalance >= forbiddenForDelegation,
+ "Token holder does not have enough tokens to delegate"
+ );
emit DelegationProposed(delegationId);
@@ -253,14 +285,18 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
/**
* @dev See {ILocker-getAndUpdateLockedAmount}.
*/
- function getAndUpdateLockedAmount(address wallet) external override returns (uint256 amount) {
+ function getAndUpdateLockedAmount(
+ address wallet
+ ) external override returns (uint256 amount) {
return _getAndUpdateLockedAmount(wallet);
}
/**
* @dev See {ILocker-getAndUpdateForbiddenForDelegationAmount}.
*/
- function getAndUpdateForbiddenForDelegationAmount(address wallet) external override returns (uint256 amount) {
+ function getAndUpdateForbiddenForDelegationAmount(
+ address wallet
+ ) external override returns (uint256 amount) {
return _getAndUpdateLockedAmount(wallet);
}
@@ -274,12 +310,23 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* - `msg.sender` must be the token holder of the delegation proposal.
* - Delegation state must be PROPOSED.
*/
- function cancelPendingDelegation(uint256 delegationId) external override checkDelegationExists(delegationId) {
- require(msg.sender == delegations[delegationId].holder, "Only token holders can cancel delegation request");
- require(getState(delegationId) == State.PROPOSED, "Token holders are only able to cancel PROPOSED delegations");
+ function cancelPendingDelegation(
+ uint256 delegationId
+ ) external override checkDelegationExists(delegationId) {
+ require(
+ msg.sender == delegations[delegationId].holder,
+ "Only token holders can cancel delegation request"
+ );
+ require(
+ getState(delegationId) == State.PROPOSED,
+ "Token holders are only able to cancel PROPOSED delegations"
+ );
delegations[delegationId].finished = _getCurrentMonth();
- _subtractFromLockedInPendingDelegations(delegations[delegationId].holder, delegations[delegationId].amount);
+ _subtractFromLockedInPendingDelegations(
+ delegations[delegationId].holder,
+ delegations[delegationId].amount
+ );
emit DelegationRequestCanceledByUser(delegationId);
}
@@ -297,10 +344,16 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* - Validator must be recipient of proposal.
* - Delegation state must be PROPOSED.
*/
- function acceptPendingDelegation(uint256 delegationId) external override checkDelegationExists(delegationId) {
+ function acceptPendingDelegation(
+ uint256 delegationId
+ ) external override checkDelegationExists(delegationId) {
require(
- _getValidatorService().checkValidatorAddressToId(msg.sender, delegations[delegationId].validatorId),
- "No permissions to accept request");
+ _getValidatorService().checkValidatorAddressToId(
+ msg.sender,
+ delegations[delegationId].validatorId
+ ),
+ "No permissions to accept request"
+ );
_accept(delegationId);
}
@@ -314,23 +367,35 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* - `msg.sender` must be the delegator or the validator.
* - Delegation state must be DELEGATED.
*/
- function requestUndelegation(uint256 delegationId) external override checkDelegationExists(delegationId) {
- require(getState(delegationId) == State.DELEGATED, "Cannot request undelegation");
+ function requestUndelegation(
+ uint256 delegationId
+ ) external override checkDelegationExists(delegationId) {
+ require(
+ getState(delegationId) == State.DELEGATED,
+ "Cannot request undelegation"
+ );
IValidatorService validatorService = _getValidatorService();
require(
delegations[delegationId].holder == msg.sender ||
- (validatorService.validatorAddressExists(msg.sender) &&
- delegations[delegationId].validatorId == validatorService.getValidatorId(msg.sender)),
- "Permission denied to request undelegation");
+ (validatorService.validatorAddressExists(msg.sender) &&
+ delegations[delegationId].validatorId ==
+ validatorService.getValidatorId(msg.sender)),
+ "Permission denied to request undelegation"
+ );
_removeValidatorFromValidatorsPerDelegators(
delegations[delegationId].holder,
- delegations[delegationId].validatorId);
+ delegations[delegationId].validatorId
+ );
processAllSlashes(msg.sender);
- delegations[delegationId].finished = _calculateDelegationEndMonth(delegationId);
+ delegations[delegationId].finished = _calculateDelegationEndMonth(
+ delegationId
+ );
require(
- block.timestamp + UNDELEGATION_PROHIBITION_WINDOW_SECONDS
- < _getTimeHelpers().monthToTimestamp(delegations[delegationId].finished),
+ block.timestamp + UNDELEGATION_PROHIBITION_WINDOW_SECONDS <
+ _getTimeHelpers().monthToTimestamp(
+ delegations[delegationId].finished
+ ),
"Undelegation requests must be sent 3 days before the end of delegation period"
);
@@ -350,7 +415,10 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
*
* See {Punisher}.
*/
- function confiscate(uint256 validatorId, uint256 amount) external override allow("Punisher") {
+ function confiscate(
+ uint256 validatorId,
+ uint256 amount
+ ) external override allow("Punisher") {
uint256 currentMonth = _getCurrentMonth();
FractionUtils.Fraction memory coefficient =
_delegatedToValidator[validatorId].reduceValue(amount, currentMonth);
@@ -363,25 +431,34 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
_effectiveDelegatedToValidator[validatorId].lastChangedMonth - currentMonth
);
for (uint256 i = 0; i < initialSubtractions.length; ++i) {
- initialSubtractions[i] = _effectiveDelegatedToValidator[validatorId]
- .subtractDiff[currentMonth + i + 1];
+ initialSubtractions[i] =
+ _effectiveDelegatedToValidator[validatorId].subtractDiff[currentMonth + i + 1];
}
}
_effectiveDelegatedToValidator[validatorId].reduceSequence(coefficient, currentMonth);
_putToSlashingLog(_slashesOfValidator[validatorId], coefficient, currentMonth);
- _slashes.push(SlashingEvent({reducingCoefficient: coefficient, validatorId: validatorId, month: currentMonth}));
+ _slashes.push(
+ SlashingEvent({
+ reducingCoefficient: coefficient,
+ validatorId: validatorId,
+ month: currentMonth
+ })
+ );
IBountyV2 bounty = _getBounty();
bounty.handleDelegationRemoving(
initialEffectiveDelegated -
- _effectiveDelegatedToValidator[validatorId].getAndUpdateValueInSequence(currentMonth),
+ _effectiveDelegatedToValidator[validatorId]
+ .getAndUpdateValueInSequence(currentMonth),
currentMonth
);
for (uint256 i = 0; i < initialSubtractions.length; ++i) {
bounty.handleDelegationAdd(
initialSubtractions[i] -
- _effectiveDelegatedToValidator[validatorId].subtractDiff[currentMonth + i + 1],
+ _effectiveDelegatedToValidator[validatorId].subtractDiff[
+ currentMonth + i + 1
+ ],
currentMonth + i + 1
);
}
@@ -392,66 +469,66 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* @dev Allows Distributor contract to return and update the effective
* amount delegated (minus slash) to a validator for a given month.
*/
- function getAndUpdateEffectiveDelegatedToValidator(uint256 validatorId, uint256 month)
+ function getAndUpdateEffectiveDelegatedToValidator(
+ uint256 validatorId,
+ uint256 month
+ )
external
override
allowTwo("Bounty", "Distributor")
returns (uint256 amount)
{
- return _effectiveDelegatedToValidator[validatorId].getAndUpdateValueInSequence(month);
+ return
+ _effectiveDelegatedToValidator[validatorId]
+ .getAndUpdateValueInSequence(month);
}
/**
* @dev Return and update the amount delegated to a validator for the
* current month.
*/
- function getAndUpdateDelegatedByHolderToValidatorNow(address holder, uint256 validatorId)
- external
- override
- returns (uint256 amount)
- {
- return _getAndUpdateDelegatedByHolderToValidator(holder, validatorId, _getCurrentMonth());
+ function getAndUpdateDelegatedByHolderToValidatorNow(
+ address holder,
+ uint256 validatorId
+ ) external override returns (uint256 amount) {
+ return
+ _getAndUpdateDelegatedByHolderToValidator(
+ holder,
+ validatorId,
+ _getCurrentMonth()
+ );
}
function getEffectiveDelegatedValuesByValidator(
uint256 validatorId
- )
- external
- view
- override
- returns (uint256[] memory amounts)
- {
- return _effectiveDelegatedToValidator[validatorId].getValuesInSequence();
+ ) external view override returns (uint256[] memory amounts) {
+ return
+ _effectiveDelegatedToValidator[validatorId].getValuesInSequence();
}
function getEffectiveDelegatedToValidator(
uint256 validatorId,
uint256 month
- )
- external
- view
- override
- returns (uint256 amount)
- {
- return _effectiveDelegatedToValidator[validatorId].getValueInSequence(month);
+ ) external view override returns (uint256 amount) {
+ return
+ _effectiveDelegatedToValidator[validatorId].getValueInSequence(
+ month
+ );
}
function getDelegatedToValidator(
uint256 validatorId,
uint256 month
- )
- external
- view
- override
- returns (uint256 amount)
- {
+ ) external view override returns (uint256 amount) {
return _delegatedToValidator[validatorId].getValue(month);
}
/**
* @dev Return Delegation struct.
*/
- function getDelegation(uint256 delegationId)
+ function getDelegation(
+ uint256 delegationId
+ )
external
view
override
@@ -467,26 +544,25 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
function getFirstDelegationMonth(
address holder,
uint256 validatorId
- )
- external
- view
- override
- returns(uint256 month)
- {
+ ) external view override returns (uint256 month) {
return _firstDelegationMonth[holder].byValidator[validatorId];
}
/**
* @dev Returns a validator's total number of delegations.
*/
- function getDelegationsByValidatorLength(uint256 validatorId) external view override returns (uint256 length) {
+ function getDelegationsByValidatorLength(
+ uint256 validatorId
+ ) external view override returns (uint256 length) {
return delegationsByValidator[validatorId].length;
}
/**
* @dev Returns a holder's total number of delegations.
*/
- function getDelegationsByHolderLength(address holder) external view override returns (uint256 length) {
+ function getDelegationsByHolderLength(
+ address holder
+ ) external view override returns (uint256 length) {
return delegationsByHolder[holder].length;
}
@@ -508,7 +584,9 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
/**
* @dev Returns the token state of a given delegation.
*/
- function getState(uint256 delegationId)
+ function getState(
+ uint256 delegationId
+ )
public
view
override
@@ -517,7 +595,12 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
{
if (delegations[delegationId].started == 0) {
if (delegations[delegationId].finished == 0) {
- if (_getCurrentMonth() == _getTimeHelpers().timestampToMonth(delegations[delegationId].created)) {
+ if (
+ _getCurrentMonth() ==
+ _getTimeHelpers().timestampToMonth(
+ delegations[delegationId].created
+ )
+ ) {
return State.PROPOSED;
} else {
return State.REJECTED;
@@ -532,7 +615,9 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
if (delegations[delegationId].finished == 0) {
return State.DELEGATED;
} else {
- if (_getCurrentMonth() < delegations[delegationId].finished) {
+ if (
+ _getCurrentMonth() < delegations[delegationId].finished
+ ) {
return State.UNDELEGATION_REQUESTED;
} else {
return State.COMPLETED;
@@ -545,7 +630,9 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
/**
* @dev Returns the amount of tokens in PENDING delegation state.
*/
- function getLockedInPendingDelegations(address holder) public view override returns (uint256 amount) {
+ function getLockedInPendingDelegations(
+ address holder
+ ) public view override returns (uint256 amount) {
uint256 currentMonth = _getCurrentMonth();
if (_lockedInPendingDelegations[holder].month < currentMonth) {
return 0;
@@ -557,8 +644,12 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
/**
* @dev Checks whether there are any unprocessed slashes.
*/
- function hasUnprocessedSlashes(address holder) public view override returns (bool hasUnprocessed) {
- return _everDelegated(holder) && _firstUnprocessedSlashByHolder[holder] < _slashes.length;
+ function hasUnprocessedSlashes(
+ address holder
+ ) public view override returns (bool hasUnprocessed) {
+ return
+ _everDelegated(holder) &&
+ _firstUnprocessedSlashByHolder[holder] < _slashes.length;
}
// private
@@ -567,9 +658,10 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* @dev Allows Nodes contract to get and update the amount delegated
* to validator for a given month.
*/
- function _getAndUpdateDelegatedToValidator(uint256 validatorId, uint256 month)
- private returns (uint256 amount)
- {
+ function _getAndUpdateDelegatedToValidator(
+ uint256 validatorId,
+ uint256 month
+ ) private returns (uint256 amount) {
return _delegatedToValidator[validatorId].getAndUpdateValue(month);
}
@@ -582,63 +674,106 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
uint256 amount,
uint256 delegationPeriod,
string memory info
- )
- private
- returns (uint256 delegationId)
- {
+ ) private returns (uint256 delegationId) {
delegationId = delegations.length;
- delegations.push(Delegation({
- holder: holder,
- validatorId: validatorId,
- amount: amount,
- delegationPeriod: delegationPeriod,
- created: block.timestamp,
- started: 0,
- finished: 0,
- info: info
- }));
+ delegations.push(
+ Delegation({
+ holder: holder,
+ validatorId: validatorId,
+ amount: amount,
+ delegationPeriod: delegationPeriod,
+ created: block.timestamp,
+ started: 0,
+ finished: 0,
+ info: info
+ })
+ );
delegationsByValidator[validatorId].push(delegationId);
delegationsByHolder[holder].push(delegationId);
- _addToLockedInPendingDelegations(delegations[delegationId].holder, delegations[delegationId].amount);
+ _addToLockedInPendingDelegations(
+ delegations[delegationId].holder,
+ delegations[delegationId].amount
+ );
}
- function _addToDelegatedToValidator(uint256 validatorId, uint256 amount, uint256 month) private {
+ function _addToDelegatedToValidator(
+ uint256 validatorId,
+ uint256 amount,
+ uint256 month
+ ) private {
_delegatedToValidator[validatorId].addToValue(amount, month);
}
- function _addToEffectiveDelegatedToValidator(uint256 validatorId, uint256 effectiveAmount, uint256 month) private {
- _effectiveDelegatedToValidator[validatorId].addToSequence(effectiveAmount, month);
+ function _addToEffectiveDelegatedToValidator(
+ uint256 validatorId,
+ uint256 effectiveAmount,
+ uint256 month
+ ) private {
+ _effectiveDelegatedToValidator[validatorId].addToSequence(
+ effectiveAmount,
+ month
+ );
}
- function _addToDelegatedByHolder(address holder, uint256 amount, uint256 month) private {
+ function _addToDelegatedByHolder(
+ address holder,
+ uint256 amount,
+ uint256 month
+ ) private {
_delegatedByHolder[holder].addToValue(amount, month);
}
function _addToDelegatedByHolderToValidator(
- address holder, uint256 validatorId, uint256 amount, uint256 month) private
- {
- _delegatedByHolderToValidator[holder][validatorId].addToValue(amount, month);
+ address holder,
+ uint256 validatorId,
+ uint256 amount,
+ uint256 month
+ ) private {
+ _delegatedByHolderToValidator[holder][validatorId].addToValue(
+ amount,
+ month
+ );
}
- function _addValidatorToValidatorsPerDelegators(address holder, uint256 validatorId) private {
- if (_numberOfValidatorsPerDelegator[holder].delegated[validatorId] == 0) {
+ function _addValidatorToValidatorsPerDelegators(
+ address holder,
+ uint256 validatorId
+ ) private {
+ if (
+ _numberOfValidatorsPerDelegator[holder].delegated[validatorId] == 0
+ ) {
_numberOfValidatorsPerDelegator[holder].number += 1;
}
_numberOfValidatorsPerDelegator[holder].delegated[validatorId] += 1;
}
- function _removeFromDelegatedByHolder(address holder, uint256 amount, uint256 month) private {
+ function _removeFromDelegatedByHolder(
+ address holder,
+ uint256 amount,
+ uint256 month
+ ) private {
_delegatedByHolder[holder].subtractFromValue(amount, month);
}
function _removeFromDelegatedByHolderToValidator(
- address holder, uint256 validatorId, uint256 amount, uint256 month) private
- {
- _delegatedByHolderToValidator[holder][validatorId].subtractFromValue(amount, month);
+ address holder,
+ uint256 validatorId,
+ uint256 amount,
+ uint256 month
+ ) private {
+ _delegatedByHolderToValidator[holder][validatorId].subtractFromValue(
+ amount,
+ month
+ );
}
- function _removeValidatorFromValidatorsPerDelegators(address holder, uint256 validatorId) private {
- if (_numberOfValidatorsPerDelegator[holder].delegated[validatorId] == 1) {
+ function _removeValidatorFromValidatorsPerDelegators(
+ address holder,
+ uint256 validatorId
+ ) private {
+ if (
+ _numberOfValidatorsPerDelegator[holder].delegated[validatorId] == 1
+ ) {
_numberOfValidatorsPerDelegator[holder].number -= 1;
}
_numberOfValidatorsPerDelegator[holder].delegated[validatorId] -= 1;
@@ -648,23 +783,25 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
address holder,
uint256 validatorId,
uint256 effectiveAmount,
- uint256 month)
- private
- {
- _effectiveDelegatedByHolderToValidator[holder][validatorId].addToSequence(effectiveAmount, month);
+ uint256 month
+ ) private {
+ _effectiveDelegatedByHolderToValidator[holder][validatorId]
+ .addToSequence(effectiveAmount, month);
}
function _removeFromEffectiveDelegatedByHolderToValidator(
address holder,
uint256 validatorId,
uint256 effectiveAmount,
- uint256 month)
- private
- {
- _effectiveDelegatedByHolderToValidator[holder][validatorId].subtractFromSequence(effectiveAmount, month);
+ uint256 month
+ ) private {
+ _effectiveDelegatedByHolderToValidator[holder][validatorId]
+ .subtractFromSequence(effectiveAmount, month);
}
- function _getAndUpdateDelegatedByHolder(address holder) private returns (uint256 amount) {
+ function _getAndUpdateDelegatedByHolder(
+ address holder
+ ) private returns (uint256 amount) {
uint256 currentMonth = _getCurrentMonth();
processAllSlashes(holder);
return _delegatedByHolder[holder].getAndUpdateValue(currentMonth);
@@ -673,37 +810,56 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
function _getAndUpdateDelegatedByHolderToValidator(
address holder,
uint256 validatorId,
- uint256 month)
- private returns (uint256 amount)
- {
- return _delegatedByHolderToValidator[holder][validatorId].getAndUpdateValue(month);
+ uint256 month
+ ) private returns (uint256 amount) {
+ return
+ _delegatedByHolderToValidator[holder][validatorId]
+ .getAndUpdateValue(month);
}
- function _addToLockedInPendingDelegations(address holder, uint256 amount) private {
+ function _addToLockedInPendingDelegations(
+ address holder,
+ uint256 amount
+ ) private {
uint256 currentMonth = _getCurrentMonth();
if (_lockedInPendingDelegations[holder].month < currentMonth) {
_lockedInPendingDelegations[holder].amount = amount;
_lockedInPendingDelegations[holder].month = currentMonth;
} else {
assert(_lockedInPendingDelegations[holder].month == currentMonth);
- _lockedInPendingDelegations[holder].amount = _lockedInPendingDelegations[holder].amount + amount;
+ _lockedInPendingDelegations[holder].amount =
+ _lockedInPendingDelegations[holder].amount +
+ amount;
}
}
- function _subtractFromLockedInPendingDelegations(address holder, uint256 amount) private {
+ function _subtractFromLockedInPendingDelegations(
+ address holder,
+ uint256 amount
+ ) private {
uint256 currentMonth = _getCurrentMonth();
assert(_lockedInPendingDelegations[holder].month == currentMonth);
- _lockedInPendingDelegations[holder].amount = _lockedInPendingDelegations[holder].amount - amount;
+ _lockedInPendingDelegations[holder].amount =
+ _lockedInPendingDelegations[holder].amount -
+ amount;
}
/**
* @dev See {ILocker-getAndUpdateLockedAmount}.
*/
- function _getAndUpdateLockedAmount(address wallet) private returns (uint256 amount) {
- return _getAndUpdateDelegatedByHolder(wallet) + getLockedInPendingDelegations(wallet);
+ function _getAndUpdateLockedAmount(
+ address wallet
+ ) private returns (uint256 amount) {
+ return
+ _getAndUpdateDelegatedByHolder(wallet) +
+ getLockedInPendingDelegations(wallet);
}
- function _updateFirstDelegationMonth(address holder, uint256 validatorId, uint256 month) private {
+ function _updateFirstDelegationMonth(
+ address holder,
+ uint256 validatorId,
+ uint256 month
+ ) private {
if (_firstDelegationMonth[holder].value == 0) {
_firstDelegationMonth[holder].value = month;
_firstUnprocessedSlashByHolder[holder] = _slashes.length;
@@ -713,7 +869,11 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
}
}
- function _removeFromDelegatedToValidator(uint256 validatorId, uint256 amount, uint256 month) private {
+ function _removeFromDelegatedToValidator(
+ uint256 validatorId,
+ uint256 amount,
+ uint256 month
+ ) private {
_delegatedToValidator[validatorId].subtractFromValue(amount, month);
}
@@ -721,28 +881,33 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
uint256 validatorId,
uint256 effectiveAmount,
uint256 month
- )
- private
- {
- _effectiveDelegatedToValidator[validatorId].subtractFromSequence(effectiveAmount, month);
+ ) private {
+ _effectiveDelegatedToValidator[validatorId].subtractFromSequence(
+ effectiveAmount,
+ month
+ );
}
function _putToSlashingLog(
SlashingLog storage log,
FractionUtils.Fraction memory coefficient,
- uint256 month)
- private
- {
+ uint256 month
+ ) private {
if (log.firstMonth == 0) {
log.firstMonth = month;
log.lastMonth = month;
log.slashes[month].reducingCoefficient = coefficient;
log.slashes[month].nextMonth = 0;
} else {
- require(log.lastMonth <= month, "Cannot put slashing event in the past");
+ require(
+ log.lastMonth <= month,
+ "Cannot put slashing event in the past"
+ );
if (log.lastMonth == month) {
- log.slashes[month].reducingCoefficient =
- log.slashes[month].reducingCoefficient.multiplyFraction(coefficient);
+ log.slashes[month].reducingCoefficient = log
+ .slashes[month]
+ .reducingCoefficient
+ .multiplyFraction(coefficient);
} else {
log.slashes[month].reducingCoefficient = coefficient;
log.slashes[month].nextMonth = 0;
@@ -752,9 +917,10 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
}
}
- function _processSlashesWithoutSignals(address holder, uint256 limit)
- private returns (SlashingSignal[] memory slashingSignals)
- {
+ function _processSlashesWithoutSignals(
+ address holder,
+ uint256 limit
+ ) private returns (SlashingSignal[] memory slashingSignals) {
if (hasUnprocessedSlashes(holder)) {
uint256 index = _firstUnprocessedSlashByHolder[holder];
uint256 end = _slashes.length;
@@ -766,31 +932,47 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
for (; index < end; ++index) {
uint256 validatorId = _slashes[index].validatorId;
uint256 month = _slashes[index].month;
- uint256 oldValue = _getAndUpdateDelegatedByHolderToValidator(holder, validatorId, month);
+ uint256 oldValue = _getAndUpdateDelegatedByHolderToValidator(
+ holder,
+ validatorId,
+ month
+ );
if (oldValue.muchGreater(0)) {
- _delegatedByHolderToValidator[holder][validatorId].reduceValueByCoefficientAndUpdateSum(
- _delegatedByHolder[holder],
- _slashes[index].reducingCoefficient,
- month);
- _effectiveDelegatedByHolderToValidator[holder][validatorId].reduceSequence(
- _slashes[index].reducingCoefficient,
- month);
+ _delegatedByHolderToValidator[holder][validatorId]
+ .reduceValueByCoefficientAndUpdateSum(
+ _delegatedByHolder[holder],
+ _slashes[index].reducingCoefficient,
+ month
+ );
+ _effectiveDelegatedByHolderToValidator[holder][validatorId]
+ .reduceSequence(
+ _slashes[index].reducingCoefficient,
+ month
+ );
slashingSignals[index - begin].holder = holder;
- slashingSignals[index - begin].penalty
- = oldValue.boundedSub(_getAndUpdateDelegatedByHolderToValidator(holder, validatorId, month));
+ slashingSignals[index - begin].penalty = oldValue
+ .boundedSub(
+ _getAndUpdateDelegatedByHolderToValidator(
+ holder,
+ validatorId,
+ month
+ )
+ );
}
}
_firstUnprocessedSlashByHolder[holder] = end;
}
}
- function _processAllSlashesWithoutSignals(address holder)
- private returns (SlashingSignal[] memory slashingSignals)
- {
+ function _processAllSlashesWithoutSignals(
+ address holder
+ ) private returns (SlashingSignal[] memory slashingSignals) {
return _processSlashesWithoutSignals(holder, 0);
}
- function _sendSlashingSignals(SlashingSignal[] memory slashingSignals) private {
+ function _sendSlashingSignals(
+ SlashingSignal[] memory slashingSignals
+ ) private {
IPunisher punisher = IPunisher(contractManager.getPunisher());
address previousHolder = address(0);
uint256 accumulatedPenalty = 0;
@@ -802,7 +984,9 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
previousHolder = slashingSignals[i].holder;
accumulatedPenalty = slashingSignals[i].penalty;
} else {
- accumulatedPenalty = accumulatedPenalty + slashingSignals[i].penalty;
+ accumulatedPenalty =
+ accumulatedPenalty +
+ slashingSignals[i].penalty;
}
}
if (accumulatedPenalty > 0) {
@@ -814,38 +998,48 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
uint256 currentMonth = _getCurrentMonth();
delegations[delegationId].started = currentMonth + 1;
if (_slashesOfValidator[delegations[delegationId].validatorId].lastMonth > 0) {
- _delegationExtras[delegationId].lastSlashingMonthBeforeDelegation =
- _slashesOfValidator[delegations[delegationId].validatorId].lastMonth;
+ _delegationExtras[delegationId]
+ .lastSlashingMonthBeforeDelegation = _slashesOfValidator[
+ delegations[delegationId].validatorId
+ ].lastMonth;
}
_addToDelegatedToValidator(
delegations[delegationId].validatorId,
delegations[delegationId].amount,
- currentMonth + 1);
+ currentMonth + 1
+ );
_addToDelegatedByHolder(
delegations[delegationId].holder,
delegations[delegationId].amount,
- currentMonth + 1);
+ currentMonth + 1
+ );
_addToDelegatedByHolderToValidator(
delegations[delegationId].holder,
delegations[delegationId].validatorId,
delegations[delegationId].amount,
- currentMonth + 1);
+ currentMonth + 1
+ );
_updateFirstDelegationMonth(
delegations[delegationId].holder,
delegations[delegationId].validatorId,
- currentMonth + 1);
+ currentMonth + 1
+ );
uint256 effectiveAmount = delegations[delegationId].amount *
- _getDelegationPeriodManager().stakeMultipliers(delegations[delegationId].delegationPeriod);
+ _getDelegationPeriodManager().stakeMultipliers(
+ delegations[delegationId].delegationPeriod
+ );
_addToEffectiveDelegatedToValidator(
delegations[delegationId].validatorId,
effectiveAmount,
- currentMonth + 1);
+ currentMonth + 1
+ );
_addToEffectiveDelegatedByHolderToValidator(
delegations[delegationId].holder,
delegations[delegationId].validatorId,
effectiveAmount,
- currentMonth + 1);
+ currentMonth + 1
+ );
_addValidatorToValidatorsPerDelegators(
delegations[delegationId].holder,
delegations[delegationId].validatorId
@@ -853,46 +1047,60 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
}
function _subtractFromAllStatistics(uint256 delegationId) private {
- uint256 amountAfterSlashing = _calculateDelegationAmountAfterSlashing(delegationId);
+ uint256 amountAfterSlashing = _calculateDelegationAmountAfterSlashing(
+ delegationId
+ );
_removeFromDelegatedToValidator(
delegations[delegationId].validatorId,
amountAfterSlashing,
- delegations[delegationId].finished);
+ delegations[delegationId].finished
+ );
_removeFromDelegatedByHolder(
delegations[delegationId].holder,
amountAfterSlashing,
- delegations[delegationId].finished);
+ delegations[delegationId].finished
+ );
_removeFromDelegatedByHolderToValidator(
delegations[delegationId].holder,
delegations[delegationId].validatorId,
amountAfterSlashing,
- delegations[delegationId].finished);
+ delegations[delegationId].finished
+ );
uint256 effectiveAmount = amountAfterSlashing *
- _getDelegationPeriodManager().stakeMultipliers(delegations[delegationId].delegationPeriod);
+ _getDelegationPeriodManager().stakeMultipliers(
+ delegations[delegationId].delegationPeriod
+ );
_removeFromEffectiveDelegatedToValidator(
delegations[delegationId].validatorId,
effectiveAmount,
- delegations[delegationId].finished);
+ delegations[delegationId].finished
+ );
_removeFromEffectiveDelegatedByHolderToValidator(
delegations[delegationId].holder,
delegations[delegationId].validatorId,
effectiveAmount,
- delegations[delegationId].finished);
+ delegations[delegationId].finished
+ );
_getBounty().handleDelegationRemoving(
effectiveAmount,
- delegations[delegationId].finished);
+ delegations[delegationId].finished
+ );
}
function _accept(uint256 delegationId) private {
- _checkIfDelegationIsAllowed(delegations[delegationId].holder, delegations[delegationId].validatorId);
+ _checkIfDelegationIsAllowed(
+ delegations[delegationId].holder,
+ delegations[delegationId].validatorId
+ );
State currentState = getState(delegationId);
if (currentState != State.PROPOSED) {
- if (currentState == State.ACCEPTED ||
+ if (
+ currentState == State.ACCEPTED ||
currentState == State.DELEGATED ||
currentState == State.UNDELEGATION_REQUESTED ||
- currentState == State.COMPLETED)
- {
+ currentState == State.COMPLETED
+ ) {
revert("The delegation has been already accepted");
} else if (currentState == State.CANCELED) {
revert("The delegation has been cancelled by token holder");
@@ -900,16 +1108,24 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
revert("The delegation request is outdated");
}
}
- require(currentState == State.PROPOSED, "Cannot set delegation state to accepted");
+ require(
+ currentState == State.PROPOSED,
+ "Cannot set delegation state to accepted"
+ );
- SlashingSignal[] memory slashingSignals = _processAllSlashesWithoutSignals(delegations[delegationId].holder);
+ SlashingSignal[]
+ memory slashingSignals = _processAllSlashesWithoutSignals(
+ delegations[delegationId].holder
+ );
_addToAllStatistics(delegationId);
uint256 amount = delegations[delegationId].amount;
uint256 effectiveAmount = amount *
- _getDelegationPeriodManager().stakeMultipliers(delegations[delegationId].delegationPeriod);
+ _getDelegationPeriodManager().stakeMultipliers(
+ delegations[delegationId].delegationPeriod
+ );
_getBounty().handleDelegationAdd(
effectiveAmount,
delegations[delegationId].started
@@ -926,30 +1142,41 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
/**
* @dev Checks whether the holder has performed a delegation.
*/
- function _everDelegated(address holder) private view returns (bool delegated) {
+ function _everDelegated(
+ address holder
+ ) private view returns (bool delegated) {
return _firstDelegationMonth[holder].value > 0;
}
/**
* @dev Returns the month when a delegation ends.
*/
- function _calculateDelegationEndMonth(uint256 delegationId) private view returns (uint256 month) {
+ function _calculateDelegationEndMonth(
+ uint256 delegationId
+ ) private view returns (uint256 month) {
uint256 currentMonth = _getCurrentMonth();
uint256 started = delegations[delegationId].started;
if (currentMonth < started) {
return started + delegations[delegationId].delegationPeriod;
} else {
- uint256 completedPeriods = (currentMonth - started) / delegations[delegationId].delegationPeriod;
- return started + (completedPeriods + 1) * delegations[delegationId].delegationPeriod;
+ uint256 completedPeriods = (currentMonth - started) /
+ delegations[delegationId].delegationPeriod;
+ return
+ started +
+ (completedPeriods + 1) *
+ delegations[delegationId].delegationPeriod;
}
}
/**
* @dev Returns the delegated amount after a slashing event.
*/
- function _calculateDelegationAmountAfterSlashing(uint256 delegationId) private view returns (uint256 amount) {
- uint256 startMonth = _delegationExtras[delegationId].lastSlashingMonthBeforeDelegation;
+ function _calculateDelegationAmountAfterSlashing(
+ uint256 delegationId
+ ) private view returns (uint256 amount) {
+ uint256 startMonth = _delegationExtras[delegationId]
+ .lastSlashingMonthBeforeDelegation;
uint256 validatorId = delegations[delegationId].validatorId;
amount = delegations[delegationId].amount;
if (startMonth == 0) {
@@ -958,13 +1185,22 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
return amount;
}
}
- for (uint256 i = startMonth;
+ for (
+ uint256 i = startMonth;
i > 0 && i < delegations[delegationId].finished;
- i = _slashesOfValidator[validatorId].slashes[i].nextMonth) {
+ i = _slashesOfValidator[validatorId].slashes[i].nextMonth
+ ) {
if (i >= delegations[delegationId].started) {
- amount = amount
- * _slashesOfValidator[validatorId].slashes[i].reducingCoefficient.numerator
- / _slashesOfValidator[validatorId].slashes[i].reducingCoefficient.denominator;
+ amount =
+ (amount *
+ _slashesOfValidator[validatorId]
+ .slashes[i]
+ .reducingCoefficient
+ .numerator) /
+ _slashesOfValidator[validatorId]
+ .slashes[i]
+ .reducingCoefficient
+ .denominator;
}
}
return amount;
@@ -978,23 +1214,39 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
* - Delegator must not have reached the validator limit.
* - Delegation must be made in or after the first delegation month.
*/
- function _checkIfDelegationIsAllowed(address holder, uint256 validatorId) private view {
+ function _checkIfDelegationIsAllowed(
+ address holder,
+ uint256 validatorId
+ ) private view {
require(
- _numberOfValidatorsPerDelegator[holder].delegated[validatorId] > 0 ||
- _numberOfValidatorsPerDelegator[holder].number < _getConstantsHolder().limitValidatorsPerDelegator(),
+ _numberOfValidatorsPerDelegator[holder].delegated[validatorId] >
+ 0 ||
+ _numberOfValidatorsPerDelegator[holder].number <
+ _getConstantsHolder().limitValidatorsPerDelegator(),
"Limit of validators is reached"
);
}
- function _getDelegationPeriodManager() private view returns (IDelegationPeriodManager delegationPeriodManager) {
- return IDelegationPeriodManager(contractManager.getDelegationPeriodManager());
+ function _getDelegationPeriodManager()
+ private
+ view
+ returns (IDelegationPeriodManager delegationPeriodManager)
+ {
+ return
+ IDelegationPeriodManager(
+ contractManager.getDelegationPeriodManager()
+ );
}
function _getBounty() private view returns (IBountyV2 bountyV2) {
return IBountyV2(contractManager.getBounty());
}
- function _getValidatorService() private view returns (IValidatorService validatorService) {
+ function _getValidatorService()
+ private
+ view
+ returns (IValidatorService validatorService)
+ {
return IValidatorService(contractManager.getValidatorService());
}
@@ -1002,7 +1254,11 @@ contract DelegationController is Permissions, ILocker, IDelegationController {
return ITimeHelpers(contractManager.getTimeHelpers());
}
- function _getConstantsHolder() private view returns (IConstantsHolder constantsHolder) {
+ function _getConstantsHolder()
+ private
+ view
+ returns (IConstantsHolder constantsHolder)
+ {
return IConstantsHolder(contractManager.getConstantsHolder());
}
}
diff --git a/contracts/delegation/DelegationPeriodManager.sol b/contracts/delegation/DelegationPeriodManager.sol
index b015c2eae..a1624d6d9 100644
--- a/contracts/delegation/DelegationPeriodManager.sol
+++ b/contracts/delegation/DelegationPeriodManager.sol
@@ -22,10 +22,11 @@
pragma solidity 0.8.17;
-import { IDelegationPeriodManager }
-from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationPeriodManager.sol";
+import {
+ IDelegationPeriodManager
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationPeriodManager.sol";
-import { Permissions } from "../Permissions.sol";
+import {Permissions} from "../Permissions.sol";
/**
* @title Delegation Period Manager
@@ -34,17 +35,17 @@ import { Permissions } from "../Permissions.sol";
* returns or `stakeMultiplier`. Currently, only delegation periods can be added.
*/
contract DelegationPeriodManager is Permissions, IDelegationPeriodManager {
+ mapping(uint256 => uint256) public stakeMultipliers;
- mapping (uint256 => uint256) public stakeMultipliers;
-
- bytes32 public constant DELEGATION_PERIOD_SETTER_ROLE = keccak256("DELEGATION_PERIOD_SETTER_ROLE");
+ bytes32 public constant DELEGATION_PERIOD_SETTER_ROLE =
+ keccak256("DELEGATION_PERIOD_SETTER_ROLE");
/**
* @dev Initial delegation period and multiplier settings.
*/
function initialize(address contractsAddress) public override initializer {
Permissions.initialize(contractsAddress);
- stakeMultipliers[2] = 100; // 2 months at 100
+ stakeMultipliers[2] = 100; // 2 months at 100
// stakeMultipliers[6] = 150; // 6 months at 150
// stakeMultipliers[12] = 200; // 12 months at 200
}
@@ -55,9 +56,18 @@ contract DelegationPeriodManager is Permissions, IDelegationPeriodManager {
*
* Emits a {DelegationPeriodWasSet} event.
*/
- function setDelegationPeriod(uint256 monthsCount, uint256 stakeMultiplier) external override {
- require(hasRole(DELEGATION_PERIOD_SETTER_ROLE, msg.sender), "DELEGATION_PERIOD_SETTER_ROLE is required");
- require(stakeMultipliers[monthsCount] == 0, "Delegation period is already set");
+ function setDelegationPeriod(
+ uint256 monthsCount,
+ uint256 stakeMultiplier
+ ) external override {
+ require(
+ hasRole(DELEGATION_PERIOD_SETTER_ROLE, msg.sender),
+ "DELEGATION_PERIOD_SETTER_ROLE is required"
+ );
+ require(
+ stakeMultipliers[monthsCount] == 0,
+ "Delegation period is already set"
+ );
stakeMultipliers[monthsCount] = stakeMultiplier;
emit DelegationPeriodWasSet(monthsCount, stakeMultiplier);
@@ -66,7 +76,9 @@ contract DelegationPeriodManager is Permissions, IDelegationPeriodManager {
/**
* @dev Checks whether given delegation period is allowed.
*/
- function isDelegationPeriodAllowed(uint256 monthsCount) external view override returns (bool allowed) {
+ function isDelegationPeriodAllowed(
+ uint256 monthsCount
+ ) external view override returns (bool allowed) {
return stakeMultipliers[monthsCount] != 0;
}
}
diff --git a/contracts/delegation/Distributor.sol b/contracts/delegation/Distributor.sol
index 96a925fc8..4f3f9ff1b 100644
--- a/contracts/delegation/Distributor.sol
+++ b/contracts/delegation/Distributor.sol
@@ -21,19 +21,22 @@
pragma solidity 0.8.17;
-import { IERC1820Registry } from "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
-import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
-import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-
-import { IDistributor } from "@skalenetwork/skale-manager-interfaces/delegation/IDistributor.sol";
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
-import { ITimeHelpers } from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
-
-import { Permissions } from "../Permissions.sol";
-import { ConstantsHolder } from "../ConstantsHolder.sol";
-import { MathUtils } from "../utils/MathUtils.sol";
-
+import {IERC1820Registry} from "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
+import {IERC777Recipient} from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol";
+import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+
+import {IDistributor} from "@skalenetwork/skale-manager-interfaces/delegation/IDistributor.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {ITimeHelpers} from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
+
+import {Permissions} from "../Permissions.sol";
+import {ConstantsHolder} from "../ConstantsHolder.sol";
+import {MathUtils} from "../utils/MathUtils.sol";
/**
* @title Distributor
@@ -46,18 +49,23 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
IERC1820Registry private _erc1820;
// validatorId => month => token
- mapping (uint256 => mapping (uint256 => uint256)) private _bountyPaid;
+ mapping(uint256 => mapping(uint256 => uint256)) private _bountyPaid;
// validatorId => month => token
- mapping (uint256 => mapping (uint256 => uint256)) private _feePaid;
+ mapping(uint256 => mapping(uint256 => uint256)) private _feePaid;
// holder => validatorId => month
- mapping (address => mapping (uint256 => uint256)) private _firstUnwithdrawnMonth;
+ mapping(address => mapping(uint256 => uint256))
+ private _firstUnwithdrawnMonth;
// validatorId => month
- mapping (uint256 => uint256) private _firstUnwithdrawnMonthForValidator;
+ mapping(uint256 => uint256) private _firstUnwithdrawnMonthForValidator;
function initialize(address contractsAddress) public override initializer {
Permissions.initialize(contractsAddress);
_erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
- _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777TokensRecipient"), address(this));
+ _erc1820.setInterfaceImplementer(
+ address(this),
+ keccak256("ERC777TokensRecipient"),
+ address(this)
+ );
}
/**
@@ -65,11 +73,7 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
*/
function getAndUpdateEarnedBountyAmount(
uint256 validatorId
- )
- external
- override
- returns (uint256 earned, uint256 endMonth)
- {
+ ) external override returns (uint256 earned, uint256 endMonth) {
return getAndUpdateEarnedBountyAmountOf(msg.sender, validatorId);
}
@@ -84,29 +88,35 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
* - Bounty must be unlocked.
*/
function withdrawBounty(uint256 validatorId, address to) external override {
- ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
+ ITimeHelpers timeHelpers = ITimeHelpers(
+ contractManager.getContract("TimeHelpers")
+ );
+ ConstantsHolder constantsHolder = ConstantsHolder(
+ contractManager.getContract("ConstantsHolder")
+ );
- require(block.timestamp >= timeHelpers.addMonths(
- constantsHolder.launchTimestamp(),
- constantsHolder.BOUNTY_LOCKUP_MONTHS()
- ), "Bounty is locked");
+ require(
+ block.timestamp >=
+ timeHelpers.addMonths(
+ constantsHolder.launchTimestamp(),
+ constantsHolder.BOUNTY_LOCKUP_MONTHS()
+ ),
+ "Bounty is locked"
+ );
uint256 bounty;
uint256 endMonth;
- (bounty, endMonth) = getAndUpdateEarnedBountyAmountOf(msg.sender, validatorId);
+ (bounty, endMonth) = getAndUpdateEarnedBountyAmountOf(
+ msg.sender,
+ validatorId
+ );
_firstUnwithdrawnMonth[msg.sender][validatorId] = endMonth;
IERC20 skaleToken = IERC20(contractManager.getContract("SkaleToken"));
require(skaleToken.transfer(to, bounty), "Failed to transfer tokens");
- emit WithdrawBounty(
- msg.sender,
- validatorId,
- to,
- bounty
- );
+ emit WithdrawBounty(msg.sender, validatorId, to, bounty);
}
/**
@@ -120,15 +130,25 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
* - Fee must be unlocked.
*/
function withdrawFee(address to) external override {
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
+ IValidatorService validatorService = IValidatorService(
+ contractManager.getContract("ValidatorService")
+ );
IERC20 skaleToken = IERC20(contractManager.getContract("SkaleToken"));
- ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
- ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));
+ ITimeHelpers timeHelpers = ITimeHelpers(
+ contractManager.getContract("TimeHelpers")
+ );
+ ConstantsHolder constantsHolder = ConstantsHolder(
+ contractManager.getContract("ConstantsHolder")
+ );
- require(block.timestamp >= timeHelpers.addMonths(
- constantsHolder.launchTimestamp(),
- constantsHolder.BOUNTY_LOCKUP_MONTHS()
- ), "Fee is locked");
+ require(
+ block.timestamp >=
+ timeHelpers.addMonths(
+ constantsHolder.launchTimestamp(),
+ constantsHolder.BOUNTY_LOCKUP_MONTHS()
+ ),
+ "Fee is locked"
+ );
// check Validator Exist inside getValidatorId
uint256 validatorId = validatorService.getValidatorId(msg.sender);
@@ -140,11 +160,7 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
require(skaleToken.transfer(to, fee), "Failed to transfer tokens");
- emit WithdrawFee(
- validatorId,
- to,
- fee
- );
+ emit WithdrawFee(validatorId, to, fee);
}
function tokensReceived(
@@ -154,11 +170,7 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
uint256 amount,
bytes calldata userData,
bytes calldata
- )
- external
- override
- allow("SkaleToken")
- {
+ ) external override allow("SkaleToken") {
require(to == address(this), "Receiver is incorrect");
require(userData.length == 32, "Data length is incorrect");
uint256 validatorId = abi.decode(userData, (uint256));
@@ -168,28 +180,41 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
/**
* @dev Return the amount of earned validator fees of `msg.sender`.
*/
- function getEarnedFeeAmount() external view override returns (uint256 earned, uint256 endMonth) {
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
- return getEarnedFeeAmountOf(validatorService.getValidatorId(msg.sender));
+ function getEarnedFeeAmount()
+ external
+ view
+ override
+ returns (uint256 earned, uint256 endMonth)
+ {
+ IValidatorService validatorService = IValidatorService(
+ contractManager.getContract("ValidatorService")
+ );
+ return
+ getEarnedFeeAmountOf(validatorService.getValidatorId(msg.sender));
}
/**
* @dev Return and update the amount of earned bounties.
*/
- function getAndUpdateEarnedBountyAmountOf(address wallet, uint256 validatorId)
- public
- override
- returns (uint256 earned, uint256 endMonth)
- {
+ function getAndUpdateEarnedBountyAmountOf(
+ address wallet,
+ uint256 validatorId
+ ) public override returns (uint256 earned, uint256 endMonth) {
IDelegationController delegationController = IDelegationController(
- contractManager.getContract("DelegationController"));
- ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
+ contractManager.getContract("DelegationController")
+ );
+ ITimeHelpers timeHelpers = ITimeHelpers(
+ contractManager.getContract("TimeHelpers")
+ );
uint256 currentMonth = timeHelpers.getCurrentMonth();
uint256 startMonth = _firstUnwithdrawnMonth[wallet][validatorId];
if (startMonth == 0) {
- startMonth = delegationController.getFirstDelegationMonth(wallet, validatorId);
+ startMonth = delegationController.getFirstDelegationMonth(
+ wallet,
+ validatorId
+ );
if (startMonth == 0) {
return (0, 0);
}
@@ -201,12 +226,18 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
endMonth = startMonth + 12;
}
for (uint256 i = startMonth; i < endMonth; ++i) {
- uint256 effectiveDelegatedToValidator =
- delegationController.getAndUpdateEffectiveDelegatedToValidator(validatorId, i);
+ uint256 effectiveDelegatedToValidator = delegationController
+ .getAndUpdateEffectiveDelegatedToValidator(validatorId, i);
if (effectiveDelegatedToValidator.muchGreater(0)) {
- earned = earned +
- _bountyPaid[validatorId][i] *
- delegationController.getAndUpdateEffectiveDelegatedByHolderToValidator(wallet, validatorId, i) /
+ earned =
+ earned +
+ (_bountyPaid[validatorId][i] *
+ delegationController
+ .getAndUpdateEffectiveDelegatedByHolderToValidator(
+ wallet,
+ validatorId,
+ i
+ )) /
effectiveDelegatedToValidator;
}
}
@@ -215,8 +246,12 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
/**
* @dev Return the amount of earned fees by validator ID.
*/
- function getEarnedFeeAmountOf(uint256 validatorId) public view override returns (uint256 earned, uint256 endMonth) {
- ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
+ function getEarnedFeeAmountOf(
+ uint256 validatorId
+ ) public view override returns (uint256 earned, uint256 endMonth) {
+ ITimeHelpers timeHelpers = ITimeHelpers(
+ contractManager.getContract("TimeHelpers")
+ );
uint256 currentMonth = timeHelpers.getCurrentMonth();
@@ -243,16 +278,24 @@ contract Distributor is Permissions, IERC777Recipient, IDistributor {
* Emits a {BountyWasPaid} event.
*/
function _distributeBounty(uint256 amount, uint256 validatorId) private {
- ITimeHelpers timeHelpers = ITimeHelpers(contractManager.getContract("TimeHelpers"));
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
+ ITimeHelpers timeHelpers = ITimeHelpers(
+ contractManager.getContract("TimeHelpers")
+ );
+ IValidatorService validatorService = IValidatorService(
+ contractManager.getContract("ValidatorService")
+ );
uint256 currentMonth = timeHelpers.getCurrentMonth();
uint256 feeRate = validatorService.getValidator(validatorId).feeRate;
- uint256 fee = amount * feeRate / 1000;
+ uint256 fee = (amount * feeRate) / 1000;
uint256 bounty = amount - fee;
- _bountyPaid[validatorId][currentMonth] = _bountyPaid[validatorId][currentMonth] + bounty;
- _feePaid[validatorId][currentMonth] = _feePaid[validatorId][currentMonth] + fee;
+ _bountyPaid[validatorId][currentMonth] =
+ _bountyPaid[validatorId][currentMonth] +
+ bounty;
+ _feePaid[validatorId][currentMonth] =
+ _feePaid[validatorId][currentMonth] +
+ fee;
if (_firstUnwithdrawnMonthForValidator[validatorId] == 0) {
_firstUnwithdrawnMonthForValidator[validatorId] = currentMonth;
diff --git a/contracts/delegation/PartialDifferences.sol b/contracts/delegation/PartialDifferences.sol
index e07fffabc..a6947e3b6 100644
--- a/contracts/delegation/PartialDifferences.sol
+++ b/contracts/delegation/PartialDifferences.sol
@@ -21,8 +21,8 @@
pragma solidity 0.8.17;
-import { MathUtils } from "../utils/MathUtils.sol";
-import { FractionUtils } from "../utils/FractionUtils.sol";
+import {MathUtils} from "../utils/MathUtils.sol";
+import {FractionUtils} from "../utils/FractionUtils.sol";
/**
* @title Partial Differences Library
@@ -44,23 +44,21 @@ library PartialDifferences {
using MathUtils for uint;
struct Sequence {
- // month => diff
- mapping (uint256 => uint256) addDiff;
- // month => diff
- mapping (uint256 => uint256) subtractDiff;
- // month => value
- mapping (uint256 => uint256) value;
-
+ // month => diff
+ mapping(uint256 => uint256) addDiff;
+ // month => diff
+ mapping(uint256 => uint256) subtractDiff;
+ // month => value
+ mapping(uint256 => uint256) value;
uint256 firstUnprocessedMonth;
uint256 lastChangedMonth;
}
struct Value {
- // month => diff
- mapping (uint256 => uint256) addDiff;
- // month => diff
- mapping (uint256 => uint256) subtractDiff;
-
+ // month => diff
+ mapping(uint256 => uint256) addDiff;
+ // month => diff
+ mapping(uint256 => uint256) subtractDiff;
uint256 value;
uint256 firstUnprocessedMonth;
uint256 lastChangedMonth;
@@ -68,8 +66,15 @@ library PartialDifferences {
// functions for sequence
- function addToSequence(Sequence storage sequence, uint256 diff, uint256 month) internal {
- require(sequence.firstUnprocessedMonth <= month, "Cannot add to the past");
+ function addToSequence(
+ Sequence storage sequence,
+ uint256 diff,
+ uint256 month
+ ) internal {
+ require(
+ sequence.firstUnprocessedMonth <= month,
+ "Cannot add to the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
sequence.firstUnprocessedMonth = month;
}
@@ -79,8 +84,15 @@ library PartialDifferences {
}
}
- function subtractFromSequence(Sequence storage sequence, uint256 diff, uint256 month) internal {
- require(sequence.firstUnprocessedMonth <= month, "Cannot subtract from the past");
+ function subtractFromSequence(
+ Sequence storage sequence,
+ uint256 diff,
+ uint256 month
+ ) internal {
+ require(
+ sequence.firstUnprocessedMonth <= month,
+ "Cannot subtract from the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
sequence.firstUnprocessedMonth = month;
}
@@ -90,14 +102,18 @@ library PartialDifferences {
}
}
- function getAndUpdateValueInSequence(Sequence storage sequence, uint256 month) internal returns (uint256 value) {
+ function getAndUpdateValueInSequence(
+ Sequence storage sequence,
+ uint256 month
+ ) internal returns (uint256 value) {
if (sequence.firstUnprocessedMonth == 0) {
return 0;
}
if (sequence.firstUnprocessedMonth <= month) {
for (uint256 i = sequence.firstUnprocessedMonth; i <= month; ++i) {
- uint256 nextValue = (sequence.value[i - 1] + sequence.addDiff[i]).boundedSub(sequence.subtractDiff[i]);
+ uint256 nextValue = (sequence.value[i - 1] +
+ sequence.addDiff[i]).boundedSub(sequence.subtractDiff[i]);
if (sequence.value[i] != nextValue) {
sequence.value[i] = nextValue;
}
@@ -117,12 +133,16 @@ library PartialDifferences {
function reduceSequence(
Sequence storage sequence,
FractionUtils.Fraction memory reducingCoefficient,
- uint256 month) internal
- {
- require(month + 1 >= sequence.firstUnprocessedMonth, "Cannot reduce value in the past");
+ uint256 month
+ ) internal {
+ require(
+ month + 1 >= sequence.firstUnprocessedMonth,
+ "Cannot reduce value in the past"
+ );
require(
reducingCoefficient.numerator <= reducingCoefficient.denominator,
- "Increasing of values is not implemented");
+ "Increasing of values is not implemented"
+ );
if (sequence.firstUnprocessedMonth == 0) {
return;
}
@@ -131,21 +151,28 @@ library PartialDifferences {
return;
}
- sequence.value[month] = sequence.value[month]
- * reducingCoefficient.numerator
- / reducingCoefficient.denominator;
+ sequence.value[month] =
+ (sequence.value[month] * reducingCoefficient.numerator) /
+ reducingCoefficient.denominator;
for (uint256 i = month + 1; i <= sequence.lastChangedMonth; ++i) {
- sequence.subtractDiff[i] = sequence.subtractDiff[i]
- * reducingCoefficient.numerator
- / reducingCoefficient.denominator;
+ sequence.subtractDiff[i] =
+ (sequence.subtractDiff[i] * reducingCoefficient.numerator) /
+ reducingCoefficient.denominator;
}
}
// functions for value
- function addToValue(Value storage sequence, uint256 diff, uint256 month) internal {
- require(sequence.firstUnprocessedMonth <= month, "Cannot add to the past");
+ function addToValue(
+ Value storage sequence,
+ uint256 diff,
+ uint256 month
+ ) internal {
+ require(
+ sequence.firstUnprocessedMonth <= month,
+ "Cannot add to the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
sequence.firstUnprocessedMonth = month;
sequence.lastChangedMonth = month;
@@ -161,8 +188,15 @@ library PartialDifferences {
}
}
- function subtractFromValue(Value storage sequence, uint256 diff, uint256 month) internal {
- require(sequence.firstUnprocessedMonth <= month + 1, "Cannot subtract from the past");
+ function subtractFromValue(
+ Value storage sequence,
+ uint256 diff,
+ uint256 month
+ ) internal {
+ require(
+ sequence.firstUnprocessedMonth <= month + 1,
+ "Cannot subtract from the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
sequence.firstUnprocessedMonth = month;
sequence.lastChangedMonth = month;
@@ -178,10 +212,14 @@ library PartialDifferences {
}
}
- function getAndUpdateValue(Value storage sequence, uint256 month) internal returns (uint256 value) {
+ function getAndUpdateValue(
+ Value storage sequence,
+ uint256 month
+ ) internal returns (uint256 value) {
require(
month + 1 >= sequence.firstUnprocessedMonth,
- "Cannot calculate value in the past");
+ "Cannot calculate value in the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
return 0;
}
@@ -189,7 +227,9 @@ library PartialDifferences {
if (sequence.firstUnprocessedMonth <= month) {
value = sequence.value;
for (uint256 i = sequence.firstUnprocessedMonth; i <= month; ++i) {
- value = (value + sequence.addDiff[i]).boundedSub(sequence.subtractDiff[i]);
+ value = (value + sequence.addDiff[i]).boundedSub(
+ sequence.subtractDiff[i]
+ );
if (sequence.addDiff[i] > 0) {
delete sequence.addDiff[i];
}
@@ -209,10 +249,12 @@ library PartialDifferences {
function reduceValue(
Value storage sequence,
uint256 amount,
- uint256 month)
- internal returns (FractionUtils.Fraction memory reducingCoefficient)
- {
- require(month + 1 >= sequence.firstUnprocessedMonth, "Cannot reduce value in the past");
+ uint256 month
+ ) internal returns (FractionUtils.Fraction memory reducingCoefficient) {
+ require(
+ month + 1 >= sequence.firstUnprocessedMonth,
+ "Cannot reduce value in the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
return FractionUtils.createFraction(0);
}
@@ -226,8 +268,10 @@ library PartialDifferences {
_amount = value;
}
- reducingCoefficient =
- FractionUtils.createFraction(value.boundedSub(_amount), value);
+ reducingCoefficient = FractionUtils.createFraction(
+ value.boundedSub(_amount),
+ value
+ );
reduceValueByCoefficient(sequence, reducingCoefficient, month);
return reducingCoefficient;
}
@@ -235,9 +279,8 @@ library PartialDifferences {
function reduceValueByCoefficient(
Value storage sequence,
FractionUtils.Fraction memory reducingCoefficient,
- uint256 month)
- internal
- {
+ uint256 month
+ ) internal {
reduceValueByCoefficientAndUpdateSumIfNeeded({
sequence: sequence,
sumSequence: sequence,
@@ -251,8 +294,8 @@ library PartialDifferences {
Value storage sequence,
Value storage sumSequence,
FractionUtils.Fraction memory reducingCoefficient,
- uint256 month) internal
- {
+ uint256 month
+ ) internal {
reduceValueByCoefficientAndUpdateSumIfNeeded({
sequence: sequence,
sumSequence: sumSequence,
@@ -267,15 +310,22 @@ library PartialDifferences {
Value storage sumSequence,
FractionUtils.Fraction memory reducingCoefficient,
uint256 month,
- bool hasSumSequence) internal
- {
- require(month + 1 >= sequence.firstUnprocessedMonth, "Cannot reduce value in the past");
+ 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(
+ month + 1 >= sumSequence.firstUnprocessedMonth,
+ "Cannot reduce value in the past"
+ );
}
require(
reducingCoefficient.numerator <= reducingCoefficient.denominator,
- "Increasing of values is not implemented");
+ "Increasing of values is not implemented"
+ );
if (sequence.firstUnprocessedMonth == 0) {
return;
}
@@ -284,25 +334,34 @@ library PartialDifferences {
return;
}
- uint256 newValue = sequence.value * reducingCoefficient.numerator / reducingCoefficient.denominator;
+ uint256 newValue = (sequence.value * reducingCoefficient.numerator) /
+ reducingCoefficient.denominator;
if (hasSumSequence) {
- subtractFromValue(sumSequence, sequence.value.boundedSub(newValue), month);
+ subtractFromValue(
+ sumSequence,
+ sequence.value.boundedSub(newValue),
+ month
+ );
}
sequence.value = newValue;
for (uint256 i = month + 1; i <= sequence.lastChangedMonth; ++i) {
- uint256 newDiff = sequence.subtractDiff[i]
- * reducingCoefficient.numerator
- / reducingCoefficient.denominator;
+ uint256 newDiff = (sequence.subtractDiff[i] *
+ reducingCoefficient.numerator) /
+ reducingCoefficient.denominator;
if (hasSumSequence) {
- sumSequence.subtractDiff[i] = sumSequence.subtractDiff[i]
+ sumSequence.subtractDiff[i] = sumSequence
+ .subtractDiff[i]
.boundedSub(sequence.subtractDiff[i].boundedSub(newDiff));
}
sequence.subtractDiff[i] = newDiff;
}
}
- function getValueInSequence(Sequence storage sequence, uint256 month) internal view returns (uint256 value) {
+ function getValueInSequence(
+ Sequence storage sequence,
+ uint256 month
+ ) internal view returns (uint256 value) {
if (sequence.firstUnprocessedMonth == 0) {
return 0;
}
@@ -318,7 +377,9 @@ library PartialDifferences {
}
}
- function getValuesInSequence(Sequence storage sequence) internal view returns (uint256[] memory values) {
+ function getValuesInSequence(
+ Sequence storage sequence
+ ) internal view returns (uint256[] memory values) {
if (sequence.firstUnprocessedMonth == 0) {
return values;
}
@@ -331,14 +392,21 @@ library PartialDifferences {
values[0] = sequence.value[sequence.firstUnprocessedMonth - 1];
for (uint256 i = 0; i + 1 < values.length; ++i) {
uint256 month = sequence.firstUnprocessedMonth + i;
- values[i + 1] = values[i] + sequence.addDiff[month] - sequence.subtractDiff[month];
+ values[i + 1] =
+ values[i] +
+ sequence.addDiff[month] -
+ sequence.subtractDiff[month];
}
}
- function getValue(Value storage sequence, uint256 month) internal view returns (uint256 value) {
+ function getValue(
+ Value storage sequence,
+ uint256 month
+ ) internal view returns (uint256 value) {
require(
month + 1 >= sequence.firstUnprocessedMonth,
- "Cannot calculate value in the past");
+ "Cannot calculate value in the past"
+ );
if (sequence.firstUnprocessedMonth == 0) {
return 0;
}
@@ -354,7 +422,9 @@ library PartialDifferences {
}
}
- function getValues(Value storage sequence) internal view returns (uint256[] memory values) {
+ function getValues(
+ Value storage sequence
+ ) internal view returns (uint256[] memory values) {
if (sequence.firstUnprocessedMonth == 0) {
return values;
}
@@ -367,7 +437,10 @@ library PartialDifferences {
values[0] = sequence.value;
for (uint256 i = 0; i + 1 < values.length; ++i) {
uint256 month = sequence.firstUnprocessedMonth + i;
- values[i + 1] = values[i] + sequence.addDiff[month] - sequence.subtractDiff[month];
+ values[i + 1] =
+ values[i] +
+ sequence.addDiff[month] -
+ sequence.subtractDiff[month];
}
}
}
diff --git a/contracts/delegation/Punisher.sol b/contracts/delegation/Punisher.sol
index 94ffd436a..5f506f0ce 100644
--- a/contracts/delegation/Punisher.sol
+++ b/contracts/delegation/Punisher.sol
@@ -21,24 +21,29 @@
pragma solidity 0.8.17;
-import { IPunisher } from "@skalenetwork/skale-manager-interfaces/delegation/IPunisher.sol";
-import { ILocker } from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {IPunisher} from "@skalenetwork/skale-manager-interfaces/delegation/IPunisher.sol";
+import {ILocker} from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
-import { Permissions } from "../Permissions.sol";
+import {Permissions} from "../Permissions.sol";
/**
* @title Punisher
* @dev This contract handles all slashing and forgiving operations.
*/
contract Punisher is Permissions, ILocker, IPunisher {
-
// holder => tokens
- mapping (address => uint256) private _locked;
+ mapping(address => uint256) private _locked;
bytes32 public constant FORGIVER_ROLE = keccak256("FORGIVER_ROLE");
- function initialize(address contractManagerAddress) public override initializer {
+ function initialize(
+ address contractManagerAddress
+ ) public override initializer {
Permissions.initialize(contractManagerAddress);
}
@@ -52,12 +57,21 @@ contract Punisher is Permissions, ILocker, IPunisher {
*
* - Validator must exist.
*/
- function slash(uint256 validatorId, uint256 amount) external override allow("SkaleDKG") {
- IValidatorService validatorService = IValidatorService(contractManager.getContract("ValidatorService"));
+ function slash(
+ uint256 validatorId,
+ uint256 amount
+ ) external override allow("SkaleDKG") {
+ IValidatorService validatorService = IValidatorService(
+ contractManager.getContract("ValidatorService")
+ );
IDelegationController delegationController = IDelegationController(
- contractManager.getContract("DelegationController"));
+ contractManager.getContract("DelegationController")
+ );
- require(validatorService.validatorExists(validatorId), "Validator does not exist");
+ require(
+ validatorService.validatorExists(validatorId),
+ "Validator does not exist"
+ );
delegationController.confiscate(validatorId, amount);
@@ -74,11 +88,18 @@ contract Punisher is Permissions, ILocker, IPunisher {
* - All slashes must have been processed.
*/
function forgive(address holder, uint256 amount) external override {
- require(hasRole(FORGIVER_ROLE, msg.sender), "FORGIVER_ROLE is required");
+ require(
+ hasRole(FORGIVER_ROLE, msg.sender),
+ "FORGIVER_ROLE is required"
+ );
IDelegationController delegationController = IDelegationController(
- contractManager.getContract("DelegationController"));
+ contractManager.getContract("DelegationController")
+ );
- require(!delegationController.hasUnprocessedSlashes(holder), "Not all slashes were calculated");
+ require(
+ !delegationController.hasUnprocessedSlashes(holder),
+ "Not all slashes were calculated"
+ );
if (amount > _locked[holder]) {
delete _locked[holder];
@@ -92,14 +113,18 @@ contract Punisher is Permissions, ILocker, IPunisher {
/**
* @dev See {ILocker-getAndUpdateLockedAmount}.
*/
- function getAndUpdateLockedAmount(address wallet) external override returns (uint256 amount) {
+ function getAndUpdateLockedAmount(
+ address wallet
+ ) external override returns (uint256 amount) {
return _getAndUpdateLockedAmount(wallet);
}
/**
* @dev See {ILocker-getAndUpdateForbiddenForDelegationAmount}.
*/
- function getAndUpdateForbiddenForDelegationAmount(address wallet) external override returns (uint256 amount) {
+ function getAndUpdateForbiddenForDelegationAmount(
+ address wallet
+ ) external override returns (uint256 amount) {
return _getAndUpdateLockedAmount(wallet);
}
@@ -107,7 +132,10 @@ contract Punisher is Permissions, ILocker, IPunisher {
* @dev Allows DelegationController contract to execute slashing of
* delegations.
*/
- function handleSlash(address holder, uint256 amount) external override allow("DelegationController") {
+ function handleSlash(
+ address holder,
+ uint256 amount
+ ) external override allow("DelegationController") {
_locked[holder] = _locked[holder] + amount;
}
@@ -116,12 +144,14 @@ contract Punisher is Permissions, ILocker, IPunisher {
/**
* @dev See {ILocker-getAndUpdateLockedAmount}.
*/
- function _getAndUpdateLockedAmount(address wallet) private returns (uint256 amount) {
+ function _getAndUpdateLockedAmount(
+ address wallet
+ ) private returns (uint256 amount) {
IDelegationController delegationController = IDelegationController(
- contractManager.getContract("DelegationController"));
+ contractManager.getContract("DelegationController")
+ );
delegationController.processAllSlashes(wallet);
return _locked[wallet];
}
-
}
diff --git a/contracts/delegation/TimeHelpers.sol b/contracts/delegation/TimeHelpers.sol
index b3f217ba9..82635738e 100644
--- a/contracts/delegation/TimeHelpers.sol
+++ b/contracts/delegation/TimeHelpers.sol
@@ -21,9 +21,9 @@
pragma solidity 0.8.17;
-import { ITimeHelpers } from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
+import {ITimeHelpers} from "@skalenetwork/skale-manager-interfaces/delegation/ITimeHelpers.sol";
-import { BokkyPooBahsDateTimeLibrary } from "../thirdparty/BokkyPooBahsDateTimeLibrary.sol";
+import {BokkyPooBahsDateTimeLibrary} from "../thirdparty/BokkyPooBahsDateTimeLibrary.sol";
/**
* @title TimeHelpers
@@ -32,50 +32,78 @@ import { BokkyPooBahsDateTimeLibrary } from "../thirdparty/BokkyPooBahsDateTimeL
* These functions are used to calculate monthly and Proof of Use epochs.
*/
contract TimeHelpers is ITimeHelpers {
+ uint256 private constant _ZERO_YEAR = 2020;
+
+ function calculateProofOfUseLockEndTime(
+ uint256 month,
+ uint256 lockUpPeriodDays
+ ) external view override returns (uint256 timestamp) {
+ timestamp = BokkyPooBahsDateTimeLibrary.addDays(
+ monthToTimestamp(month),
+ lockUpPeriodDays
+ );
+ }
- uint256 constant private _ZERO_YEAR = 2020;
-
- function calculateProofOfUseLockEndTime(uint256 month, uint256 lockUpPeriodDays)
+ function getCurrentMonth()
external
view
+ virtual
override
- returns (uint256 timestamp)
+ returns (uint256 month)
{
- timestamp = BokkyPooBahsDateTimeLibrary.addDays(monthToTimestamp(month), lockUpPeriodDays);
- }
-
- function getCurrentMonth() external view virtual override returns (uint256 month) {
return timestampToMonth(block.timestamp);
}
- function timestampToYear(uint256 timestamp) external view virtual override returns (uint256 year) {
- (year, , ) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
+ function timestampToYear(
+ uint256 timestamp
+ ) external view virtual override returns (uint256 year) {
+ uint256 month;
+ uint256 day;
+ (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(
+ timestamp
+ );
require(year >= _ZERO_YEAR, "Timestamp is too far in the past");
return year - _ZERO_YEAR;
}
- function addDays(uint256 fromTimestamp, uint256 n) external pure override returns (uint256 result) {
+ function addDays(
+ uint256 fromTimestamp,
+ uint256 n
+ ) external pure override returns (uint256 result) {
return BokkyPooBahsDateTimeLibrary.addDays(fromTimestamp, n);
}
- function addMonths(uint256 fromTimestamp, uint256 n) external pure override returns (uint256 result) {
+ function addMonths(
+ uint256 fromTimestamp,
+ uint256 n
+ ) external pure override returns (uint256 result) {
return BokkyPooBahsDateTimeLibrary.addMonths(fromTimestamp, n);
}
- function addYears(uint256 fromTimestamp, uint256 n) external pure override returns (uint256 result) {
+ function addYears(
+ uint256 fromTimestamp,
+ uint256 n
+ ) external pure override returns (uint256 result) {
return BokkyPooBahsDateTimeLibrary.addYears(fromTimestamp, n);
}
- function timestampToMonth(uint256 timestamp) public view virtual override returns (uint256 month) {
+ function timestampToMonth(
+ uint256 timestamp
+ ) public view virtual override returns (uint256 month) {
uint256 year;
- (year, month, ) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
+ uint256 day;
+ (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(
+ timestamp
+ );
require(year >= _ZERO_YEAR, "Timestamp is too far in the past");
month = month - 1 + (year - _ZERO_YEAR) * 12;
require(month > 0, "Timestamp is too far in the past");
return month;
}
- function monthToTimestamp(uint256 month) public view virtual override returns (uint256 timestamp) {
+ function monthToTimestamp(
+ uint256 month
+ ) public view virtual override returns (uint256 timestamp) {
uint256 year = _ZERO_YEAR;
uint256 _month = month;
year = year + _month / 12;
diff --git a/contracts/delegation/TokenState.sol b/contracts/delegation/TokenState.sol
index 9c0f09cc9..e2c889534 100644
--- a/contracts/delegation/TokenState.sol
+++ b/contracts/delegation/TokenState.sol
@@ -21,12 +21,13 @@
pragma solidity 0.8.17;
-import { ITokenState } from "@skalenetwork/skale-manager-interfaces/delegation/ITokenState.sol";
-import { ILocker } from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
-
-import { Permissions } from "../Permissions.sol";
+import {ITokenState} from "@skalenetwork/skale-manager-interfaces/delegation/ITokenState.sol";
+import {ILocker} from "@skalenetwork/skale-manager-interfaces/delegation/ILocker.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {Permissions} from "../Permissions.sol";
/**
* @title Token State
@@ -45,19 +46,24 @@ import { Permissions } from "../Permissions.sol";
* `getAndUpdateForbiddenForDelegationAmount`. This lock enforces slashing.
*/
contract TokenState is Permissions, ILocker, ITokenState {
-
string[] private _lockers;
IDelegationController private _delegationController;
- bytes32 public constant LOCKER_MANAGER_ROLE = keccak256("LOCKER_MANAGER_ROLE");
+ bytes32 public constant LOCKER_MANAGER_ROLE =
+ keccak256("LOCKER_MANAGER_ROLE");
modifier onlyLockerManager() {
- require(hasRole(LOCKER_MANAGER_ROLE, msg.sender), "LOCKER_MANAGER_ROLE is required");
+ require(
+ hasRole(LOCKER_MANAGER_ROLE, msg.sender),
+ "LOCKER_MANAGER_ROLE is required"
+ );
_;
}
- function initialize(address contractManagerAddress) public override initializer {
+ function initialize(
+ address contractManagerAddress
+ ) public override initializer {
Permissions.initialize(contractManagerAddress);
_setupRole(LOCKER_MANAGER_ROLE, msg.sender);
addLocker("DelegationController");
@@ -67,16 +73,21 @@ contract TokenState is Permissions, ILocker, ITokenState {
/**
* @dev See {ILocker-getAndUpdateLockedAmount}.
*/
- function getAndUpdateLockedAmount(address holder) external override returns (uint256 amount) {
+ function getAndUpdateLockedAmount(
+ address holder
+ ) external override returns (uint256 amount) {
if (address(_delegationController) == address(0)) {
- _delegationController =
- IDelegationController(contractManager.getContract("DelegationController"));
+ _delegationController = IDelegationController(
+ contractManager.getContract("DelegationController")
+ );
}
uint256 locked = 0;
if (_delegationController.getDelegationsByHolderLength(holder) > 0) {
// the holder ever delegated
for (uint256 i = 0; i < _lockers.length; ++i) {
- ILocker locker = ILocker(contractManager.getContract(_lockers[i]));
+ ILocker locker = ILocker(
+ contractManager.getContract(_lockers[i])
+ );
locked = locked + locker.getAndUpdateLockedAmount(holder);
}
}
@@ -86,11 +97,15 @@ contract TokenState is Permissions, ILocker, ITokenState {
/**
* @dev See {ILocker-getAndUpdateForbiddenForDelegationAmount}.
*/
- function getAndUpdateForbiddenForDelegationAmount(address holder) external override returns (uint256 amount) {
+ function getAndUpdateForbiddenForDelegationAmount(
+ address holder
+ ) external override returns (uint256 amount) {
uint256 forbidden = 0;
for (uint256 i = 0; i < _lockers.length; ++i) {
ILocker locker = ILocker(contractManager.getContract(_lockers[i]));
- forbidden = forbidden + locker.getAndUpdateForbiddenForDelegationAmount(holder);
+ forbidden =
+ forbidden +
+ locker.getAndUpdateForbiddenForDelegationAmount(holder);
}
return forbidden;
}
@@ -100,19 +115,22 @@ contract TokenState is Permissions, ILocker, ITokenState {
*
* Emits a {LockerWasRemoved} event.
*/
- function removeLocker(string calldata locker) external override onlyLockerManager {
+ function removeLocker(
+ string calldata locker
+ ) external override onlyLockerManager {
uint256 index;
+ uint256 lockersLength = _lockers.length;
bytes32 hash = keccak256(abi.encodePacked(locker));
- for (index = 0; index < _lockers.length; ++index) {
+ for (index = 0; index < lockersLength; ++index) {
if (keccak256(abi.encodePacked(_lockers[index])) == hash) {
break;
}
}
- if (index < _lockers.length) {
- if (index < _lockers.length - 1) {
- _lockers[index] = _lockers[_lockers.length - 1];
+ if (index < lockersLength) {
+ if (index < lockersLength - 1) {
+ _lockers[index] = _lockers[lockersLength - 1];
}
- delete _lockers[_lockers.length - 1];
+ delete _lockers[lockersLength - 1];
_lockers.pop();
emit LockerWasRemoved(locker);
}
diff --git a/contracts/delegation/ValidatorService.sol b/contracts/delegation/ValidatorService.sol
index 3bf6ce6c6..bd1a002c3 100644
--- a/contracts/delegation/ValidatorService.sol
+++ b/contracts/delegation/ValidatorService.sol
@@ -21,14 +21,53 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
-
-import { ECDSAUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
-
-import { IValidatorService } from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
-import { IDelegationController } from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
-
-import { Permissions } from "../Permissions.sol";
+pragma solidity 0.8.26;
+
+import {
+ ECDSAUpgradeable
+} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
+import {
+ IValidatorService
+} from "@skalenetwork/skale-manager-interfaces/delegation/IValidatorService.sol";
+import {
+ IDelegationController
+} from "@skalenetwork/skale-manager-interfaces/delegation/IDelegationController.sol";
+import {
+ IPaymasterController
+} from "@skalenetwork/skale-manager-interfaces/IPaymasterController.sol";
+
+import {AddressIsNotSet, RoleRequired} from "../CommonErrors.sol";
+import {Permissions} from "../Permissions.sol";
+
+
+error ValidatorDoesNotExist(uint256 id);
+error AddressIsAlreadyInUse(address validatorAddress);
+error WrongFeeValue(uint256 value);
+error ValidatorIsAlreadyEnabled(uint256 validatorId);
+error ValidatorIsAlreadyDisabled(uint256 validatorId);
+error SenderHasToBeEqualToRequestedAddress(
+ address sender,
+ address requestedAddress
+);
+error WrongSignature();
+error NodeAddressIsAValidator(address nodeAddress, uint256 validatorId);
+error AcceptingRequestIsAlreadyEnabled(uint256 validatorId);
+error AcceptingRequestIsAlreadyDisabled(uint256 validatorId);
+error NoPermissionsToUnlinkNode(uint256 validatorId, address nodeAddress);
+error NodeAddressIsNotAssignedToValidator(address nodeAddress);
+error ValidatorIsNotAuthorized(
+ uint256 validatorId
+);
+error ValidatorIsNotCurrentlyAcceptingNewRequests(uint256 validatorId);
+error AmountDoesNotMeetTheValidatorsMinimumDelegationAmount(
+ uint256 amount,
+ uint256 minimum
+);
+error ValidatorAddressDoesNotExist(address validatorAddress);
+error ValidatorCannotOverrideNodeAddress(
+ uint256 validatorId,
+ address nodeAddress
+);
/**
* @title ValidatorService
@@ -42,34 +81,40 @@ import { Permissions } from "../Permissions.sol";
* register nodes.
*/
contract ValidatorService is Permissions, IValidatorService {
-
using ECDSAUpgradeable for bytes32;
- mapping (uint256 => Validator) public validators;
- mapping (uint256 => bool) private _trustedValidators;
+ mapping(uint256 => Validator) public validators;
+ mapping(uint256 => bool) private _trustedValidators;
uint256[] public trustedValidatorsList;
// address => validatorId
- mapping (address => uint256) private _validatorAddressToId;
+ mapping(address => uint256) private _validatorAddressToId;
// address => validatorId
- mapping (address => uint256) private _nodeAddressToValidatorId;
+ mapping(address => uint256) private _nodeAddressToValidatorId;
// validatorId => nodeAddress[]
- mapping (uint256 => address[]) private _nodeAddresses;
+ mapping(uint256 => address[]) private _nodeAddresses;
uint256 public numberOfValidators;
bool public useWhitelist;
- bytes32 public constant VALIDATOR_MANAGER_ROLE = keccak256("VALIDATOR_MANAGER_ROLE");
+ bytes32 public constant VALIDATOR_MANAGER_ROLE =
+ keccak256("VALIDATOR_MANAGER_ROLE");
modifier onlyValidatorManager() {
- require(hasRole(VALIDATOR_MANAGER_ROLE, msg.sender), "VALIDATOR_MANAGER_ROLE is required");
+ if (!hasRole(VALIDATOR_MANAGER_ROLE, msg.sender)) {
+ revert RoleRequired(VALIDATOR_MANAGER_ROLE);
+ }
_;
}
modifier checkValidatorExists(uint256 validatorId) {
- require(validatorExists(validatorId), "Validator with such ID does not exist");
+ if (!validatorExists(validatorId)) {
+ revert ValidatorDoesNotExist(validatorId);
+ }
_;
}
- function initialize(address contractManagerAddress) public override initializer {
+ function initialize(
+ address contractManagerAddress
+ ) public override initializer {
Permissions.initialize(contractManagerAddress);
useWhitelist = true;
}
@@ -90,13 +135,13 @@ contract ValidatorService is Permissions, IValidatorService {
string calldata description,
uint256 feeRate,
uint256 minimumDelegationAmount
- )
- external
- override
- returns (uint256 validatorId)
- {
- require(!validatorAddressExists(msg.sender), "Validator with such address already exists");
- require(feeRate <= 1000, "Fee rate of validator should be lower than 100%");
+ ) external override returns (uint256 validatorId) {
+ if (validatorAddressExists(msg.sender)) {
+ revert AddressIsAlreadyInUse(msg.sender);
+ }
+ if (1000 < feeRate) {
+ revert WrongFeeValue(feeRate);
+ }
validatorId = ++numberOfValidators;
validators[validatorId] = IValidatorService.Validator({
name: name,
@@ -111,6 +156,11 @@ contract ValidatorService is Permissions, IValidatorService {
_setValidatorAddress(validatorId, msg.sender);
emit ValidatorRegistered(validatorId);
+
+ IPaymasterController paymasterController = IPaymasterController(
+ contractManager.getContract("PaymasterController")
+ );
+ paymasterController.addValidator(validatorId, msg.sender);
}
/**
@@ -123,13 +173,12 @@ contract ValidatorService is Permissions, IValidatorService {
*
* - Validator must not already be enabled.
*/
- function enableValidator(uint256 validatorId)
- external
- override
- checkValidatorExists(validatorId)
- onlyValidatorManager
- {
- require(!_trustedValidators[validatorId], "Validator is already enabled");
+ function enableValidator(
+ uint256 validatorId
+ ) external override checkValidatorExists(validatorId) onlyValidatorManager {
+ if (_trustedValidators[validatorId]) {
+ revert ValidatorIsAlreadyEnabled(validatorId);
+ }
_trustedValidators[validatorId] = true;
trustedValidatorsList.push(validatorId);
emit ValidatorWasEnabled(validatorId);
@@ -145,18 +194,18 @@ contract ValidatorService is Permissions, IValidatorService {
*
* - Validator must not already be disabled.
*/
- function disableValidator(uint256 validatorId)
- external
- override
- checkValidatorExists(validatorId)
- onlyValidatorManager
- {
- require(_trustedValidators[validatorId], "Validator is already disabled");
+ function disableValidator(
+ uint256 validatorId
+ ) external override checkValidatorExists(validatorId) onlyValidatorManager {
+ if (!_trustedValidators[validatorId]) {
+ revert ValidatorIsAlreadyDisabled(validatorId);
+ }
_trustedValidators[validatorId] = false;
uint256 position = _find(trustedValidatorsList, validatorId);
if (position < trustedValidatorsList.length) {
- trustedValidatorsList[position] =
- trustedValidatorsList[trustedValidatorsList.length - 1];
+ trustedValidatorsList[position] = trustedValidatorsList[
+ trustedValidatorsList.length - 1
+ ];
}
trustedValidatorsList.pop();
emit ValidatorWasDisabled(validatorId);
@@ -180,9 +229,15 @@ contract ValidatorService is Permissions, IValidatorService {
* - New address must not be null.
* - New address must not be already registered as a validator.
*/
- function requestForNewAddress(address newValidatorAddress) external override {
- require(newValidatorAddress != address(0), "New address cannot be null");
- require(_validatorAddressToId[newValidatorAddress] == 0, "Address already registered");
+ function requestForNewAddress(
+ address newValidatorAddress
+ ) external override {
+ if (newValidatorAddress == address(0)) {
+ revert AddressIsNotSet();
+ }
+ if (_validatorAddressToId[newValidatorAddress] != 0) {
+ revert AddressIsAlreadyInUse(newValidatorAddress);
+ }
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
@@ -199,19 +254,27 @@ contract ValidatorService is Permissions, IValidatorService {
*
* - Must be owner of new address.
*/
- function confirmNewAddress(uint256 validatorId)
- external
- override
- checkValidatorExists(validatorId)
- {
- require(
- getValidator(validatorId).requestedAddress == msg.sender,
- "The validator address cannot be changed because it is not the actual owner"
- );
+ function confirmNewAddress(
+ uint256 validatorId
+ ) external override checkValidatorExists(validatorId) {
+ if (getValidator(validatorId).requestedAddress != msg.sender) {
+ revert SenderHasToBeEqualToRequestedAddress(
+ msg.sender,
+ getValidator(validatorId).requestedAddress
+ );
+ }
delete validators[validatorId].requestedAddress;
_setValidatorAddress(validatorId, msg.sender);
- emit ValidatorAddressChanged(validatorId, validators[validatorId].validatorAddress);
+ emit ValidatorAddressChanged(
+ validatorId,
+ validators[validatorId].validatorAddress
+ );
+
+ IPaymasterController paymasterController = IPaymasterController(
+ contractManager.getContract("PaymasterController")
+ );
+ paymasterController.setValidatorAddress(validatorId, msg.sender);
}
/**
@@ -223,14 +286,25 @@ contract ValidatorService is Permissions, IValidatorService {
* - Signature must be valid.
* - Address must not be assigned to a validator.
*/
- function linkNodeAddress(address nodeAddress, bytes calldata sig) external override {
+ function linkNodeAddress(
+ address nodeAddress,
+ bytes calldata sig
+ ) external override {
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
- require(
- keccak256(abi.encodePacked(validatorId)).toEthSignedMessageHash().recover(sig) == nodeAddress,
- "Signature is not pass"
- );
- require(_validatorAddressToId[nodeAddress] == 0, "Node address is a validator");
+ if (
+ keccak256(abi.encodePacked(validatorId))
+ .toEthSignedMessageHash()
+ .recover(sig) != nodeAddress
+ ) {
+ revert WrongSignature();
+ }
+ if (_validatorAddressToId[nodeAddress] != 0) {
+ revert NodeAddressIsAValidator(
+ nodeAddress,
+ _validatorAddressToId[nodeAddress]
+ );
+ }
_addNodeAddress(validatorId, nodeAddress);
emit NodeAddressWasAdded(validatorId, nodeAddress);
@@ -252,7 +326,9 @@ contract ValidatorService is Permissions, IValidatorService {
/**
* @dev Allows a validator to set a minimum delegation amount.
*/
- function setValidatorMDA(uint256 minimumDelegationAmount) external override {
+ function setValidatorMDA(
+ uint256 minimumDelegationAmount
+ ) external override {
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
@@ -261,7 +337,8 @@ contract ValidatorService is Permissions, IValidatorService {
validators[validatorId].minimumDelegationAmount,
minimumDelegationAmount
);
- validators[validatorId].minimumDelegationAmount = minimumDelegationAmount;
+ validators[validatorId]
+ .minimumDelegationAmount = minimumDelegationAmount;
}
/**
@@ -271,18 +348,28 @@ contract ValidatorService is Permissions, IValidatorService {
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
- emit SetValidatorName(validatorId, validators[validatorId].name, newName);
+ emit SetValidatorName(
+ validatorId,
+ validators[validatorId].name,
+ newName
+ );
validators[validatorId].name = newName;
}
/**
* @dev Allows a validator to set a new validator description.
*/
- function setValidatorDescription(string calldata newDescription) external override {
+ function setValidatorDescription(
+ string calldata newDescription
+ ) external override {
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
- emit SetValidatorDescription(validatorId, validators[validatorId].description, newDescription);
+ emit SetValidatorDescription(
+ validatorId,
+ validators[validatorId].description,
+ newDescription
+ );
validators[validatorId].description = newDescription;
}
@@ -296,7 +383,9 @@ contract ValidatorService is Permissions, IValidatorService {
function startAcceptingNewRequests() external override {
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
- require(!isAcceptingNewRequests(validatorId), "Accepting request is already enabled");
+ if (isAcceptingNewRequests(validatorId)) {
+ revert AcceptingRequestIsAlreadyEnabled(validatorId);
+ }
validators[validatorId].acceptNewRequests = true;
emit AcceptingNewRequests(validatorId, true);
@@ -312,27 +401,32 @@ contract ValidatorService is Permissions, IValidatorService {
function stopAcceptingNewRequests() external override {
// check Validator Exist inside getValidatorId
uint256 validatorId = getValidatorId(msg.sender);
- require(isAcceptingNewRequests(validatorId), "Accepting request is already disabled");
+ if (!isAcceptingNewRequests(validatorId)) {
+ revert AcceptingRequestIsAlreadyDisabled(validatorId);
+ }
validators[validatorId].acceptNewRequests = false;
emit AcceptingNewRequests(validatorId, false);
}
- function removeNodeAddress(uint256 validatorId, address nodeAddress)
- external
- override
- allowTwo("ValidatorService", "Nodes")
- {
- require(_nodeAddressToValidatorId[nodeAddress] == validatorId,
- "Validator does not have permissions to unlink node");
+ function removeNodeAddress(
+ uint256 validatorId,
+ address nodeAddress
+ ) external override allowTwo("ValidatorService", "Nodes") {
+ if (_nodeAddressToValidatorId[nodeAddress] != validatorId) {
+ revert NoPermissionsToUnlinkNode(validatorId, nodeAddress);
+ }
delete _nodeAddressToValidatorId[nodeAddress];
for (uint256 i = 0; i < _nodeAddresses[validatorId].length; ++i) {
if (_nodeAddresses[validatorId][i] == nodeAddress) {
if (i + 1 < _nodeAddresses[validatorId].length) {
- _nodeAddresses[validatorId][i] =
- _nodeAddresses[validatorId][_nodeAddresses[validatorId].length - 1];
+ _nodeAddresses[validatorId][i] = _nodeAddresses[
+ validatorId
+ ][_nodeAddresses[validatorId].length - 1];
}
- delete _nodeAddresses[validatorId][_nodeAddresses[validatorId].length - 1];
+ delete _nodeAddresses[validatorId][
+ _nodeAddresses[validatorId].length - 1
+ ];
_nodeAddresses[validatorId].pop();
break;
}
@@ -342,43 +436,50 @@ contract ValidatorService is Permissions, IValidatorService {
/**
* @dev Returns the amount of validator bond (self-delegation).
*/
- function getAndUpdateBondAmount(uint256 validatorId)
- external
- override
- returns (uint256 bond)
- {
+ function getAndUpdateBondAmount(
+ uint256 validatorId
+ ) external override returns (uint256 bond) {
IDelegationController delegationController = IDelegationController(
contractManager.getContract("DelegationController")
);
- return delegationController.getAndUpdateDelegatedByHolderToValidatorNow(
- getValidator(validatorId).validatorAddress,
- validatorId
- );
+ return
+ delegationController.getAndUpdateDelegatedByHolderToValidatorNow(
+ getValidator(validatorId).validatorAddress,
+ validatorId
+ );
}
/**
* @dev Returns node addresses linked to the msg.sender.
*/
- function getMyNodesAddresses() external view override returns (address[] memory addresses) {
+ function getMyNodesAddresses()
+ external
+ view
+ override
+ returns (address[] memory addresses)
+ {
return getNodeAddresses(getValidatorId(msg.sender));
}
/**
* @dev Returns the list of trusted validators.
*/
- function getTrustedValidators() external view override returns (uint256[] memory trustedValidators) {
+ function getTrustedValidators()
+ external
+ view
+ override
+ returns (uint256[] memory trustedValidators)
+ {
return trustedValidatorsList;
}
/**
* @dev Checks whether the validator ID is linked to the validator address.
*/
- function checkValidatorAddressToId(address validatorAddress, uint256 validatorId)
- external
- view
- override
- returns (bool valid)
- {
+ function checkValidatorAddressToId(
+ address validatorAddress,
+ uint256 validatorId
+ ) external view override returns (bool valid) {
return getValidatorId(validatorAddress) == validatorId ? true : false;
}
@@ -389,64 +490,88 @@ contract ValidatorService is Permissions, IValidatorService {
*
* - Node address must be linked to a validator.
*/
- function getValidatorIdByNodeAddress(address nodeAddress) external view override returns (uint256 validatorId) {
+ function getValidatorIdByNodeAddress(
+ address nodeAddress
+ ) external view override returns (uint256 validatorId) {
validatorId = _nodeAddressToValidatorId[nodeAddress];
- require(validatorId != 0, "Node address is not assigned to a validator");
+ if (validatorId == 0) {
+ revert NodeAddressIsNotAssignedToValidator(nodeAddress);
+ }
}
/**
* @dev Returns the validator ID linked to a node address without revert.
*/
- function getValidatorIdByNodeAddressWithoutRevert(address nodeAddress)
- external
- view
- override
- returns (uint256 validatorId)
- {
+ function getValidatorIdByNodeAddressWithoutRevert(
+ address nodeAddress
+ ) external view override returns (uint256 validatorId) {
validatorId = _nodeAddressToValidatorId[nodeAddress];
}
- function checkValidatorCanReceiveDelegation(uint256 validatorId, uint256 amount) external view override {
- require(isAuthorizedValidator(validatorId), "Validator is not authorized to accept delegation request");
- require(isAcceptingNewRequests(validatorId), "The validator is not currently accepting new requests");
- require(
- validators[validatorId].minimumDelegationAmount <= amount,
- "Amount does not meet the validator's minimum delegation amount"
- );
+ function checkValidatorCanReceiveDelegation(
+ uint256 validatorId,
+ uint256 amount
+ ) external view override {
+ if (!isAuthorizedValidator(validatorId)) {
+ revert ValidatorIsNotAuthorized(
+ validatorId
+ );
+ }
+ if (!isAcceptingNewRequests(validatorId)) {
+ revert ValidatorIsNotCurrentlyAcceptingNewRequests(validatorId);
+ }
+ if (amount < validators[validatorId].minimumDelegationAmount) {
+ revert AmountDoesNotMeetTheValidatorsMinimumDelegationAmount(
+ amount,
+ validators[validatorId].minimumDelegationAmount
+ );
+ }
}
/**
* @dev Returns a validator's node addresses.
*/
- function getNodeAddresses(uint256 validatorId) public view override returns (address[] memory nodeAddresses) {
+ function getNodeAddresses(
+ uint256 validatorId
+ ) public view override returns (address[] memory nodeAddresses) {
return _nodeAddresses[validatorId];
}
/**
* @dev Checks whether validator ID exists.
*/
- function validatorExists(uint256 validatorId) public view override returns (bool exist) {
+ function validatorExists(
+ uint256 validatorId
+ ) public view override returns (bool exist) {
return validatorId <= numberOfValidators && validatorId != 0;
}
/**
* @dev Checks whether validator address exists.
*/
- function validatorAddressExists(address validatorAddress) public view override returns (bool exist) {
+ function validatorAddressExists(
+ address validatorAddress
+ ) public view override returns (bool exist) {
return _validatorAddressToId[validatorAddress] != 0;
}
/**
* @dev Checks whether validator address exists.
*/
- function checkIfValidatorAddressExists(address validatorAddress) public view override {
- require(validatorAddressExists(validatorAddress), "Validator address does not exist");
+ function checkIfValidatorAddressExists(
+ address validatorAddress
+ ) public view override {
+ if (!validatorAddressExists(validatorAddress)) {
+ revert ValidatorAddressDoesNotExist(validatorAddress);
+ }
}
/**
* @dev Returns the Validator struct.
*/
- function getValidator(uint256 validatorId)
+ function getValidator(
+ uint256 validatorId
+ )
public
view
override
@@ -459,7 +584,9 @@ contract ValidatorService is Permissions, IValidatorService {
/**
* @dev Returns the validator ID for the given validator address.
*/
- function getValidatorId(address validatorAddress) public view override returns (uint256 id) {
+ function getValidatorId(
+ address validatorAddress
+ ) public view override returns (uint256 id) {
checkIfValidatorAddressExists(validatorAddress);
return _validatorAddressToId[validatorAddress];
}
@@ -467,7 +594,9 @@ contract ValidatorService is Permissions, IValidatorService {
/**
* @dev Checks whether the validator is currently accepting new delegation requests.
*/
- function isAcceptingNewRequests(uint256 validatorId)
+ function isAcceptingNewRequests(
+ uint256 validatorId
+ )
public
view
override
@@ -477,7 +606,9 @@ contract ValidatorService is Permissions, IValidatorService {
return validators[validatorId].acceptNewRequests;
}
- function isAuthorizedValidator(uint256 validatorId)
+ function isAuthorizedValidator(
+ uint256 validatorId
+ )
public
view
override
@@ -496,11 +627,16 @@ contract ValidatorService is Permissions, IValidatorService {
*
* - Address is not already in use by another validator.
*/
- function _setValidatorAddress(uint256 validatorId, address validatorAddress) private {
+ function _setValidatorAddress(
+ uint256 validatorId,
+ address validatorAddress
+ ) private {
if (_validatorAddressToId[validatorAddress] == validatorId) {
return;
}
- require(_validatorAddressToId[validatorAddress] == 0, "Address is in use by another validator");
+ if (_validatorAddressToId[validatorAddress] != 0) {
+ revert AddressIsAlreadyInUse(validatorAddress);
+ }
address oldAddress = validators[validatorId].validatorAddress;
delete _validatorAddressToId[oldAddress];
_nodeAddressToValidatorId[validatorAddress] = validatorId;
@@ -519,12 +655,17 @@ contract ValidatorService is Permissions, IValidatorService {
if (_nodeAddressToValidatorId[nodeAddress] == validatorId) {
return;
}
- require(_nodeAddressToValidatorId[nodeAddress] == 0, "Validator cannot override node address");
+ if (_nodeAddressToValidatorId[nodeAddress] != 0) {
+ revert ValidatorCannotOverrideNodeAddress(validatorId, nodeAddress);
+ }
_nodeAddressToValidatorId[nodeAddress] = validatorId;
_nodeAddresses[validatorId].push(nodeAddress);
}
- function _find(uint256[] memory array, uint256 value) private pure returns (uint256 index) {
+ function _find(
+ uint256[] memory array,
+ uint256 value
+ ) private pure returns (uint256 index) {
for (index = 0; index < array.length; index++) {
if (array[index] == value) {
return index;
diff --git a/contracts/dkg/SkaleDkgAlright.sol b/contracts/dkg/SkaleDkgAlright.sol
index 12441181f..8c617af93 100644
--- a/contracts/dkg/SkaleDkgAlright.sol
+++ b/contracts/dkg/SkaleDkgAlright.sol
@@ -23,11 +23,12 @@
pragma solidity 0.8.17;
-import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
-import { IKeyStorage } from "@skalenetwork/skale-manager-interfaces/IKeyStorage.sol";
-import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
-import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+import {ISkaleDKG} from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
+import {IKeyStorage} from "@skalenetwork/skale-manager-interfaces/IKeyStorage.sol";
+import {IContractManager} from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
+import {IConstantsHolder} from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+import {GroupIndexIsInvalid} from "../CommonErrors.sol";
/**
* @title SkaleDkgAlright
@@ -35,7 +36,6 @@ import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConsta
* Joint-Feldman protocol.
*/
library SkaleDkgAlright {
-
event AllDataReceived(bytes32 indexed schainHash, uint256 nodeIndex);
event SuccessfulDKG(bytes32 indexed schainHash);
@@ -48,37 +48,54 @@ library SkaleDkgAlright {
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints,
mapping(bytes32 => uint256) storage lastSuccessfulDKG,
mapping(bytes32 => uint256) storage startAlrightTimestamp
-
- )
- external
- {
+ ) external {
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
- (uint256 index, ) = skaleDKG.checkAndReturnIndexInGroup(schainHash, fromNodeIndex, true);
+ (uint256 index, bool valid) = skaleDKG.checkAndReturnIndexInGroup(
+ schainHash,
+ fromNodeIndex,
+ true
+ );
+ if (!valid) {
+ revert GroupIndexIsInvalid(index);
+ }
uint256 numberOfParticipant = channels[schainHash].n;
- require(numberOfParticipant == dkgProcess[schainHash].numberOfBroadcasted, "Still Broadcasting phase");
require(
- startAlrightTimestamp[schainHash] + _getComplaintTimeLimit(contractManager) > block.timestamp,
+ numberOfParticipant == dkgProcess[schainHash].numberOfBroadcasted,
+ "Still Broadcasting phase"
+ );
+ require(
+ startAlrightTimestamp[schainHash] +
+ _getComplaintTimeLimit(contractManager) >
+ block.timestamp,
"Incorrect time for alright"
);
require(
complaints[schainHash].fromNodeToComplaint != fromNodeIndex ||
- (fromNodeIndex == 0 && complaints[schainHash].startComplaintBlockTimestamp == 0),
+ (fromNodeIndex == 0 &&
+ complaints[schainHash].startComplaintBlockTimestamp == 0),
"Node has already sent complaint"
);
- require(!dkgProcess[schainHash].completed[index], "Node is already alright");
+ require(
+ !dkgProcess[schainHash].completed[index],
+ "Node is already alright"
+ );
dkgProcess[schainHash].completed[index] = true;
dkgProcess[schainHash].numberOfCompleted++;
emit AllDataReceived(schainHash, fromNodeIndex);
if (dkgProcess[schainHash].numberOfCompleted == numberOfParticipant) {
lastSuccessfulDKG[schainHash] = block.timestamp;
channels[schainHash].active = false;
- IKeyStorage(contractManager.getContract("KeyStorage")).finalizePublicKey(schainHash);
+ IKeyStorage(contractManager.getContract("KeyStorage"))
+ .finalizePublicKey(schainHash);
emit SuccessfulDKG(schainHash);
}
}
- function _getComplaintTimeLimit(IContractManager contractManager) private view returns (uint256 timeLimit) {
- return IConstantsHolder(contractManager.getConstantsHolder()).complaintTimeLimit();
+ function _getComplaintTimeLimit(
+ IContractManager contractManager
+ ) private view returns (uint256 timeLimit) {
+ return
+ IConstantsHolder(contractManager.getConstantsHolder())
+ .complaintTimeLimit();
}
-
}
diff --git a/contracts/dkg/SkaleDkgBroadcast.sol b/contracts/dkg/SkaleDkgBroadcast.sol
index c598f17e6..194f25864 100644
--- a/contracts/dkg/SkaleDkgBroadcast.sol
+++ b/contracts/dkg/SkaleDkgBroadcast.sol
@@ -23,12 +23,13 @@
pragma solidity 0.8.17;
-import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
-import { IKeyStorage } from "@skalenetwork/skale-manager-interfaces/IKeyStorage.sol";
-import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
-import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
-import { INodeRotation } from "@skalenetwork/skale-manager-interfaces/INodeRotation.sol";
+import {ISkaleDKG} from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
+import {IKeyStorage} from "@skalenetwork/skale-manager-interfaces/IKeyStorage.sol";
+import {IContractManager} from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
+import {IConstantsHolder} from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+import {INodeRotation} from "@skalenetwork/skale-manager-interfaces/INodeRotation.sol";
+import {GroupIndexIsInvalid} from "../CommonErrors.sol";
/**
* @title SkaleDkgBroadcast
@@ -36,7 +37,6 @@ import { INodeRotation } from "@skalenetwork/skale-manager-interfaces/INodeRotat
* Joint-Feldman protocol.
*/
library SkaleDkgBroadcast {
-
/**
* @dev Emitted when a node broadcasts key share.
*/
@@ -47,7 +47,6 @@ library SkaleDkgBroadcast {
ISkaleDKG.KeyShare[] secretKeyContribution
);
-
/**
* @dev Broadcasts verification vector and secret key contribution to all
* other nodes in the group.
@@ -70,36 +69,40 @@ library SkaleDkgBroadcast {
mapping(bytes32 => ISkaleDKG.ProcessDKG) storage dkgProcess,
mapping(bytes32 => mapping(uint256 => bytes32)) storage hashedData,
uint256 rotationCounter
- )
- external
- {
+ ) external {
uint256 n = channels[schainHash].n;
uint256 schainRotationCounter = INodeRotation(
contractManager.getContract("NodeRotation")
).getRotation(schainHash).rotationCounter;
require(schainRotationCounter == rotationCounter, "Incorrect rotation counter");
require(verificationVector.length == getT(n), "Incorrect number of verification vectors");
+ require(secretKeyContribution.length == n, "Incorrect number of secret key shares");
require(
- secretKeyContribution.length == n,
- "Incorrect number of secret key shares"
- );
- require(
- channels[schainHash].startedBlockTimestamp + _getComplaintTimeLimit(contractManager) > block.timestamp,
+ channels[schainHash].startedBlockTimestamp +
+ _getComplaintTimeLimit(contractManager) >
+ block.timestamp,
"Incorrect time for broadcast"
);
- (uint256 index, ) = ISkaleDKG(contractManager.getContract("SkaleDKG")).checkAndReturnIndexInGroup(
- schainHash, nodeIndex, true
- );
+ (uint256 index, bool valid) = ISkaleDKG(
+ contractManager.getContract("SkaleDKG")
+ ).checkAndReturnIndexInGroup(schainHash, nodeIndex, true);
+ if (!valid) {
+ revert GroupIndexIsInvalid(index);
+ }
require(!dkgProcess[schainHash].broadcasted[index], "This node has already broadcasted");
dkgProcess[schainHash].broadcasted[index] = true;
dkgProcess[schainHash].numberOfBroadcasted++;
- if (dkgProcess[schainHash].numberOfBroadcasted == channels[schainHash].n) {
- ISkaleDKG(contractManager.getContract("SkaleDKG")).setStartAlrightTimestamp(schainHash);
+ if ( dkgProcess[schainHash].numberOfBroadcasted == channels[schainHash].n ) {
+ ISkaleDKG(contractManager.getContract("SkaleDKG"))
+ .setStartAlrightTimestamp(schainHash);
}
- hashedData[schainHash][index] = ISkaleDKG(contractManager.getContract("SkaleDKG")).hashData(
- secretKeyContribution, verificationVector
+ hashedData[schainHash][index] = ISkaleDKG(
+ contractManager.getContract("SkaleDKG")
+ ).hashData(secretKeyContribution, verificationVector);
+ IKeyStorage(contractManager.getContract("KeyStorage")).adding(
+ schainHash,
+ verificationVector[0]
);
- IKeyStorage(contractManager.getContract("KeyStorage")).adding(schainHash, verificationVector[0]);
emit BroadcastAndKeyShare(
schainHash,
nodeIndex,
@@ -112,8 +115,11 @@ library SkaleDkgBroadcast {
return (n * 2 + 1) / 3;
}
- function _getComplaintTimeLimit(IContractManager contractManager) private view returns (uint256 timeLimit) {
- return IConstantsHolder(contractManager.getConstantsHolder()).complaintTimeLimit();
+ function _getComplaintTimeLimit(
+ IContractManager contractManager
+ ) private view returns (uint256 timeLimit) {
+ return
+ IConstantsHolder(contractManager.getConstantsHolder())
+ .complaintTimeLimit();
}
-
}
diff --git a/contracts/dkg/SkaleDkgComplaint.sol b/contracts/dkg/SkaleDkgComplaint.sol
index 3b628200d..c19fea010 100644
--- a/contracts/dkg/SkaleDkgComplaint.sol
+++ b/contracts/dkg/SkaleDkgComplaint.sol
@@ -23,9 +23,9 @@
pragma solidity 0.8.17;
-import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
-import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
-import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
+import {ISkaleDKG} from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
+import {IConstantsHolder} from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+import {IContractManager} from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
/**
* @title SkaleDkgComplaint
@@ -33,7 +33,6 @@ import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContra
* Joint-Feldman protocol.
*/
library SkaleDkgComplaint {
-
/**
* @dev Emitted when an incorrect complaint is sent.
*/
@@ -43,8 +42,10 @@ library SkaleDkgComplaint {
* @dev Emitted when a complaint is sent.
*/
event ComplaintSent(
- bytes32 indexed schainHash, uint256 indexed fromNodeIndex, uint256 indexed toNodeIndex);
-
+ bytes32 indexed schainHash,
+ uint256 indexed fromNodeIndex,
+ uint256 indexed toNodeIndex
+ );
/**
* @dev Creates a complaint from a node (accuser) to a given node.
@@ -64,11 +65,12 @@ library SkaleDkgComplaint {
mapping(bytes32 => ISkaleDKG.Channel) storage channels,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints,
mapping(bytes32 => uint256) storage startAlrightTimestamp
- )
- external
- {
+ ) external {
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
- require(skaleDKG.isNodeBroadcasted(schainHash, fromNodeIndex), "Node has not broadcasted");
+ require(
+ skaleDKG.isNodeBroadcasted(schainHash, fromNodeIndex),
+ "Node has not broadcasted"
+ );
if (skaleDKG.isNodeBroadcasted(schainHash, toNodeIndex)) {
_handleComplaintWhenBroadcasted({
schainHash: schainHash,
@@ -80,7 +82,12 @@ library SkaleDkgComplaint {
});
} else {
// not broadcasted in 30 min
- _handleComplaintWhenNotBroadcasted(schainHash, toNodeIndex, contractManager, channels);
+ _handleComplaintWhenNotBroadcasted(
+ schainHash,
+ toNodeIndex,
+ contractManager,
+ channels
+ );
}
skaleDKG.setBadNode(schainHash, toNodeIndex);
}
@@ -91,17 +98,25 @@ library SkaleDkgComplaint {
uint256 toNodeIndex,
IContractManager contractManager,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints
- )
- external
- {
+ ) external {
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
- require(skaleDKG.isNodeBroadcasted(schainHash, fromNodeIndex), "Node has not broadcasted");
- require(skaleDKG.isNodeBroadcasted(schainHash, toNodeIndex), "Accused node has not broadcasted");
- require(!skaleDKG.isAllDataReceived(schainHash, fromNodeIndex), "Node has already sent alright");
+ require(
+ skaleDKG.isNodeBroadcasted(schainHash, fromNodeIndex),
+ "Node has not broadcasted"
+ );
+ require(
+ skaleDKG.isNodeBroadcasted(schainHash, toNodeIndex),
+ "Accused node has not broadcasted"
+ );
+ require(
+ !skaleDKG.isAllDataReceived(schainHash, fromNodeIndex),
+ "Node has already sent alright"
+ );
if (complaints[schainHash].nodeToComplaint == type(uint256).max) {
complaints[schainHash].nodeToComplaint = toNodeIndex;
complaints[schainHash].fromNodeToComplaint = fromNodeIndex;
- complaints[schainHash].startComplaintBlockTimestamp = block.timestamp;
+ complaints[schainHash].startComplaintBlockTimestamp = block
+ .timestamp;
emit ComplaintSent(schainHash, fromNodeIndex, toNodeIndex);
} else {
emit ComplaintError("First complaint has already been processed");
@@ -115,16 +130,16 @@ library SkaleDkgComplaint {
IContractManager contractManager,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints,
mapping(bytes32 => uint256) storage startAlrightTimestamp
- )
- private
- {
+ ) private {
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
// missing alright
if (complaints[schainHash].nodeToComplaint == type(uint256).max) {
if (
skaleDKG.isEveryoneBroadcasted(schainHash) &&
!skaleDKG.isAllDataReceived(schainHash, toNodeIndex) &&
- startAlrightTimestamp[schainHash] + _getComplaintTimeLimit(contractManager) <= block.timestamp
+ startAlrightTimestamp[schainHash] +
+ _getComplaintTimeLimit(contractManager) <=
+ block.timestamp
) {
// missing alright
skaleDKG.finalizeSlashing(schainHash, toNodeIndex);
@@ -138,10 +153,15 @@ library SkaleDkgComplaint {
return;
} else if (complaints[schainHash].nodeToComplaint == toNodeIndex) {
// 30 min after incorrect data complaint
- if (complaints[schainHash].startComplaintBlockTimestamp + _getComplaintTimeLimit(contractManager)
- <= block.timestamp
+ if (
+ complaints[schainHash].startComplaintBlockTimestamp +
+ _getComplaintTimeLimit(contractManager) <=
+ block.timestamp
) {
- skaleDKG.finalizeSlashing(schainHash, complaints[schainHash].nodeToComplaint);
+ skaleDKG.finalizeSlashing(
+ schainHash,
+ complaints[schainHash].nodeToComplaint
+ );
return;
}
emit ComplaintError("The same complaint rejected");
@@ -150,24 +170,31 @@ library SkaleDkgComplaint {
emit ComplaintError("One complaint is already sent");
}
-
function _handleComplaintWhenNotBroadcasted(
bytes32 schainHash,
uint256 toNodeIndex,
IContractManager contractManager,
mapping(bytes32 => ISkaleDKG.Channel) storage channels
- )
- private
- {
- if (channels[schainHash].startedBlockTimestamp + _getComplaintTimeLimit(contractManager) <= block.timestamp) {
- ISkaleDKG(contractManager.getContract("SkaleDKG")).finalizeSlashing(schainHash, toNodeIndex);
+ ) private {
+ if (
+ channels[schainHash].startedBlockTimestamp +
+ _getComplaintTimeLimit(contractManager) <=
+ block.timestamp
+ ) {
+ ISkaleDKG(contractManager.getContract("SkaleDKG")).finalizeSlashing(
+ schainHash,
+ toNodeIndex
+ );
return;
}
emit ComplaintError("Complaint sent too early");
}
- function _getComplaintTimeLimit(IContractManager contractManager) private view returns (uint256 timeLimit) {
- return IConstantsHolder(contractManager.getConstantsHolder()).complaintTimeLimit();
+ function _getComplaintTimeLimit(
+ IContractManager contractManager
+ ) private view returns (uint256 timeLimit) {
+ return
+ IConstantsHolder(contractManager.getConstantsHolder())
+ .complaintTimeLimit();
}
-
}
diff --git a/contracts/dkg/SkaleDkgPreResponse.sol b/contracts/dkg/SkaleDkgPreResponse.sol
index 282fe3d84..50054f938 100644
--- a/contracts/dkg/SkaleDkgPreResponse.sol
+++ b/contracts/dkg/SkaleDkgPreResponse.sol
@@ -23,12 +23,13 @@
pragma solidity 0.8.17;
-import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
-import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
+import {ISkaleDKG} from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
+import {IContractManager} from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
-import { G1Operations } from "../utils/fieldOperations/G1Operations.sol";
-import { G2Operations } from "../utils/fieldOperations/G2Operations.sol";
-import { Precompiled } from "../utils/Precompiled.sol";
+import {G1Operations} from "../utils/fieldOperations/G1Operations.sol";
+import {G2Operations} from "../utils/fieldOperations/G2Operations.sol";
+import {GroupIndexIsInvalid} from "../CommonErrors.sol";
+import {Precompiled} from "../utils/Precompiled.sol";
/**
* @title SkaleDkgPreResponse
@@ -47,9 +48,7 @@ library SkaleDkgPreResponse {
IContractManager contractManager,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints,
mapping(bytes32 => mapping(uint256 => bytes32)) storage hashedData
- )
- external
- {
+ ) external {
ISkaleDKG skaleDKG = ISkaleDKG(contractManager.getContract("SkaleDKG"));
uint256 index = _preResponseCheck({
schainHash: schainHash,
@@ -74,11 +73,11 @@ library SkaleDkgPreResponse {
bytes32 schainHash,
ISkaleDKG.G2Point[] memory verificationVectorMultiplication,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints
- )
- private
- {
+ ) private {
complaints[schainHash].keyShare = share;
- complaints[schainHash].sumOfVerVec = _calculateSum(verificationVectorMultiplication);
+ complaints[schainHash].sumOfVerVec = _calculateSum(
+ verificationVectorMultiplication
+ );
complaints[schainHash].isResponse = true;
}
@@ -91,34 +90,51 @@ library SkaleDkgPreResponse {
ISkaleDKG skaleDKG,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints,
mapping(bytes32 => mapping(uint256 => bytes32)) storage hashedData
- )
- private
- view
- returns (uint256 index)
- {
- (uint256 indexOnSchain, ) = skaleDKG.checkAndReturnIndexInGroup(schainHash, fromNodeIndex, true);
- require(complaints[schainHash].nodeToComplaint == fromNodeIndex, "Not this Node");
- require(!complaints[schainHash].isResponse, "Already submitted pre response data");
+ ) private view returns (uint256 index) {
+ (uint256 indexOnSchain, bool valid) = skaleDKG
+ .checkAndReturnIndexInGroup(schainHash, fromNodeIndex, true);
+ if (!valid) {
+ revert GroupIndexIsInvalid(index);
+ }
+ require(
+ complaints[schainHash].nodeToComplaint == fromNodeIndex,
+ "Not this Node"
+ );
+ require(
+ !complaints[schainHash].isResponse,
+ "Already submitted pre response data"
+ );
require(
- hashedData[schainHash][indexOnSchain] == skaleDKG.hashData(secretKeyContribution, verificationVector),
+ hashedData[schainHash][indexOnSchain] ==
+ skaleDKG.hashData(secretKeyContribution, verificationVector),
"Broadcasted Data is not correct"
);
require(
- verificationVector.length == verificationVectorMultiplication.length,
+ verificationVector.length ==
+ verificationVectorMultiplication.length,
"Incorrect length of multiplied verification vector"
);
- (index, ) = skaleDKG.checkAndReturnIndexInGroup(schainHash, complaints[schainHash].fromNodeToComplaint, true);
+ (index, valid) = skaleDKG.checkAndReturnIndexInGroup(
+ schainHash,
+ complaints[schainHash].fromNodeToComplaint,
+ true
+ );
+ if (!valid) {
+ revert GroupIndexIsInvalid(index);
+ }
require(
- _checkCorrectVectorMultiplication(index, verificationVector, verificationVectorMultiplication),
+ _checkCorrectVectorMultiplication(
+ index,
+ verificationVector,
+ verificationVectorMultiplication
+ ),
"Multiplied verification vector is incorrect"
);
}
- function _calculateSum(ISkaleDKG.G2Point[] memory verificationVectorMultiplication)
- private
- view
- returns (ISkaleDKG.G2Point memory result)
- {
+ function _calculateSum(
+ ISkaleDKG.G2Point[] memory verificationVectorMultiplication
+ ) private view returns (ISkaleDKG.G2Point memory result) {
ISkaleDKG.G2Point memory value = G2Operations.getG2Zero();
for (uint256 i = 0; i < verificationVectorMultiplication.length; i++) {
value = value.addG2(verificationVectorMultiplication[i]);
@@ -130,16 +146,22 @@ library SkaleDkgPreResponse {
uint256 indexOnSchain,
ISkaleDKG.G2Point[] memory verificationVector,
ISkaleDKG.G2Point[] memory verificationVectorMultiplication
- )
- private
- view
- returns (bool correct)
- {
+ ) private view returns (bool correct) {
ISkaleDKG.Fp2Point memory value = G1Operations.getG1Generator();
ISkaleDKG.Fp2Point memory tmp = G1Operations.getG1Generator();
for (uint256 i = 0; i < verificationVector.length; i++) {
- (tmp.a, tmp.b) = Precompiled.bn256ScalarMul(value.a, value.b, (indexOnSchain + 1) ** i);
- if (!_checkPairing(tmp, verificationVector[i], verificationVectorMultiplication[i])) {
+ (tmp.a, tmp.b) = Precompiled.bn256ScalarMul(
+ value.a,
+ value.b,
+ (indexOnSchain + 1) ** i
+ );
+ if (
+ !_checkPairing(
+ tmp,
+ verificationVector[i],
+ verificationVectorMultiplication[i]
+ )
+ ) {
return false;
}
}
@@ -150,28 +172,24 @@ library SkaleDkgPreResponse {
ISkaleDKG.Fp2Point memory g1Mul,
ISkaleDKG.G2Point memory verificationVector,
ISkaleDKG.G2Point memory verificationVectorMultiplication
- )
- private
- view
- returns (bool valid)
- {
+ ) private view returns (bool valid) {
require(G1Operations.checkRange(g1Mul), "g1Mul is not valid");
g1Mul.b = G1Operations.negate(g1Mul.b);
ISkaleDKG.Fp2Point memory one = G1Operations.getG1Generator();
- return Precompiled.bn256Pairing({
- x1: one.a,
- y1: one.b,
- a1: verificationVectorMultiplication.x.b,
- b1: verificationVectorMultiplication.x.a,
- c1: verificationVectorMultiplication.y.b,
- d1: verificationVectorMultiplication.y.a,
- x2: g1Mul.a,
- y2: g1Mul.b,
- a2: verificationVector.x.b,
- b2: verificationVector.x.a,
- c2: verificationVector.y.b,
- d2: verificationVector.y.a
- });
+ return
+ Precompiled.bn256Pairing({
+ x1: one.a,
+ y1: one.b,
+ a1: verificationVectorMultiplication.x.b,
+ b1: verificationVectorMultiplication.x.a,
+ c1: verificationVectorMultiplication.y.b,
+ d1: verificationVectorMultiplication.y.a,
+ x2: g1Mul.a,
+ y2: g1Mul.b,
+ a2: verificationVector.x.b,
+ b2: verificationVector.x.a,
+ c2: verificationVector.y.b,
+ d2: verificationVector.y.a
+ });
}
-
}
diff --git a/contracts/dkg/SkaleDkgResponse.sol b/contracts/dkg/SkaleDkgResponse.sol
index 84872885e..4b7697d91 100644
--- a/contracts/dkg/SkaleDkgResponse.sol
+++ b/contracts/dkg/SkaleDkgResponse.sol
@@ -23,17 +23,17 @@
pragma solidity 0.8.17;
-import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
-import { ISchainsInternal } from "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol";
-import { IDecryption } from "@skalenetwork/skale-manager-interfaces/IDecryption.sol";
-import { INodes } from "@skalenetwork/skale-manager-interfaces/INodes.sol";
-import { IECDH } from "@skalenetwork/skale-manager-interfaces/thirdparty/IECDH.sol";
-import { IContractManager } from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
-import { IConstantsHolder } from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
-
-import { G1Operations } from "../utils/fieldOperations/G1Operations.sol";
-import { G2Operations } from "../utils/fieldOperations/G2Operations.sol";
-import { Precompiled } from "../utils/Precompiled.sol";
+import {ISkaleDKG} from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
+import {ISchainsInternal} from "@skalenetwork/skale-manager-interfaces/ISchainsInternal.sol";
+import {IDecryption} from "@skalenetwork/skale-manager-interfaces/IDecryption.sol";
+import {INodes} from "@skalenetwork/skale-manager-interfaces/INodes.sol";
+import {IECDH} from "@skalenetwork/skale-manager-interfaces/thirdparty/IECDH.sol";
+import {IContractManager} from "@skalenetwork/skale-manager-interfaces/IContractManager.sol";
+import {IConstantsHolder} from "@skalenetwork/skale-manager-interfaces/IConstantsHolder.sol";
+
+import {G1Operations} from "../utils/fieldOperations/G1Operations.sol";
+import {G2Operations} from "../utils/fieldOperations/G2Operations.sol";
+import {Precompiled} from "../utils/Precompiled.sol";
/**
* @title SkaleDkgResponse
@@ -51,19 +51,25 @@ library SkaleDkgResponse {
IContractManager contractManager,
mapping(bytes32 => ISkaleDKG.Channel) storage channels,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints
- )
- external
- {
- uint256 index = ISchainsInternal(contractManager.getContract("SchainsInternal"))
- .getNodeIndexInGroup(schainHash, fromNodeIndex);
+ ) external {
+ uint256 index = ISchainsInternal(
+ contractManager.getContract("SchainsInternal")
+ ).getNodeIndexInGroup(schainHash, fromNodeIndex);
require(index < channels[schainHash].n, "Node is not in this group");
- require(complaints[schainHash].nodeToComplaint == fromNodeIndex, "Not this Node");
require(
- complaints[schainHash].startComplaintBlockTimestamp
- + _getComplaintTimeLimit(contractManager) > block.timestamp,
+ complaints[schainHash].nodeToComplaint == fromNodeIndex,
+ "Not this Node"
+ );
+ require(
+ complaints[schainHash].startComplaintBlockTimestamp +
+ _getComplaintTimeLimit(contractManager) >
+ block.timestamp,
"Incorrect time for response"
);
- require(complaints[schainHash].isResponse, "Have not submitted pre-response data");
+ require(
+ complaints[schainHash].isResponse,
+ "Have not submitted pre-response data"
+ );
uint256 badNode = _verifyDataAndSlash({
schainHash: schainHash,
secretNumber: secretNumber,
@@ -71,7 +77,10 @@ library SkaleDkgResponse {
contractManager: contractManager,
complaints: complaints
});
- ISkaleDKG(contractManager.getContract("SkaleDKG")).setBadNode(schainHash, badNode);
+ ISkaleDKG(contractManager.getContract("SkaleDKG")).setBadNode(
+ schainHash,
+ badNode
+ );
}
function _verifyDataAndSlash(
@@ -80,50 +89,51 @@ library SkaleDkgResponse {
ISkaleDKG.G2Point memory multipliedShare,
IContractManager contractManager,
mapping(bytes32 => ISkaleDKG.ComplaintData) storage complaints
- )
- private
- returns (uint256 badNode)
- {
- bytes32[2] memory publicKey = INodes(contractManager.getContract("Nodes")).getNodePublicKey(
- complaints[schainHash].fromNodeToComplaint
- );
+ ) private returns (uint256 badNode) {
+ bytes32[2] memory publicKey = INodes(
+ contractManager.getContract("Nodes")
+ ).getNodePublicKey(complaints[schainHash].fromNodeToComplaint);
uint256 pkX = uint256(publicKey[0]);
- (pkX, ) = IECDH(contractManager.getContract("ECDH")).deriveKey(secretNumber, pkX, uint256(publicKey[1]));
+ // Value of pkY is not needed for proper DKG work.
+ // Encoding is only done by using half of the keys.
+ // slither-disable-next-line unused-return
+ (pkX, ) = IECDH(contractManager.getContract("ECDH")).deriveKey(
+ secretNumber,
+ pkX,
+ uint256(publicKey[1])
+ );
bytes32 key = bytes32(pkX);
// Decrypt secret key contribution
- uint256 secret = IDecryption(contractManager.getContract("Decryption")).decrypt(
- complaints[schainHash].keyShare,
- sha256(abi.encodePacked(key))
- );
+ uint256 secret = IDecryption(contractManager.getContract("Decryption"))
+ .decrypt(
+ complaints[schainHash].keyShare,
+ sha256(abi.encodePacked(key))
+ );
badNode = (
_checkCorrectMultipliedShare(multipliedShare, secret) &&
- multipliedShare.isEqual(complaints[schainHash].sumOfVerVec) ?
- complaints[schainHash].fromNodeToComplaint :
- complaints[schainHash].nodeToComplaint
+ multipliedShare.isEqual(complaints[schainHash].sumOfVerVec)
+ ? complaints[schainHash].fromNodeToComplaint
+ : complaints[schainHash].nodeToComplaint
+ );
+ ISkaleDKG(contractManager.getContract("SkaleDKG")).finalizeSlashing(
+ schainHash,
+ badNode
);
- ISkaleDKG(contractManager.getContract("SkaleDKG")).finalizeSlashing(schainHash, badNode);
}
function _checkCorrectMultipliedShare(
ISkaleDKG.G2Point memory multipliedShare,
uint256 secret
- )
- private
- view
- returns (bool correct)
- {
+ ) private view returns (bool correct) {
if (!multipliedShare.isG2()) {
return false;
}
ISkaleDKG.G2Point memory tmp = multipliedShare;
ISkaleDKG.Fp2Point memory g1 = G1Operations.getG1Generator();
- ISkaleDKG.Fp2Point memory share = ISkaleDKG.Fp2Point({
- a: 0,
- b: 0
- });
+ ISkaleDKG.Fp2Point memory share = ISkaleDKG.Fp2Point({a: 0, b: 0});
(share.a, share.b) = Precompiled.bn256ScalarMul(g1.a, g1.b, secret);
require(G1Operations.checkRange(share), "share is not valid");
share.b = G1Operations.negate(share.b);
@@ -132,24 +142,28 @@ library SkaleDkgResponse {
ISkaleDKG.G2Point memory g2 = G2Operations.getG2Generator();
- return Precompiled.bn256Pairing({
- x1: share.a,
- y1: share.b,
- a1: g2.x.b,
- b1: g2.x.a,
- c1: g2.y.b,
- d1: g2.y.a,
- x2: g1.a,
- y2: g1.b,
- a2: tmp.x.b,
- b2: tmp.x.a,
- c2: tmp.y.b,
- d2: tmp.y.a
- });
+ return
+ Precompiled.bn256Pairing({
+ x1: share.a,
+ y1: share.b,
+ a1: g2.x.b,
+ b1: g2.x.a,
+ c1: g2.y.b,
+ d1: g2.y.a,
+ x2: g1.a,
+ y2: g1.b,
+ a2: tmp.x.b,
+ b2: tmp.x.a,
+ c2: tmp.y.b,
+ d2: tmp.y.a
+ });
}
- function _getComplaintTimeLimit(IContractManager contractManager) private view returns (uint256 timeLimit) {
- return IConstantsHolder(contractManager.getConstantsHolder()).complaintTimeLimit();
+ function _getComplaintTimeLimit(
+ IContractManager contractManager
+ ) private view returns (uint256 timeLimit) {
+ return
+ IConstantsHolder(contractManager.getConstantsHolder())
+ .complaintTimeLimit();
}
-
}
diff --git a/contracts/test/ImaMock.sol b/contracts/test/ImaMock.sol
new file mode 100644
index 000000000..d52baff85
--- /dev/null
+++ b/contracts/test/ImaMock.sol
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: AGPL-3.0-only
+
+/*
+ LockerMock.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 .
+*/
+
+pragma solidity 0.8.26;
+
+import { IMessageListener } from "@skalenetwork/ima-interfaces/IMessageListener.sol";
+
+contract ImaMock is IMessageListener {
+ event MessageProcessed(
+ address sender,
+ address destinationContract,
+ bytes data
+ );
+
+ event MessageSent(
+ bytes32 targetChainHash,
+ address targetContract,
+ bytes data
+ );
+
+ function postIncomingMessages(
+ string calldata /* fromSchainName */,
+ uint256 /* startingCounter */,
+ Message[] calldata messages,
+ Signature calldata /* sign */
+ ) external override {
+ for (uint256 i = 0; i < messages.length; ++i) {
+ emit MessageProcessed(
+ messages[i].sender,
+ messages[i].destinationContract,
+ messages[i].data
+ );
+ }
+ }
+
+ function postOutgoingMessage(
+ bytes32 targetChainHash,
+ address targetContract,
+ bytes memory data
+ ) external override {
+ emit MessageSent(targetChainHash, targetContract, data);
+ }
+}
diff --git a/contracts/test/LockerMock.sol b/contracts/test/LockerMock.sol
index 813f7962f..c3a36b349 100644
--- a/contracts/test/LockerMock.sol
+++ b/contracts/test/LockerMock.sol
@@ -28,7 +28,14 @@ contract LockerMock is ILocker {
return 13;
}
- function getAndUpdateForbiddenForDelegationAmount(address) external pure override returns (uint256 amount) {
+ function getAndUpdateForbiddenForDelegationAmount(
+ address
+ )
+ external
+ pure
+ override
+ returns (uint256 amount)
+ {
return 13;
}
}
diff --git a/contracts/test/MathUtilsTester.sol b/contracts/test/MathUtilsTester.sol
index 315921395..4d393988e 100644
--- a/contracts/test/MathUtilsTester.sol
+++ b/contracts/test/MathUtilsTester.sol
@@ -32,7 +32,15 @@ contract MathUtilsTester is IMathUtilsTester {
return a.boundedSub(b);
}
- function boundedSubWithoutEvent(uint256 a, uint256 b) external pure override returns (uint256 result) {
+ function boundedSubWithoutEvent(
+ uint256 a,
+ uint256 b
+ )
+ external
+ pure
+ override
+ returns (uint256 result)
+ {
return a.boundedSubWithoutEvent(b);
}
diff --git a/contracts/test/NodesMock.sol b/contracts/test/NodesMock.sol
index b06153938..34a716c84 100644
--- a/contracts/test/NodesMock.sol
+++ b/contracts/test/NodesMock.sol
@@ -53,7 +53,14 @@ contract NodesMock is Permissions, INodesMock {
function changeNodeLastRewardDate(uint256 nodeId) external override {
lastRewardDate[nodeId] = block.timestamp;
}
- function getNodeLastRewardDate(uint256 nodeIndex) external view override returns (uint256 timestamp) {
+ function getNodeLastRewardDate(
+ uint256 nodeIndex
+ )
+ external
+ view
+ override
+ returns (uint256 timestamp)
+ {
require(nodeIndex < nodesCount, "Node does not exist");
return lastRewardDate[nodeIndex];
}
diff --git a/contracts/test/PartialDifferencesTester.sol b/contracts/test/PartialDifferencesTester.sol
index e203f1628..f5f16395d 100644
--- a/contracts/test/PartialDifferencesTester.sol
+++ b/contracts/test/PartialDifferencesTester.sol
@@ -46,7 +46,14 @@ contract PartialDifferencesTester is IPartialDifferencesTester {
_sequences[sequence].subtractFromSequence(diff, month);
}
- function getAndUpdateSequenceItem(uint256 sequence, uint256 month) external override returns (uint256 item) {
+ function getAndUpdateSequenceItem(
+ uint256 sequence,
+ uint256 month
+ )
+ external
+ override
+ returns (uint256 item)
+ {
require(sequence < _sequences.length, "Sequence does not exist");
return _sequences[sequence].getAndUpdateValueInSequence(month);
}
diff --git a/contracts/test/ReentrancyTester.sol b/contracts/test/ReentrancyTester.sol
index da091fa1b..418108413 100644
--- a/contracts/test/ReentrancyTester.sol
+++ b/contracts/test/ReentrancyTester.sol
@@ -34,15 +34,22 @@ import { IReentrancyTester } from "./interfaces/IReentrancyTester.sol";
contract ReentrancyTester is Permissions, IERC777Recipient, IERC777Sender, IReentrancyTester {
- IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+ IERC1820Registry private _erc1820 =
+ IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
bool private _reentrancyCheck = false;
bool private _burningAttack = false;
uint256 private _amount = 0;
constructor (address contractManagerAddress) {
Permissions.initialize(contractManagerAddress);
- _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777TokensRecipient"), address(this));
- _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777TokensSender"), address(this));
+ _erc1820.setInterfaceImplementer(
+ address(this),
+ keccak256("ERC777TokensRecipient"), address(this)
+ );
+ _erc1820.setInterfaceImplementer(
+ address(this),
+ keccak256("ERC777TokensSender"), address(this)
+ );
}
function tokensReceived(
diff --git a/contracts/test/SafeMock.sol b/contracts/test/SafeMock.sol
index 1ca75adfb..5c8f5cdc7 100644
--- a/contracts/test/SafeMock.sol
+++ b/contracts/test/SafeMock.sol
@@ -21,7 +21,9 @@
pragma solidity 0.8.17;
-import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
+import {
+ OwnableUpgradeable
+} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { ISafeMock } from "./interfaces/ISafeMock.sol";
@@ -30,8 +32,9 @@ contract SafeMock is OwnableUpgradeable, ISafeMock {
bool public constant IS_SAFE_MOCK = true;
bytes32 public constant SAFE_TX_TYPE_HASH = keccak256(
- "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,"
- "address gasToken,address refundReceiver,uint256 nonce)"
+ "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,"
+ "uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,"
+ "uint256 nonce)"
);
bytes32 public constant DOMAIN_SEPARATOR_TYPE_HASH = keccak256(
"EIP712Domain(uint256 chainId,address verifyingContract)"
@@ -42,7 +45,14 @@ contract SafeMock is OwnableUpgradeable, ISafeMock {
multiSend(""); // this is needed to remove slither warning
}
- function transferProxyAdminOwnership(OwnableUpgradeable proxyAdmin, address newOwner) external override onlyOwner {
+ function transferProxyAdminOwnership(
+ OwnableUpgradeable proxyAdmin,
+ address newOwner
+ )
+ external
+ override
+ onlyOwner
+ {
proxyAdmin.transferOwnership(newOwner);
}
@@ -52,7 +62,7 @@ contract SafeMock is OwnableUpgradeable, ISafeMock {
/// @dev Sends multiple transactions and reverts all if one fails.
/// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of
- /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),
+ /// operation as a uint8 with 0 for a call or 1 for a delegatecall,
/// to as a address (=> 20 bytes),
/// value as a uint256 (=> 32 bytes),
/// data length as a uint256 (=> 32 bytes),
@@ -79,7 +89,8 @@ contract SafeMock is OwnableUpgradeable, ISafeMock {
let to := shr(0x60, mload(add(transactions, add(i, 0x01))))
// We offset the load address by 21 byte (operation byte + 20 address bytes)
let value := mload(add(transactions, add(i, 0x15)))
- // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)
+ // We offset the load address by 53 byte
+ // (operation byte + 20 address bytes + 32 value bytes)
let dataLength := mload(add(transactions, add(i, 0x35)))
// We offset the load address by 85 byte
// (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)
diff --git a/contracts/test/SchainsInternalMock.sol b/contracts/test/SchainsInternalMock.sol
index f6bd4292b..6d1668177 100644
--- a/contracts/test/SchainsInternalMock.sol
+++ b/contracts/test/SchainsInternalMock.sol
@@ -45,11 +45,27 @@ contract SchainsInternalMock is SchainsInternal, ISchainsInternalMock {
delete schainToException[schainHash];
}
- function _addAddressToSchain(bytes32, address) internal override pure returns (bool successful) {
+ function _addAddressToSchain(
+ bytes32,
+ address
+ )
+ internal
+ override
+ pure
+ returns (bool successful)
+ {
return true;
}
- function _removeAddressFromSchain(bytes32, address) internal override pure returns (bool successful) {
+ function _removeAddressFromSchain(
+ bytes32,
+ address
+ )
+ internal
+ override
+ pure
+ returns (bool successful)
+ {
return true;
}
}
diff --git a/contracts/test/SegmentTreeTester.sol b/contracts/test/SegmentTreeTester.sol
index b0088b3c6..e44e9af50 100644
--- a/contracts/test/SegmentTreeTester.sol
+++ b/contracts/test/SegmentTreeTester.sol
@@ -20,7 +20,7 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity 0.8.26;
import { IRandom, Random, SegmentTree } from "../utils/SegmentTree.sol";
import { ISegmentTreeTester } from "./interfaces/ISegmentTreeTester.sol";
@@ -58,7 +58,14 @@ contract SegmentTreeTester is ISegmentTreeTester {
_tree.removeFromPlace(place, elem);
}
- function moveFromPlaceToPlace(uint256 fromPlace, uint256 toPlace, uint256 elem) external override {
+ function moveFromPlaceToPlace(
+ uint256 fromPlace,
+ uint256 toPlace,
+ uint256 elem
+ )
+ external
+ override
+ {
_tree.moveFromPlaceToPlace(fromPlace, toPlace, elem);
}
diff --git a/contracts/test/SkaleManagerMock.sol b/contracts/test/SkaleManagerMock.sol
index 8e895dbfe..e2ce88a0f 100644
--- a/contracts/test/SkaleManagerMock.sol
+++ b/contracts/test/SkaleManagerMock.sol
@@ -32,21 +32,33 @@ import { ISkaleManagerMock } from "./interfaces/ISkaleManagerMock.sol";
contract SkaleManagerMock is Permissions, IERC777Recipient, ISkaleManagerMock {
- IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
+ IERC1820Registry private _erc1820 =
+ IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
bytes32 constant public ADMIN_ROLE = keccak256("ADMIN_ROLE");
constructor (address contractManagerAddress) {
Permissions.initialize(contractManagerAddress);
- _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777TokensRecipient"), address(this));
+ _erc1820.setInterfaceImplementer(
+ address(this),
+ keccak256("ERC777TokensRecipient"),
+ address(this)
+ );
}
function payBounty(uint256 validatorId, uint256 amount) external override {
IERC777 skaleToken = IERC777(contractManager.getContract("SkaleToken"));
- require(IMintableToken(address(skaleToken)).mint(address(this), amount, "", ""), "Token was not minted");
require(
- IMintableToken(address(skaleToken))
- .mint(contractManager.getContract("Distributor"), amount, abi.encode(validatorId), ""),
+ IMintableToken(address(skaleToken)).mint(address(this), amount, "", ""),
+ "Token was not minted"
+ );
+ require(
+ IMintableToken(address(skaleToken)).mint(
+ contractManager.getContract("Distributor"),
+ amount,
+ abi.encode(validatorId),
+ ""
+ ),
"Token was not minted"
);
}
diff --git a/contracts/test/TimeHelpersWithDebug.sol b/contracts/test/TimeHelpersWithDebug.sol
index fb27b805c..cb2e5d80f 100644
--- a/contracts/test/TimeHelpersWithDebug.sol
+++ b/contracts/test/TimeHelpersWithDebug.sol
@@ -21,7 +21,9 @@
pragma solidity 0.8.17;
-import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
+import {
+ OwnableUpgradeable
+} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { TimeHelpers } from "../delegation/TimeHelpers.sol";
import { ITimeHelpersWithDebug } from "./interfaces/ITimeHelpersWithDebug.sol";
@@ -90,9 +92,16 @@ contract TimeHelpersWithDebug is TimeHelpers, OwnableUpgradeable, ITimeHelpersWi
}
}
- function _findTimeBeforeTimeShift(uint256 shiftedTimestamp) private view returns (uint256 timestamp) {
+ function _findTimeBeforeTimeShift(
+ uint256 shiftedTimestamp
+ )
+ private
+ view
+ returns (uint256 timestamp)
+ {
uint256 lastTimeShiftIndex = _timeShift.length - 1;
- if (_timeShift[lastTimeShiftIndex].pointInTime + _timeShift[lastTimeShiftIndex].shift < shiftedTimestamp) {
+ if (_timeShift[lastTimeShiftIndex].pointInTime + _timeShift[lastTimeShiftIndex].shift
+ < shiftedTimestamp) {
return shiftedTimestamp - _timeShift[lastTimeShiftIndex].shift;
} else {
if (shiftedTimestamp <= _timeShift[0].pointInTime + _timeShift[0].shift) {
@@ -106,7 +115,8 @@ contract TimeHelpersWithDebug is TimeHelpers, OwnableUpgradeable, ITimeHelpersWi
uint256 right = lastTimeShiftIndex;
while (left + 1 < right) {
uint256 middle = (left + right) / 2;
- if (_timeShift[middle].pointInTime + _timeShift[middle].shift < shiftedTimestamp) {
+ if (_timeShift[middle].pointInTime + _timeShift[middle].shift
+ < shiftedTimestamp) {
left = middle;
} else {
right = middle;
diff --git a/contracts/test/interfaces/IPartialDifferencesTester.sol b/contracts/test/interfaces/IPartialDifferencesTester.sol
index 4860a3c85..f38964db2 100644
--- a/contracts/test/interfaces/IPartialDifferencesTester.sol
+++ b/contracts/test/interfaces/IPartialDifferencesTester.sol
@@ -26,7 +26,10 @@ interface IPartialDifferencesTester {
function createSequence() external;
function addToSequence(uint256 sequence, uint256 diff, uint256 month) external;
function subtractFromSequence(uint256 sequence, uint256 diff, uint256 month) external;
- function getAndUpdateSequenceItem(uint256 sequence, uint256 month) external returns (uint256 item);
+ function getAndUpdateSequenceItem(
+ uint256 sequence,
+ uint256 month
+ ) external returns (uint256 item);
function reduceSequence(
uint256 sequence,
uint256 a,
diff --git a/contracts/test/interfaces/ISafeMock.sol b/contracts/test/interfaces/ISafeMock.sol
index d32b97df4..d83b1e656 100644
--- a/contracts/test/interfaces/ISafeMock.sol
+++ b/contracts/test/interfaces/ISafeMock.sol
@@ -21,7 +21,9 @@
pragma solidity 0.8.17;
-import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
+import {
+ OwnableUpgradeable
+} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
interface ISafeMock {
diff --git a/contracts/test/interfaces/ISegmentTreeTester.sol b/contracts/test/interfaces/ISegmentTreeTester.sol
index 6aff638cc..097fb6cc3 100644
--- a/contracts/test/interfaces/ISegmentTreeTester.sol
+++ b/contracts/test/interfaces/ISegmentTreeTester.sol
@@ -19,7 +19,7 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity 0.8.26;
interface ISegmentTreeTester {
diff --git a/contracts/thirdparty/openzeppelin/ERC777.sol b/contracts/thirdparty/openzeppelin/ERC777.sol
index e892f6917..49449aeb5 100644
--- a/contracts/thirdparty/openzeppelin/ERC777.sol
+++ b/contracts/thirdparty/openzeppelin/ERC777.sol
@@ -13,10 +13,6 @@ import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol";
-/* Added by SKALE */
-import "../../Permissions.sol";
-/* End of added by SKALE */
-
/**
* @dev Implementation of the {IERC777} interface.
*
diff --git a/contracts/utils/FractionUtils.sol b/contracts/utils/FractionUtils.sol
index 39a5bf417..cd0005f58 100644
--- a/contracts/utils/FractionUtils.sol
+++ b/contracts/utils/FractionUtils.sol
@@ -29,7 +29,14 @@ library FractionUtils {
uint256 denominator;
}
- function createFraction(uint256 numerator, uint256 denominator) internal pure returns (Fraction memory fraction) {
+ function createFraction(
+ uint256 numerator,
+ uint256 denominator
+ )
+ internal
+ pure
+ returns (Fraction memory fraction)
+ {
require(denominator > 0, "Division by zero");
fraction = Fraction({numerator: numerator, denominator: denominator});
reduceFraction(fraction);
@@ -46,8 +53,16 @@ library FractionUtils {
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 fraction) {
+ // 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 fraction)
+ {
return createFraction(a.numerator * b.numerator, a.denominator * b.denominator);
}
diff --git a/contracts/utils/Precompiled.sol b/contracts/utils/Precompiled.sol
index 5720baab7..f077ede65 100644
--- a/contracts/utils/Precompiled.sol
+++ b/contracts/utils/Precompiled.sol
@@ -19,12 +19,20 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity ^0.8.17;
library Precompiled {
- function bigModExp(uint256 base, uint256 power, uint256 modulus) internal view returns (uint256 value) {
+ function bigModExp(
+ uint256 base,
+ uint256 power,
+ uint256 modulus
+ )
+ internal
+ view
+ returns (uint256 value)
+ {
uint256[6] memory inputToBigModExp;
inputToBigModExp[0] = 32;
inputToBigModExp[1] = 32;
@@ -42,7 +50,15 @@ library Precompiled {
return out[0];
}
- function bn256ScalarMul(uint256 x, uint256 y, uint256 k) internal view returns (uint256 xValue, uint256 yValue) {
+ function bn256ScalarMul(
+ uint256 x,
+ uint256 y,
+ uint256 k
+ )
+ internal
+ view
+ returns (uint256 xValue, uint256 yValue)
+ {
uint256[3] memory inputToMul;
uint256[2] memory output;
inputToMul[0] = x;
diff --git a/contracts/utils/Random.sol b/contracts/utils/Random.sol
index 290b9f511..d4f14a5dd 100644
--- a/contracts/utils/Random.sol
+++ b/contracts/utils/Random.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
/*
- SegmentTree.sol - SKALE Manager
+ Random.sol - SKALE Manager
Copyright (C) 2018-Present SKALE Labs
@author Artem Payvin
@author Dmytro Stebaiev
@@ -20,7 +20,7 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity ^0.8.17;
import { IRandom } from "@skalenetwork/skale-manager-interfaces/utils/IRandom.sol";
@@ -37,7 +37,13 @@ library Random {
return IRandom.RandomGenerator({seed: seed});
}
- function createFromEntropy(bytes memory entropy) internal pure returns (IRandom.RandomGenerator memory generator) {
+ function createFromEntropy(
+ bytes memory entropy
+ )
+ internal
+ pure
+ returns (IRandom.RandomGenerator memory generator)
+ {
return create(uint(keccak256(entropy)));
}
@@ -52,7 +58,14 @@ library Random {
/**
* @dev Generates random value in range [0, max)
*/
- function random(IRandom.RandomGenerator memory self, uint256 max) internal pure returns (uint256 value) {
+ function random(
+ IRandom.RandomGenerator memory self,
+ uint256 max
+ )
+ internal
+ pure
+ returns (uint256 value)
+ {
assert(max > 0);
uint256 maxRand = type(uint256).max - type(uint256).max % max;
if (type(uint).max - maxRand == max - 1) {
diff --git a/contracts/utils/SegmentTree.sol b/contracts/utils/SegmentTree.sol
index cdbeab9c4..337d080de 100644
--- a/contracts/utils/SegmentTree.sol
+++ b/contracts/utils/SegmentTree.sol
@@ -20,7 +20,7 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity 0.8.26;
import { IRandom, Random } from "./Random.sol";
@@ -251,7 +251,14 @@ library SegmentTree {
*
* - `place` must be in range [1, size]
*/
- function sumFromPlaceToLast(Tree storage self, uint256 place) public view returns (uint256 sum) {
+ function sumFromPlaceToLast(
+ Tree storage self,
+ uint256 place
+ )
+ public
+ view
+ returns (uint256 sum)
+ {
require(_correctPlace(self, place), "Incorrect place");
if (place == 1) {
return self.tree[0];
diff --git a/contracts/utils/StringUtils.sol b/contracts/utils/StringUtils.sol
index a6af0d20d..6caebd68e 100644
--- a/contracts/utils/StringUtils.sol
+++ b/contracts/utils/StringUtils.sol
@@ -24,7 +24,14 @@ pragma solidity 0.8.17;
library StringUtils {
- function strConcat(string memory a, string memory b) internal pure returns (string memory result) {
+ function strConcat(
+ string memory a,
+ string memory b
+ )
+ internal
+ pure
+ returns (string memory result)
+ {
bytes memory _ba = bytes(a);
bytes memory _bb = bytes(b);
diff --git a/contracts/utils/fieldOperations/Fp2Operations.sol b/contracts/utils/fieldOperations/Fp2Operations.sol
index b8a4ea405..5215f6c26 100644
--- a/contracts/utils/fieldOperations/Fp2Operations.sol
+++ b/contracts/utils/fieldOperations/Fp2Operations.sol
@@ -22,7 +22,7 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity ^0.8.17;
import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
@@ -31,9 +31,16 @@ import { Precompiled } from "../Precompiled.sol";
library Fp2Operations {
- uint256 constant public P = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
+ uint256 constant public P =
+ 21888242871839275222246405745257275088696311157297823662689037894645226208583;
- function inverseFp2(ISkaleDKG.Fp2Point memory value) internal view returns (ISkaleDKG.Fp2Point memory result) {
+ function inverseFp2(
+ ISkaleDKG.Fp2Point memory value
+ )
+ internal
+ view
+ returns (ISkaleDKG.Fp2Point memory result)
+ {
uint256 p = P;
uint256 t0 = mulmod(value.a, value.a, p);
uint256 t1 = mulmod(value.b, value.b, p);
@@ -53,7 +60,10 @@ library Fp2Operations {
pure
returns (ISkaleDKG.Fp2Point memory result)
{
- return ISkaleDKG.Fp2Point({ a: addmod(value1.a, value2.a, P), b: addmod(value1.b, value2.b, P) });
+ return ISkaleDKG.Fp2Point({
+ a: addmod(value1.a, value2.a, P),
+ b: addmod(value1.b, value2.b, P)
+ });
}
function scalarMulFp2(ISkaleDKG.Fp2Point memory value, uint256 scalar)
@@ -64,7 +74,12 @@ library Fp2Operations {
return ISkaleDKG.Fp2Point({ a: mulmod(scalar, value.a, P), b: mulmod(scalar, value.b, P) });
}
- function minusFp2(ISkaleDKG.Fp2Point memory diminished, ISkaleDKG.Fp2Point memory subtracted) internal pure
+ function minusFp2(
+ ISkaleDKG.Fp2Point memory diminished,
+ ISkaleDKG.Fp2Point memory subtracted
+ )
+ internal
+ pure
returns (ISkaleDKG.Fp2Point memory difference)
{
uint256 p = P;
@@ -105,10 +120,20 @@ library Fp2Operations {
p);
}
- function squaredFp2(ISkaleDKG.Fp2Point memory value) internal pure returns (ISkaleDKG.Fp2Point memory result) {
+ function squaredFp2(
+ ISkaleDKG.Fp2Point memory value
+ )
+ internal
+ pure
+ returns (ISkaleDKG.Fp2Point memory result)
+ {
uint256 p = P;
uint256 ab = mulmod(value.a, value.b, p);
- uint256 multiplication = mulmod(addmod(value.a, value.b, p), addmod(value.a, mulmod(p - 1, value.b, p), p), p);
+ uint256 multiplication = mulmod(
+ addmod(value.a, value.b, p),
+ addmod(value.a, mulmod(p - 1, value.b, p), p),
+ p
+ );
return ISkaleDKG.Fp2Point({ a: multiplication, b: addmod(ab, ab, p) });
}
diff --git a/contracts/utils/fieldOperations/G2Operations.sol b/contracts/utils/fieldOperations/G2Operations.sol
index 5f4cc422e..e201713e8 100644
--- a/contracts/utils/fieldOperations/G2Operations.sol
+++ b/contracts/utils/fieldOperations/G2Operations.sol
@@ -22,7 +22,7 @@
along with SKALE Manager. If not, see .
*/
-pragma solidity 0.8.17;
+pragma solidity ^0.8.17;
import { ISkaleDKG } from "@skalenetwork/skale-manager-interfaces/ISkaleDKG.sol";
@@ -75,7 +75,13 @@ library G2Operations {
return sum;
}
- ISkaleDKG.Fp2Point memory s = value2.y.minusFp2(value1.y).mulFp2(value2.x.minusFp2(value1.x).inverseFp2());
+ ISkaleDKG.Fp2Point memory s = value2.y
+ .minusFp2(value1.y)
+ .mulFp2(
+ value2.x
+ .minusFp2(value1.x)
+ .inverseFp2()
+ );
sum.x = s.squaredFp2().minusFp2(value1.x.addFp2(value2.x));
sum.y = value1.y.addFp2(s.mulFp2(sum.x.minusFp2(value1.x)));
uint256 p = Fp2Operations.P;
@@ -122,7 +128,14 @@ library G2Operations {
});
}
- function isG2Point(ISkaleDKG.Fp2Point memory x, ISkaleDKG.Fp2Point memory y) internal pure returns (bool result) {
+ function isG2Point(
+ ISkaleDKG.Fp2Point memory x,
+ ISkaleDKG.Fp2Point memory y
+ )
+ internal
+ pure
+ returns (bool result)
+ {
if (isG2ZeroPoint(x, y)) {
return true;
}
diff --git a/hardhat.config.ts b/hardhat.config.ts
index cc5f5d9c5..d676a76a6 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -82,6 +82,15 @@ const config: HardhatUserConfig = {
runs: 100
}
}
+ },
+ {
+ version: '0.8.26',
+ settings: {
+ optimizer: {
+ enabled: true,
+ runs: 300
+ }
+ }
}
]
},
diff --git a/migrations/deploy.ts b/migrations/deploy.ts
index 9936fd0d3..60705c1bd 100644
--- a/migrations/deploy.ts
+++ b/migrations/deploy.ts
@@ -61,10 +61,10 @@ export const contracts = [
"SkaleDKG",
"SkaleVerifier",
"SkaleManager",
- "Pricing",
"BountyV2",
"Wallets",
- "SyncManager"
+ "SyncManager",
+ "PaymasterController"
]
async function main() {
diff --git a/migrations/upgrade.ts b/migrations/upgrade.ts
index 3975137f2..b4d0d4923 100644
--- a/migrations/upgrade.ts
+++ b/migrations/upgrade.ts
@@ -1,9 +1,9 @@
import chalk from "chalk";
import {contracts} from "./deploy";
-import {ethers} from "hardhat";
+import {ethers, upgrades} from "hardhat";
import {Upgrader, AutoSubmitter} from "@skalenetwork/upgrade-tools";
import {skaleContracts, Instance} from "@skalenetwork/skale-contracts-ethers-v6";
-import {SkaleManager} from "../typechain-types";
+import {ContractManager, PaymasterController, SkaleManager} from "../typechain-types";
import {Manifest, getImplementationAddress} from "@openzeppelin/upgrades-core";
import {Transaction} from "ethers";
@@ -59,7 +59,57 @@ class SkaleManagerUpgrader extends Upgrader {
}));
}
- // deployNewContracts = () => { };
+ deployNewContracts = async () => {
+ const [deployer] = await ethers.getSigners();
+
+ const contractManager = await this.instance.getContract("ContractManager") as ContractManager;
+
+ const paymasterControllerFactory = await ethers.getContractFactory("PaymasterController");
+ console.log("Deploy PaymasterController");
+ const paymasterController = await upgrades.deployProxy(
+ paymasterControllerFactory,
+ [await ethers.resolveAddress(contractManager)]
+ ) as unknown as PaymasterController;
+ await paymasterController.deploymentTransaction()?.wait();
+
+ const ima = process.env.IMA ?? "0x8629703a9903515818C2FeB45a6f6fA5df8Da404";
+ const marionette = process.env.MARIONETTE ?? "0xef777804e94eac176bbdbb3b3c9da06de87227ba";
+ const paymaster = process.env.PAYMASTER ?? "0x0d66cA00CbAD4219734D7FDF921dD7Caadc1F78D";
+ const paymasterChainHash = process.env.PAYMASTER_CHAIN_HASH ?? ethers.solidityPackedKeccak256(["string"], ["elated-tan-skat"]); // Europa
+
+ console.log(`Set IMA address to ${ima}`);
+ await (await paymasterController.setImaAddress(ima)).wait();
+
+ console.log(`Set Marionette address to ${marionette}`);
+ await (await paymasterController.setMarionetteAddress(marionette)).wait();
+
+ console.log(`Set Paymaster address to ${paymaster}`);
+ await (await paymasterController.setPaymasterAddress(paymaster)).wait();
+
+ console.log(`Set Paymaster schain hash to ${paymasterChainHash}`);
+ await (await paymasterController.setPaymasterChainHash(paymasterChainHash)).wait();
+
+ console.log("Revoke PAYMASTER_SETTER_ROLE");
+ await (await paymasterController.revokeRole(
+ await paymasterController.PAYMASTER_SETTER_ROLE(),
+ deployer
+ )).wait();
+
+ const owner = await contractManager.owner();
+ if (!await paymasterController.hasRole(await paymasterController.DEFAULT_ADMIN_ROLE(), owner)) {
+ console.log(`Grant ownership to ${owner}`);
+ await (await paymasterController.grantRole(
+ await paymasterController.DEFAULT_ADMIN_ROLE(),
+ owner
+ )).wait();
+
+ console.log(`Revoke ownership from ${ethers.resolveAddress(deployer)}`);
+ await (await paymasterController.revokeRole(
+ await paymasterController.DEFAULT_ADMIN_ROLE(),
+ deployer
+ )).wait();
+ }
+ };
// initialize = async () => { };
}
@@ -97,10 +147,21 @@ async function prepareContractsList(instance: Instance) {
async function main() {
const skaleManager = await getSkaleManagerInstance();
+ let contractsToUpgrade = [
+ "Nodes",
+ "Schains",
+ "ValidatorService"
+ ];
+ if (process.env.UPGRADE_ALL) {
+ contractsToUpgrade = await prepareContractsList(skaleManager);
+ }
+ // TODO: remove after 1.12.0 release
+ contractsToUpgrade = contractsToUpgrade.filter((contract) => contract !== "PaymasterController")
+ // End of TODO
const upgrader = new SkaleManagerUpgrader(
"1.11.0",
skaleManager,
- await prepareContractsList(skaleManager)
+ contractsToUpgrade
);
await upgrader.upgrade();
}
diff --git a/package.json b/package.json
index b09043724..0d3fa0390 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,8 @@
}
],
"scripts": {
- "compile": "npx hardhat clean && npx hardhat compile",
+ "compile": "npx hardhat compile",
+ "cleanCompile": "npx hardhat clean && yarn compile",
"docs": "scripts/prepare-docs.sh",
"fullCheck": "yarn lint && yarn tsc && yarn eslint && yarn cspell && yarn slither",
"hooks": "git config core.hooksPath .githooks || true",
@@ -44,13 +45,16 @@
"@openzeppelin/contracts": "^4.9.3",
"@openzeppelin/contracts-upgradeable": "^4.9.6",
"@openzeppelin/hardhat-upgrades": "^3.2.0",
- "@skalenetwork/skale-manager-interfaces": "3.1.0",
+ "@skalenetwork/ima-interfaces": "2.0.0-develop.67",
+ "@skalenetwork/marionette-interfaces": "^0.0.0-main.6",
+ "@skalenetwork/paymaster-interfaces": "^1.0.0-main.10",
+ "@skalenetwork/skale-manager-interfaces": "3.2.0-develop.0",
"@skalenetwork/upgrade-tools": "^3.0.0-linter.42",
"@typechain/hardhat": "^9.1.0",
"dotenv": "^16.3.1",
"ethereumjs-util": "^7.1.5",
"ethers": "^6.13.1",
- "hardhat": "^2.22.5"
+ "hardhat": "^2.22.8"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
@@ -79,7 +83,7 @@
"ethereum-waffle": "^3.4.4",
"ganache": "^7.9.1",
"hardhat-dependency-compiler": "^1.2.1",
- "solhint": "5.0.1",
+ "solhint": "^5.0.3",
"solidity-coverage": "^0.8.4",
"solidity-docgen": "^0.5.17",
"ts-generator": "^0.1.1",
diff --git a/scripts/requirements.txt b/scripts/requirements.txt
index 61cce5d71..6bdff3f80 100644
--- a/scripts/requirements.txt
+++ b/scripts/requirements.txt
@@ -1 +1 @@
-slither-analyzer==0.8.3
+slither-analyzer==0.10.3
diff --git a/scripts/test_upgrade.sh b/scripts/test_upgrade.sh
index 0ac4a9255..7c8c218a2 100755
--- a/scripts/test_upgrade.sh
+++ b/scripts/test_upgrade.sh
@@ -53,6 +53,14 @@ rm -r --interactive=never $DEPLOYED_DIR
# TODO: use contracts.json file when deployed version starts supporting it
# SKALE_MANAGER_ADDRESS=$(cat data/$CONTRACTS_FILENAME | jq -r .SkaleManager)
SKALE_MANAGER_ADDRESS=$(cat data/$ABI_FILENAME | jq -r .skale_manager_address)
-ALLOW_NOT_ATOMIC_UPGRADE="OK" TARGET="$SKALE_MANAGER_ADDRESS" npx hardhat run migrations/upgrade.ts --network localhost
+export ALLOW_NOT_ATOMIC_UPGRADE="OK"
+export TARGET="$SKALE_MANAGER_ADDRESS"
+export UPGRADE_ALL=true
+# TODO: Remove after release 1.12.0
+export IMA="$SKALE_MANAGER_ADDRESS"
+export MARIONETTE="$SKALE_MANAGER_ADDRESS"
+export PAYMASTER="$SKALE_MANAGER_ADDRESS"
+# End of TODO
+npx hardhat run migrations/upgrade.ts --network localhost
npx ganache instances stop $GANACHE_SESSION
diff --git a/slither.config.json b/slither.config.json
index b91030d04..69ab44d09 100644
--- a/slither.config.json
+++ b/slither.config.json
@@ -1,4 +1,4 @@
{
- "detectors_to_exclude": "similar-names,reentrancy-events,solc-version,assembly,timestamp,calls-loop,reentrancy-no-eth,public-mappings-nested,incorrect-equality,dead-code",
- "filter_paths": "@openzeppelin/contracts/|@openzeppelin/contracts-upgradeable/|thirdparty|test"
+ "detectors_to_exclude": "similar-names,reentrancy-events,solc-version,assembly,timestamp,calls-loop,reentrancy-no-eth,public-mappings-nested,incorrect-equality,dead-code,pragma",
+ "filter_paths": "(node_modules/|contracts/hardhat-dependency-compiler/|thirdparty/|test/)"
}
diff --git a/test/NodesData.ts b/test/NodesData.ts
index 527fd325d..cc9d2b636 100644
--- a/test/NodesData.ts
+++ b/test/NodesData.ts
@@ -190,7 +190,8 @@ describe("NodesData", () => {
it("should not modify node domain name by hacker", async () => {
await nodes.connect(hacker).setDomainName(0, "new.domain.name")
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(hacker);
});
// it("should get array of ips of active nodes", async () => {
@@ -330,9 +331,13 @@ describe("NodesData", () => {
await nodes.initExit(0);
status = await nodes.getNodeStatus(0);
assert.equal(status, 1n);
- await nodes.setNodeInMaintenance(0).should.be.eventually.rejectedWith("Node is not Active");
+ await nodes.setNodeInMaintenance(0)
+ .should.be.revertedWithCustomError(nodes, "NodeIsNotActive")
+ .withArgs(0);
await nodes.completeExit(0);
- await nodes.setNodeInMaintenance(0).should.be.eventually.rejectedWith("Node is not Active");
+ await nodes.setNodeInMaintenance(0)
+ .should.be.revertedWithCustomError(nodes, "NodeIsNotActive")
+ .withArgs(0);
});
it("should decrease number of active nodes after setting node in maintenance", async () => {
diff --git a/test/NodesFunctionality.ts b/test/NodesFunctionality.ts
index d39084947..689b493d8 100644
--- a/test/NodesFunctionality.ts
+++ b/test/NodesFunctionality.ts
@@ -81,7 +81,8 @@ describe("NodesFunctionality", () => {
publicKey: getPublicKey(nodeAddress),
name: "D2",
domainName: "some.domain.name"
- }).should.be.eventually.rejectedWith("IP address is zero or is not available");
+ }).should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x00000000");
});
it("should fail to create node if port is zero", async () => {
@@ -95,7 +96,7 @@ describe("NodesFunctionality", () => {
publicKey: getPublicKey(nodeAddress),
name: "D2",
domainName: "some.domain.name"
- }).should.be.eventually.rejectedWith("Port is zero");
+ }).should.be.revertedWithCustomError(nodes, "PortIsNotSet");
});
it("should fail to create node if public Key is incorrect", async () => {
@@ -109,7 +110,8 @@ describe("NodesFunctionality", () => {
publicKey: getPublicKey(nodeAddress),
name: "D2",
domainName: "some.domain.name"
- }).should.be.eventually.rejectedWith("Public Key is incorrect");
+ }).should.be.revertedWithCustomError(nodes, "PublicKeyIsIncorrect")
+ .withArgs(getPublicKey(nodeAddress));
});
it("should create node", async () => {
@@ -151,7 +153,8 @@ describe("NodesFunctionality", () => {
it("should fail to delete non active node", async () => {
await nodes.completeExit(0)
- .should.be.eventually.rejectedWith("Node is not Leaving");
+ .should.be.revertedWithCustomError(nodes, "NodeIsNotLeaving")
+ .withArgs(0);
});
it("should delete node", async () => {
@@ -169,7 +172,8 @@ describe("NodesFunctionality", () => {
it("should complete exiting", async () => {
await nodes.completeExit(0)
- .should.be.eventually.rejectedWith("Node is not Leaving");
+ .should.be.revertedWithCustomError(nodes, "NodeIsNotLeaving")
+ .withArgs(0);
await nodes.initExit(0);
@@ -178,9 +182,15 @@ describe("NodesFunctionality", () => {
it("should change IP", async () => {
await nodes.connect(holder).changeIP(0, "0x7f000001", "0x00000000").should.be.eventually.rejectedWith("Caller is not an admin");
- await nodes.connect(owner).changeIP(0, "0x7f000001", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(0, "0x00000000", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(0, "0x7f000002", "0x7f000001").should.be.eventually.rejectedWith("IP address is not the same");
+ await nodes.connect(owner).changeIP(0, "0x7f000001", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x7f000001");
+ await nodes.connect(owner).changeIP(0, "0x00000000", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x00000000");
+ await nodes.connect(owner).changeIP(0, "0x7f000002", "0x7f000001")
+ .should.be.revertedWithCustomError(nodes, "IpAndPublicIpIsDifferent")
+ .withArgs("0x7f000002", "0x7f000001");
expect(await nodes.getNodeIP(0)).to.equal("0x7f000001");
expect(await nodes.nodesIPCheck("0x7f000001")).to.equal(true);
expect(await nodes.nodesIPCheck("0x7f000002")).to.equal(false);
@@ -210,7 +220,8 @@ describe("NodesFunctionality", () => {
it("should mark node as incompliant", async () => {
await nodes.setNodeIncompliant(nodeId)
- .should.be.eventually.rejectedWith("COMPLIANCE_ROLE is required");
+ .should.be.revertedWithCustomError(nodes, "RoleRequired")
+ .withArgs(await nodes.COMPLIANCE_ROLE());
await nodes.grantRole(await nodes.COMPLIANCE_ROLE(), owner.address);
(await nodes.incompliant(nodeId)).should.be.equal(false);
@@ -282,7 +293,8 @@ describe("NodesFunctionality", () => {
it("should complete exiting from first node", async () => {
await nodes.completeExit(0)
- .should.be.eventually.rejectedWith("Node is not Leaving");
+ .should.be.revertedWithCustomError(nodes, "NodeIsNotLeaving")
+ .withArgs(0);
await nodes.initExit(0);
@@ -291,7 +303,8 @@ describe("NodesFunctionality", () => {
it("should complete exiting from second node", async () => {
await nodes.completeExit(1)
- .should.be.eventually.rejectedWith("Node is not Leaving");
+ .should.be.revertedWithCustomError(nodes, "NodeIsNotLeaving")
+ .withArgs(1);
await nodes.initExit(1);
@@ -300,15 +313,31 @@ describe("NodesFunctionality", () => {
it("should change IP", async () => {
await nodes.connect(holder).changeIP(0, "0x7f000001", "0x00000000").should.be.eventually.rejectedWith("Caller is not an admin");
- await nodes.connect(owner).changeIP(0, "0x7f000001", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(0, "0x00000000", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(0, "0x7f000002", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(0, "0x7f000003", "0x7f000002").should.be.eventually.rejectedWith("IP address is not the same");
+ await nodes.connect(owner).changeIP(0, "0x7f000001", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x7f000001");
+ await nodes.connect(owner).changeIP(0, "0x00000000", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x00000000");
+ await nodes.connect(owner).changeIP(0, "0x7f000002", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x7f000002");
+ await nodes.connect(owner).changeIP(0, "0x7f000003", "0x7f000002")
+ .should.be.revertedWithCustomError(nodes, "IpAndPublicIpIsDifferent")
+ .withArgs("0x7f000003", "0x7f000002");
await nodes.connect(holder).changeIP(1, "0x7f000002", "0x00000000").should.be.eventually.rejectedWith("Caller is not an admin");
- await nodes.connect(owner).changeIP(1, "0x7f000002", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(1, "0x00000000", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(1, "0x7f000001", "0x00000000").should.be.eventually.rejectedWith("IP address is zero or is not available");
- await nodes.connect(owner).changeIP(0, "0x7f000004", "0x7f000002").should.be.eventually.rejectedWith("IP address is not the same");
+ await nodes.connect(owner).changeIP(1, "0x7f000002", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x7f000002");
+ await nodes.connect(owner).changeIP(1, "0x00000000", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x00000000");
+ await nodes.connect(owner).changeIP(1, "0x7f000001", "0x00000000")
+ .should.be.revertedWithCustomError(nodes, "IpIsNotAvailable")
+ .withArgs("0x7f000001");
+ await nodes.connect(owner).changeIP(0, "0x7f000004", "0x7f000002")
+ .should.be.revertedWithCustomError(nodes, "IpAndPublicIpIsDifferent")
+ .withArgs("0x7f000004", "0x7f000002");
expect(await nodes.getNodeIP(0)).to.equal("0x7f000001");
expect(await nodes.nodesIPCheck("0x7f000001")).to.equal(true);
expect(await nodes.nodesIPCheck("0x7f000002")).to.equal(true);
@@ -371,7 +400,7 @@ describe("NodesFunctionality", () => {
await delegationController.connect(validator).acceptPendingDelegation(delegationId);
await nodes.checkPossibilityCreatingNode(nodeAddress.address)
- .should.be.eventually.rejectedWith("Validator must meet the Minimum Staking Requirement");
+ .should.be.revertedWithCustomError(nodes, "MinimumStakingRequirementIsNotMet");
});
it("should allow to create node if new epoch is started", async () => {
@@ -382,7 +411,7 @@ describe("NodesFunctionality", () => {
await nextMonth(contractManager);
await nodes.checkPossibilityCreatingNode(nodeAddress.address)
- .should.be.eventually.rejectedWith("Validator must meet the Minimum Staking Requirement");
+ .should.be.revertedWithCustomError(nodes, "MinimumStakingRequirementIsNotMet");
await constantsHolder.setMSR(amount);
@@ -416,7 +445,7 @@ describe("NodesFunctionality", () => {
await nextMonth(contractManager);
await nodes.checkPossibilityCreatingNode(nodeAddress.address)
- .should.be.eventually.rejectedWith("Validator must meet the Minimum Staking Requirement");
+ .should.be.revertedWithCustomError(nodes, "MinimumStakingRequirementIsNotMet");
await constantsHolder.setMSR(amount);
diff --git a/test/Pricing.ts b/test/Pricing.ts
deleted file mode 100644
index e379cc727..000000000
--- a/test/Pricing.ts
+++ /dev/null
@@ -1,324 +0,0 @@
-import {Wallet} from "ethers";
-import * as chai from "chai";
-import chaiAsPromised from "chai-as-promised";
-
-import {ContractManager,
- Nodes,
- Pricing,
- SchainsInternal,
- ValidatorService,
- ConstantsHolder,
- NodeRotation} from "../typechain-types";
-
-import {privateKeys} from "./tools/private-keys";
-
-import {deployContractManager} from "./tools/deploy/contractManager";
-import {deployNodes} from "./tools/deploy/nodes";
-import {deployPricing} from "./tools/deploy/pricing";
-import {deploySchainsInternal} from "./tools/deploy/schainsInternal";
-import {skipTime, currentTime} from "./tools/time";
-import {deployValidatorService} from "./tools/deploy/delegation/validatorService";
-import {deploySchains} from "./tools/deploy/schains";
-import {deployConstantsHolder} from "./tools/deploy/constantsHolder";
-import {deployNodeRotation} from "./tools/deploy/nodeRotation";
-import {deploySkaleManagerMock} from "./tools/deploy/test/skaleManagerMock";
-import {ethers} from "hardhat";
-import {SignerWithAddress} from "@nomicfoundation/hardhat-ethers/signers";
-import {getPublicKey, getValidatorIdSignature} from "./tools/signatures";
-import {stringKeccak256} from "./tools/hashes";
-import {fastBeforeEach} from "./tools/mocha";
-
-chai.should();
-chai.use(chaiAsPromised);
-
-describe("Pricing", () => {
- let owner: SignerWithAddress;
- let holder: SignerWithAddress;
- let validator: SignerWithAddress;
- let nodeAddress1: Wallet;
- let nodeAddress2: Wallet;
- let nodeAddress3: Wallet;
- let nodeAddress4: Wallet;
- let nodeAddress5: Wallet;
-
- let contractManager: ContractManager;
- let pricing: Pricing;
- let schainsInternal: SchainsInternal;
- let nodes: Nodes;
- let validatorService: ValidatorService;
- let constants: ConstantsHolder;
- let nodeRotation: NodeRotation;
-
- fastBeforeEach(async () => {
- [owner, holder, validator] = await ethers.getSigners();
-
- nodeAddress1 = new Wallet(String(privateKeys[0])).connect(ethers.provider);
- nodeAddress2 = new Wallet(String(privateKeys[1])).connect(ethers.provider);
- nodeAddress3 = new Wallet(String(privateKeys[2])).connect(ethers.provider);
- nodeAddress4 = new Wallet(String(privateKeys[3])).connect(ethers.provider);
- nodeAddress5 = new Wallet(String(privateKeys[4])).connect(ethers.provider);
-
-
- contractManager = await deployContractManager();
-
- nodes = await deployNodes(contractManager);
- schainsInternal = await deploySchainsInternal(contractManager);
- await deploySchains(contractManager);
- pricing = await deployPricing(contractManager);
- validatorService = await deployValidatorService(contractManager);
- constants = await deployConstantsHolder(contractManager);
- nodeRotation = await deployNodeRotation(contractManager);
-
- const skaleManagerMock = await deploySkaleManagerMock(contractManager);
- await contractManager.setContractsAddress("SkaleManager", skaleManagerMock);
-
- await validatorService.connect(validator).registerValidator("Validator", "D2", 0, 0);
- const validatorIndex = await validatorService.getValidatorId(validator.address);
- const signature1 = await getValidatorIdSignature(validatorIndex, nodeAddress1);
- const signature2 = await getValidatorIdSignature(validatorIndex, nodeAddress2);
- const signature3 = await getValidatorIdSignature(validatorIndex, nodeAddress3);
- const signature4 = await getValidatorIdSignature(validatorIndex, nodeAddress4);
- const signature5 = await getValidatorIdSignature(validatorIndex, nodeAddress5);
- await validatorService.connect(validator).linkNodeAddress(nodeAddress1.address, signature1);
- await validatorService.connect(validator).linkNodeAddress(nodeAddress2.address, signature2);
- await validatorService.connect(validator).linkNodeAddress(nodeAddress3.address, signature3);
- await validatorService.connect(validator).linkNodeAddress(nodeAddress4.address, signature4);
- await validatorService.connect(validator).linkNodeAddress(nodeAddress5.address, signature5);
- const NODE_MANAGER_ROLE = await nodes.NODE_MANAGER_ROLE();
- await nodes.grantRole(NODE_MANAGER_ROLE, owner.address);
- });
-
- describe("on initialized contracts", () => {
- fastBeforeEach(async () => {
- await schainsInternal.initializeSchain("BobSchain", holder.address, ethers.ZeroAddress, 10, 2);
- await schainsInternal.initializeSchain("DavidSchain", holder.address, ethers.ZeroAddress, 10, 4);
- await schainsInternal.initializeSchain("JacobSchain", holder.address, ethers.ZeroAddress, 10, 8);
- await nodes.createNode(
- nodeAddress1.address,
- {
- port: 8545,
- nonce: 0,
- ip: "0x7f000001",
- publicIp: "0x7f000001",
- publicKey: getPublicKey(nodeAddress1),
- name: "elvis1",
- domainName: "some.domain.name"
- });
-
- await nodes.createNode(
- nodeAddress2.address,
- {
- port: 8545,
- nonce: 0,
- ip: "0x7f000003",
- publicIp: "0x7f000003",
- publicKey: getPublicKey(nodeAddress2),
- name: "elvis2",
- domainName: "some.domain.name"
- });
-
- await nodes.createNode(
- nodeAddress3.address,
- {
- port: 8545,
- nonce: 0,
- ip: "0x7f000005",
- publicIp: "0x7f000005",
- publicKey: getPublicKey(nodeAddress3),
- name: "elvis3",
- domainName: "some.domain.name"
- });
-
- await nodes.createNode(
- nodeAddress4.address,
- {
- port: 8545,
- nonce: 0,
- ip: "0x7f000007",
- publicIp: "0x7f000007",
- publicKey: getPublicKey(nodeAddress4),
- name: "elvis4",
- domainName: "some.domain.name"
- });
- });
-
- it("should increase number of schains", async () => {
- const numberOfSchains = await schainsInternal.numberOfSchains();
- numberOfSchains.should.be.equal(3);
- });
-
- it("should increase number of nodes", async () => {
- const numberOfNodes = await nodes.getNumberOfNodes();
- numberOfNodes.should.be.equal(4);
- });
-
- describe("on existing nodes and schains", () => {
- const bobSchainHash = stringKeccak256("BobSchain");
- const davidSchainHash = stringKeccak256("DavidSchain");
- const jacobSchainHash = stringKeccak256("JacobSchain");
-
- fastBeforeEach(async () => {
- await schainsInternal.createGroupForSchain(bobSchainHash, 1, 32);
- await schainsInternal.createGroupForSchain(davidSchainHash, 1, 32);
- await schainsInternal.createGroupForSchain(jacobSchainHash, 2, 128);
- });
-
- async function getLoadCoefficient() {
- const numberOfNodes = await nodes.getNumberOfNodes();
- let sumNode = 0;
- for (let i = 0; i < numberOfNodes; i++) {
- if (await nodes.isNodeActive(i)) {
- const getActiveSchains = await schainsInternal.getActiveSchains(i);
- for (const schain of getActiveSchains) {
- const partOfNode = await schainsInternal.getSchainsPartOfNode(schain);
- const isNodeLeft = await nodes.isNodeLeft(i);
- if (partOfNode !== 0n && !isNodeLeft) {
- sumNode += Number(partOfNode);
- }
- }
- }
- }
- return sumNode / (128 * Number(await nodes.getNumberOnlineNodes()));
- }
-
- it("should check load percentage of network", async () => {
- const newLoadPercentage = Math.floor(await getLoadCoefficient() * 100);
- const loadPercentage = await pricing.getTotalLoadPercentage();
- loadPercentage.should.be.equal(newLoadPercentage);
- });
-
- it("should check total number of nodes", async () => {
- await pricing.initNodes();
- const totalNodes = await pricing.totalNodes();
- totalNodes.should.be.equal(4);
- });
-
- it("should not change price when no any new nodes have been added", async () => {
- await pricing.initNodes();
- await skipTime(61);
- await pricing.adjustPrice()
- .should.be.eventually.rejectedWith("No changes to node supply");
- });
-
- it("should not change price when the price is updated more often than necessary", async () => {
- await pricing.initNodes();
- await pricing.adjustPrice()
- .should.be.eventually.rejectedWith("It's not a time to update a price");
- });
-
- describe("change price when changing the number of nodes", () => {
- let oldPrice: bigint;
- let lastUpdated: bigint;
-
- fastBeforeEach(async () => {
- await pricing.initNodes();
- oldPrice = await pricing.price();
- lastUpdated = await pricing.lastUpdated();
- });
-
- async function getPrice(secondSincePreviousUpdate: bigint) {
- const MIN_PRICE = Number(await constants.MIN_PRICE());
- const ADJUSTMENT_SPEED = Number(await constants.ADJUSTMENT_SPEED());
- const OPTIMAL_LOAD_PERCENTAGE = Number(await constants.OPTIMAL_LOAD_PERCENTAGE());
- const COOLDOWN_TIME = Number(await constants.COOLDOWN_TIME());
-
- const priceChangeSpeed = ADJUSTMENT_SPEED * Number(oldPrice) / MIN_PRICE *
- (await getLoadCoefficient() * 100 - OPTIMAL_LOAD_PERCENTAGE);
- let price = Number(oldPrice) + priceChangeSpeed * Number(secondSincePreviousUpdate) / COOLDOWN_TIME;
- if (price < MIN_PRICE) {
- price = MIN_PRICE;
- }
- return BigInt(Math.floor(price));
- }
-
- it("should change price when new active node has been added", async () => {
- await nodes.createNode(
- nodeAddress5.address,
- {
- port: 8545,
- nonce: 0,
- ip: "0x7f000010",
- publicIp: "0x7f000011",
- publicKey: getPublicKey(nodeAddress5),
- name: "vadim",
- domainName: "some.domain.name"
- });
- const MINUTES_PASSED = 2n;
- await skipTime(lastUpdated + MINUTES_PASSED * 60n - BigInt(await currentTime()));
-
- await pricing.adjustPrice();
- const receivedPrice = await pricing.price();
-
- const correctPrice = await getPrice(await pricing.lastUpdated() - lastUpdated);
-
- receivedPrice.should.be.equal(correctPrice);
- oldPrice.should.be.above(receivedPrice);
- });
-
- it("should change price when active node has been removed", async () => {
- // search non full node to rotate
- let nodeToExit = -1;
- let numberOfSchains = 0;
- for (let i = 0; i < await nodes.getNumberOfNodes(); i++) {
- if (await nodes.isNodeActive(i)) {
- const getActiveSchains = await schainsInternal.getActiveSchains(i);
- let totalPartOfNode = 0n;
- numberOfSchains = 0;
- for (const schain of getActiveSchains) {
- const partOfNode = await schainsInternal.getSchainsPartOfNode(schain);
- ++numberOfSchains;
- totalPartOfNode += partOfNode;
- }
- if (totalPartOfNode < 100) {
- nodeToExit = i;
- break;
- }
- }
- }
-
- await nodes.initExit(nodeToExit);
- for(let i = 0; i < numberOfSchains; ++i) {
- await nodeRotation.exitFromSchain(nodeToExit);
- }
- await nodes.completeExit(nodeToExit);
-
- const MINUTES_PASSED = 2n;
- await skipTime(lastUpdated + MINUTES_PASSED * 60n - BigInt(await currentTime()));
-
- await pricing.adjustPrice();
- const receivedPrice = await pricing.price();
-
- const correctPrice = await getPrice(await pricing.lastUpdated() - lastUpdated);
-
- receivedPrice.should.be.equal(correctPrice);
- oldPrice.should.be.below(receivedPrice);
- });
-
- it("should set price to min of too many minutes passed and price is less than min", async () => {
- await nodes.createNode(
- nodeAddress5.address,
- {
- port: 8545,
- nonce: 0,
- ip: "0x7f000010",
- publicIp: "0x7f000011",
- publicKey: getPublicKey(nodeAddress5),
- name: "vadim",
- domainName: "some.domain.name"
- });
-
- const MINUTES_PASSED = 30n;
- await skipTime(lastUpdated + MINUTES_PASSED * 60n - BigInt(await currentTime()));
-
- await pricing.adjustPrice();
- const receivedPrice = await pricing.price();
-
- const correctPrice = await getPrice(await pricing.lastUpdated() - lastUpdated);
-
- receivedPrice.should.be.equal(correctPrice);
- oldPrice.should.be.above(receivedPrice);
- });
- });
- });
- });
-});
diff --git a/test/Schains.ts b/test/Schains.ts
index d03230b8e..5c93cda4e 100644
--- a/test/Schains.ts
+++ b/test/Schains.ts
@@ -127,12 +127,13 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Not enough money to create Schain");
+ ).should.be.revertedWithCustomError(schains, "NotEnoughFunds");
});
it("should not allow everyone to create schains as the foundation", async () => {
await schains.addSchainByFoundation(5, SchainType.SMALL, 0, "d2", ethers.ZeroAddress, ethers.ZeroAddress, [])
- .should.be.eventually.rejectedWith("Sender is not authorized to create schain");
+ .should.be.revertedWithCustomError(schains, "RoleRequired")
+ .withArgs(await schains.SCHAIN_CREATOR_ROLE());
})
it("should fail when schain type is wrong", async () => {
@@ -177,7 +178,8 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Schain name is not available");
+ ).should.be.revertedWithCustomError(schains, "SchainNameIsNotAvailable")
+ .withArgs("Mainnet");
});
it("should fail when schain name is None", async () => {
@@ -196,7 +198,8 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Schain name is not available");
+ ).should.be.revertedWithCustomError(schains, "SchainNameIsNotAvailable")
+ .withArgs("");
});
it("should fail when nodes count is too low", async () => {
@@ -1079,7 +1082,8 @@ describe("Schains", () => {
await schainsInternal.getSchains().should.be.eventually.empty;
await schains.getOption(schainHash, "one")
- .should.be.eventually.rejectedWith("The schain does not exist");
+ .should.be.revertedWithCustomError(schains, "SchainDoesNotExist")
+ .withArgs(schainHash);
});
it("should allow the foundation to create schain without tokens", async () => {
@@ -1491,7 +1495,8 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Schain name is not available");
+ ).should.be.revertedWithCustomError(schains, "SchainNameIsNotAvailable")
+ .withArgs("D2");
});
it("should be able to delete schain", async () => {
@@ -1518,7 +1523,7 @@ describe("Schains", () => {
await schains.deleteSchain(
nodeAddress1.address,
"D2",
- ).should.be.eventually.rejectedWith("Message sender is not the owner of the Schain");
+ ).should.be.revertedWithCustomError(schains, "SenderIsNotTheOwnerOfTheSchain");
});
});
@@ -1558,7 +1563,8 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Schain name is not available");
+ ).should.be.revertedWithCustomError(schains, "SchainNameIsNotAvailable")
+ .withArgs("D2");
});
it("should be able to delete schain", async () => {
@@ -1573,7 +1579,7 @@ describe("Schains", () => {
await schains.deleteSchain(
nodeAddress1.address,
"D2",
- ).should.be.eventually.rejectedWith("Message sender is not the owner of the Schain");
+ ).should.be.revertedWithCustomError(schains, "SenderIsNotTheOwnerOfTheSchain");
});
});
});
@@ -1697,7 +1703,8 @@ describe("Schains", () => {
it("should reject initExit if node in maintenance", async () => {
await nodes.setNodeInMaintenance(0);
- await nodes.initExit(0).should.be.eventually.rejectedWith("Node should be Active");
+ await nodes.initExit(0).should.be.revertedWithCustomError(nodes, "NodeIsNotActive")
+ .withArgs(0);
});
it("should rotate 2 nodes consistently", async () => {
@@ -1957,7 +1964,8 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Schain name is not available");
+ ).should.be.revertedWithCustomError(schains, "SchainNameIsNotAvailable")
+ .withArgs("d2");
schainNameAvailable = await schainsInternal.isSchainNameAvailable("d3");
assert.equal(schainNameAvailable, false);
await schains.addSchain(
@@ -1974,7 +1982,8 @@ describe("Schains", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Schain name is not available");
+ ).should.be.revertedWithCustomError(schains, "SchainNameIsNotAvailable")
+ .withArgs("d3");
schainNameAvailable = await schainsInternal.isSchainNameAvailable("d4");
assert.equal(schainNameAvailable, true);
await schains.addSchain(
@@ -2626,8 +2635,9 @@ describe("Schains", () => {
if (!(await nodes.isNodeLeft(rotIndex))) {
await skaleManager.connect(nodeAddress2).nodeExit(rotIndex);
}
- await validatorService.getValidatorIdByNodeAddress(nodeAddress2.address)
- .should.be.eventually.rejectedWith("Node address is not assigned to a validator");
+ await validatorService.getValidatorIdByNodeAddress(nodeAddress2)
+ .should.be.revertedWithCustomError(validatorService, "NodeAddressIsNotAssignedToValidator")
+ .withArgs(nodeAddress2);
await schainsInternal.getActiveSchains(rotIndex).should.be.eventually.empty;
});
@@ -2645,7 +2655,8 @@ describe("Schains", () => {
await skaleManager.connect(validator).nodeExit(rotatedNodeIndex);
}
await validatorService.getValidatorIdByNodeAddress(nodeAddress2.address)
- .should.be.eventually.rejectedWith("Node address is not assigned to a validator");
+ .should.be.revertedWithCustomError(validatorService, "NodeAddressIsNotAssignedToValidator")
+ .withArgs(nodeAddress2);
await schainsInternal.getActiveSchains(rotatedNodeIndex).should.be.eventually.empty;
});
@@ -2663,7 +2674,8 @@ describe("Schains", () => {
await skaleManager.nodeExit(rotatedNodeIndex);
}
await validatorService.getValidatorIdByNodeAddress(nodeAddress2.address)
- .should.be.eventually.rejectedWith("Node address is not assigned to a validator");
+ .should.be.revertedWithCustomError(validatorService, "NodeAddressIsNotAssignedToValidator")
+ .withArgs(nodeAddress2);
await schainsInternal.getActiveSchains(rotatedNodeIndex).should.be.eventually.empty;
});
@@ -2683,7 +2695,8 @@ describe("Schains", () => {
await skaleManager.connect(nodeAddress3).nodeExit(rotIndex);
}
await validatorService.getValidatorIdByNodeAddress(nodeAddress3.address)
- .should.be.eventually.rejectedWith("Node address is not assigned to a validator");
+ .should.be.revertedWithCustomError(validatorService, "NodeAddressIsNotAssignedToValidator")
+ .withArgs(nodeAddress3);
await schainsInternal.getActiveSchains(rotIndex).should.be.eventually.empty;
});
diff --git a/test/SkaleManager.ts b/test/SkaleManager.ts
index 0531965f5..3fbaf2852 100644
--- a/test/SkaleManager.ts
+++ b/test/SkaleManager.ts
@@ -205,7 +205,9 @@ describe("SkaleManager", () => {
"0x7f000001", // public ip
getPublicKey(nodeAddress), // public key
"d2", // name
- "some.domain.name").should.be.eventually.rejectedWith("Validator is not authorized to create a node");
+ "some.domain.name")
+ .should.be.revertedWithCustomError(validatorService, "ValidatorIsNotAuthorized")
+ .withArgs(validatorId);
await validatorService.enableValidator(validatorId);
await skaleManager.connect(nodeAddress).createNode(
8545, // port
@@ -238,8 +240,9 @@ describe("SkaleManager", () => {
it("should reject if node in maintenance call nodeExit", async () => {
await nodesContract.setNodeInMaintenance(0);
- await nodesContract.initExit(0).should.be.eventually.rejectedWith("Node should be Active");
- // await skaleManager.connect(nodeAddress).nodeExit(0).should.be.eventually.rejectedWith("Node should be Leaving");
+ await nodesContract.initExit(0)
+ .should.be.revertedWithCustomError(nodesContract, "NodeIsNotActive")
+ .withArgs(0);
});
it("should be Left if there is no schains and node has exited", async () => {
@@ -384,14 +387,16 @@ describe("SkaleManager", () => {
it("should fail to initiate exiting of first node from another account", async () => {
await nodesContract.connect(hacker).initExit(0)
- .should.be.eventually.rejectedWith("NODE_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(nodesContract, "RoleRequired")
+ .withArgs(await nodesContract.NODE_MANAGER_ROLE());
await skaleManager.connect(hacker).nodeExit(0)
.should.be.eventually.rejectedWith("Sender is not permitted to call this function");
});
it("should fail to initiate exiting of second node from another account", async () => {
await nodesContract.connect(hacker).initExit(1)
- .should.be.eventually.rejectedWith("NODE_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(nodesContract, "RoleRequired")
+ .withArgs(await nodesContract.NODE_MANAGER_ROLE());
await skaleManager.connect(hacker).nodeExit(1)
.should.be.eventually.rejectedWith("Sender is not permitted to call this function");
});
@@ -442,7 +447,8 @@ describe("SkaleManager", () => {
"0x7f000001", // public ip
getPublicKey(nodeAddress), // public key
"d2", // name
- "some.domain.name").should.be.eventually.rejectedWith("Validator must meet the Minimum Staking Requirement");
+ "some.domain.name"
+ ).should.be.revertedWithCustomError(nodesContract, "MinimumStakingRequirementIsNotMet");
});
describe("when developer has SKALE tokens", () => {
@@ -488,7 +494,7 @@ describe("SkaleManager", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("Minimal schain lifetime should be satisfied");
+ ).should.be.revertedWithCustomError(schains, "SchainLifetimeIsTooSmall");
await constantsHolder.setMinimalSchainLifetime(4);
await skaleToken.connect(developer).send(
@@ -529,7 +535,7 @@ describe("SkaleManager", () => {
options: []
}]
)
- ).should.be.eventually.rejectedWith("It is not a time for creating Schain");
+ ).should.be.revertedWithCustomError(schains, "SchainIsCreatedTooEarly");
});
describe("when schain is created", () => {
@@ -556,7 +562,7 @@ describe("SkaleManager", () => {
it("should fail to delete schain if sender is not owner of it", async () => {
await skaleManager.connect(hacker).deleteSchain("d2")
- .should.be.eventually.rejectedWith("Message sender is not the owner of the Schain");
+ .should.be.revertedWithCustomError(schains, "SenderIsNotTheOwnerOfTheSchain");
});
it("should delete schain", async () => {
@@ -595,7 +601,7 @@ describe("SkaleManager", () => {
it("should fail to delete schain if sender is not owner of it", async () => {
await skaleManager.connect(hacker).deleteSchain("d3")
- .should.be.eventually.rejectedWith("Message sender is not the owner of the Schain");
+ .should.be.revertedWithCustomError(schains, "SenderIsNotTheOwnerOfTheSchain");
});
it("should delete schain by root", async () => {
diff --git a/test/Wallets.ts b/test/Wallets.ts
index 0f7e311e5..a5d2be001 100644
--- a/test/Wallets.ts
+++ b/test/Wallets.ts
@@ -126,7 +126,8 @@ describe("Wallets", () => {
it("should revert if someone sends ETH to contract Wallets", async() => {
const amount = ethers.parseEther("1.0");
await owner.sendTransaction({to: wallets, value: amount})
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(owner);
});
it("should recharge validator wallet sending ETH to contract Wallets", async() => {
@@ -155,7 +156,9 @@ describe("Wallets", () => {
const validator1BalanceAfterWithdraw = await ethers.provider.getBalance(validator1);
validator1BalanceAfterWithdraw.should.be.equal(validator1Balance + amount - await ethSpent(tx));
await wallets.connect(validator2).withdrawFundsFromValidatorWallet(amount).should.be.eventually.rejectedWith("Balance is too low");
- await wallets.withdrawFundsFromValidatorWallet(amount).should.be.eventually.rejectedWith("Validator address does not exist");
+ await wallets.withdrawFundsFromValidatorWallet(amount)
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(owner);
});
describe("when nodes and schains have been created", () => {
diff --git a/test/delegation/Delegation.ts b/test/delegation/Delegation.ts
index 49ce02231..3f721a760 100644
--- a/test/delegation/Delegation.ts
+++ b/test/delegation/Delegation.ts
@@ -370,7 +370,8 @@ describe("Delegation", () => {
it("should not allow holder to delegate to unregistered validator", async () => {
await delegationController.connect(holder1).delegate(13, 1, 2, "D2 is even")
- .should.be.eventually.rejectedWith("Validator with such ID does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorDoesNotExist")
+ .withArgs(13);
});
it("should calculate bond amount if validator delegated to itself", async () => {
diff --git a/test/delegation/DelegationController.ts b/test/delegation/DelegationController.ts
index 063c552fc..c18749751 100644
--- a/test/delegation/DelegationController.ts
+++ b/test/delegation/DelegationController.ts
@@ -91,13 +91,15 @@ describe("DelegationController", () => {
it("should reject delegation if validator with such id does not exist", async () => {
const nonExistedValidatorId = 2;
await delegationController.connect(holder1).delegate(nonExistedValidatorId, amount, delegationPeriod, info)
- .should.be.eventually.rejectedWith("Validator with such ID does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorDoesNotExist")
+ .withArgs(nonExistedValidatorId);
});
it("should reject delegation if it doesn't meet minimum delegation amount", async () => {
amount = 99;
await delegationController.connect(holder1).delegate(validatorId, amount, delegationPeriod, info)
- .should.be.eventually.rejectedWith("Amount does not meet the validator's minimum delegation amount");
+ .should.be.revertedWithCustomError(validatorService, "AmountDoesNotMeetTheValidatorsMinimumDelegationAmount")
+ .withArgs(amount, (await validatorService.getValidator(validatorId)).minimumDelegationAmount);
});
it("should reject delegation if request doesn't meet allowed delegation period", async () => {
@@ -146,7 +148,8 @@ describe("DelegationController", () => {
await skaleToken.mint(holder1.address, amount, "0x", "0x");
await validatorService.disableValidator(validatorId);
await delegationController.connect(holder1).delegate(validatorId, amount, delegationPeriod, info)
- .should.be.eventually.rejectedWith("Validator is not authorized to accept delegation request");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorIsNotAuthorized")
+ .withArgs(validatorId);
await validatorService.disableWhitelist();
await delegationController.connect(holder1).delegate(validatorId, amount, delegationPeriod, info);
});
@@ -191,7 +194,8 @@ describe("DelegationController", () => {
it("should reject accepting request if such validator doesn't exist", async () => {
await delegationController.connect(validator2).acceptPendingDelegation(delegationId)
- .should.be.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(validator2);
});
it("should reject accepting request if validator already canceled it", async () => {
diff --git a/test/delegation/ValidatorService.ts b/test/delegation/ValidatorService.ts
index 3c7f12efe..4a91229c9 100644
--- a/test/delegation/ValidatorService.ts
+++ b/test/delegation/ValidatorService.ts
@@ -78,12 +78,14 @@ describe("ValidatorService", () => {
"Really good validator",
1500,
100)
- .should.be.eventually.rejectedWith("Fee rate of validator should be lower than 100%");
+ .should.be.revertedWithCustomError(validatorService, "WrongFeeValue")
+ .withArgs(1500);
});
it("should allow only owner to call disableWhitelist", async() => {
await validatorService.connect(validator1).disableWhitelist()
- .should.be.eventually.rejectedWith("VALIDATOR_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(validatorService, "RoleRequired")
+ .withArgs(await validatorService.VALIDATOR_MANAGER_ROLE());
await validatorService.connect(owner).disableWhitelist();
});
@@ -110,7 +112,8 @@ describe("ValidatorService", () => {
"Really good validator",
500,
100)
- .should.be.eventually.rejectedWith("Validator with such address already exists");
+ .should.be.revertedWithCustomError(validatorService, "AddressIsAlreadyInUse")
+ .withArgs(validator1);
});
it("should reset name, description, minimum delegation amount", async () => {
@@ -137,7 +140,8 @@ describe("ValidatorService", () => {
const signature = await getValidatorIdSignature(validatorId, nodeAddress);
await validatorService.connect(validator1).linkNodeAddress(nodeAddress.address, signature);
await validatorService.connect(nodeAddress).unlinkNodeAddress(validator1.address)
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(nodeAddress);
});
it("should reject if validator tried to override node address of another validator", async () => {
@@ -152,7 +156,8 @@ describe("ValidatorService", () => {
const signature2 = await getValidatorIdSignature(validatorId2, nodeAddress);
await validatorService.connect(validator1).linkNodeAddress(nodeAddress.address, signature1);
await validatorService.connect(validator2).linkNodeAddress(nodeAddress.address, signature2)
- .should.be.eventually.rejectedWith("Validator cannot override node address");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorCannotOverrideNodeAddress")
+ .withArgs(validatorId2, nodeAddress);
const id = await validatorService.getValidatorIdByNodeAddress(nodeAddress.address);
id.should.be.equal(validatorId1);
});
@@ -166,7 +171,8 @@ describe("ValidatorService", () => {
const validatorId = await validatorService.getValidatorId(validator1.address);
const signature = await getValidatorIdSignature(validatorId, validator2);
await validatorService.connect(validator1).linkNodeAddress(validator2.address, signature)
- .should.be.eventually.rejectedWith("Node address is a validator");
+ .should.be.revertedWithCustomError(validatorService, "NodeAddressIsAValidator")
+ .withArgs(validator2, await validatorService.getValidatorId(validator2));
});
it("should unlink node address for validator", async () => {
@@ -179,13 +185,15 @@ describe("ValidatorService", () => {
500,
100);
await validatorService.connect(validator2).unlinkNodeAddress(nodeAddress.address)
- .should.be.eventually.rejectedWith("Validator does not have permissions to unlink node");
+ .should.be.revertedWithCustomError(validatorService, "NoPermissionsToUnlinkNode")
+ .withArgs(await validatorService.getValidatorId(validator2), nodeAddress);
const id = await validatorService.getValidatorIdByNodeAddress(nodeAddress.address);
id.should.be.equal(validatorId);
await validatorService.connect(validator1).unlinkNodeAddress(nodeAddress.address);
await validatorService.connect(validator1).getValidatorId(nodeAddress.address)
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(nodeAddress);
});
it("should not allow changing the address to the address of an existing validator", async () => {
@@ -195,7 +203,8 @@ describe("ValidatorService", () => {
500,
100);
await validatorService.connect(validator2).requestForNewAddress(validator1.address)
- .should.be.eventually.rejectedWith("Address already registered");
+ .should.be.revertedWithCustomError(validatorService, "AddressIsAlreadyInUse")
+ .withArgs(validator1);
});
describe("when validator requests for a new address", () => {
@@ -212,7 +221,8 @@ describe("ValidatorService", () => {
it("should reject when hacker tries to change validator address", async () => {
const validatorId = 1;
await validatorService.connect(validator2).confirmNewAddress(validatorId)
- .should.be.eventually.rejectedWith("The validator address cannot be changed because it is not the actual owner");
+ .should.be.revertedWithCustomError(validatorService, "SenderHasToBeEqualToRequestedAddress")
+ .withArgs(validator2, validator3);
});
it("should set new address for validator", async () => {
@@ -221,28 +231,32 @@ describe("ValidatorService", () => {
await validatorService.connect(validator3).confirmNewAddress(validatorId);
(await validatorService.getValidatorId(validator3.address)).should.be.equal(validatorId);
await validatorService.getValidatorId(validator1.address)
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(validator1);
});
});
it("should reject when someone tries to set new address for validator that doesn't exist", async () => {
await validatorService.requestForNewAddress(validator2.address)
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(owner);
});
it("should reject if validator tries to set new address as null", async () => {
await validatorService.requestForNewAddress("0x0000000000000000000000000000000000000000")
- .should.be.eventually.rejectedWith("New address cannot be null");
+ .should.be.revertedWithCustomError(validatorService, "AddressIsNotSet");
});
it("should reject if provided validatorId equals zero", async () => {
await validatorService.enableValidator(0)
- .should.be.eventually.rejectedWith("Validator with such ID does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorDoesNotExist")
+ .withArgs(0);
});
it("should allow only VALIDATOR_MANAGER_ROLE to enable validator", async () => {
await validatorService.connect(holder).enableValidator(1)
- .should.be.eventually.rejectedWith("VALIDATOR_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(validatorService, "RoleRequired")
+ .withArgs(await validatorService.VALIDATOR_MANAGER_ROLE());
await deploySkaleManager(contractManager);
const VALIDATOR_MANAGER_ROLE = await validatorService.VALIDATOR_MANAGER_ROLE();
await validatorService.grantRole(VALIDATOR_MANAGER_ROLE, holder.address);
@@ -252,7 +266,8 @@ describe("ValidatorService", () => {
it("should allow only VALIDATOR_MANAGER_ROLE to disable validator", async () => {
await validatorService.enableValidator(1);
await validatorService.connect(holder).disableValidator(1)
- .should.be.eventually.rejectedWith("VALIDATOR_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(validatorService, "RoleRequired")
+ .withArgs(await validatorService.VALIDATOR_MANAGER_ROLE());
await deploySkaleManager(contractManager);
const VALIDATOR_MANAGER_ROLE = await validatorService.VALIDATOR_MANAGER_ROLE();
await validatorService.grantRole(VALIDATOR_MANAGER_ROLE, holder.address);
@@ -308,15 +323,18 @@ describe("ValidatorService", () => {
it("should allow to enable validator in whitelist", async () => {
await validatorService.connect(validator1).enableValidator(validatorId)
- .should.be.eventually.rejectedWith("VALIDATOR_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(validatorService, "RoleRequired")
+ .withArgs(await validatorService.VALIDATOR_MANAGER_ROLE());
await validatorService.enableValidator(validatorId);
});
it("should allow to disable validator from whitelist", async () => {
await validatorService.connect(validator1).disableValidator(validatorId)
- .should.be.eventually.rejectedWith("VALIDATOR_MANAGER_ROLE is required");
+ .should.be.revertedWithCustomError(validatorService, "RoleRequired")
+ .withArgs(await validatorService.VALIDATOR_MANAGER_ROLE());
await validatorService.disableValidator(validatorId)
- .should.be.eventually.rejectedWith("Validator is already disabled");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorIsAlreadyDisabled")
+ .withArgs(validatorId);
await validatorService.enableValidator(validatorId);
await validatorService.isAuthorizedValidator(validatorId).should.eventually.be.true;
@@ -326,7 +344,8 @@ describe("ValidatorService", () => {
it("should not allow to send delegation request if validator isn't authorized", async () => {
await delegationController.connect(holder).delegate(validatorId, amount, delegationPeriod, info)
- .should.be.eventually.rejectedWith("Validator is not authorized to accept delegation request");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorIsNotAuthorized")
+ .withArgs(validatorId);
});
it("should allow to send delegation request if validator is authorized", async () => {
@@ -340,11 +359,13 @@ describe("ValidatorService", () => {
await delegationController.connect(holder).delegate(validatorId, amount, delegationPeriod, info);
await validatorService.connect(holder).stopAcceptingNewRequests()
- .should.be.eventually.rejectedWith("Validator address does not exist");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorAddressDoesNotExist")
+ .withArgs(holder);
await validatorService.connect(validator1).stopAcceptingNewRequests()
await delegationController.connect(holder).delegate(validatorId, amount, delegationPeriod, info)
- .should.be.eventually.rejectedWith("The validator is not currently accepting new requests");
+ .should.be.revertedWithCustomError(validatorService, "ValidatorIsNotCurrentlyAcceptingNewRequests")
+ .withArgs(validatorId);
await validatorService.connect(validator1).startAcceptingNewRequests();
await delegationController.connect(holder).delegate(validatorId, amount, delegationPeriod, info);
diff --git a/test/tools/deploy/delegation/validatorService.ts b/test/tools/deploy/delegation/validatorService.ts
index a6ab1a042..46518dcb2 100644
--- a/test/tools/deploy/delegation/validatorService.ts
+++ b/test/tools/deploy/delegation/validatorService.ts
@@ -1,6 +1,7 @@
import {ContractManager, ValidatorService} from "../../../../typechain-types";
import {deployConstantsHolder} from "../constantsHolder";
import {deployFunctionFactory} from "../factory";
+import {deployPaymasterController} from "../paymasterController";
import {deployDelegationController} from "./delegationController";
const name = "ValidatorService";
@@ -8,6 +9,7 @@ const name = "ValidatorService";
async function deployDependencies(contractManager: ContractManager) {
await deployDelegationController(contractManager);
await deployConstantsHolder(contractManager);
+ await deployPaymasterController(contractManager);
}
export const deployValidatorService = deployFunctionFactory(
diff --git a/test/tools/deploy/paymasterController.ts b/test/tools/deploy/paymasterController.ts
new file mode 100644
index 000000000..35512009d
--- /dev/null
+++ b/test/tools/deploy/paymasterController.ts
@@ -0,0 +1,21 @@
+import {ethers} from "hardhat";
+import {ContractManager, PaymasterController} from "../../../typechain-types";
+import {deployFunctionFactory} from "./factory";
+import {deployImaMock} from "./test/imaMock";
+
+export const deployPaymasterController = deployFunctionFactory(
+ "PaymasterController",
+ async (contractManager: ContractManager) => {
+ const ima = await deployImaMock(contractManager);
+
+ // Initialize
+ const paymasterControllerFactory = await ethers.getContractFactory("PaymasterController");
+ const paymasterController = await paymasterControllerFactory.attach(
+ await contractManager.getContract("PaymasterController")
+ ) as unknown as PaymasterController;
+ await paymasterController.setImaAddress(ima);
+ await paymasterController.setMarionetteAddress(paymasterController);
+ await paymasterController.setPaymasterAddress(paymasterController);
+ await paymasterController.setPaymasterChainHash(ethers.solidityPackedKeccak256(["string"], ["d2"]));
+ },
+);
diff --git a/test/tools/deploy/pricing.ts b/test/tools/deploy/pricing.ts
deleted file mode 100644
index f985062a3..000000000
--- a/test/tools/deploy/pricing.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import {ContractManager, Pricing} from "../../../typechain-types";
-import {deployFunctionFactory} from "./factory";
-import {deployNodes} from "./nodes";
-import {deploySchainsInternal} from "./schainsInternal";
-
-export const deployPricing = deployFunctionFactory(
- "Pricing",
- async (contractManager: ContractManager) => {
- await deployNodes(contractManager);
- await deploySchainsInternal(contractManager);
- }
-);
diff --git a/test/tools/deploy/test/imaMock.ts b/test/tools/deploy/test/imaMock.ts
new file mode 100644
index 000000000..dc301ec90
--- /dev/null
+++ b/test/tools/deploy/test/imaMock.ts
@@ -0,0 +1,5 @@
+import {ImaMock} from "../../../../typechain-types";
+import {deployWithConstructorFunctionFactory} from "../factory";
+
+export const deployImaMock
+ = deployWithConstructorFunctionFactory("ImaMock");
diff --git a/yarn.lock b/yarn.lock
index ece2f28a1..8e1f94816 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1118,53 +1118,53 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
-"@nomicfoundation/edr-darwin-arm64@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz#bbb43f0e01f40839b0bd38c2c443cb6910ae955f"
- integrity sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg==
+"@nomicfoundation/edr-darwin-arm64@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.5.2.tgz#72f7a826c9f0f2c91308edca562de3b9484ac079"
+ integrity sha512-Gm4wOPKhbDjGTIRyFA2QUAPfCXA1AHxYOKt3yLSGJkQkdy9a5WW+qtqKeEKHc/+4wpJSLtsGQfpzyIzggFfo/A==
-"@nomicfoundation/edr-darwin-x64@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz#b1ffcd9142418fd8498de34a7336b3f977907c86"
- integrity sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg==
+"@nomicfoundation/edr-darwin-x64@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.5.2.tgz#6d0fedb219d664631c6feddc596ab8c3bbc36fa8"
+ integrity sha512-ClyABq2dFCsrYEED3/UIO0c7p4H1/4vvlswFlqUyBpOkJccr75qIYvahOSJRM62WgUFRhbSS0OJXFRwc/PwmVg==
-"@nomicfoundation/edr-linux-arm64-gnu@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz#8173d16d4f6f2b3e82ba7096d2a1ea3619d8bfa7"
- integrity sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ==
+"@nomicfoundation/edr-linux-arm64-gnu@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.5.2.tgz#60e4d52d963141bc2bb4a02639dc590a7fbdda2f"
+ integrity sha512-HWMTVk1iOabfvU2RvrKLDgtFjJZTC42CpHiw2h6rfpsgRqMahvIlx2jdjWYzFNy1jZKPTN1AStQ/91MRrg5KnA==
-"@nomicfoundation/edr-linux-arm64-musl@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz#b1ce293a7c3e0d9f70391e1aef1a82b83b997567"
- integrity sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg==
+"@nomicfoundation/edr-linux-arm64-musl@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.5.2.tgz#6676a09eab57c435a16ffc144658c896acca9baa"
+ integrity sha512-CwsQ10xFx/QAD5y3/g5alm9+jFVuhc7uYMhrZAu9UVF+KtVjeCvafj0PaVsZ8qyijjqVuVsJ8hD1x5ob7SMcGg==
-"@nomicfoundation/edr-linux-x64-gnu@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz#4c12c4e4bfd3d837f5663ad7cbf7cb6d5634ef83"
- integrity sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA==
+"@nomicfoundation/edr-linux-x64-gnu@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.5.2.tgz#f558d9697ce961410e7a7468f9ab8c8a601b9df6"
+ integrity sha512-CWVCEdhWJ3fmUpzWHCRnC0/VLBDbqtqTGTR6yyY1Ep3S3BOrHEAvt7h5gx85r2vLcztisu2vlDq51auie4IU1A==
-"@nomicfoundation/edr-linux-x64-musl@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz#8842004aa1a47c504f10863687da28b65dca7baa"
- integrity sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw==
+"@nomicfoundation/edr-linux-x64-musl@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.5.2.tgz#c9c9cbb2997499f75c1d022be724b0551d44569f"
+ integrity sha512-+aJDfwhkddy2pP5u1ISg3IZVAm0dO836tRlDTFWtvvSMQ5hRGqPcWwlsbobhDQsIxhPJyT7phL0orCg5W3WMeA==
-"@nomicfoundation/edr-win32-x64-msvc@0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz#29d8bbb2edf9912a95f5453855cf17cdcb269957"
- integrity sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A==
+"@nomicfoundation/edr-win32-x64-msvc@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.5.2.tgz#f16db88bf4fe09a996af0a25096e09deecb72bfa"
+ integrity sha512-CcvvuA3sAv7liFNPsIR/68YlH6rrybKzYttLlMr80d4GKJjwJ5OKb3YgE6FdZZnOfP19HEHhsLcE0DPLtY3r0w==
-"@nomicfoundation/edr@^0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.4.0.tgz#4895ecb6ef321136db837458949c37cce4a29459"
- integrity sha512-T96DMSogO8TCdbKKctvxfsDljbhFOUKWc9fHJhSeUh71EEho2qR4951LKQF7t7UWEzguVYh/idQr5L/E3QeaMw==
+"@nomicfoundation/edr@^0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.5.2.tgz#e8c7b3d3dd4a312432ab3930dec60f76dc5c4926"
+ integrity sha512-hW/iLvUQZNTVjFyX/I40rtKvvDOqUEyIi96T28YaLfmPL+3LW2lxmYLUXEJ6MI14HzqxDqrLyhf6IbjAa2r3Dw==
dependencies:
- "@nomicfoundation/edr-darwin-arm64" "0.4.0"
- "@nomicfoundation/edr-darwin-x64" "0.4.0"
- "@nomicfoundation/edr-linux-arm64-gnu" "0.4.0"
- "@nomicfoundation/edr-linux-arm64-musl" "0.4.0"
- "@nomicfoundation/edr-linux-x64-gnu" "0.4.0"
- "@nomicfoundation/edr-linux-x64-musl" "0.4.0"
- "@nomicfoundation/edr-win32-x64-msvc" "0.4.0"
+ "@nomicfoundation/edr-darwin-arm64" "0.5.2"
+ "@nomicfoundation/edr-darwin-x64" "0.5.2"
+ "@nomicfoundation/edr-linux-arm64-gnu" "0.5.2"
+ "@nomicfoundation/edr-linux-arm64-musl" "0.5.2"
+ "@nomicfoundation/edr-linux-x64-gnu" "0.5.2"
+ "@nomicfoundation/edr-linux-x64-musl" "0.5.2"
+ "@nomicfoundation/edr-win32-x64-msvc" "0.5.2"
"@nomicfoundation/ethereumjs-common@4.0.4":
version "4.0.4"
@@ -1505,6 +1505,11 @@
"@pnpm/network.ca-file" "^1.0.1"
config-chain "^1.1.11"
+"@quant-finance/solidity-datetime@^2.2.0":
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/@quant-finance/solidity-datetime/-/solidity-datetime-2.2.0.tgz#50f2d00a571d8cc2d962257b40b70fc44450dcaa"
+ integrity sha512-iO0EnqPKTzGCgQOkI9lerpJc0XKUhMNurSjHcA7p7nlP2K2z3U4kk9OC9eQkZUrdBtltft+kIibiDdIOYWuQMg==
+
"@resolver-engine/core@^0.3.3":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967"
@@ -1693,6 +1698,34 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
+"@skalenetwork/ima-interfaces@2.0.0-develop.67":
+ version "2.0.0-develop.67"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/ima-interfaces/-/ima-interfaces-2.0.0-develop.67.tgz#49b01c33cf04bc86c98a0425c742a0d993b9901f"
+ integrity sha512-PxzeXmIWuusESISG1lkeZVFXFpAL4szS673uFZPmFhcGXKrTf8ItG4n1eVFzUx4/egJkztRMk5Q9TJ9Unnv5vg==
+ dependencies:
+ "@skalenetwork/skale-manager-interfaces" "^3.2.0-develop.0"
+
+"@skalenetwork/ima-interfaces@^2.0.0-paymaster.0":
+ version "2.0.0-paymaster.0"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/ima-interfaces/-/ima-interfaces-2.0.0-paymaster.0.tgz#77663aec147ba430dc292aaf5b446eff21ed5fd4"
+ integrity sha512-B9PMcWcd+KkF0fudoQEAuTB2FohtOL/0l+GNlt4HvNvz/dOpsbVkCySrCQ/dCljV0/FSj45eJBgkTNCXyxYrbg==
+ dependencies:
+ "@skalenetwork/skale-manager-interfaces" "^3.2.0-paymaster.0"
+
+"@skalenetwork/marionette-interfaces@^0.0.0-main.6":
+ version "0.0.0-main.6"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/marionette-interfaces/-/marionette-interfaces-0.0.0-main.6.tgz#51dcb8a9efbb4070606c4b4197d1317bbf404cd5"
+ integrity sha512-j+njN/HWTpcgDil8CP9rjMrL5e2l53astPevC3N5izJsJ63HNnP4phcPNQ9/nrNRfzff/3vsjVOns1xABX8Nvw==
+ dependencies:
+ "@skalenetwork/ima-interfaces" "^2.0.0-paymaster.0"
+
+"@skalenetwork/paymaster-interfaces@^1.0.0-main.10":
+ version "1.0.0-main.10"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/paymaster-interfaces/-/paymaster-interfaces-1.0.0-main.10.tgz#abe2394bd948c3fac808e8cf09d91b99a59ac94d"
+ integrity sha512-P7Vc5F+hxeBrTDft2Th7jYY1N3lyzxsVMHkGhJd8Xjc3eSs4tLwvOE15vJPVBwwvqgnsdQwtsfNs+vF49o89LA==
+ dependencies:
+ "@quant-finance/solidity-datetime" "^2.2.0"
+
"@skalenetwork/skale-contracts-ethers-v6@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@skalenetwork/skale-contracts-ethers-v6/-/skale-contracts-ethers-v6-1.0.0.tgz#2ec9e1e6113c0b0e0e7abaa492702baa9d647148"
@@ -1708,10 +1741,20 @@
dependencies:
axios "^1.4.0"
-"@skalenetwork/skale-manager-interfaces@3.1.0":
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-3.1.0.tgz#e97750462b1dafa9eee1c347802d5405afc9474f"
- integrity sha512-lVJM6nRfIrlwRy7N009jGCZa5nDJo2/QMrKN0A2nRz/sqT8wWlOQUeDKrJ1mC5Esdbzhya6T6hTiZbN2yNwcRg==
+"@skalenetwork/skale-manager-interfaces@3.2.0-develop.0":
+ version "3.2.0-develop.0"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-3.2.0-develop.0.tgz#01e64eeabf2b14b320074eb588b557bbd33bab39"
+ integrity sha512-f++aLtSwjLJgAb3dHAm/SMHvx2a0L3uWwF7aam1wCtB6YZrFLR3flzlH3Ms3JlLZtfl5iE7VBmsuidhAqpbfpw==
+
+"@skalenetwork/skale-manager-interfaces@^3.2.0-develop.0":
+ version "3.2.0-paymaster.2"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-3.2.0-paymaster.2.tgz#6b114041b623a030331e0a7853a2eab136fc2daf"
+ integrity sha512-tmqWNkafjJxIZNVp2EmysvXor5F4G+f5A4qTMWqCZ7yMrCAvGzTETpMiHGjJJCUwSIaaqd62DjDjQi69r+BUkg==
+
+"@skalenetwork/skale-manager-interfaces@^3.2.0-paymaster.0":
+ version "3.2.0-paymaster.0"
+ resolved "https://registry.yarnpkg.com/@skalenetwork/skale-manager-interfaces/-/skale-manager-interfaces-3.2.0-paymaster.0.tgz#4fee7d3a6dfd1dc8c446f6d28a2252fce426b537"
+ integrity sha512-AC0g3dMAtHORQnxm9QoZIgpNqTNwe/ahK9kPyTQFV/Ht3/sIoWkx0vXUiAwsDzK56HAVFXfc+LqfmEnKiefDqg==
"@skalenetwork/upgrade-tools@^3.0.0-linter.42":
version "3.0.0-linter.42"
@@ -4004,6 +4047,11 @@ commander@^11.1.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906"
integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==
+commander@^8.1.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
+ integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
+
comment-json@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.2.3.tgz#50b487ebbf43abe44431f575ebda07d30d015365"
@@ -6661,14 +6709,14 @@ hardhat-dependency-compiler@^1.2.1:
resolved "https://registry.yarnpkg.com/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.2.1.tgz#31a00e388029591b648f49ade74f56bfab11243b"
integrity sha512-xG5iwbspTtxOEiP5UsPngEYQ1Hg+fjTjliapIjdTQmwGkCPofrsDhQDV2O/dopcYzcR68nTx2X8xTewYHgA2rQ==
-hardhat@^2.22.5:
- version "2.22.5"
- resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.5.tgz#7e1a4311fa9e34a1cfe337784eae06706f6469a5"
- integrity sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw==
+hardhat@^2.22.8:
+ version "2.22.8"
+ resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.8.tgz#348dcdb48c44648ae7723f6efb511785e2b220c5"
+ integrity sha512-hPh2feBGRswkXkoXUFW6NbxgiYtEzp/3uvVFjYROy6fA9LH8BobUyxStlyhSKj4+v1Y23ZoUBOVWL84IcLACrA==
dependencies:
"@ethersproject/abi" "^5.1.2"
"@metamask/eth-sig-util" "^4.0.0"
- "@nomicfoundation/edr" "^0.4.0"
+ "@nomicfoundation/edr" "^0.5.2"
"@nomicfoundation/ethereumjs-common" "4.0.4"
"@nomicfoundation/ethereumjs-tx" "5.0.4"
"@nomicfoundation/ethereumjs-util" "9.0.4"
@@ -6702,7 +6750,7 @@ hardhat@^2.22.5:
raw-body "^2.4.1"
resolve "1.17.0"
semver "^6.3.0"
- solc "0.7.3"
+ solc "0.8.26"
source-map-support "^0.5.13"
stacktrace-parser "^0.1.10"
tsort "0.0.1"
@@ -10406,18 +10454,16 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
-solc@0.7.3:
- version "0.7.3"
- resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a"
- integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==
+solc@0.8.26:
+ version "0.8.26"
+ resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.26.tgz#afc78078953f6ab3e727c338a2fefcd80dd5b01a"
+ integrity sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==
dependencies:
command-exists "^1.2.8"
- commander "3.0.2"
+ commander "^8.1.0"
follow-redirects "^1.12.1"
- fs-extra "^0.30.0"
js-sha3 "0.8.0"
memorystream "^0.3.1"
- require-from-string "^2.0.0"
semver "^5.5.0"
tmp "0.0.33"
@@ -10446,10 +10492,10 @@ solc@^0.6.3, solc@^0.6.7:
semver "^5.5.0"
tmp "0.0.33"
-solhint@5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/solhint/-/solhint-5.0.1.tgz#f0f783bd9d945e5a27b102295a3f28edba241d6c"
- integrity sha512-QeQLS9HGCnIiibt+xiOa/+MuP7BWz9N7C5+Mj9pLHshdkNhuo3AzCpWmjfWVZBUuwIUO3YyCRVIcYLR3YOKGfg==
+solhint@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/solhint/-/solhint-5.0.3.tgz#b57f6d2534fe09a60f9db1b92e834363edd1cbde"
+ integrity sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==
dependencies:
"@solidity-parser/parser" "^0.18.0"
ajv "^6.12.6"