Module: btcstaking
Description
The btcstaking module manages all aspects of finality providers (FPs) and BTC delegations within the Babylon chain. It provides functionalities to create FPs, delegate BTC, submit covenant signatures, handle unbonding, and periodically update the active sets of FPs and BTC delegations.
Messages
MsgCreateFinalityProvider
When a Babylon node receives MsgCreateFinalityProvider
, it does the following:
Validates a proof of possession (POP) signed by the BTC private key for the Babylon address
Ensures the requested commission rate is greater than the module parameter
MinCommissionRate
and does not exceed 100%Confirms that no existing FP uses the same BTC public key (
btc_pk
)
If these checks pass, a new FinalityProvider
object is created and stored.
MsgEditFinalityProvider
When a Babylon node receives MsgEditFinalityProvider
, it does the following:
Ensures the message signer is the staker address registered as the FP
Validates the new commission rate to be greater than
MinCommissionRate
and not exceed 100%
If valid, the node updates the stored FP information (commission rate and description).
MsgCreateBTCDelegation
The MsgCreateBTCDelegation
message is typically submitted via the btc-staker↗. Upon receiving this message, a Babylon node does the following:
Performs a POP by verifying a signature of the Babylon address made with the staker’s BTC private key
Computes the staking transaction (TX) hash from the provided staking TX data and ensures it does not duplicate any existing delegation
Checks that the target FP has not been slashed
Depending on whether the staking TX has been executed on the BTC network, one of two options applies:
For Staking TXs not yet executed on BTC,
StartHeight
andEndHeight
are set to 0.Or, for already executed staking TXs, a proof is attached, and the node sets
StartHeight
to the BTC block height of execution andEndHeight
to the BTC block height at which the delegation expires.
The node also verifies the following:
The submitted
UnbondingTime
matches theUnbondingTimeBlocks
parameter.The staking TX is valid based on the staker’s BTC-account public key, FP’s BTC public key, covenant committee public keys (meeting
CovenantQuorum
), staking duration, and BTC amount staked.No duplicate public keys exist among the staker, the FP, and the covenant committee.
Correct Taproot scripts (
timelockPathScript
,unbondingPathScript
,slashingPathScript
) are generated to form the Merklized script tree and final P2TR address.The staking TX includes an appropriate
TxOut
, referencing a Taproot script that enforces one of the timelock, unbonding, or slashing conditions.The timelock-script lock period is within the bounds
[MinStakingTimeBlocks, MaxStakingTimeBlocks]
.The BTC amount in the staking
TxOut
is within[MinStakingValueSat, MaxStakingValueSat]
.The slashing and unbonding TX references are valid and conform to the script checks and parameter constraints.
The unbonding fee (the difference between the staking TX amount and unbonding TX amount) matches
UnbondingFeeSat
.
If the staking TX has not been executed on BTC, an extra gas fee (DelegationCreationBaseGasFee
) is charged to prevent spam. Once all validations are complete, the delegation information is stored. If a valid BTC proof is attached, the event BTCDelegationStatus_EXPIRED
is scheduled for the delegation’s expiration. After collecting sufficient covenant committee signatures, the BTCDelegationStatus_ACTIVE
event is emitted.
MsgAddBTCDelegationInclusionProof
When a Babylon node receives MsgAddBTCDelegationInclusionProof
, it does the following:
Uses the provided staking TX hash to retrieve the corresponding delegation
Confirms the delegation meets the
CovenantQuorum
requirement for committee signaturesEnsures the delegation is not already in an unbonding state
Validates the submitted proof to confirm the staking TX has been included in a BTC block and sufficient time has elapsed for finalization (based on the latest BTC block height stored in the btclightclient module)
Ensures the staking TX was executed after the
MsgCreateBTCDelegation
submission for delegations that lacked an initial proof
If validated, the node schedules an event for when the delegation becomes active, based on the latest BTC block height and its calculated expiration time. Upon successful execution, the gas fee is refunded.
MsgAddCovenantSigs
The MsgAddCovenantSigs
message is typically submitted via covenant-emulator↗. When a Babylon node receives this message, it does the following:
Retrieves the delegation using the provided
StakingTxHash
Verifies the public key in the message is a recognized member of the covenant committee and has not already been used for this delegation or its unbonding
Ensures the delegation is in either an
UNBONDED
orEXPIRED
stateChecks that the number of
SlashingTxSigs
andSlashingUnbondingTxSigs
matches the number of FPs referenced by the delegationValidates the Schnorr signatures for the covenant, including the covenant adaptor signatures for slashing and unbonding transactions
If all validations pass, the node updates the delegation with the new signatures. Gas fees incurred during execution are refunded.
MsgBTCUndelegate
The MsgBTCUndelegate
message is typically submitted via vigilante — btcstaking-tracker↗. When a Babylon node receives this message, it does the following:
Retrieves the delegation using the staking TX hash and ensures it is in the
ACTIVE
stateValidates the submitted unbonding TX data and proof to confirm it has been executed on the BTC network
Emits an
EventBTCDelgationUnbondedEarly
event if the unbonding TX matches the one provided in the originalMsgCreateBTCDelegation
— otherwise checks whether the submitted unbonding TX correctly references the staking TX (if valid, it emits anEventUnexpectedUnbondingTx
event)Resets the
BtcUndelegation
field of the delegation to indicate it is unbonded and emits aBTCDelegationStatus_UNBONDED
event to update the FP’s voting powerRefunds any gas costs incurred
MsgSelectiveSlashingEvidence
The MsgSelectiveSlashingEvidence
message allows reporting of selective slashing violations. When a Babylon node receives this message, it does the following:
Retrieves the delegation based on the provided staking TX hash and verifies that the delegation is in
ACTIVE
orUNBONDING
stateChecks that the submitted
RecoveredFpBtcSk
matches the FP’s BTC public keyEnsures the FP has not already been slashed
Records the block height at which the FP was slashed (on both the Babylon chain and the BTC network), which triggers a future voting-power update event (
EventPowerDistUpdate
)
Upon successful execution, the gas fee is refunded.
MsgUpdateParams
The MsgUpdateParams
message updates the btcstaking module’s parameters. It can only be executed through a governance proposal.
ABCI++ handler
BeginBlock
The BeginBlock
function in the btcstaking module tracks the latest BTC tip height for operations involving BTC delegations. This data is crucial for verifying proofs and processing delegations (including activation, unbonding, and status changes) in coordination with the btclightclient module.
Test coverage
The x/btcstaking package itself has low test coverage (13.9%), while the keeper module has relatively high coverage (75.2%), and the types module is barely tested (4.3%).
ok github.com/babylonlabs-io/babylon/x/btcstaking 1.830s coverage: 13.9% of statements
ok github.com/babylonlabs-io/babylon/x/btcstaking/keeper 12.753s coverage: 75.2% of statements
ok github.com/babylonlabs-io/babylon/x/btcstaking/types 1.513s coverage: 4.3% of statements
Attack surface
There are a lot of essential/core messages exposed in BTC staking as it is a crucial part of the node. Any issues in MsgCreateBTCDelegation
could allow for delegations to be made even to the POS. Staking without respecting the invariants on BTC could allow for false power in the staking system. Any issues in MsgAddBTCDelegationInclusionProof
could also result in the same issues if the proof is not correctly validated against the corresponding BTC delegation, or certain issues could allow valid proofs to not be accepted. The MsgBTCUndelegate
issues in BTCUndelegate
could result in valid unbonding TXs to not be recognized; as such, an unbonded BTC delegation would still count towards an FP. Other messages are also exposed, whose failure might result in similar situations.