Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add CSPerksRegistry contract #374

Merged
merged 8 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ lib/
!src/lib
GAS.md
artifacts/
docs/
135 changes: 135 additions & 0 deletions src/CSPerksRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// SPDX-FileCopyrightText: 2024 Lido <[email protected]>
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.24;

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 CSPerksRegistry is
ICSPerksRegistry,
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 ICSPerksRegistry
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 > 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])
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 ICSPerksRegistry
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 ICSPerksRegistry
function setPerformanceLeewayData(

Check warning on line 77 in src/CSPerksRegistry.sol

View workflow job for this annotation

GitHub Actions / Linters

Function order is incorrect, external function can not go after external view function (line 62)
uint256 curveId,
uint256[] calldata keyPivots,
uint256[] calldata performanceLeeways
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (keyPivots.length + 1 != performanceLeeways.length)
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 InvalidPerformanceLeewayData();
}
}
for (uint256 i = 0; i < performanceLeeways.length; ++i) {
if (performanceLeeways[i] > MAX_BP)
revert InvalidPerformanceLeewayData();
}
_performanceLeewayPivotsData[curveId] = keyPivots;
_performanceLeewayValuesData[curveId] = performanceLeeways;

emit PerformanceLeewayDataSet(curveId);
}

/// @inheritdoc ICSPerksRegistry
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 ICSPerksRegistry
function setPriorityQueueLimit(
uint256 curveId,
uint256 limit
) external onlyRole(DEFAULT_ADMIN_ROLE) {
_priorityQueueLimits[curveId] = limit;
emit PriorityQueueLimitSet(curveId, limit);
}

/// @inheritdoc ICSPerksRegistry
function getPriorityQueueLimit(
uint256 curveId
) external view returns (uint256 limit) {
return _priorityQueueLimits[curveId];
}
}
86 changes: 86 additions & 0 deletions src/interfaces/ICSPerksRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-FileCopyrightText: 2024 Lido <[email protected]>
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.24;

interface ICSPerksRegistry {
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 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])
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 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])
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 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])
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 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])
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 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
function getPriorityQueueLimit(
uint256 curveId
) external view returns (uint256 limit);
}
Loading
Loading