Stale Gingerbread Rat
Medium
File: babylon/btcstaking/staking.go
Issue Summary: Insufficient integer arithmetic validation in fee calculation will cause an economic vulnerability for the Babylon staking protocol as an attacker will craft slashing transactions with fees below the minimum required threshold, potentially disrupting transaction processing and economic security mechanisms.
Detailed Description:
The vulnerability exists in the validateSlashingTx
function where fee calculation does not adequately protect against near-minimum fee scenarios. By constructing a transaction with outputs that sum to just slightly less than the input value, an attacker can potentially create transactions with fees lower than the system's minimum fee requirement.
In [babylon/btcstaking/staking.go:393-396](https://github.com/sherlock-audit/2024-12-babylon/blob/main/babylon/btcstaking/staking.go#L393)
, the missing explicit fee validation and direct subtraction of output sum from input value allows potential manipulation of transaction fee calculation, enabling transactions with fees below the minimum required threshold.
Here's the internal pre-conditions for this vulnerability:
Attacker needs to construct a slashing transaction where slashingTxOutSum
is just slightly less than stakingOutputValue
slashingTxMinFee
needs to be set to a specific value that can be marginally circumvented
The Bitcoin transaction validation logic must not have additional safeguards beyond the current fee calculation method
The staking transaction must have sufficient initial value to allow for near-zero fee manipulation
The Bitcoin transaction construction must support creating outputs with very precise values close to the input amount
For this vulnerability, the external pre-conditions could be:
Bitcoin network transaction fee market needs to allow low-fee transactions to be potentially included in a block Bitcoin mempool configuration on nodes must have lenient fee acceptance thresholds Block space utilization needs to be low enough to potentially allow near-minimum fee transactions Bitcoin network's transaction standardness rules must not automatically reject transactions with fees marginally below recommended minimums
These external pre-conditions describe the broader network and protocol environment that would enable the potential exploitation of the fee calculation vulnerability in the Bitcoin transaction construction. The conditions highlight how the effectiveness of the attack could depend on specific characteristics of the Bitcoin network's current state and transaction processing rules.
- Attacker creates a custom slashing transaction targeting a Bitcoin staking output
- Attacker calculates precise output values to make
slashingTxOutSum
marginally less thanstakingOutputValue
- Attacker constructs transaction outputs summing to just below the total input value
- Attacker exploits the fee calculation logic to create a transaction with fees below
slashingTxMinFee
- Attacker submits the slashing transaction to the Bitcoin network
- Transaction passes the initial validation in
validateSlashingTx
due to precise output value manipulation - Transaction potentially gets processed with lower than intended fees, disrupting economic security mechanisms
The Babylon staking protocol suffers potential economic disruption by losing the ability to enforce minimum transaction fees, which could lead to network congestion and reduced transaction processing reliability. Attackers can potentially create slashing transactions with fees below the intended minimum, undermining the economic security mechanisms of the Bitcoin staking protocol.
func ProveFeeEvasionVulnerability(
stakingOutputValue int64,
minimumFee int64,
) (*wire.MsgTx, error) {
// Create a mock slashing transaction
tx := wire.NewMsgTx(wire.TxVersion)
// Carefully craft outputs to be just below the total input value
mainOutputValue := stakingOutputValue - minimumFee - 1
// First output: Slashing destination (main portion of funds)
slashingPkScript := []byte{0x51} // Dummy script
tx.AddTxOut(wire.NewTxOut(mainOutputValue, slashingPkScript))
// Second output: Change output (tiny amount)
changePkScript := []byte{0x52} // Another dummy script
tx.AddTxOut(wire.NewTxOut(minimumFee - 1, changePkScript))
// Verify the total output is just 1 satoshi less than input
totalOutputSum := mainOutputValue + (minimumFee - 1)
fmt.Printf("Staking Output Value: %d\n", stakingOutputValue)
fmt.Printf("Total Output Sum: %d\n", totalOutputSum)
fmt.Printf("Fee Calculation: %d\n", stakingOutputValue - totalOutputSum)
// This transaction would technically pass the fee validation
// but with a fee less than the minimum required
return tx, nil
}
func TestFeeEvasionVulnerability() {
// Example with 1 BTC staking output and 10,000 satoshi minimum fee
stakingOutputValue := int64(100_000_000) // 1 BTC in satoshis
minimumFee := int64(10_000) // 10,000 satoshis
maliciousTx, err := ProveFeeEvasionVulnerability(
stakingOutputValue,
minimumFee,
)
if err != nil {
fmt.Println("Error creating transaction:", err)
return
}
// Demonstrate the vulnerability
fmt.Println("Malicious Transaction Created Successfully")
fmt.Println("Transaction Outputs:")
for i, out := range maliciousTx.TxOut {
fmt.Printf("Output %d: %d satoshis\n", i, out.Value)
}
}
No response