From 0ab6efbdbde87cd4fc710939ffa5ceb0e449ae39 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 17:07:44 +0800 Subject: [PATCH 1/8] fixed:Missing operator status validation --- src/iBTC_NetworkMiddleware.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index ac36750..4617c0a 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -369,6 +369,10 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade // STAKE AND OPS // //////////////////////////////////////////////////////////////// function getOperatorStake(address operator, uint48 epoch) public view returns (uint256 stake) { + if (!operators.contains(operator)) { + revert OperatorNotRegistred(); + } + if (totalStakeCached[epoch]) { return operatorStakeCache[epoch][operator]; } From cb009b583824aa8ad07dcc55dbcc470d964e7d88 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 17:13:52 +0800 Subject: [PATCH 2/8] Ignore return value --- src/libraries/MapWithTimeData.sol | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libraries/MapWithTimeData.sol b/src/libraries/MapWithTimeData.sol index 934be93..7524d34 100644 --- a/src/libraries/MapWithTimeData.sol +++ b/src/libraries/MapWithTimeData.sol @@ -11,6 +11,7 @@ library MapWithTimeData { error AlreadyAdded(); error NotEnabled(); error AlreadyEnabled(); + error SetOperationFailed(); uint256 private constant ENABLED_TIME_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFF; uint256 private constant DISABLED_TIME_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFF << 48; @@ -29,7 +30,10 @@ library MapWithTimeData { } value |= uint256(Time.timestamp()) << 48; - self.set(addr, value); + bool success = self.set(addr, value); + if (!success) { + revert SetOperationFailed(); + } } function enable(EnumerableMap.AddressToUintMap storage self, address addr) internal { @@ -39,8 +43,10 @@ library MapWithTimeData { revert AlreadyEnabled(); } - value = uint256(Time.timestamp()); - self.set(addr, value); + bool success = self.set(addr, value); + if (!success) { + revert SetOperationFailed(); + } } function atWithTimes( From a53b8eb793394be6cd0689c32719ed867c41f582 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 17:18:02 +0800 Subject: [PATCH 3/8] Missing epoch strat timestamp validation --- src/iBTC_NetworkMiddleware.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index 4617c0a..6f12b70 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -387,6 +387,10 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade continue; } + if (epochStartTs < Time.timestamp()) { + revert TooOldEpoch(); + } + for (uint96 j = 0; j < subnetworksCnt; ++j) { stake += IBaseDelegator(IVault(vault).delegator()).stakeAt( NETWORK.subnetwork(j), operator, epochStartTs, new bytes(0) @@ -422,6 +426,10 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade continue; } + if (epochStartTs < Time.timestamp()) { + revert TooOldEpoch(); + } + bytes32 key = getOperatorKeyAt(operator, epochStartTs); if (key == bytes32(0)) { continue; From d85c381e56d1c83636ee88538ab457730e88f071 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 18:53:05 +0800 Subject: [PATCH 4/8] fixed: deleted some unecessary changes, which trigger more bugs --- src/iBTC_NetworkMiddleware.sol | 41 ++++++++++++++++++++----------- src/libraries/MapWithTimeData.sol | 22 ++++++++++------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index 6f12b70..389208d 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -99,15 +99,26 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade //////////////////////////////////////////////////////////////// // EVENTS // //////////////////////////////////////////////////////////////// + event OperatorRegistered(address indexed operator, bytes32 key, uint256 timestamp); + event OperatorKeyUpdated(address indexed operator, bytes32 key, uint256 timestamp); + event OperatorPaused(address indexed operator, uint256 timestamp); + event OperatorUnpaused(address indexed operator, uint256 timestamp); + event OperatorUnregistered(address indexed operator, uint256 timestamp); + event VaultRegistered(address indexed vault, uint256 timestamp); + event VaultPaused(address indexed vault, uint256 timestamp); + event VaultUnpaused(address indexed vault, uint256 timestamp); + event VaultUnregistered(address indexed vault, uint256 timestamp); + event SubnetworksCntSet(uint256 subnetworksCnt, uint256 timestamp); + event RewardTokenSet(address rewardToken, uint256 timestamp); + event StakerRewardsSet(address stakerRewards, uint256 timestamp); + event OperatorRewardsSet(address operatorRewards, uint256 timestamp); event StakerRewardsDistributed(uint48 indexed epoch, uint256 rewardAmount, uint256 totalStake, uint256 timestamp); event OperatorRewardsDistributed(uint48 indexed epoch, uint256 rewardAmount, uint256 timestamp); - event RewardTokenSet(address rewardToken); - event StakerRewardsSet(address stakerRewards); - event OperatorRewardsSet(address operatorRewards); //////////////////////////////////////////////////////////////// // MODIFIERS // //////////////////////////////////////////////////////////////// + modifier updateStakeCache( uint48 epoch ) { @@ -250,6 +261,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade updateKey(operator, key); operators.add(operator); operators.enable(operator); + emit OperatorRegistered(operator, key, Time.timestamp()); } function updateOperatorKey(address operator, bytes32 key) external onlyOwner { @@ -258,18 +270,21 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade } updateKey(operator, key); + emit OperatorKeyUpdated(operator, key, Time.timestamp()); } function pauseOperator( address operator ) external onlyOwner { operators.disable(operator); + emit OperatorPaused(operator, Time.timestamp()); } function unpauseOperator( address operator ) external onlyOwner { operators.enable(operator); + emit OperatorUnpaused(operator, Time.timestamp()); } function unregisterOperator( @@ -282,6 +297,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade } operators.remove(operator); + emit OperatorUnregistered(operator, Time.timestamp()); } function registerVault( @@ -308,18 +324,21 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade vaults.add(vault); vaults.enable(vault); + emit VaultRegistered(vault, Time.timestamp()); } function pauseVault( address vault ) external onlyOwner { vaults.disable(vault); + emit VaultPaused(vault, Time.timestamp()); } function unpauseVault( address vault ) external onlyOwner { vaults.enable(vault); + emit VaultUnpaused(vault, Time.timestamp()); } function unregisterVault( @@ -332,6 +351,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade } vaults.remove(vault); + emit VaultUnregistered(vault, Time.timestamp()); } function setSubnetworksCnt( @@ -342,27 +362,28 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade } subnetworksCnt = _subnetworksCnt; + emit SubnetworksCntSet(_subnetworksCnt, Time.timestamp()); } function setRewardToken( address _rewardToken ) external onlyOwner { REWARD_TOKEN = _rewardToken; - emit RewardTokenSet(_rewardToken); + emit RewardTokenSet(_rewardToken, Time.timestamp()); } function setStakerRewards( address _stakerRewards ) external onlyOwner { STAKER_REWARDS = _stakerRewards; - emit StakerRewardsSet(_stakerRewards); + emit StakerRewardsSet(_stakerRewards, Time.timestamp()); } function setOperatorRewards( address _operatorRewards ) external onlyOwner { OPERATOR_REWARDS = _operatorRewards; - emit OperatorRewardsSet(_operatorRewards); + emit OperatorRewardsSet(_operatorRewards, Time.timestamp()); } //////////////////////////////////////////////////////////////// @@ -387,10 +408,6 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade continue; } - if (epochStartTs < Time.timestamp()) { - revert TooOldEpoch(); - } - for (uint96 j = 0; j < subnetworksCnt; ++j) { stake += IBaseDelegator(IVault(vault).delegator()).stakeAt( NETWORK.subnetwork(j), operator, epochStartTs, new bytes(0) @@ -426,10 +443,6 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade continue; } - if (epochStartTs < Time.timestamp()) { - revert TooOldEpoch(); - } - bytes32 key = getOperatorKeyAt(operator, epochStartTs); if (key == bytes32(0)) { continue; diff --git a/src/libraries/MapWithTimeData.sol b/src/libraries/MapWithTimeData.sol index 7524d34..8cd5a53 100644 --- a/src/libraries/MapWithTimeData.sol +++ b/src/libraries/MapWithTimeData.sol @@ -11,7 +11,6 @@ library MapWithTimeData { error AlreadyAdded(); error NotEnabled(); error AlreadyEnabled(); - error SetOperationFailed(); uint256 private constant ENABLED_TIME_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFF; uint256 private constant DISABLED_TIME_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFF << 48; @@ -30,10 +29,12 @@ library MapWithTimeData { } value |= uint256(Time.timestamp()) << 48; - bool success = self.set(addr, value); - if (!success) { - revert SetOperationFailed(); - } + self.set(addr, value); + //NOTE: it fails with the success check + // bool success = self.set(addr, value); + // if (!success) { + // revert EnableOperationFailed(); + // } } function enable(EnumerableMap.AddressToUintMap storage self, address addr) internal { @@ -43,10 +44,13 @@ library MapWithTimeData { revert AlreadyEnabled(); } - bool success = self.set(addr, value); - if (!success) { - revert SetOperationFailed(); - } + value = uint256(Time.timestamp()); + self.set(addr, value); + //NOTE: it fails with the success check + // bool success = self.set(addr, value); + // if (!success) { + // revert EnableOperationFailed(); + // } } function atWithTimes( From a86b308b1790389c65d03856e998be7879cfe494 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 19:34:12 +0800 Subject: [PATCH 5/8] fixed spell miss --- src/iBTC_NetworkMiddleware.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index 389208d..7f36a36 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -41,11 +41,11 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade error NotVault(); error OperatorNotOptedIn(); - error OperatorNotRegistred(); + error OperatorNotRegistered(); error OperarorGracePeriodNotPassed(); - error OperatorAlreadyRegistred(); + error OperatorAlreadyRegistered(); - error VaultAlreadyRegistred(); + error VaultAlreadyRegistered(); error VaultEpochTooShort(); error VaultGracePeriodNotPassed(); @@ -247,7 +247,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade //////////////////////////////////////////////////////////////// function registerOperator(address operator, bytes32 key) external onlyOwner { if (operators.contains(operator)) { - revert OperatorAlreadyRegistred(); + revert OperatorAlreadyRegistered(); } if (!IRegistry(OPERATOR_REGISTRY).isEntity(operator)) { @@ -266,7 +266,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade function updateOperatorKey(address operator, bytes32 key) external onlyOwner { if (!operators.contains(operator)) { - revert OperatorNotRegistred(); + revert OperatorNotRegistered(); } updateKey(operator, key); @@ -304,7 +304,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade address vault ) external onlyOwner { if (vaults.contains(vault)) { - revert VaultAlreadyRegistred(); + revert VaultAlreadyRegistered(); } if (!IRegistry(VAULT_REGISTRY).isEntity(vault)) { @@ -391,7 +391,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade //////////////////////////////////////////////////////////////// function getOperatorStake(address operator, uint48 epoch) public view returns (uint256 stake) { if (!operators.contains(operator)) { - revert OperatorNotRegistred(); + revert OperatorNotRegistered(); } if (totalStakeCached[epoch]) { From 4a780cea668d20917241cce0c4b3fd396791a934 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 19:36:18 +0800 Subject: [PATCH 6/8] fixed spell miss --- src/iBTC_NetworkMiddleware.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index 7f36a36..1dee45e 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -42,7 +42,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade error OperatorNotOptedIn(); error OperatorNotRegistered(); - error OperarorGracePeriodNotPassed(); + error OperatorGracePeriodNotPassed(); error OperatorAlreadyRegistered(); error VaultAlreadyRegistered(); @@ -293,7 +293,7 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade (, uint48 disabledTime) = operators.getTimes(operator); if (disabledTime == 0 || disabledTime + SLASHING_WINDOW > Time.timestamp()) { - revert OperarorGracePeriodNotPassed(); + revert OperatorGracePeriodNotPassed(); } operators.remove(operator); From 4c8b9d603c280bc55779f1196532c7b3c258f3db Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 23 Jan 2025 23:05:16 +0800 Subject: [PATCH 7/8] ignore success check --- src/libraries/MapWithTimeData.sol | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/libraries/MapWithTimeData.sol b/src/libraries/MapWithTimeData.sol index 8cd5a53..934be93 100644 --- a/src/libraries/MapWithTimeData.sol +++ b/src/libraries/MapWithTimeData.sol @@ -30,11 +30,6 @@ library MapWithTimeData { value |= uint256(Time.timestamp()) << 48; self.set(addr, value); - //NOTE: it fails with the success check - // bool success = self.set(addr, value); - // if (!success) { - // revert EnableOperationFailed(); - // } } function enable(EnumerableMap.AddressToUintMap storage self, address addr) internal { @@ -46,11 +41,6 @@ library MapWithTimeData { value = uint256(Time.timestamp()); self.set(addr, value); - //NOTE: it fails with the success check - // bool success = self.set(addr, value); - // if (!success) { - // revert EnableOperationFailed(); - // } } function atWithTimes( From 1f59ff523f43369c539f80d2fcd515cb8ad080e0 Mon Sep 17 00:00:00 2001 From: scolear Date: Fri, 24 Jan 2025 13:37:22 +0100 Subject: [PATCH 8/8] fix: revert operator check --- src/iBTC_NetworkMiddleware.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index 1dee45e..f4a2ef2 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -390,10 +390,6 @@ contract NetworkMiddleware is Initializable, SimpleKeyRegistry32, OwnableUpgrade // STAKE AND OPS // //////////////////////////////////////////////////////////////// function getOperatorStake(address operator, uint48 epoch) public view returns (uint256 stake) { - if (!operators.contains(operator)) { - revert OperatorNotRegistered(); - } - if (totalStakeCached[epoch]) { return operatorStakeCache[epoch][operator]; }