Skip to content

Commit

Permalink
Add staking slash handler / msg
Browse files Browse the repository at this point in the history
  • Loading branch information
Mauro Lacy committed Sep 16, 2024
1 parent b571d63 commit 768c47a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 10 deletions.
6 changes: 4 additions & 2 deletions contracts/btc-staking/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_json_binary, Deps, DepsMut, Empty, Env, MessageInfo, QueryResponse, Reply, Response,
to_json_binary, Addr, Deps, DepsMut, Empty, Env, MessageInfo, QueryResponse, Reply, Response,
StdResult,
};
use cw2::set_contract_version;
Expand All @@ -12,7 +12,7 @@ use babylon_bindings::BabylonMsg;
use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
use crate::queries;
use crate::staking::handle_btc_staking;
use crate::staking::{handle_btc_staking, handle_slash_fp};
use crate::state::config::{Config, ADMIN, CONFIG, PARAMS};

pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
Expand All @@ -30,6 +30,7 @@ pub fn instantiate(
let config = Config {
denom,
babylon: info.sender,
finality: Addr::unchecked(""), // TODO: Instantiate finality contract and set address in reply handler
};
CONFIG.save(deps.storage, &config)?;

Expand Down Expand Up @@ -122,6 +123,7 @@ pub fn execute(
&slashed_del,
&unbonded_del,
),
ExecuteMsg::Slash { fp_btc_pk_hex } => handle_slash_fp(deps, env, &info, &fp_btc_pk_hex),
}
}

Expand Down
29 changes: 21 additions & 8 deletions contracts/btc-staking/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,20 @@ fn handle_slashed_delegation(
Ok(slashing_event)
}

/// handle_slash_fp handles FP slashing at the staking level
pub fn handle_slash_fp(
deps: DepsMut,
env: Env,
info: &MessageInfo,
fp_btc_pk_hex: &str,
) -> Result<Response<BabylonMsg>, ContractError> {
let config = CONFIG.load(deps.storage)?;
if info.sender != config.finality && !ADMIN.is_admin(deps.as_ref(), &info.sender)? {
return Err(ContractError::Unauthorized);
}
slash_finality_provider(deps, env, fp_btc_pk_hex)
}

/// btc_undelegate adds the signature of the unbonding tx signed by the staker to the given BTC
/// delegation
fn btc_undelegate(
Expand All @@ -338,11 +352,10 @@ fn btc_undelegate(
/// `slash_finality_provider` slashes a finality provider with the given PK.
/// A slashed finality provider will not have voting power
pub(crate) fn slash_finality_provider(
deps: &mut DepsMut,
deps: DepsMut,
env: Env,
fp_btc_pk_hex: &str,
height: u64,
) -> Result<(), ContractError> {
) -> Result<Response<BabylonMsg>, ContractError> {
// Ensure finality provider exists
let mut fp = FPS.load(deps.storage, fp_btc_pk_hex)?;

Expand All @@ -353,12 +366,12 @@ pub(crate) fn slash_finality_provider(
));
}
// Set the finality provider as slashed
fp.slashed_height = height;
fp.slashed_height = env.block.height;

// Set BTC slashing height (if available from the babylon contract)
// FIXME: Turn this into a hard error
// return fmt.Errorf("failed to get current BTC tip")
let btc_height = get_btc_tip_height(deps).unwrap_or_default();
let btc_height = get_btc_tip_height(&deps).unwrap_or_default();
fp.slashed_btc_height = btc_height;

// Record slashed event. The next `BeginBlock` will consume this event for updating the active
Expand All @@ -374,7 +387,8 @@ pub(crate) fn slash_finality_provider(
// Save the finality provider back
FPS.save(deps.storage, fp_btc_pk_hex, &fp)?;

Ok(())
// TODO: Add events
Ok(Response::new())
}

/// get_btc_tip_height queries the Babylon contract for the latest BTC tip height
Expand All @@ -397,8 +411,7 @@ pub(crate) mod tests {
use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env};

use crate::contract::tests::{
create_new_finality_provider, create_new_fp_sk, get_active_btc_delegation,
get_btc_del_unbonding_sig, get_derived_btc_delegation, get_params, CREATOR, INIT_ADMIN,
create_new_finality_provider, get_active_btc_delegation, get_params, CREATOR, INIT_ADMIN,
};
use crate::contract::{execute, instantiate};
use crate::msg::{ExecuteMsg, InstantiateMsg};
Expand Down
1 change: 1 addition & 0 deletions contracts/btc-staking/src/state/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(crate) const ADMIN: Admin = Admin::new("admin");
pub struct Config {
pub denom: String,
pub babylon: Addr,
pub finality: Addr,
// covenant_pks is the list of public keys held by the covenant committee each PK
// follows encoding in BIP-340 spec on Bitcoin
// pub covenant_pks: Vec<BIP340PubKey>,
Expand Down
7 changes: 7 additions & 0 deletions packages/apis/src/btc_staking_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ pub enum ExecuteMsg {
slashed_del: Vec<SlashedBtcDelegation>,
unbonded_del: Vec<UnbondedBtcDelegation>,
},
/// Slash finality provider staking power.
/// Used by the finality contract only.
/// The finality contract will call this message to slash the finality provider's staking power
/// when the finality provider is found to be malicious
Slash {
fp_btc_pk_hex: String
},
}

#[cw_serde]
Expand Down

0 comments on commit 768c47a

Please sign in to comment.