Skip to content

Commit

Permalink
Merge pull request #1083 from skalenetwork/paymaster
Browse files Browse the repository at this point in the history
Add PaymasterController
  • Loading branch information
DimaStebaev committed Aug 28, 2024
2 parents 0b319f3 + 0332c97 commit 37ff5da
Show file tree
Hide file tree
Showing 77 changed files with 3,498 additions and 1,762 deletions.
6 changes: 5 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
/* eslint-env node */

// cspell:words venv

module.exports = {
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"ignorePatterns": [
"coverage/**",
"typechain-types/**"
"typechain-types/**",
"venv/**"
],
"env": {
"node": true
Expand Down
4 changes: 3 additions & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
"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",
"func-name-mixedcase": "error",
"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",
Expand Down
62 changes: 48 additions & 14 deletions contracts/BountyV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
pragma solidity 0.8.17;

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Compiler version 0.8.17 does not satisfy the 0.8.26 semver requirement

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {PartialDifferences.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {ConstantsHolder.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {Permissions.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {INodes.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {ITimeHelpers.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {IDelegationController.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (18.x)

Wrong Import Order for {IBountyV2.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Compiler version 0.8.17 does not satisfy the 0.8.26 semver requirement

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {PartialDifferences.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {ConstantsHolder.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {Permissions.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {INodes.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {ITimeHelpers.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {IDelegationController.sol}

Check warning on line 22 in contracts/BountyV2.sol

View workflow job for this annotation

GitHub Actions / test (20.x)

Wrong Import Order for {IBountyV2.sol}

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";

Expand Down Expand Up @@ -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;
Expand All @@ -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"
);
_;
}

Expand All @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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")),
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions contracts/CommonErrors.sol
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/

pragma solidity ^0.8.17;


error AddressIsNotSet();
error GroupIndexIsInvalid(uint256 index);
error IsNotContract(address account);
error NotEnoughFunds();
error RoleRequired(bytes32 role);
81 changes: 67 additions & 14 deletions contracts/ConstantsHolder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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"
);
_;
}

Expand All @@ -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"
Expand Down Expand Up @@ -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),
Expand All @@ -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")),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand Down
Loading

0 comments on commit 37ff5da

Please sign in to comment.