Scruffy Gingerbread Cormorant
Medium
Babylon node gives preference to unbonding status over expiration status for a delegation even though unbonding time is already considered in the expiration check. This status is used for determining the applicability of slashing. As a result, a delegator may experience slashing if they unbond close to expiration time and their finality provider is slashed.
func (d *BTCDelegation) GetStatus(
btcHeight uint32,
covenantQuorum uint32,
) BTCDelegationStatus {
if d.IsUnbondedEarly() {
return BTCDelegationStatus_UNBONDED
}
// we are still pending covenant quorum
if !d.HasCovenantQuorums(covenantQuorum) {
return BTCDelegationStatus_PENDING
}
// we are still pending activation by inclusion proof
if !d.HasInclusionProof() {
// staking tx has not been included in a block yet
return BTCDelegationStatus_VERIFIED
}
// At this point we already have covenant quorum and inclusion proof,
// we can check the status based on the BTC height
if btcHeight < d.StartHeight {
// staking tx's timelock has not begun, or is less than unbonding time BTC
// blocks left
return BTCDelegationStatus_UNBONDED
}
// if the endheight is lower than the btc height + unbonding time
// the btc delegation should be considered expired
if btcHeight+d.UnbondingTime > d.EndHeight {
return BTCDelegationStatus_EXPIRED
}
// - we have covenant quorum
// - we have inclusion proof
// - we are not unbonded early
// - we are not expired
return BTCDelegationStatus_ACTIVE
}
The order for determining status of a delegation is (ignoring other statuses)
- Check if unbonded early (returns UNBONDED)
- Check if expired (returns EXPIRED)
A delegation is considered expired if the BTC height is larger than endHeight-unbondingTime
. This is likely because there is no point of unbonding after such BTC height as timelock expiry of original staking tx will occur before unbonding tx timelock expiry. More importantly, such expired delegations do not contribute to consensus and are not considered for slashing.
However, if a delegator unbonds just before the expiration time, their status will be UNBONDED instead of EXPIRED after BTC height endHeight-unbondingTime
and they will be subject to slashing.
This is an inconsistency in the protocol behavior (if a delegator unbonds early they get slashed vs not if they remain bonded for the same potential violation by their finality provider) and will result in fund loss for delegator due to unexpected slashing.
NA
NA
- Delegator unbonds early close to expiration time
- Finality provider gets slashed
- Delegator which otherwise would have been in EXPIRED state and hence not slashed, actually get slashed because of being UNBONDED state even though they tried to unbond early
Incorrect slashing of early unbonding delegator resulting in loss of funds.
- Stake and unbond close to expiration time. Verify the unbonded status during expiration time
- active: false
btc_pk: 17cdfb68f4c9fda0422dbb438ab5448a7b49c4f789df96d7a334fd50b30b3c5e
covenant_sigs:
- adaptor_sigs:
- Ak2FY1tkiH5gEmWakX4bv+HUp1IGSmLITaUzESrKZNEA5HCPg5euyNDzh/2y3VP6Rh6va4bETURLkbNanM+uKWkB
cov_pk: 2d4ccbe538f846a750d82a77cd742895e51afcf23d86d05004a356b783902748
delegator_slash_sig_hex: 9e9146cd6d2f5b9bf9cbd4f35eb0b5116ba88b8ae382b5f6f96f301da1e8038fd1f10e055dc6101c7161e522d6f319278a1e073743a839a37b84e5d2b146abec
end_height: 172
fp_btc_pk_list:
- 0378e061171d701068b65b8d040dd86d241c73cb28303d19beed2aeb2243cad9
params_version: 0
slashing_tx_hex: 01000000013745fbe8a443e7c5fb5dc05d541c9a96559b579ea3c10a2def6e244ffbac910c0000000000ffffffff02a0860100000000001976a914010101010101010101010101010101010101010188acb8b70d00000000002251208db3c78aae0a35fc29ae066ceb82a70efcce45dbb304081a32f78c2c3312340700000000
staker_addr: bbn1twkfusstasrdzkc9sgtp07wyej9mev5ew69t57
staking_output_idx: 0
staking_time: 30
staking_tx_hex: 01000000013f3100b8929c1a003c64c24d51daf041acd7b2d669552ca5e5b47e2c1de094620100000000ffffffff0240420f00000000002251207f659e93bf108487b0f6fe9e474d1a7bb41e48ae2ed08a5de381f52a2dc72b7ecf788b3b00000000160014713733769b43479326dd235b21d08e649e2a7d8500000000
start_height: 142
status_desc: UNBONDED
total_sat: "1000000"
unbonding_time: 5
- Simulate slashing the FP during expiration time and see the delegator being slashed as well even though it should have been skipped by vigilante
2025-02-25T11:59:21.237992Z debug signed and assembled witness for slashing tx of unbonded BTC delegation 17cdfb68f4c9fda0422dbb438ab5448a7b49c4f789df96d7a334fd50b30b3c5e under finality provider 0378e061171d701068b65b8d040dd86d241c73cb28303d19beed2aeb2243cad9 {"module": "btcstaking-tracker", "module": "slasher"}
2025-02-25T11:59:21.243051Z info successfully submitted slashing tx (txHash: d73360d2b76e8263ce008cb9a3c386470a00ba32ffaa4250c421f7993f5bee04) for BTC delegation 17cdfb68f4c9fda0422dbb438ab5448a7b49c4f789df96d7a334fd50b30b3c5e under finality provider 0378e061171d701068b65b8d040dd86d241c73cb28303d19beed2aeb2243cad9 {"module": "btcstaking-tracker", "module": "slasher"}
2025-02-25T11:59:21.243111Z info successfully slash BTC delegation with staking tx hash 01000000013f3100b8929c1a003c64c24d51daf041acd7b2d669552ca5e5b47e2c1de094620100000000ffffffff0240420f00000000002251207f659e93bf108487b0f6fe9e474d1a7bb41e48ae2ed08a5de381f52a2dc72b7ecf788b3b00000000160014713733769b43479326dd235b21d08e649e2a7d8500000000 under finality provider 0378e061171d701068b65b8d040dd86d241c73cb28303d19beed2aeb2243cad9 {"module": "btcstaking-tracker", "module": "slasher"}
If the same sequence of slashing is done without unbonding, the delegator is not slashed.
Slashing should only be performed till BTC height smaller than endHeight-unbondingTime
even for unbonding cases.