Skip to content

Commit

Permalink
Merge pull request #196 from decentrio/feat/vesting-delegate-remake
Browse files Browse the repository at this point in the history
feat: allow depositing vesting tokens in the vault
  • Loading branch information
trinitys7 authored Aug 21, 2024
2 parents 7c142c2 + ad46461 commit c6a34ff
Show file tree
Hide file tree
Showing 13 changed files with 1,235 additions and 64 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions contracts/provider/external-staking/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,21 @@ mod utils;
use anyhow::Result as AnyResult;

use cosmwasm_std::{coin, coins, to_json_binary, Decimal, Uint128};
use cw_multi_test::App as MtApp;
use mesh_native_staking::contract::sv::mt::CodeId as NativeStakingCodeId;
use mesh_native_staking::contract::sv::InstantiateMsg as NativeStakingInstantiateMsg;
use mesh_native_staking_proxy::contract::sv::mt::CodeId as NativeStakingProxyCodeId;
use mesh_vault::contract::sv::mt::CodeId as VaultCodeId;
use mesh_vault::contract::VaultContract;
use mesh_vault::mock::sv::mt::{CodeId as VaultCodeId, VaultMockProxy};
use mesh_vault::mock::VaultMock;
use mesh_vault::msg::{LocalStakingInfo, StakingInitInfo};

use mesh_sync::ValueRange;

use cw_multi_test::App as MtApp;
use sylvia::multitest::{App, Proxy};

use crate::contract::sv::mt::ExternalStakingContractProxy;
use crate::test_methods::sv::mt::TestMethodsProxy;
use mesh_apis::cross_staking_api::sv::mt::CrossStakingApiProxy;
use mesh_vault::contract::sv::mt::VaultContractProxy;

use crate::contract::sv::mt::CodeId;
use crate::contract::ExternalStakingContract;
Expand Down Expand Up @@ -47,7 +46,7 @@ fn setup<'app>(
owner: &'app str,
unbond_period: u64,
) -> AnyResult<(
Proxy<'app, MtApp, VaultContract<'app>>,
Proxy<'app, MtApp, VaultMock<'app>>,
Proxy<'app, MtApp, ExternalStakingContract<'app>>,
)> {
let native_staking_proxy_code = NativeStakingProxyCodeId::store_code(app);
Expand Down
4 changes: 2 additions & 2 deletions contracts/provider/external-staking/src/multitest/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use cosmwasm_std::{to_json_binary, Addr, Coin};
use cw_multi_test::{App as MtApp, AppResponse};
use mesh_apis::{converter_api::RewardInfo, ibc::AddValidator};
use mesh_sync::Tx;
use mesh_vault::contract::{sv::mt::VaultContractProxy, VaultContract};
use mesh_vault::mock::{sv::mt::VaultMockProxy, VaultMock};
use sylvia::multitest::{App, Proxy};

use crate::{
Expand Down Expand Up @@ -59,7 +59,7 @@ impl AppExt for App<MtApp> {
}
}

type Vault<'app> = Proxy<'app, MtApp, VaultContract<'app>>;
type Vault<'app> = Proxy<'app, MtApp, VaultMock<'app>>;
type Contract<'app> = Proxy<'app, MtApp, ExternalStakingContract<'app>>;

pub(crate) trait ContractExt {
Expand Down
9 changes: 4 additions & 5 deletions contracts/provider/native-staking-proxy/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ use cosmwasm_std::testing::mock_env;
use cosmwasm_std::{coin, coins, to_json_binary, Addr, Decimal, Validator};

use cw_multi_test::{App as MtApp, StakingInfo};

use sylvia::multitest::{App, Proxy};

use mesh_vault::contract::sv::mt::VaultContractProxy;
use mesh_vault::contract::VaultContract;
use mesh_vault::mock::sv::mt::VaultMockProxy;
use mesh_vault::mock::VaultMock;
use mesh_vault::msg::LocalStakingInfo;

use crate::contract;
Expand Down Expand Up @@ -60,8 +59,8 @@ fn setup<'app>(
owner: &'app str,
user: &str,
validators: &[&str],
) -> AnyResult<Proxy<'app, MtApp, VaultContract<'app>>> {
let vault_code = mesh_vault::contract::sv::mt::CodeId::store_code(app);
) -> AnyResult<Proxy<'app, MtApp, VaultMock<'app>>> {
let vault_code = mesh_vault::mock::sv::mt::CodeId::store_code(app);
let staking_code = mesh_native_staking::contract::sv::mt::CodeId::store_code(app);
let staking_proxy_code = contract::sv::mt::CodeId::store_code(app);

Expand Down
4 changes: 2 additions & 2 deletions contracts/provider/native-staking/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use mesh_native_staking_proxy::contract::sv::mt::{
};
use mesh_native_staking_proxy::contract::NativeStakingProxyContract;
use mesh_sync::ValueRange;
use mesh_vault::contract::sv::mt::VaultContractProxy;
use mesh_vault::mock::sv::mt::VaultMockProxy;
use mesh_vault::msg::LocalStakingInfo;

use crate::contract;
Expand Down Expand Up @@ -256,7 +256,7 @@ fn releasing_proxy_stake() {
let app = app(&[(user, (300, OSMO))], &[validator]);

// Contracts setup
let vault_code = mesh_vault::contract::sv::mt::CodeId::store_code(&app);
let vault_code = mesh_vault::mock::sv::mt::CodeId::store_code(&app);
let staking_code = contract::sv::mt::CodeId::store_code(&app);
let staking_proxy_code = NativeStakingProxyCodeId::store_code(&app);

Expand Down
1 change: 1 addition & 0 deletions contracts/provider/vault/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mt = ["library", "sylvia/mt"]
[dependencies]
mesh-apis = { workspace = true }
mesh-sync = { workspace = true }
mesh-bindings = { workspace = true }

sylvia = { workspace = true }
cosmwasm-schema = { workspace = true }
Expand Down
82 changes: 56 additions & 26 deletions contracts/provider/vault/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_std::{
coin, ensure, Addr, BankMsg, Binary, Coin, Decimal, DepsMut, Fraction, Order, Reply, Response,
coin, ensure, Addr, Binary, Coin, Decimal, DepsMut, Fraction, Order, Reply, Response,
StdResult, Storage, SubMsg, SubMsgResponse, Uint128, WasmMsg,
};
use cw2::set_contract_version;
Expand All @@ -12,8 +12,10 @@ use mesh_apis::local_staking_api::{
sv::LocalStakingApiQueryMsg, LocalStakingApiHelper, SlashRatioResponse,
};
use mesh_apis::vault_api::{self, SlashInfo, VaultApi};
use mesh_bindings::{ProviderCustomMsg, ProviderMsg};
use mesh_sync::Tx::InFlightStaking;
use mesh_sync::{max_range, ValueRange};

use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx, ReplyCtx};
use sylvia::{contract, schemars};

Expand Down Expand Up @@ -66,6 +68,8 @@ pub struct VaultContract<'a> {
#[contract]
#[sv::error(ContractError)]
#[sv::messages(vault_api as VaultApi)]
/// Workaround for lack of support in communication `Empty` <-> `Custom` Contracts.
#[sv::custom(msg=ProviderCustomMsg)]
impl VaultContract<'_> {
pub fn new() -> Self {
Self {
Expand All @@ -91,7 +95,7 @@ impl VaultContract<'_> {
ctx: InstantiateCtx,
denom: String,
local_staking: Option<LocalStakingInfo>,
) -> Result<Response, ContractError> {
) -> Result<Response<ProviderCustomMsg>, ContractError> {
nonpayable(&ctx.info)?;

let config = Config { denom };
Expand Down Expand Up @@ -140,31 +144,45 @@ impl VaultContract<'_> {
}

#[sv::msg(exec)]
fn bond(&self, ctx: ExecCtx) -> Result<Response, ContractError> {
fn bond(
&self,
ctx: ExecCtx,
amount: Coin,
) -> Result<Response<ProviderCustomMsg>, ContractError> {
nonpayable(&ctx.info)?;

let denom = self.config.load(ctx.deps.storage)?.denom;
let amount = must_pay(&ctx.info, &denom)?;
ensure!(denom == amount.denom, ContractError::UnexpectedDenom(denom));

let mut user = self
.users
.may_load(ctx.deps.storage, &ctx.info.sender)?
.unwrap_or_default();
user.collateral += amount;
user.collateral += amount.amount;
self.users.save(ctx.deps.storage, &ctx.info.sender, &user)?;

let amt = amount.amount;
let msg = ProviderMsg::Bond {
delegator: ctx.info.sender.clone().into_string(),
amount,
};
let resp = Response::new()
.add_attribute("action", "bond")
.add_message(msg)
.add_attribute("action", "unbond")
.add_attribute("sender", ctx.info.sender)
.add_attribute("amount", amount.to_string());
.add_attribute("amount", amt.to_string());

Ok(resp)
}

#[sv::msg(exec)]
fn unbond(&self, ctx: ExecCtx, amount: Coin) -> Result<Response, ContractError> {
fn unbond(
&self,
ctx: ExecCtx,
amount: Coin,
) -> Result<Response<ProviderCustomMsg>, ContractError> {
nonpayable(&ctx.info)?;

let denom = self.config.load(ctx.deps.storage)?.denom;

ensure!(denom == amount.denom, ContractError::UnexpectedDenom(denom));

let mut user = self
Expand All @@ -180,17 +198,16 @@ impl VaultContract<'_> {

user.collateral -= amount.amount;
self.users.save(ctx.deps.storage, &ctx.info.sender, &user)?;

let msg = BankMsg::Send {
to_address: ctx.info.sender.to_string(),
amount: vec![amount.clone()],
let amt = amount.amount;
let msg = ProviderMsg::Unbond {
delegator: ctx.info.sender.clone().into_string(),
amount,
};

let resp = Response::new()
.add_message(msg)
.add_attribute("action", "unbond")
.add_attribute("sender", ctx.info.sender)
.add_attribute("amount", amount.to_string());
.add_attribute("amount", amt.to_string());

Ok(resp)
}
Expand All @@ -206,7 +223,7 @@ impl VaultContract<'_> {
amount: Coin,
// action to take with that stake
msg: Binary,
) -> Result<Response, ContractError> {
) -> Result<Response<ProviderCustomMsg>, ContractError> {
nonpayable(&ctx.info)?;

let config = self.config.load(ctx.deps.storage)?;
Expand Down Expand Up @@ -253,7 +270,7 @@ impl VaultContract<'_> {
amount: Coin,
// action to take with that stake
msg: Binary,
) -> Result<Response, ContractError> {
) -> Result<Response<ProviderCustomMsg>, ContractError> {
nonpayable(&ctx.info)?;

let config = self.config.load(ctx.deps.storage)?;
Expand Down Expand Up @@ -490,7 +507,11 @@ impl VaultContract<'_> {
}

#[sv::msg(reply)]
fn reply(&self, ctx: ReplyCtx, reply: Reply) -> Result<Response, ContractError> {
fn reply(
&self,
ctx: ReplyCtx,
reply: Reply,
) -> Result<Response<ProviderCustomMsg>, ContractError> {
match reply.id {
REPLY_ID_INSTANTIATE => self.reply_init_callback(ctx.deps, reply.result.unwrap()),
_ => Err(ContractError::InvalidReplyId(reply.id)),
Expand All @@ -501,7 +522,7 @@ impl VaultContract<'_> {
&self,
deps: DepsMut,
reply: SubMsgResponse,
) -> Result<Response, ContractError> {
) -> Result<Response<ProviderCustomMsg>, ContractError> {
let init_data = parse_instantiate_response_data(&reply.data.unwrap())?;
let local_staking = Addr::unchecked(init_data.contract_address);

Expand Down Expand Up @@ -981,6 +1002,7 @@ impl Default for VaultContract<'_> {

impl VaultApi for VaultContract<'_> {
type Error = ContractError;
type ExecC = ProviderCustomMsg;

/// This must be called by the remote staking contract to release this claim
fn release_cross_stake(
Expand All @@ -990,7 +1012,7 @@ impl VaultApi for VaultContract<'_> {
owner: String,
// amount to unstake on that contract
amount: Coin,
) -> Result<Response, ContractError> {
) -> Result<Response<Self::ExecC>, ContractError> {
nonpayable(&ctx.info)?;

self.unstake(&mut ctx, owner.clone(), amount.clone())?;
Expand All @@ -1011,7 +1033,7 @@ impl VaultApi for VaultContract<'_> {
mut ctx: ExecCtx,
// address of the user who originally called stake_remote
owner: String,
) -> Result<Response, ContractError> {
) -> Result<Response<Self::ExecC>, ContractError> {
let denom = self.config.load(ctx.deps.storage)?.denom;
let amount = must_pay(&ctx.info, &denom)?;

Expand All @@ -1032,7 +1054,7 @@ impl VaultApi for VaultContract<'_> {
mut ctx: ExecCtx,
slashes: Vec<SlashInfo>,
validator: String,
) -> Result<Response, Self::Error> {
) -> Result<Response<Self::ExecC>, Self::Error> {
nonpayable(&ctx.info)?;

let msgs = self.slash(&mut ctx, &slashes, &validator)?;
Expand Down Expand Up @@ -1060,7 +1082,7 @@ impl VaultApi for VaultContract<'_> {
mut ctx: ExecCtx,
slashes: Vec<SlashInfo>,
validator: String,
) -> Result<Response, Self::Error> {
) -> Result<Response<Self::ExecC>, Self::Error> {
nonpayable(&ctx.info)?;

let msgs = self.slash(&mut ctx, &slashes, &validator)?;
Expand All @@ -1082,7 +1104,11 @@ impl VaultApi for VaultContract<'_> {
Ok(resp)
}

fn commit_tx(&self, mut ctx: ExecCtx, tx_id: u64) -> Result<Response, ContractError> {
fn commit_tx(
&self,
mut ctx: ExecCtx,
tx_id: u64,
) -> Result<Response<Self::ExecC>, ContractError> {
self.commit_stake(&mut ctx, tx_id)?;

let resp = Response::new()
Expand All @@ -1093,7 +1119,11 @@ impl VaultApi for VaultContract<'_> {
Ok(resp)
}

fn rollback_tx(&self, mut ctx: ExecCtx, tx_id: u64) -> Result<Response, ContractError> {
fn rollback_tx(
&self,
mut ctx: ExecCtx,
tx_id: u64,
) -> Result<Response<Self::ExecC>, ContractError> {
self.rollback_stake(&mut ctx, tx_id)?;

let resp = Response::new()
Expand Down
3 changes: 2 additions & 1 deletion contracts/provider/vault/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pub mod contract;
pub mod error;
pub mod mock;
pub mod msg;
#[cfg(test)]
mod multitest;
pub mod multitest;
mod state;
pub mod txs;
Loading

0 comments on commit c6a34ff

Please sign in to comment.