Platform: Code4rena
Start Date: 10/05/2024
Pot Size: $300,500 USDC
Total HM: 4
Participants: 27
Period: 17 days
Judge: Picodes
Total Solo HM: 1
Id: 375
League: ETH
Rank: 24/27
Findings: 1
Award: $0.00
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Sathish9098
Also found by: Audinarey, Dup1337, K42, KupiaSec, LessDupes, Rhaydden, SpicyMeatball, Takarez, ZanyBonzy, bronze_pickaxe, carlitox477, dontonka, forgebyola, fyamf, guhu95, hihen, josephdara, ladboy233, slvDev, twcctop, xuwinnie, zanderbyte
0 USDC - $0.00
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/rollup/BOLDUpgradeAction.sol#L341-#L363 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/rollup/RollupCore.sol#L274-#L279
During the process of upgrading the rollup contract, there exists a potential issue where the number of stakers exceeds the expected limit by the protocol. The function responsible for refunding existing stakers, pausing and upgrading the old rollup, uses a check to ensure the stakers count does not exceeds 50. However the rollup itself does not include any preventative measures to ensure that the number of stakers does not surpass this limit when creating a new stakes RollupCore.createnewStake()
. As a result, if the number of stakers exceeds 50, only the first 50 stakers will be force refunded, while the rest may not receive their refunds.
As I understand the expectations are that the number of stakers will not get close to this number, nothings prevents this to happen. Stakers beyond the initial 50 may not receive their refunds during the upgrade process, leading to potential financial losses and dissatisfaction among affected stakeholders. Failure to ensure fair treatment of all stakers could erode trust in the smart contract system and damage the project's reputation within the community.
The provided code snippet illustrates the logic for handling the upgrade process and force refunding the stakers. It is shown how the stakerCount
is hardcoded to 50 if it exceeds that number:
/// @dev Refund the existing stakers, pause and upgrade the current rollup to /// allow them to withdraw after pausing function cleanupOldRollup() private { IOldRollupAdmin(address(OLD_ROLLUP)).pause(); uint64 stakerCount = ROLLUP_READER.stakerCount(); // since we for-loop these stakers we set an arbitrary limit - we dont // expect any instances to have close to this number of stakers if (stakerCount > 50) { @> stakerCount = 50; } for (uint64 i = 0; i < stakerCount; i++) { address stakerAddr = ROLLUP_READER.getStakerAddress(i); OldStaker memory staker = ROLLUP_READER.getStaker(stakerAddr); if (staker.isStaked && staker.currentChallenge == 0) { address[] memory stakersToRefund = new address[](1); stakersToRefund[0] = stakerAddr; IOldRollupAdmin(address(OLD_ROLLUP)).forceRefundStaker(stakersToRefund); } } // upgrade the rollup to one that allows validators to withdraw even whilst paused DoubleLogicUUPSUpgradeable(address(OLD_ROLLUP)).upgradeSecondaryTo(IMPL_PATCHED_OLD_ROLLUP_USER); }
Manual review
Implementing an upper bound for stakers when creating a new stake in the RollupCore::createNewStake()
function can help mitigate the risk of exceeding the staker limit during rollup upgrades
Invalid Validation
#0 - c4-judge
2024-06-05T08:21:20Z
Picodes changed the severity to QA (Quality Assurance)
#1 - c4-judge
2024-06-08T16:43:10Z
This previously downgraded issue has been upgraded by Picodes
#2 - c4-judge
2024-06-08T16:43:23Z
Picodes changed the severity to QA (Quality Assurance)
#3 - c4-judge
2024-06-10T17:24:01Z
Picodes marked the issue as grade-b