Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure max slashable #78

Merged
merged 3 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions contracts/provider/external-staking/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl ExternalStakingContract<'_> {
Ok(id)
}

#[allow(clippy::too_many_arguments)]
#[msg(instantiate)]
pub fn instantiate(
&self,
Expand All @@ -89,15 +90,21 @@ impl ExternalStakingContract<'_> {
vault: String,
unbonding_period: u64,
remote_contact: crate::msg::AuthorizedEndpoint,
max_slashing: Decimal,
) -> Result<Response, ContractError> {
let vault = ctx.deps.api.addr_validate(&vault)?;
let vault = VaultApiHelper(vault);

if max_slashing > Decimal::one() {
return Err(ContractError::InvalidMaxSlashing);
}

let config = Config {
denom,
rewards_denom,
vault,
unbonding_period,
max_slashing,
};

self.config.save(ctx.deps.storage, &config)?;
Expand Down Expand Up @@ -899,16 +906,11 @@ pub mod cross_staking {
}

#[msg(query)]
fn max_slash(&self, _ctx: QueryCtx) -> Result<MaxSlashResponse, ContractError> {
// TODO: Properly set this value
// Arbitrary value - only to make some testing possible
//
// Probably should be queried from remote chain
let resp = MaxSlashResponse {
max_slash: Decimal::percent(5),
};

Ok(resp)
fn max_slash(&self, ctx: QueryCtx) -> Result<MaxSlashResponse, ContractError> {
let Config { max_slashing, .. } = self.config.load(ctx.deps.storage)?;
Ok(MaxSlashResponse {
max_slash: max_slashing,
})
}
}
}
3 changes: 3 additions & 0 deletions contracts/provider/external-staking/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ pub enum ContractError {
#[error("Invalid denom, {0} expected")]
InvalidDenom(String),

#[error("You cannot use a max slashing rate over 1.0 (100%)")]
InvalidMaxSlashing,

#[error("Not enough tokens staked, up to {0} can be unbond")]
NotEnoughStake(Uint128),

Expand Down
6 changes: 5 additions & 1 deletion contracts/provider/external-staking/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use crate::msg::{AuthorizedEndpoint, ReceiveVirtualStake, StakeInfo};
const OSMO: &str = "osmo";
const STAR: &str = "star";

const SLASHING_PERCENTAGE: u64 = 10;

// Shortcut setuping all needed contracts
//
// Returns vault and external staking proxies
Expand All @@ -37,6 +39,7 @@ fn setup<'app>(
let native_staking_instantiate = NativeStakingInstantiateMsg {
denom: OSMO.to_owned(),
proxy_code_id: native_staking_proxy_code.code_id(),
max_slashing: Decimal::percent(5),
maurolacy marked this conversation as resolved.
Show resolved Hide resolved
};

let staking_init = StakingInitInfo {
Expand All @@ -59,6 +62,7 @@ fn setup<'app>(
vault.contract_addr.to_string(),
unbond_period,
remote_contact,
Decimal::percent(SLASHING_PERCENTAGE),
)
.call(owner)?;

Expand All @@ -78,7 +82,7 @@ fn instantiate() {
assert_eq!(stakes.stakes, []);

let max_slash = contract.cross_staking_api_proxy().max_slash().unwrap();
assert_eq!(max_slash.max_slash, Decimal::percent(5));
assert_eq!(max_slash.max_slash, Decimal::percent(SLASHING_PERCENTAGE));
}

#[test]
Expand Down
6 changes: 4 additions & 2 deletions contracts/provider/external-staking/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{BlockInfo, Timestamp, Uint128, Uint256};
use cosmwasm_std::{BlockInfo, Decimal, Timestamp, Uint128, Uint256};
use mesh_apis::vault_api::VaultApiHelper;

use crate::points_alignment::PointsAlignment;
Expand All @@ -13,8 +13,10 @@ pub struct Config {
pub rewards_denom: String,
/// Vault contract address
pub vault: VaultApiHelper,
/// Ubbounding period for claims in seconds
/// Unbounding period for claims in seconds
ethanfrey marked this conversation as resolved.
Show resolved Hide resolved
pub unbonding_period: u64,
/// Max slash percentage (from InstantiateMsg, maybe later from the chain)
pub max_slashing: Decimal,
}

/// All single stake related information - entry per `(user, validator)` pair, including
Expand Down
1 change: 1 addition & 0 deletions contracts/provider/native-staking-proxy/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ fn setup<'app>(
msg: to_binary(&mesh_native_staking::contract::InstantiateMsg {
denom: OSMO.to_owned(),
proxy_code_id: staking_proxy_code.code_id(),
max_slashing: Decimal::percent(5),
})
.unwrap(),
label: None,
Expand Down
11 changes: 7 additions & 4 deletions contracts/provider/native-staking/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cosmwasm_std::{from_slice, Addr, DepsMut, Reply, Response, SubMsgResponse};
use cosmwasm_std::{from_slice, Addr, Decimal, DepsMut, Reply, Response, SubMsgResponse};
use cw2::set_contract_version;
use cw_storage_plus::{Item, Map};
use cw_utils::parse_instantiate_response_data;
Expand All @@ -18,9 +18,6 @@ pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

pub const REPLY_ID_INSTANTIATE: u64 = 2;

// TODO: Hardcoded for now. Revisit for v1.
pub const MAX_SLASH_PERCENTAGE: u64 = 10;

pub struct NativeStakingContract<'a> {
pub config: Item<'a, Config>,
/// Map of proxy contract address by owner address
Expand Down Expand Up @@ -50,11 +47,17 @@ impl NativeStakingContract<'_> {
ctx: InstantiateCtx,
denom: String,
proxy_code_id: u64,
max_slashing: Decimal,
) -> Result<Response, ContractError> {
if max_slashing > Decimal::one() {
return Err(ContractError::InvalidMaxSlashing);
}

let config = Config {
denom,
proxy_code_id,
vault: ctx.info.sender,
max_slashing,
};
self.config.save(ctx.deps.storage, &config)?;
set_contract_version(ctx.deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Expand Down
3 changes: 3 additions & 0 deletions contracts/provider/native-staking/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ pub enum ContractError {

#[error("Missing instantiate reply data")]
NoInstantiateData {},

#[error("You cannot use a max slashing rate over 1.0 (100%)")]
InvalidMaxSlashing,
}
10 changes: 6 additions & 4 deletions contracts/provider/native-staking/src/local_staking_api.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use cosmwasm_std::{ensure_eq, from_slice, to_binary, Binary, Decimal, Response, SubMsg, WasmMsg};
use cosmwasm_std::{ensure_eq, from_slice, to_binary, Binary, Response, SubMsg, WasmMsg};
use cw_utils::must_pay;
use sylvia::types::QueryCtx;
use sylvia::{contract, types::ExecCtx};

#[allow(unused_imports)]
use mesh_apis::local_staking_api::{self, LocalStakingApi, MaxSlashResponse};

use crate::contract::{NativeStakingContract, MAX_SLASH_PERCENTAGE, REPLY_ID_INSTANTIATE};
use crate::contract::{NativeStakingContract, REPLY_ID_INSTANTIATE};
use crate::error::ContractError;
use crate::msg::StakeMsg;

// FIXME: Move to sylvia contract macro
use crate::contract::BoundQuerier;
use crate::state::Config;

#[contract]
#[messages(local_staking_api as LocalStakingApi)]
Expand Down Expand Up @@ -79,9 +80,10 @@ impl LocalStakingApi for NativeStakingContract<'_> {
/// Returns the maximum percentage that can be slashed
/// TODO: Any way to query this from the chain? Or we just pass in InstantiateMsg?
#[msg(query)]
ethanfrey marked this conversation as resolved.
Show resolved Hide resolved
fn max_slash(&self, _ctx: QueryCtx) -> Result<MaxSlashResponse, Self::Error> {
fn max_slash(&self, ctx: QueryCtx) -> Result<MaxSlashResponse, Self::Error> {
let Config { max_slashing, .. } = self.config.load(ctx.deps.storage)?;
Ok(MaxSlashResponse {
max_slash: Decimal::percent(MAX_SLASH_PERCENTAGE),
max_slash: max_slashing,
})
}
}
21 changes: 18 additions & 3 deletions contracts/provider/native-staking/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ use crate::msg::{OwnerByProxyResponse, ProxyByOwnerResponse};

const OSMO: &str = "OSMO";

const SLASHING_PERCENTAGE: u64 = 15;

fn slashing_rate() -> Decimal {
Decimal::percent(SLASHING_PERCENTAGE)
}

#[test]
fn instantiation() {
let app = App::default();
Expand All @@ -25,7 +31,11 @@ fn instantiation() {
let staking_code = contract::multitest_utils::CodeId::store_code(&app);

let staking = staking_code
.instantiate(OSMO.to_owned(), staking_proxy_code.code_id())
.instantiate(
OSMO.to_owned(),
staking_proxy_code.code_id(),
slashing_rate(),
)
.with_label("Staking")
.call(owner)
.unwrap();
Expand All @@ -34,7 +44,7 @@ fn instantiation() {
assert_eq!(config.denom, OSMO);

let res = staking.local_staking_api_proxy().max_slash().unwrap();
assert_eq!(res.max_slash, Decimal::percent(10));
assert_eq!(res.max_slash, slashing_rate());
}

#[test]
Expand All @@ -60,7 +70,11 @@ fn receiving_stake() {
let staking_code = contract::multitest_utils::CodeId::store_code(&app);

let staking = staking_code
.instantiate(OSMO.to_owned(), staking_proxy_code.code_id())
.instantiate(
OSMO.to_owned(),
staking_proxy_code.code_id(),
slashing_rate(),
)
.with_label("Staking")
.call(owner)
.unwrap();
Expand Down Expand Up @@ -196,6 +210,7 @@ fn releasing_proxy_stake() {
msg: to_binary(&crate::contract::InstantiateMsg {
denom: OSMO.to_owned(),
proxy_code_id: staking_proxy_code.code_id(),
max_slashing: slashing_rate(),
})
.unwrap(),
label: None,
Expand Down
5 changes: 4 additions & 1 deletion contracts/provider/native-staking/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use cosmwasm_std::{Addr, Decimal};

#[cw_serde]
pub struct Config {
Expand All @@ -11,4 +11,7 @@ pub struct Config {

/// The address of the vault contract (where we get and return stake)
pub vault: Addr,

/// Max slash percentage (from InstantiateMsg, maybe later from the chain)
pub max_slashing: Decimal,
}
Loading