#38460 [BC-Low] The coordinator can set a higher BTC tx fee than the current network to make users t
Submitted on Jan 3rd 2025 at 22:44:27 UTC by @f4lc0n for Attackathon | Stacks
Report ID: #38460
Report Type: Blockchain/DLT
Report severity: Low
Target: https://github.com/stacks-network/sbtc/tree/immunefi_attackaton_0.9/signer
Impacts:
Direct loss of funds
Description
Brief/Intro
When a signer acts as a coordinator, he will initiate BTC transactions to transfer the deposited BTC to the signer's multi-wallet.
The problem now is that signers do not check the fee_rate of the BTC transaction set by the coordinator. Therefore, a malicious signer can set a higher fee_rate to make users pay more fees.
Vulnerability Details
The signer/src/bitcoin/validation.rs::construct_package_sighashes code is as follows.
pub async fn construct_package_sighashes<C>(
&self,
ctx: &C,
btc_ctx: &BitcoinTxContext,
) -> Result<Vec<BitcoinTxValidationData>, Error>
where
C: Context + Send + Sync,
{
let cache = self.fetch_all_reports(&ctx.get_storage(), btc_ctx).await?;
self.pre_validation(ctx, &cache).await?;
let signer_utxo = ctx
.get_storage()
.get_signer_utxo(&btc_ctx.chain_tip)
.await?
.ok_or(Error::MissingSignerUtxo)?;
let mut signer_state = SignerBtcState {
fee_rate: self.fee_rate,
utxo: signer_utxo,
public_key: bitcoin::XOnlyPublicKey::from(btc_ctx.aggregate_key),
last_fees: self.last_fees,
magic_bytes: [b'T', b'3'], //TODO(#472): Use the correct magic bytes.
};
let mut outputs = Vec::new();
for requests in self.request_package.iter() {
let (output, new_signer_state) = self
.construct_tx_sighashes(ctx, btc_ctx, requests, signer_state, &cache)
.await?;
signer_state = new_signer_state;
outputs.push(output);
}
Ok(outputs)
}It directly uses the fee_rate passed by the coordinator without checking it. Then the coordinator can send a fee_rate higher than the current main network to make users to consume more fees.
Fix
Check the fee_rate provided by the coordinator to make sure it is not much higher than the current mainnet.
Impact Details
Users usually set a transaction fee higher than the current mainnet to ensure that their deposits are executed. The remaining transaction fees will normally be returned to the user in the form of sBTC. Attackers can use this bug to make users lose this part of the redundant transaction fees.
However, the user's loss is limited, so I think the bug is Medium.
References
None
Proof of Concept
Proof of Concept
Base on: https://github.com/stacks-network/sbtc/releases/tag/0.0.9-rc4
Patch
signer/src/config/mod.rs, add attacker flag configPatch
signer/src/main.rs, load attacker flagPatch
docker/docker-compose.yml, add attacker flagPatch
signer/src/transaction_coordinator.rs, add attack action. It will set 10xfee_rate.Run docker
Add this code to
signer/src/bin/poc9.rsPatch
signer/Cargo.toml, addpoc9binWaiting for the sBTC contract to be deployed. Then run the
poc9tool. It will send 40 BTC to the signers BTC address and trigger deposits every 10 seconds.Wait until the trigger the coordinator is sbtc-signer-3.
In BTC explorer, you will find that the transaction initiated by sbtc-signer-3 consumes more transaction fees (x10) than other transactions.
Last updated
Was this helpful?