The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: low
Invalid

Confirmed stakers may be considered as pending on Arbitrum & lose out on rewards

Summary

distributeAssets() distributes rewards to confirmed stakers. It does so by first calling consolidatePendingStakes() which ensures that anyone who staked more than 24 hours (1 day) ago is eligible. The consolidatePendingStakes() function is used at multiple places inside the protocol.

function consolidatePendingStakes() private {
@----> uint256 deadline = block.timestamp - 1 days;
for (int256 i = 0; uint256(i) < pendingStakes.length; i++) {
PendingStake memory _stake = pendingStakes[uint256(i)];
if (_stake.createdAt < deadline) {
positions[_stake.holder].holder = _stake.holder;
positions[_stake.holder].TST += _stake.TST;
positions[_stake.holder].EUROs += _stake.EUROs;
deletePendingStake(uint256(i));
// pause iterating on loop because there has been a deletion. "next" item has same index
i--;
}
}
}

This deadline check however is not accurate as block.timestamp may return a past timestamp on Arbitrum and quite possibly on other L2 chains.

Vulnerability Details

As the arbitrum docs explain, the block.timestamp can return a time which is up to 24 hours earlier than the current time, which means it's possible that the block.timestamp has had the same value since the last 24 hours.

As mentioned, block timestamps are usually set based on the sequencer's clock. Because there's a possibility that the sequencer fails to post batches on the parent chain (for example, Ethereum) for a period of time, it should have the ability to slightly adjust the timestamp of the block to account for those delays and prevent any potential reorganisations of the chain.

Note:

To limit the degree to which the sequencer can adjust timestamps, some boundaries are set, currently to 24 hours earlier than the current time, and 1 hour in the future.

Consider this:

  • Alice stakes at real-world time Jan-08-2024 06:42:21 AM +UTC

  • Arbitrum block.timestamp is at Jan-08-2024 06:42:21 AM +UTC too

  • 24 hours pass

  • Real-world time is Jan-09-2024 06:42:21 AM +UTC

  • Arbitrum is lagging by 23 hours and hence outputs block.timestamp as Jan-08-2024 07:42:21 AM +UTC

Even though Alice should be a confirmed staker now, she is considered as pending by the function consolidatePendingStakes(). Any reward distribution she was eligible for when distributeAssets() is called, is missed out.

Impact

Staker misses out on rewards and is considered in "pending" status instead of "confirmed" status.

Tools Used

Manual review

Recommendations

We can consider making use of multiple external sources which can be checked to see if there is a huge mismatch between the block.timestamp values.

Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

informational/invalid

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.