Skip to content

Consensus quorum bug halts bridge at N%3==0 + gas overcharge ignoring MaxFeePerGas #287

Description

@siti280

Hi Push Chain team — reporting two issues found via manual source review of push-chain-node (x/uexecutor). Both reproducible from the code; no mainnet exploitation done. Posting publicly since no security contact / private advisory is enabled on the repo.

1) Quorum off-by-one (bridge liveness halt)

File: x/uexecutor/keeper/voting.go:33 (and :97 outbound)
votesNeeded := (VotesThresholdNumeratortotalValidators)/VotesThresholdDenominator + 1
With Numerator=2, Denominator=3, correct >2/3 quorum = ceil(2N/3), but code = floor(2N/3)+1.
When eligible validator count N is a multiple of 3 (3,6,9,12...), required votes = 100%.
One offline validator then blocks ALL inbound/outbound finalization -> bridge halt.
Fix: votesNeeded := (totalValidators
VotesThresholdNumerator + VotesThresholdDenominator - 1) / VotesThresholdDenominator (drop the +1). Add test for N=1..200.

2) Gas overcharge ignores MaxFeePerGas

File: x/uexecutor/keeper/fees.go CalculateGasCost (47-91)
lines 69-77 (EIP-1559 cap) are commented out -> effectiveGasPrice = baseFee only.
DeductGasFeesFromReceipt (line 137) burns baseFeegasUsed with no MaxFeePerGas check.
Since baseFee is validator-controlled, raising it overcharges users far above their signed cap.
Fix: re-enable effectiveGasPrice = min(baseFee+maxPriorityFeePerGas, maxFeePerGas); clamp gasCost to MaxFeePerGas
gasUsed in DeductGasFeesFromReceipt.

Happy to provide full PoC / clarify. Please advise on coordinated fix + disclosure. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions