Skip to content

Latest commit

 

History

History
65 lines (41 loc) · 4.15 KB

068.md

File metadata and controls

65 lines (41 loc) · 4.15 KB

Scruffy Gingerbread Cormorant

Medium

Governance Jailing Bypass due to Sequence Order Violation in Jail/Unjail Events

Summary

The lack of proper sequencing of jail and unjail events will cause governance-initiated jailing to be ineffective for finality providers as unjail events will override jail events regardless of their intended order as per the Babylon chain transaction sequencing.

Root Cause

In ProcessAllPowerDistUpdateEvents function , the code processes all jail and unjail events by category rather than respecting their Babylon chain transaction sequencing. Specifically, in https://github.com/sherlock-audit/2024-12-babylon/blob/main/babylon/x/finality/keeper/power_dist_change.go#L277-L287 the following code applies jail and unjail statuses without respecting sequence:

// set IsJailed to be true if the fp is jailed
if _, ok := jailedFPs[fpBTCPKHex]; ok {
    fp.IsJailed = true
}

// set IsJailed to be false if the fp is unjailed
if _, ok := unjailedFPs[fpBTCPKHex]; ok {
    fp.IsJailed = false
}

Since the unjail check is applied after the jail check in the same iteration, an unjail event will always override a jail event for the same finality provider, regardless of message that eventually emitted these events (ResumeFinalityProposal OR UnjailFinalityProvider in finality/keeper/msg_server.go ) had the higher or lower sequence number.

In typical case, having jail and unjail events for same finality provider is impossible for the same block as unjailing is feasible only after certain wait period post jailing and jailing also needs liveness across few blocks, which gets reset on unjailing. However in case of Babylon there is a governance mechanism which can jail finality provider at any time and does not check the current jailed status - HandleResumeFinalityProposal - which attempts to jail finality providers in order to reduce their voting power for past blocks and resume finality processing from a halting height. Although both the unjail message UnjailFinalityProvider and the governance proposal's ResumeFinalityProposal are ordered by cosmos chain, that should determine their processing order, the current implementation ignores this order while processing the corresponding events in ProcessAllPowerDistUpdateEvents.

Internal Pre-conditions

NA

External Pre-conditions

NA

Attack Path

  1. A finality provider is jailed for missing blocks due to regular liveness checks
  2. The finality provider serves their jail time and becomes eligible for unjail
  3. However, finality has halted due to their votes being missing starting at a halting height even before the finality provider was jailed
  4. The finality provider submits an unjail message to return to active status
  5. Governance sends ResumeFinalityProposal to jail certain finality providers (including this one) to resume finality by removing their votes. Governance may not be able to exclude this finality provider from jailed list as it might be necessary to reach quorum at the halting height.
  6. The HandleResumeFinalityProposal function is called and tries to jail the specified finality providers for an extended period (JailedUntil = currentTime.Add(params.JailDuration))
  7. During the next update cycle, ProcessAllPowerDistUpdateEvents is called which processes both jail and unjail events
  8. Even though the finality provider was intentionally jailed by governance with a potentially higher sequence number, the unjail message is processed in the same batch
  9. The unjail check happens after the jail check, setting IsJailed = false and effectively undoing the governance-initiated jail action
  10. The finality provider remains part of voting power distribution, contrary to the governance decision.

Impact

The finality provider is incorrectly included in consensus with voting power while it should have remained jailed until the new, extended jail duration set by governance (JailedUntil = currentTime.Add(params.JailDuration)). This premature release bypasses the governance-imposed jailing intended to ensure network stability during finality recovery and may result in chain halt as quorum may not be reached.

PoC

No response

Mitigation

No response