From 3105201d04ef0a2a8546ee97c4798075772463ec Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Tue, 17 Dec 2024 18:27:40 +0100 Subject: [PATCH 1/6] feat: Add CSBenefitsRegistry contract --- src/CSBenefitsRegistry.sol | 130 ++++++++ src/interfaces/ICSBenefitsRegistry.sol | 86 +++++ test/CSBenefitsRegistry.t.sol | 425 +++++++++++++++++++++++++ 3 files changed, 641 insertions(+) create mode 100644 src/CSBenefitsRegistry.sol create mode 100644 src/interfaces/ICSBenefitsRegistry.sol create mode 100644 test/CSBenefitsRegistry.t.sol diff --git a/src/CSBenefitsRegistry.sol b/src/CSBenefitsRegistry.sol new file mode 100644 index 00000000..35f579aa --- /dev/null +++ b/src/CSBenefitsRegistry.sol @@ -0,0 +1,130 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.24; + +import { ICSBenefitsRegistry } from "./interfaces/ICSBenefitsRegistry.sol"; +import { AccessControlEnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol"; +import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + +contract CSBenefitsRegistry is + ICSBenefitsRegistry, + Initializable, + AccessControlEnumerableUpgradeable +{ + uint256 internal constant MAX_BP = 10000; + + mapping(uint256 => uint256) internal _priorityQueueLimits; + + mapping(uint256 => uint256[]) internal _rewardSharePivotsData; + mapping(uint256 => uint256[]) internal _rewardShareValuesData; + + mapping(uint256 => uint256[]) internal _performanceLeewayPivotsData; + mapping(uint256 => uint256[]) internal _performanceLeewayValuesData; + + constructor() { + _disableInitializers(); + } + + /// @notice initialize contract + function initialize(address admin) external initializer { + if (admin == address(0)) revert ZeroAdminAddress(); + __AccessControlEnumerable_init(); + _grantRole(DEFAULT_ADMIN_ROLE, admin); + } + + /// @inheritdoc ICSBenefitsRegistry + function setRewardShareData( + uint256 curveId, + uint256[] calldata keyPivots, + uint256[] calldata rewardShares + ) external onlyRole(DEFAULT_ADMIN_ROLE) { + if (keyPivots.length + 1 != rewardShares.length) + revert InvalidRewardShareData(); + if (keyPivots.length > 1) { + for (uint256 i = 0; i < keyPivots.length - 1; ++i) { + if (keyPivots[i] >= keyPivots[i + 1]) + revert InvalidRewardShareData(); + } + } + for (uint256 i = 0; i < rewardShares.length; ++i) { + if (rewardShares[i] > MAX_BP) revert InvalidRewardShareData(); + } + _rewardSharePivotsData[curveId] = keyPivots; + _rewardShareValuesData[curveId] = rewardShares; + + emit RewardShareDataSet(curveId); + } + + /// @inheritdoc ICSBenefitsRegistry + function getRewardShareData( + uint256 curveId + ) + external + view + returns (uint256[] memory keyPivots, uint256[] memory rewardShares) + { + if (_rewardShareValuesData[curveId].length == 0) revert NoData(); + return ( + _rewardSharePivotsData[curveId], + _rewardShareValuesData[curveId] + ); + } + + /// @inheritdoc ICSBenefitsRegistry + function setPerformanceLeewayData( + uint256 curveId, + uint256[] calldata keyPivots, + uint256[] calldata performanceLeeways + ) external onlyRole(DEFAULT_ADMIN_ROLE) { + if (keyPivots.length + 1 != performanceLeeways.length) + revert InvalidRewardShareData(); + if (keyPivots.length > 1) { + for (uint256 i = 0; i < keyPivots.length - 1; ++i) { + if (keyPivots[i] >= keyPivots[i + 1]) + revert InvalidRewardShareData(); + } + } + for (uint256 i = 0; i < performanceLeeways.length; ++i) { + if (performanceLeeways[i] > MAX_BP) revert InvalidRewardShareData(); + } + _performanceLeewayPivotsData[curveId] = keyPivots; + _performanceLeewayValuesData[curveId] = performanceLeeways; + + emit PerformanceLeewayDataSet(curveId); + } + + /// @inheritdoc ICSBenefitsRegistry + function getPerformanceLeewayData( + uint256 curveId + ) + external + view + returns ( + uint256[] memory keyPivots, + uint256[] memory performanceLeeways + ) + { + if (_performanceLeewayValuesData[curveId].length == 0) revert NoData(); + return ( + _performanceLeewayPivotsData[curveId], + _performanceLeewayValuesData[curveId] + ); + } + + /// @inheritdoc ICSBenefitsRegistry + function setPriorityQueueLimit( + uint256 curveId, + uint256 limit + ) external onlyRole(DEFAULT_ADMIN_ROLE) { + _priorityQueueLimits[curveId] = limit; + emit PriorityQueueLimitSet(curveId, limit); + } + + /// @inheritdoc ICSBenefitsRegistry + function getPriorityQueueLimit( + uint256 curveId + ) external view returns (uint256 limit) { + return _priorityQueueLimits[curveId]; + } +} diff --git a/src/interfaces/ICSBenefitsRegistry.sol b/src/interfaces/ICSBenefitsRegistry.sol new file mode 100644 index 00000000..0a633ce9 --- /dev/null +++ b/src/interfaces/ICSBenefitsRegistry.sol @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.24; + +interface ICSBenefitsRegistry { + event RewardShareDataSet(uint256 indexed curveId); + event PerformanceLeewayDataSet(uint256 indexed curveId); + event PriorityQueueLimitSet(uint256 indexed curveId, uint256 limit); + + error InvalidRewardShareData(); + error InvalidPerformanceLeewayData(); + error InvalidPriorityQueueLimit(); + error NoData(); + error ZeroAdminAddress(); + + /// @notice Set reward share parameters for the curveId + /// @dev keyPivots = [10, 50] and rewardShares = [10000, 8000, 5000] stands for + /// 100% rewards for the keys 1-10, 80% rewards fot the keys 11-50, and 50% rewards for the keys > 50 + /// @param curveId Curve Id to associate reward share data with + /// @param keyPivots Pivot numbers of the keys (ex. [10, 50]) + /// @param rewardShares Reward share percentages in BP (ex. [10000, 8000, 5000]) + function setRewardShareData( + uint256 curveId, + uint256[] calldata keyPivots, + uint256[] calldata rewardShares + ) external; + + /// @notice Get reward share parameters by the curveId. + /// @dev Reverts if the values are not set for the given curveId. + /// @dev keyPivots = [10, 50] and rewardShares = [10000, 8000, 5000] stands for + /// 100% rewards for the keys 1-10, 80% rewards fot the keys 11-50, and 50% rewards for the keys > 50 + /// @param curveId Curve Id to get reward share data for + /// @return keyPivots Pivot numbers of the keys (ex. [10, 50]) + /// @return rewardShares Reward share percentages in BP (ex. [10000, 8000, 5000]) + function getRewardShareData( + uint256 curveId + ) + external + view + returns (uint256[] memory keyPivots, uint256[] memory rewardShares); + + /// @notice Set performance leeway parameters for the curveId + /// @dev keyPivots = [100, 500] and performanceLeeways = [500, 450, 400] stands for + /// 5% performance leeway for the keys 1-100, 4.5% performance leeway fot the keys 101-500, and 4% performance leeway for the keys > 500 + /// @param curveId Curve Id to associate performance leeway data with + /// @param keyPivots Pivot numbers of the keys (ex. [100, 500]) + /// @param performanceLeeways Performance leeway percentages in BP (ex. [500, 450, 400]) + function setPerformanceLeewayData( + uint256 curveId, + uint256[] calldata keyPivots, + uint256[] calldata performanceLeeways + ) external; + + /// @notice Get performance leeway parameters by the curveId. + /// @dev Reverts if the values are not set for the given curveId. + /// @dev keyPivots = [100, 500] and performanceLeeways = [500, 450, 400] stands for + /// 5% performance leeway for the keys 1-100, 4.5% performance leeway fot the keys 101-500, and 4% performance leeway for the keys > 500 + /// @param curveId Curve Id to get performance leeway data for + /// @return keyPivots Pivot numbers of the keys (ex. [100, 500]) + /// @return performanceLeeways Performance leeway percentages in BP (ex. [500, 450, 400]) + function getPerformanceLeewayData( + uint256 curveId + ) + external + view + returns ( + uint256[] memory keyPivots, + uint256[] memory performanceLeeways + ); + + /// @notice Set priority queue limit for the curveId. + /// @dev The first `limit` keys for the Node Operator with the given `curveId` will be placed in the priority queue. + /// @param curveId Curve Id to associate priority queue limit with + /// @param limit Priority queue limit + function setPriorityQueueLimit(uint256 curveId, uint256 limit) external; + + /// @notice Get priority queue limit by the curveId. + /// @dev Default value is returned if the value is not set for the given curveId. + /// @dev The first `limit` keys for the Node Operator with the given `curveId` will be placed in the priority queue. + /// @param curveId Curve Id to get priority queue limit for + /// @return limit Priority queue limit) + function getPriorityQueueLimit( + uint256 curveId + ) external view returns (uint256 limit); +} diff --git a/test/CSBenefitsRegistry.t.sol b/test/CSBenefitsRegistry.t.sol new file mode 100644 index 00000000..579a336e --- /dev/null +++ b/test/CSBenefitsRegistry.t.sol @@ -0,0 +1,425 @@ +// SPDX-FileCopyrightText: 2024 Lido +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.24; + +import "forge-std/Test.sol"; + +import { CSBenefitsRegistry } from "../src/CSBenefitsRegistry.sol"; +import { ICSBenefitsRegistry } from "../src/interfaces/ICSBenefitsRegistry.sol"; + +import { Utilities } from "./helpers/Utilities.sol"; +import { Fixtures } from "./helpers/Fixtures.sol"; + +import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + +contract CSBenefitsRegistryBaseTest is Test, Utilities, Fixtures { + address internal admin; + address internal stranger; + + CSBenefitsRegistry internal benefitsRegistry; + + function setUp() public virtual { + admin = nextAddress("ADMIN"); + stranger = nextAddress("STRANGER"); + + benefitsRegistry = new CSBenefitsRegistry(); + } +} + +contract CSBenefitsRegistryInitTest is CSBenefitsRegistryBaseTest { + function test_constructor_RevertWhen_InitOnImpl() public { + vm.expectRevert(Initializable.InvalidInitialization.selector); + benefitsRegistry.initialize(admin); + } + + function test_initialize_happyPath() public { + _enableInitializers(address(benefitsRegistry)); + + benefitsRegistry.initialize(admin); + + assertTrue( + benefitsRegistry.hasRole( + benefitsRegistry.DEFAULT_ADMIN_ROLE(), + admin + ) + ); + } + + function test_initialize_RevertWhen_ZeroAdminAddress() public { + _enableInitializers(address(benefitsRegistry)); + vm.expectRevert(ICSBenefitsRegistry.ZeroAdminAddress.selector); + benefitsRegistry.initialize(address(0)); + } +} + +contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { + function setUp() public virtual override { + super.setUp(); + _enableInitializers(address(benefitsRegistry)); + benefitsRegistry.initialize(admin); + } + + function test_setRewardShareData_set_valid_data() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 10; + + uint256[] memory rewardShares = new uint256[](2); + rewardShares[0] = 10000; + rewardShares[1] = 8000; + + vm.expectEmit(true, true, true, true, address(benefitsRegistry)); + emit ICSBenefitsRegistry.RewardShareDataSet(curveId); + vm.prank(admin); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + } + + function test_setRewardShareData_RevertWhen_not_admin() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 10; + + uint256[] memory rewardShares = new uint256[](2); + rewardShares[0] = 10000; + rewardShares[1] = 8000; + + bytes32 role = benefitsRegistry.DEFAULT_ADMIN_ROLE(); + expectRoleRevert(stranger, role); + vm.prank(stranger); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + } + + function test_setRewardShareData_RevertWhen_invalid_data_length() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](2); + keyPivots[0] = 10; + keyPivots[1] = 100; + + uint256[] memory rewardShares = new uint256[](2); + rewardShares[0] = 10000; + rewardShares[1] = 8000; + + vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + } + + function test_setRewardShareData_RevertWhen_invalid_pivots_sort() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](2); + keyPivots[0] = 100; + keyPivots[1] = 10; + + uint256[] memory rewardShares = new uint256[](3); + rewardShares[0] = 10000; + rewardShares[1] = 8000; + rewardShares[2] = 5000; + + vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + } + + function test_setRewardShareData_RevertWhen_invalid_bp_values() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 10; + + uint256[] memory rewardShares = new uint256[](2); + rewardShares[0] = 100000; + rewardShares[1] = 8000; + + vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + } + + function test_getRewardShareData_usual_data() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 10; + + uint256[] memory rewardShares = new uint256[](2); + rewardShares[0] = 10000; + rewardShares[1] = 8000; + + vm.prank(admin); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + + ( + uint256[] memory keyPivotsOut, + uint256[] memory rewardSharesOut + ) = benefitsRegistry.getRewardShareData(curveId); + + assertEq(keyPivotsOut.length, keyPivots.length); + for (uint256 i = 0; i < keyPivotsOut.length; ++i) { + assertEq(keyPivotsOut[i], keyPivots[i]); + } + + assertEq(rewardSharesOut.length, rewardShares.length); + for (uint256 i = 0; i < rewardSharesOut.length; ++i) { + assertEq(rewardSharesOut[i], rewardShares[i]); + } + } + + function test_getRewardShareData_no_pivots_data() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](0); + + uint256[] memory rewardShares = new uint256[](1); + rewardShares[0] = 8000; + + vm.prank(admin); + benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + + ( + uint256[] memory keyPivotsOut, + uint256[] memory rewardSharesOut + ) = benefitsRegistry.getRewardShareData(curveId); + + assertEq(keyPivotsOut.length, keyPivots.length); + + assertEq(rewardSharesOut.length, rewardShares.length); + for (uint256 i = 0; i < rewardSharesOut.length; ++i) { + assertEq(rewardSharesOut[i], rewardShares[i]); + } + } + + function test_getRewardShareData_RevertWhen_no_data() public { + uint256 curveId = 0; + vm.expectRevert(ICSBenefitsRegistry.NoData.selector); + ( + uint256[] memory keyPivotsOut, + uint256[] memory rewardSharesOut + ) = benefitsRegistry.getRewardShareData(curveId); + } +} + +contract CSBenefitsRegistryPerformanceLeewayDataTest is + CSBenefitsRegistryBaseTest +{ + function setUp() public virtual override { + super.setUp(); + _enableInitializers(address(benefitsRegistry)); + benefitsRegistry.initialize(admin); + } + + function test_setPerformanceLeewayData_set_valid_data() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 100; + + uint256[] memory performanceLeeways = new uint256[](2); + performanceLeeways[0] = 500; + performanceLeeways[1] = 400; + + vm.expectEmit(true, true, true, true, address(benefitsRegistry)); + emit ICSBenefitsRegistry.PerformanceLeewayDataSet(curveId); + vm.prank(admin); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + } + + function test_setPerformanceLeewayData_RevertWhen_not_admin() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 100; + + uint256[] memory performanceLeeways = new uint256[](2); + performanceLeeways[0] = 500; + performanceLeeways[1] = 400; + + bytes32 role = benefitsRegistry.DEFAULT_ADMIN_ROLE(); + expectRoleRevert(stranger, role); + vm.prank(stranger); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + } + + function test_setPerformanceLeewayData_RevertWhen_invalid_data_length() + public + { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](2); + keyPivots[0] = 10; + keyPivots[1] = 100; + + uint256[] memory performanceLeeways = new uint256[](2); + performanceLeeways[0] = 500; + performanceLeeways[1] = 400; + + vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + } + + function test_setPerformanceLeewayData_RevertWhen_invalid_pivots_sort() + public + { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](2); + keyPivots[0] = 100; + keyPivots[1] = 10; + + uint256[] memory performanceLeeways = new uint256[](3); + performanceLeeways[0] = 500; + performanceLeeways[1] = 400; + performanceLeeways[2] = 300; + + vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + } + + function test_setPerformanceLeewayData_RevertWhen_invalid_bp_values() + public + { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 100; + + uint256[] memory performanceLeeways = new uint256[](2); + performanceLeeways[0] = 50000; + performanceLeeways[1] = 400; + + vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + } + + function test_getPerformanceLeewayData_usual_data() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](1); + keyPivots[0] = 100; + + uint256[] memory performanceLeeways = new uint256[](2); + performanceLeeways[0] = 500; + performanceLeeways[1] = 400; + + vm.prank(admin); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + + ( + uint256[] memory keyPivotsOut, + uint256[] memory performanceLeewaysOut + ) = benefitsRegistry.getPerformanceLeewayData(curveId); + + assertEq(keyPivotsOut.length, keyPivots.length); + for (uint256 i = 0; i < keyPivotsOut.length; ++i) { + assertEq(keyPivotsOut[i], keyPivots[i]); + } + + assertEq(performanceLeewaysOut.length, performanceLeeways.length); + for (uint256 i = 0; i < performanceLeewaysOut.length; ++i) { + assertEq(performanceLeewaysOut[i], performanceLeeways[i]); + } + } + + function test_getPerformanceLeewayData_no_pivots_data() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](0); + + uint256[] memory performanceLeeways = new uint256[](1); + performanceLeeways[0] = 500; + + vm.prank(admin); + benefitsRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + + ( + uint256[] memory keyPivotsOut, + uint256[] memory performanceLeewaysOut + ) = benefitsRegistry.getPerformanceLeewayData(curveId); + + assertEq(keyPivotsOut.length, keyPivots.length); + + assertEq(performanceLeewaysOut.length, performanceLeeways.length); + for (uint256 i = 0; i < performanceLeewaysOut.length; ++i) { + assertEq(performanceLeewaysOut[i], performanceLeeways[i]); + } + } + + function test_getPerformanceLeewayData_RevertWhen_no_data() public { + uint256 curveId = 0; + vm.expectRevert(ICSBenefitsRegistry.NoData.selector); + ( + uint256[] memory keyPivotsOut, + uint256[] memory performanceLeewaysOut + ) = benefitsRegistry.getPerformanceLeewayData(curveId); + } +} + +contract CSBenefitsRegistryPriorityQueueLimitTest is + CSBenefitsRegistryBaseTest +{ + function setUp() public virtual override { + super.setUp(); + _enableInitializers(address(benefitsRegistry)); + benefitsRegistry.initialize(admin); + } + + function test_setPriorityQueueLimit_set_valid_data() public { + uint256 curveId = 1; + uint256 limit = 20; + + vm.expectEmit(true, true, true, true, address(benefitsRegistry)); + emit ICSBenefitsRegistry.PriorityQueueLimitSet(curveId, limit); + vm.prank(admin); + benefitsRegistry.setPriorityQueueLimit(curveId, limit); + } + + function test_setPriorityQueueLimit_RevertWhen_not_admin() public { + uint256 curveId = 1; + uint256 limit = 20; + + bytes32 role = benefitsRegistry.DEFAULT_ADMIN_ROLE(); + expectRoleRevert(stranger, role); + vm.prank(stranger); + benefitsRegistry.setPriorityQueueLimit(curveId, limit); + } + + function test_getPerformanceLeewayData_usual_data() public { + uint256 curveId = 1; + uint256 limit = 20; + + vm.prank(admin); + benefitsRegistry.setPriorityQueueLimit(curveId, limit); + + uint256 limitOut = benefitsRegistry.getPriorityQueueLimit(curveId); + + assertEq(limitOut, limit); + } + + function test_getPerformanceLeewayData_default_return() public { + uint256 curveId = 0; + uint256 limitOut = benefitsRegistry.getPriorityQueueLimit(curveId); + + assertEq(limitOut, 0); + } +} From 841f17e41c0b12328948411fd2a1375d33018f4c Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Thu, 9 Jan 2025 09:23:12 +0100 Subject: [PATCH 2/6] chore: Typos --- src/interfaces/ICSBenefitsRegistry.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/interfaces/ICSBenefitsRegistry.sol b/src/interfaces/ICSBenefitsRegistry.sol index 0a633ce9..78e8f880 100644 --- a/src/interfaces/ICSBenefitsRegistry.sol +++ b/src/interfaces/ICSBenefitsRegistry.sol @@ -16,7 +16,7 @@ interface ICSBenefitsRegistry { /// @notice Set reward share parameters for the curveId /// @dev keyPivots = [10, 50] and rewardShares = [10000, 8000, 5000] stands for - /// 100% rewards for the keys 1-10, 80% rewards fot the keys 11-50, and 50% rewards for the keys > 50 + /// 100% rewards for the keys 1-10, 80% rewards for the keys 11-50, and 50% rewards for the keys > 50 /// @param curveId Curve Id to associate reward share data with /// @param keyPivots Pivot numbers of the keys (ex. [10, 50]) /// @param rewardShares Reward share percentages in BP (ex. [10000, 8000, 5000]) @@ -29,7 +29,7 @@ interface ICSBenefitsRegistry { /// @notice Get reward share parameters by the curveId. /// @dev Reverts if the values are not set for the given curveId. /// @dev keyPivots = [10, 50] and rewardShares = [10000, 8000, 5000] stands for - /// 100% rewards for the keys 1-10, 80% rewards fot the keys 11-50, and 50% rewards for the keys > 50 + /// 100% rewards for the keys 1-10, 80% rewards for the keys 11-50, and 50% rewards for the keys > 50 /// @param curveId Curve Id to get reward share data for /// @return keyPivots Pivot numbers of the keys (ex. [10, 50]) /// @return rewardShares Reward share percentages in BP (ex. [10000, 8000, 5000]) @@ -42,7 +42,7 @@ interface ICSBenefitsRegistry { /// @notice Set performance leeway parameters for the curveId /// @dev keyPivots = [100, 500] and performanceLeeways = [500, 450, 400] stands for - /// 5% performance leeway for the keys 1-100, 4.5% performance leeway fot the keys 101-500, and 4% performance leeway for the keys > 500 + /// 5% performance leeway for the keys 1-100, 4.5% performance leeway for the keys 101-500, and 4% performance leeway for the keys > 500 /// @param curveId Curve Id to associate performance leeway data with /// @param keyPivots Pivot numbers of the keys (ex. [100, 500]) /// @param performanceLeeways Performance leeway percentages in BP (ex. [500, 450, 400]) @@ -55,7 +55,7 @@ interface ICSBenefitsRegistry { /// @notice Get performance leeway parameters by the curveId. /// @dev Reverts if the values are not set for the given curveId. /// @dev keyPivots = [100, 500] and performanceLeeways = [500, 450, 400] stands for - /// 5% performance leeway for the keys 1-100, 4.5% performance leeway fot the keys 101-500, and 4% performance leeway for the keys > 500 + /// 5% performance leeway for the keys 1-100, 4.5% performance leeway for the keys 101-500, and 4% performance leeway for the keys > 500 /// @param curveId Curve Id to get performance leeway data for /// @return keyPivots Pivot numbers of the keys (ex. [100, 500]) /// @return performanceLeeways Performance leeway percentages in BP (ex. [500, 450, 400]) @@ -79,7 +79,7 @@ interface ICSBenefitsRegistry { /// @dev Default value is returned if the value is not set for the given curveId. /// @dev The first `limit` keys for the Node Operator with the given `curveId` will be placed in the priority queue. /// @param curveId Curve Id to get priority queue limit for - /// @return limit Priority queue limit) + /// @return limit Priority queue limit function getPriorityQueueLimit( uint256 curveId ) external view returns (uint256 limit); From b762d2e5c1ccc9ab9d593902570f2e26c29d2e23 Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Thu, 9 Jan 2025 09:25:21 +0100 Subject: [PATCH 3/6] chore: Rename Benefits to Perks --- ...nefitsRegistry.sol => CSPerksRegistry.sol} | 18 +-- ...efitsRegistry.sol => ICSPerksRegistry.sol} | 2 +- ...tsRegistry.t.sol => CSPerksRegistry.t.sol} | 134 +++++++++--------- 3 files changed, 77 insertions(+), 77 deletions(-) rename src/{CSBenefitsRegistry.sol => CSPerksRegistry.sol} (91%) rename src/interfaces/{ICSBenefitsRegistry.sol => ICSPerksRegistry.sol} (99%) rename test/{CSBenefitsRegistry.t.sol => CSPerksRegistry.t.sol} (69%) diff --git a/src/CSBenefitsRegistry.sol b/src/CSPerksRegistry.sol similarity index 91% rename from src/CSBenefitsRegistry.sol rename to src/CSPerksRegistry.sol index 35f579aa..eea90d7a 100644 --- a/src/CSBenefitsRegistry.sol +++ b/src/CSPerksRegistry.sol @@ -3,12 +3,12 @@ pragma solidity 0.8.24; -import { ICSBenefitsRegistry } from "./interfaces/ICSBenefitsRegistry.sol"; +import { ICSPerksRegistry } from "./interfaces/ICSPerksRegistry.sol"; import { AccessControlEnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -contract CSBenefitsRegistry is - ICSBenefitsRegistry, +contract CSPerksRegistry is + ICSPerksRegistry, Initializable, AccessControlEnumerableUpgradeable { @@ -33,7 +33,7 @@ contract CSBenefitsRegistry is _grantRole(DEFAULT_ADMIN_ROLE, admin); } - /// @inheritdoc ICSBenefitsRegistry + /// @inheritdoc ICSPerksRegistry function setRewardShareData( uint256 curveId, uint256[] calldata keyPivots, @@ -56,7 +56,7 @@ contract CSBenefitsRegistry is emit RewardShareDataSet(curveId); } - /// @inheritdoc ICSBenefitsRegistry + /// @inheritdoc ICSPerksRegistry function getRewardShareData( uint256 curveId ) @@ -71,7 +71,7 @@ contract CSBenefitsRegistry is ); } - /// @inheritdoc ICSBenefitsRegistry + /// @inheritdoc ICSPerksRegistry function setPerformanceLeewayData( uint256 curveId, uint256[] calldata keyPivots, @@ -94,7 +94,7 @@ contract CSBenefitsRegistry is emit PerformanceLeewayDataSet(curveId); } - /// @inheritdoc ICSBenefitsRegistry + /// @inheritdoc ICSPerksRegistry function getPerformanceLeewayData( uint256 curveId ) @@ -112,7 +112,7 @@ contract CSBenefitsRegistry is ); } - /// @inheritdoc ICSBenefitsRegistry + /// @inheritdoc ICSPerksRegistry function setPriorityQueueLimit( uint256 curveId, uint256 limit @@ -121,7 +121,7 @@ contract CSBenefitsRegistry is emit PriorityQueueLimitSet(curveId, limit); } - /// @inheritdoc ICSBenefitsRegistry + /// @inheritdoc ICSPerksRegistry function getPriorityQueueLimit( uint256 curveId ) external view returns (uint256 limit) { diff --git a/src/interfaces/ICSBenefitsRegistry.sol b/src/interfaces/ICSPerksRegistry.sol similarity index 99% rename from src/interfaces/ICSBenefitsRegistry.sol rename to src/interfaces/ICSPerksRegistry.sol index 78e8f880..3f7dc78b 100644 --- a/src/interfaces/ICSBenefitsRegistry.sol +++ b/src/interfaces/ICSPerksRegistry.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; -interface ICSBenefitsRegistry { +interface ICSPerksRegistry { event RewardShareDataSet(uint256 indexed curveId); event PerformanceLeewayDataSet(uint256 indexed curveId); event PriorityQueueLimitSet(uint256 indexed curveId, uint256 limit); diff --git a/test/CSBenefitsRegistry.t.sol b/test/CSPerksRegistry.t.sol similarity index 69% rename from test/CSBenefitsRegistry.t.sol rename to test/CSPerksRegistry.t.sol index 579a336e..42b15197 100644 --- a/test/CSBenefitsRegistry.t.sol +++ b/test/CSPerksRegistry.t.sol @@ -5,59 +5,59 @@ pragma solidity 0.8.24; import "forge-std/Test.sol"; -import { CSBenefitsRegistry } from "../src/CSBenefitsRegistry.sol"; -import { ICSBenefitsRegistry } from "../src/interfaces/ICSBenefitsRegistry.sol"; +import { CSPerksRegistry } from "../src/CSPerksRegistry.sol"; +import { ICSPerksRegistry } from "../src/interfaces/ICSPerksRegistry.sol"; import { Utilities } from "./helpers/Utilities.sol"; import { Fixtures } from "./helpers/Fixtures.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -contract CSBenefitsRegistryBaseTest is Test, Utilities, Fixtures { +contract CSPerksRegistryBaseTest is Test, Utilities, Fixtures { address internal admin; address internal stranger; - CSBenefitsRegistry internal benefitsRegistry; + CSPerksRegistry internal PerksRegistry; function setUp() public virtual { admin = nextAddress("ADMIN"); stranger = nextAddress("STRANGER"); - benefitsRegistry = new CSBenefitsRegistry(); + PerksRegistry = new CSPerksRegistry(); } } -contract CSBenefitsRegistryInitTest is CSBenefitsRegistryBaseTest { +contract CSPerksRegistryInitTest is CSPerksRegistryBaseTest { function test_constructor_RevertWhen_InitOnImpl() public { vm.expectRevert(Initializable.InvalidInitialization.selector); - benefitsRegistry.initialize(admin); + PerksRegistry.initialize(admin); } function test_initialize_happyPath() public { - _enableInitializers(address(benefitsRegistry)); + _enableInitializers(address(PerksRegistry)); - benefitsRegistry.initialize(admin); + PerksRegistry.initialize(admin); assertTrue( - benefitsRegistry.hasRole( - benefitsRegistry.DEFAULT_ADMIN_ROLE(), + PerksRegistry.hasRole( + PerksRegistry.DEFAULT_ADMIN_ROLE(), admin ) ); } function test_initialize_RevertWhen_ZeroAdminAddress() public { - _enableInitializers(address(benefitsRegistry)); - vm.expectRevert(ICSBenefitsRegistry.ZeroAdminAddress.selector); - benefitsRegistry.initialize(address(0)); + _enableInitializers(address(PerksRegistry)); + vm.expectRevert(ICSPerksRegistry.ZeroAdminAddress.selector); + PerksRegistry.initialize(address(0)); } } -contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { +contract CSPerksRegistryRewardShareDataTest is CSPerksRegistryBaseTest { function setUp() public virtual override { super.setUp(); - _enableInitializers(address(benefitsRegistry)); - benefitsRegistry.initialize(admin); + _enableInitializers(address(PerksRegistry)); + PerksRegistry.initialize(admin); } function test_setRewardShareData_set_valid_data() public { @@ -69,10 +69,10 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[0] = 10000; rewardShares[1] = 8000; - vm.expectEmit(true, true, true, true, address(benefitsRegistry)); - emit ICSBenefitsRegistry.RewardShareDataSet(curveId); + vm.expectEmit(true, true, true, true, address(PerksRegistry)); + emit ICSPerksRegistry.RewardShareDataSet(curveId); vm.prank(admin); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); } function test_setRewardShareData_RevertWhen_not_admin() public { @@ -84,10 +84,10 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[0] = 10000; rewardShares[1] = 8000; - bytes32 role = benefitsRegistry.DEFAULT_ADMIN_ROLE(); + bytes32 role = PerksRegistry.DEFAULT_ADMIN_ROLE(); expectRoleRevert(stranger, role); vm.prank(stranger); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); } function test_setRewardShareData_RevertWhen_invalid_data_length() public { @@ -100,9 +100,9 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[0] = 10000; rewardShares[1] = 8000; - vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); vm.prank(admin); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); } function test_setRewardShareData_RevertWhen_invalid_pivots_sort() public { @@ -116,9 +116,9 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[1] = 8000; rewardShares[2] = 5000; - vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); vm.prank(admin); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); } function test_setRewardShareData_RevertWhen_invalid_bp_values() public { @@ -130,9 +130,9 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[0] = 100000; rewardShares[1] = 8000; - vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); vm.prank(admin); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); } function test_getRewardShareData_usual_data() public { @@ -145,12 +145,12 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[1] = 8000; vm.prank(admin); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); ( uint256[] memory keyPivotsOut, uint256[] memory rewardSharesOut - ) = benefitsRegistry.getRewardShareData(curveId); + ) = PerksRegistry.getRewardShareData(curveId); assertEq(keyPivotsOut.length, keyPivots.length); for (uint256 i = 0; i < keyPivotsOut.length; ++i) { @@ -171,12 +171,12 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { rewardShares[0] = 8000; vm.prank(admin); - benefitsRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); ( uint256[] memory keyPivotsOut, uint256[] memory rewardSharesOut - ) = benefitsRegistry.getRewardShareData(curveId); + ) = PerksRegistry.getRewardShareData(curveId); assertEq(keyPivotsOut.length, keyPivots.length); @@ -188,21 +188,21 @@ contract CSBenefitsRegistryRewardShareDataTest is CSBenefitsRegistryBaseTest { function test_getRewardShareData_RevertWhen_no_data() public { uint256 curveId = 0; - vm.expectRevert(ICSBenefitsRegistry.NoData.selector); + vm.expectRevert(ICSPerksRegistry.NoData.selector); ( uint256[] memory keyPivotsOut, uint256[] memory rewardSharesOut - ) = benefitsRegistry.getRewardShareData(curveId); + ) = PerksRegistry.getRewardShareData(curveId); } } -contract CSBenefitsRegistryPerformanceLeewayDataTest is - CSBenefitsRegistryBaseTest +contract CSPerksRegistryPerformanceLeewayDataTest is + CSPerksRegistryBaseTest { function setUp() public virtual override { super.setUp(); - _enableInitializers(address(benefitsRegistry)); - benefitsRegistry.initialize(admin); + _enableInitializers(address(PerksRegistry)); + PerksRegistry.initialize(admin); } function test_setPerformanceLeewayData_set_valid_data() public { @@ -214,10 +214,10 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[0] = 500; performanceLeeways[1] = 400; - vm.expectEmit(true, true, true, true, address(benefitsRegistry)); - emit ICSBenefitsRegistry.PerformanceLeewayDataSet(curveId); + vm.expectEmit(true, true, true, true, address(PerksRegistry)); + emit ICSPerksRegistry.PerformanceLeewayDataSet(curveId); vm.prank(admin); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -233,10 +233,10 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[0] = 500; performanceLeeways[1] = 400; - bytes32 role = benefitsRegistry.DEFAULT_ADMIN_ROLE(); + bytes32 role = PerksRegistry.DEFAULT_ADMIN_ROLE(); expectRoleRevert(stranger, role); vm.prank(stranger); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -255,9 +255,9 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[0] = 500; performanceLeeways[1] = 400; - vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); vm.prank(admin); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -277,9 +277,9 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[1] = 400; performanceLeeways[2] = 300; - vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); vm.prank(admin); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -297,9 +297,9 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[0] = 50000; performanceLeeways[1] = 400; - vm.expectRevert(ICSBenefitsRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); vm.prank(admin); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -316,7 +316,7 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[1] = 400; vm.prank(admin); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -325,7 +325,7 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is ( uint256[] memory keyPivotsOut, uint256[] memory performanceLeewaysOut - ) = benefitsRegistry.getPerformanceLeewayData(curveId); + ) = PerksRegistry.getPerformanceLeewayData(curveId); assertEq(keyPivotsOut.length, keyPivots.length); for (uint256 i = 0; i < keyPivotsOut.length; ++i) { @@ -346,7 +346,7 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is performanceLeeways[0] = 500; vm.prank(admin); - benefitsRegistry.setPerformanceLeewayData( + PerksRegistry.setPerformanceLeewayData( curveId, keyPivots, performanceLeeways @@ -355,7 +355,7 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is ( uint256[] memory keyPivotsOut, uint256[] memory performanceLeewaysOut - ) = benefitsRegistry.getPerformanceLeewayData(curveId); + ) = PerksRegistry.getPerformanceLeewayData(curveId); assertEq(keyPivotsOut.length, keyPivots.length); @@ -367,41 +367,41 @@ contract CSBenefitsRegistryPerformanceLeewayDataTest is function test_getPerformanceLeewayData_RevertWhen_no_data() public { uint256 curveId = 0; - vm.expectRevert(ICSBenefitsRegistry.NoData.selector); + vm.expectRevert(ICSPerksRegistry.NoData.selector); ( uint256[] memory keyPivotsOut, uint256[] memory performanceLeewaysOut - ) = benefitsRegistry.getPerformanceLeewayData(curveId); + ) = PerksRegistry.getPerformanceLeewayData(curveId); } } -contract CSBenefitsRegistryPriorityQueueLimitTest is - CSBenefitsRegistryBaseTest +contract CSPerksRegistryPriorityQueueLimitTest is + CSPerksRegistryBaseTest { function setUp() public virtual override { super.setUp(); - _enableInitializers(address(benefitsRegistry)); - benefitsRegistry.initialize(admin); + _enableInitializers(address(PerksRegistry)); + PerksRegistry.initialize(admin); } function test_setPriorityQueueLimit_set_valid_data() public { uint256 curveId = 1; uint256 limit = 20; - vm.expectEmit(true, true, true, true, address(benefitsRegistry)); - emit ICSBenefitsRegistry.PriorityQueueLimitSet(curveId, limit); + vm.expectEmit(true, true, true, true, address(PerksRegistry)); + emit ICSPerksRegistry.PriorityQueueLimitSet(curveId, limit); vm.prank(admin); - benefitsRegistry.setPriorityQueueLimit(curveId, limit); + PerksRegistry.setPriorityQueueLimit(curveId, limit); } function test_setPriorityQueueLimit_RevertWhen_not_admin() public { uint256 curveId = 1; uint256 limit = 20; - bytes32 role = benefitsRegistry.DEFAULT_ADMIN_ROLE(); + bytes32 role = PerksRegistry.DEFAULT_ADMIN_ROLE(); expectRoleRevert(stranger, role); vm.prank(stranger); - benefitsRegistry.setPriorityQueueLimit(curveId, limit); + PerksRegistry.setPriorityQueueLimit(curveId, limit); } function test_getPerformanceLeewayData_usual_data() public { @@ -409,16 +409,16 @@ contract CSBenefitsRegistryPriorityQueueLimitTest is uint256 limit = 20; vm.prank(admin); - benefitsRegistry.setPriorityQueueLimit(curveId, limit); + PerksRegistry.setPriorityQueueLimit(curveId, limit); - uint256 limitOut = benefitsRegistry.getPriorityQueueLimit(curveId); + uint256 limitOut = PerksRegistry.getPriorityQueueLimit(curveId); assertEq(limitOut, limit); } function test_getPerformanceLeewayData_default_return() public { uint256 curveId = 0; - uint256 limitOut = benefitsRegistry.getPriorityQueueLimit(curveId); + uint256 limitOut = PerksRegistry.getPriorityQueueLimit(curveId); assertEq(limitOut, 0); } From 81a07eb0d6d6d323fa5fd047d78da92a72e5b48a Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Thu, 9 Jan 2025 09:57:23 +0100 Subject: [PATCH 4/6] chore: Fix lint --- .prettierignore | 1 + test/CSPerksRegistry.t.sol | 13 +++---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.prettierignore b/.prettierignore index 473209b3..dc5229ae 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,3 +5,4 @@ lib/ !src/lib GAS.md artifacts/ +docs/ diff --git a/test/CSPerksRegistry.t.sol b/test/CSPerksRegistry.t.sol index 42b15197..b1542ce4 100644 --- a/test/CSPerksRegistry.t.sol +++ b/test/CSPerksRegistry.t.sol @@ -39,10 +39,7 @@ contract CSPerksRegistryInitTest is CSPerksRegistryBaseTest { PerksRegistry.initialize(admin); assertTrue( - PerksRegistry.hasRole( - PerksRegistry.DEFAULT_ADMIN_ROLE(), - admin - ) + PerksRegistry.hasRole(PerksRegistry.DEFAULT_ADMIN_ROLE(), admin) ); } @@ -196,9 +193,7 @@ contract CSPerksRegistryRewardShareDataTest is CSPerksRegistryBaseTest { } } -contract CSPerksRegistryPerformanceLeewayDataTest is - CSPerksRegistryBaseTest -{ +contract CSPerksRegistryPerformanceLeewayDataTest is CSPerksRegistryBaseTest { function setUp() public virtual override { super.setUp(); _enableInitializers(address(PerksRegistry)); @@ -375,9 +370,7 @@ contract CSPerksRegistryPerformanceLeewayDataTest is } } -contract CSPerksRegistryPriorityQueueLimitTest is - CSPerksRegistryBaseTest -{ +contract CSPerksRegistryPriorityQueueLimitTest is CSPerksRegistryBaseTest { function setUp() public virtual override { super.setUp(); _enableInitializers(address(PerksRegistry)); From 31d4ceb4d492b263acb425a90c0947b4e9341135 Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Fri, 10 Jan 2025 13:52:15 +0100 Subject: [PATCH 5/6] chore: Comment --- src/interfaces/ICSPerksRegistry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/ICSPerksRegistry.sol b/src/interfaces/ICSPerksRegistry.sol index 3f7dc78b..bf90cc1d 100644 --- a/src/interfaces/ICSPerksRegistry.sol +++ b/src/interfaces/ICSPerksRegistry.sol @@ -76,7 +76,7 @@ interface ICSPerksRegistry { function setPriorityQueueLimit(uint256 curveId, uint256 limit) external; /// @notice Get priority queue limit by the curveId. - /// @dev Default value is returned if the value is not set for the given curveId. + /// @dev Zero is returned if the value is not set for the given curveId. /// @dev The first `limit` keys for the Node Operator with the given `curveId` will be placed in the priority queue. /// @param curveId Curve Id to get priority queue limit for /// @return limit Priority queue limit From 0f1877bb16292f2fa17c0addb5a5e793a8c497d7 Mon Sep 17 00:00:00 2001 From: Dmitry Gusakov Date: Mon, 13 Jan 2025 10:50:03 +0100 Subject: [PATCH 6/6] chore: Review fixes --- src/CSPerksRegistry.sol | 11 +++++++--- test/CSPerksRegistry.t.sol | 44 +++++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/CSPerksRegistry.sol b/src/CSPerksRegistry.sol index eea90d7a..0d498fd4 100644 --- a/src/CSPerksRegistry.sol +++ b/src/CSPerksRegistry.sol @@ -41,6 +41,8 @@ contract CSPerksRegistry is ) external onlyRole(DEFAULT_ADMIN_ROLE) { if (keyPivots.length + 1 != rewardShares.length) revert InvalidRewardShareData(); + if (keyPivots.length > 0 && keyPivots[0] == 0) + revert InvalidRewardShareData(); if (keyPivots.length > 1) { for (uint256 i = 0; i < keyPivots.length - 1; ++i) { if (keyPivots[i] >= keyPivots[i + 1]) @@ -78,15 +80,18 @@ contract CSPerksRegistry is uint256[] calldata performanceLeeways ) external onlyRole(DEFAULT_ADMIN_ROLE) { if (keyPivots.length + 1 != performanceLeeways.length) - revert InvalidRewardShareData(); + revert InvalidPerformanceLeewayData(); + if (keyPivots.length > 0 && keyPivots[0] == 0) + revert InvalidPerformanceLeewayData(); if (keyPivots.length > 1) { for (uint256 i = 0; i < keyPivots.length - 1; ++i) { if (keyPivots[i] >= keyPivots[i + 1]) - revert InvalidRewardShareData(); + revert InvalidPerformanceLeewayData(); } } for (uint256 i = 0; i < performanceLeeways.length; ++i) { - if (performanceLeeways[i] > MAX_BP) revert InvalidRewardShareData(); + if (performanceLeeways[i] > MAX_BP) + revert InvalidPerformanceLeewayData(); } _performanceLeewayPivotsData[curveId] = keyPivots; _performanceLeewayValuesData[curveId] = performanceLeeways; diff --git a/test/CSPerksRegistry.t.sol b/test/CSPerksRegistry.t.sol index b1542ce4..2e587e37 100644 --- a/test/CSPerksRegistry.t.sol +++ b/test/CSPerksRegistry.t.sol @@ -118,6 +118,22 @@ contract CSPerksRegistryRewardShareDataTest is CSPerksRegistryBaseTest { PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); } + function test_setRewardShareData_RevertWhen_first_pivot_is_zero() public { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](2); + keyPivots[0] = 0; + keyPivots[1] = 10; + + uint256[] memory rewardShares = new uint256[](3); + rewardShares[0] = 10000; + rewardShares[1] = 8000; + rewardShares[2] = 5000; + + vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); + vm.prank(admin); + PerksRegistry.setRewardShareData(curveId, keyPivots, rewardShares); + } + function test_setRewardShareData_RevertWhen_invalid_bp_values() public { uint256 curveId = 1; uint256[] memory keyPivots = new uint256[](1); @@ -250,7 +266,7 @@ contract CSPerksRegistryPerformanceLeewayDataTest is CSPerksRegistryBaseTest { performanceLeeways[0] = 500; performanceLeeways[1] = 400; - vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidPerformanceLeewayData.selector); vm.prank(admin); PerksRegistry.setPerformanceLeewayData( curveId, @@ -272,7 +288,29 @@ contract CSPerksRegistryPerformanceLeewayDataTest is CSPerksRegistryBaseTest { performanceLeeways[1] = 400; performanceLeeways[2] = 300; - vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidPerformanceLeewayData.selector); + vm.prank(admin); + PerksRegistry.setPerformanceLeewayData( + curveId, + keyPivots, + performanceLeeways + ); + } + + function test_setPerformanceLeewayData_RevertWhen_first_pivot_is_zero() + public + { + uint256 curveId = 1; + uint256[] memory keyPivots = new uint256[](2); + keyPivots[0] = 0; + keyPivots[1] = 10; + + uint256[] memory performanceLeeways = new uint256[](3); + performanceLeeways[0] = 500; + performanceLeeways[1] = 400; + performanceLeeways[2] = 300; + + vm.expectRevert(ICSPerksRegistry.InvalidPerformanceLeewayData.selector); vm.prank(admin); PerksRegistry.setPerformanceLeewayData( curveId, @@ -292,7 +330,7 @@ contract CSPerksRegistryPerformanceLeewayDataTest is CSPerksRegistryBaseTest { performanceLeeways[0] = 50000; performanceLeeways[1] = 400; - vm.expectRevert(ICSPerksRegistry.InvalidRewardShareData.selector); + vm.expectRevert(ICSPerksRegistry.InvalidPerformanceLeewayData.selector); vm.prank(admin); PerksRegistry.setPerformanceLeewayData( curveId,