Skip to content

Commit

Permalink
Interfaces chore (#368)
Browse files Browse the repository at this point in the history
Co-authored-by: Vladimir Gorkavenko <[email protected]>
  • Loading branch information
skhomuti and vgorkavenko authored Dec 4, 2024
1 parent 195ec64 commit 82dd433
Show file tree
Hide file tree
Showing 33 changed files with 1,557 additions and 1,152 deletions.
189 changes: 36 additions & 153 deletions src/CSAccounting.sol

Large diffs are not rendered by default.

28 changes: 4 additions & 24 deletions src/CSEarlyAdoption.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ contract CSEarlyAdoption is ICSEarlyAdoption {

mapping(address => bool) internal _consumedAddresses;

event Consumed(address indexed member);

error InvalidProof();
error AlreadyConsumed();
error InvalidTreeRoot();
error InvalidCurveId();
error ZeroModuleAddress();
error SenderIsNotModule();

constructor(bytes32 treeRoot, uint256 curveId, address module) {
if (treeRoot == bytes32(0)) revert InvalidTreeRoot();
if (curveId == 0) revert InvalidCurveId();
Expand All @@ -35,10 +26,7 @@ contract CSEarlyAdoption is ICSEarlyAdoption {
MODULE = module;
}

/// @notice Validate EA eligibility proof and mark it as consumed
/// @dev Called only by the module
/// @param member Address to be verified alongside the proof
/// @param proof Merkle proof of EA eligibility
/// @inheritdoc ICSEarlyAdoption
function consume(address member, bytes32[] calldata proof) external {
if (msg.sender != MODULE) revert SenderIsNotModule();
if (_consumedAddresses[member]) revert AlreadyConsumed();
Expand All @@ -47,28 +35,20 @@ contract CSEarlyAdoption is ICSEarlyAdoption {
emit Consumed(member);
}

/// @notice Check if the address has already consumed EA access
/// @param member Address to check
/// @return Consumed flag
/// @inheritdoc ICSEarlyAdoption
function isConsumed(address member) external view returns (bool) {
return _consumedAddresses[member];
}

/// @notice Check is the address is eligible to consume EA access
/// @param member Address to check
/// @param proof Merkle proof of EA eligibility
/// @return Boolean flag if the proof is valid or not
/// @inheritdoc ICSEarlyAdoption
function verifyProof(
address member,
bytes32[] calldata proof
) public view returns (bool) {
return MerkleProof.verifyCalldata(proof, TREE_ROOT, hashLeaf(member));
}

/// @notice Get a hash of a leaf in EA Merkle tree
/// @param member EA member address
/// @return Hash of the leaf
/// @dev Double hash the leaf to prevent second preimage attacks
/// @inheritdoc ICSEarlyAdoption
function hashLeaf(address member) public pure returns (bytes32) {
return keccak256(bytes.concat(keccak256(abi.encode(member))));
}
Expand Down
56 changes: 6 additions & 50 deletions src/CSFeeDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,34 +40,6 @@ contract CSFeeDistributor is
/// @notice Total Amount of stETH shares available for claiming by NOs
uint256 public totalClaimableShares;

/// @dev Emitted when fees are distributed
event FeeDistributed(uint256 indexed nodeOperatorId, uint256 shares);

/// @dev Emitted when distribution data is updated
event DistributionDataUpdated(
uint256 totalClaimableShares,
bytes32 treeRoot,
string treeCid
);

/// @dev Emitted when distribution log is updated
event DistributionLogUpdated(string logCid);

error ZeroAccountingAddress();
error ZeroStEthAddress();
error ZeroAdminAddress();
error ZeroOracleAddress();
error NotAccounting();
error NotOracle();

error InvalidTreeRoot();
error InvalidTreeCID();
error InvalidLogCID();
error InvalidShares();
error InvalidProof();
error FeeSharesDecrease();
error NotEnoughShares();

constructor(address stETH, address accounting, address oracle) {
if (accounting == address(0)) revert ZeroAccountingAddress();
if (oracle == address(0)) revert ZeroOracleAddress();
Expand All @@ -87,11 +59,7 @@ contract CSFeeDistributor is
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}

/// @notice Distribute fees to the Accounting in favor of the Node Operator
/// @param nodeOperatorId ID of the Node Operator
/// @param shares Total Amount of stETH shares earned as fees
/// @param proof Merkle proof of the leaf
/// @return sharesToDistribute Amount of stETH shares distributed
/// @inheritdoc ICSFeeDistributor
function distributeFees(
uint256 nodeOperatorId,
uint256 shares,
Expand All @@ -117,7 +85,7 @@ contract CSFeeDistributor is
emit FeeDistributed(nodeOperatorId, sharesToDistribute);
}

/// @notice Receive the data of the Merkle tree from the Oracle contract and process it
/// @inheritdoc ICSFeeDistributor
function processOracleReport(
bytes32 _treeRoot,
string calldata _treeCid,
Expand Down Expand Up @@ -163,10 +131,7 @@ contract CSFeeDistributor is
emit DistributionLogUpdated(_logCid);
}

/// @notice Recover ERC20 tokens (except for stETH) from the contract
/// @dev Any stETH transferred to feeDistributor is treated as a donation and can not be recovered
/// @param token Address of the ERC20 token to recover
/// @param amount Amount of the ERC20 token to recover
/// @inheritdoc AssetRecoverer
function recoverERC20(address token, uint256 amount) external override {
_onlyRecoverer();
if (token == address(STETH)) {
Expand All @@ -175,17 +140,12 @@ contract CSFeeDistributor is
AssetRecovererLib.recoverERC20(token, amount);
}

/// @notice Get the Amount of stETH shares that are pending to be distributed
/// @return pendingShares Amount shares that are pending to distribute
/// @inheritdoc ICSFeeDistributor
function pendingSharesToDistribute() external view returns (uint256) {
return STETH.sharesOf(address(this)) - totalClaimableShares;
}

/// @notice Get the Amount of stETH shares that can be distributed in favor of the Node Operator
/// @param nodeOperatorId ID of the Node Operator
/// @param shares Total Amount of stETH shares earned as fees
/// @param proof Merkle proof of the leaf
/// @return sharesToDistribute Amount of stETH shares that can be distributed
/// @inheritdoc ICSFeeDistributor
function getFeesToDistribute(
uint256 nodeOperatorId,
uint256 shares,
Expand All @@ -210,11 +170,7 @@ contract CSFeeDistributor is
}
}

/// @notice Get a hash of a leaf
/// @param nodeOperatorId ID of the Node Operator
/// @param shares Amount of stETH shares
/// @return Hash of the leaf
/// @dev Double hash the leaf to prevent second preimage attacks
/// @inheritdoc ICSFeeDistributor
function hashLeaf(
uint256 nodeOperatorId,
uint256 shares
Expand Down
53 changes: 9 additions & 44 deletions src/CSFeeOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,16 @@ import { BaseOracle } from "./lib/base-oracle/BaseOracle.sol";

import { ICSFeeDistributor } from "./interfaces/ICSFeeDistributor.sol";
import { AssetRecoverer } from "./abstract/AssetRecoverer.sol";
import { IAssetRecovererLib } from "./lib/AssetRecovererLib.sol";
import { ICSFeeOracle } from "./interfaces/ICSFeeOracle.sol";

contract CSFeeOracle is
ICSFeeOracle,
BaseOracle,
PausableUntil,
AssetRecoverer,
IAssetRecovererLib
AssetRecoverer
{
/// @notice No assets are stored in the contract

struct ReportData {
/// @dev Version of the oracle consensus rules. Current version expected
/// by the oracle can be obtained by calling getConsensusVersion().
uint256 consensusVersion;
/// @dev Reference slot for which the report was calculated. If the slot
/// contains a block, the state being reported should include all state
/// changes resulting from that block. The epoch containing the slot
/// should be finalized prior to calculating the report.
uint256 refSlot;
/// @notice Merkle Tree root.
bytes32 treeRoot;
/// @notice CID of the published Merkle tree.
string treeCid;
/// @notice CID of the file with log of the last frame reported.
string logCid;
/// @notice Total amount of fees distributed in the report.
uint256 distributed;
}

/// @notice An ACL role granting the permission to manage the contract (update variables).
bytes32 public constant CONTRACT_MANAGER_ROLE =
keccak256("CONTRACT_MANAGER_ROLE");
Expand All @@ -62,16 +43,6 @@ contract CSFeeOracle is
/// performance over the network computed by the off-chain oracle.
uint256 public avgPerfLeewayBP;

/// @dev Emitted when a new fee distributor contract is set
event FeeDistributorContractSet(address feeDistributorContract);

event PerfLeewaySet(uint256 valueBP);

error ZeroAdminAddress();
error ZeroFeeDistributorAddress();
error InvalidPerfLeeway();
error SenderNotAllowed();

constructor(
uint256 secondsPerSlot,
uint256 genesisTime
Expand All @@ -94,25 +65,21 @@ contract CSFeeOracle is
_setPerformanceLeeway(_avgPerfLeewayBP);
}

/// @notice Set a new fee distributor contract
/// @param feeDistributorContract Address of the new fee distributor contract
/// @inheritdoc ICSFeeOracle
function setFeeDistributorContract(
address feeDistributorContract
) external onlyRole(CONTRACT_MANAGER_ROLE) {
_setFeeDistributorContract(feeDistributorContract);
}

/// @notice Set a new performance threshold value in basis points
/// @param valueBP performance threshold in basis points
/// @inheritdoc ICSFeeOracle
function setPerformanceLeeway(
uint256 valueBP
) external onlyRole(CONTRACT_MANAGER_ROLE) {
_setPerformanceLeeway(valueBP);
}

/// @notice Submit the data for a committee report
/// @param data Data for a committee report
/// @param contractVersion Version of the oracle consensus rules
/// @inheritdoc ICSFeeOracle
function submitReportData(
ReportData calldata data,
uint256 contractVersion
Expand All @@ -129,19 +96,17 @@ contract CSFeeOracle is
_handleConsensusReportData(data);
}

/// @notice Resume accepting oracle reports
/// @inheritdoc ICSFeeOracle
function resume() external onlyRole(RESUME_ROLE) {
_resume();
}

/// @notice Pause accepting oracle reports for a `duration` seconds
/// @param duration Duration of the pause in seconds
/// @inheritdoc ICSFeeOracle
function pauseFor(uint256 duration) external onlyRole(PAUSE_ROLE) {
_pauseFor(duration);
}

/// @notice Pause accepting oracle reports until a timestamp
/// @param pauseUntilInclusive Timestamp until which the oracle reports are paused
/// @inheritdoc ICSFeeOracle
function pauseUntil(
uint256 pauseUntilInclusive
) external onlyRole(PAUSE_ROLE) {
Expand Down
Loading

0 comments on commit 82dd433

Please sign in to comment.