Public randomness reset due to block-height overflow
Description
In the MsgCommitPubRandList
function, a finality provider (FP) is not allowed to modify a previously set block-height range under normal conditions. However, due to the lack of handling for uint64
overflow in block-height calculations, it is possible to reset public randomness for an already committed block-height range. This occurs when a very large starting height is used in combination with NumPubRand
, causing the computed range to wrap around and allowing a previously set range to be reset.
Despite this, in the GetTimestampedPubRandCommitForHeight
function inside AddFinalitySig
, an error is thrown if the epoch in which the public randomness was set has not been finalized. This prevents a malicious FP from avoiding private-key recovery when signing different blocks at the same height. However, the underlying issue remains and should be addressed.
Impact
An FP can bypass the intended restriction on modifying public randomness by exploiting uint64
overflow. While this does not currently allow an FP to avoid key recovery or manipulate signatures in finalized epochs, it could introduce inconsistencies in how public randomness is stored and referenced. This could complicate future protocol behavior and introduce unexpected vulnerabilities if additional functionality is built on top of this mechanism.
Recommendations
A check should be added in CommitPubRandList
to ensure that req.startHeight + req.NumPubRand
does not wrap around. One possible approach is to return an error if the condition req.startHeight < (req.startHeight + req.NumPubRand)
is not satisfied. This would prevent the range from resetting due to integer overflow.
Remediation
This issue has been acknowledged by Babylon Labs, and a fix was implemented in commit 159abe3e↗.
This was remediated by the above recommendation.