Skip to content

Commit

Permalink
feat: create route to withdraw rewards (#146)
Browse files Browse the repository at this point in the history
* feat: create route to withdraw rewards

* fix: fix test name

* fix: fix comment
  • Loading branch information
matthiasmatt authored Jul 2, 2024
1 parent 334f706 commit e6a3a65
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 7 deletions.
Binary file modified artifacts/broker_bank.wasm
Binary file not shown.
Binary file modified artifacts/broker_staking.wasm
Binary file not shown.
5 changes: 2 additions & 3 deletions artifacts/checksums.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
3878c8fec84001d1260da6d8b7ea91af5bc3d3433d8cab293ae24de94a9fdda0 broker_bank.wasm
dfd48116b2181f477d42b7d0d697057e16814c0b703ef592a8757ca681c6e5ad broker_staking.wasm
e3d3422db32e4e6ebe0247a22f6be733ccf6b637bfeb4ff8ffcd8122a68d7853 broker_bank.wasm
40288f4cda1e48740269ab6425ca234b9b99419c165aaf1d410fa37c40843e49 broker_staking.wasm
382c05baf544f2886de849933ecf59e8bc3bcdcdd552d5a63537bd6d63f2ecf1 controller.wasm
05948cad982935aa30a9c2011649ab40a38172ab50df5781a3e24f72b76dcc56 core_compounder.wasm
ed4a89ae4669b22863fcabd18e3bd7e40d039899f863a07eb0449eed059a898e core_token_vesting_v2.wasm
b56a880d4c67d9f353f549b502256f73159f89b50aa6dae683948e117efa4792 cw3_flex_multisig.wasm
1ecff403bbf3b5fcedccb5de76a0ef5f1fdbcc5f60890e3388f5425584899f0b incentives.wasm
Expand Down
33 changes: 31 additions & 2 deletions contracts/broker-staking/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use broker_bank::state::{IS_HALTED, OPERATORS, TO_ADDRS};
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_json_binary, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo,
Response, StakingMsg, StdResult, Uint128,
to_json_binary, Binary, Coin, CosmosMsg, Deps, DepsMut, DistributionMsg,
Env, MessageInfo, Response, StakingMsg, StdResult, Uint128,
};

use crate::msg::{ExecuteMsg, StakeMsg, UnstakeMsg};
Expand Down Expand Up @@ -59,9 +59,38 @@ pub fn execute(
ExecuteMsg::WithdrawAll { to } => {
withdraw_all(deps, env, info, to, contract_addr)
}
ExecuteMsg::ClaimRewards {} => claim_rewards(deps, env, info),
}
}

pub fn claim_rewards(
deps: DepsMut,
env: Env,
info: MessageInfo,
) -> Result<Response, ContractError> {
let is_halted = IS_HALTED.load(deps.storage)?;
assert_not_halted(is_halted)?;

Permissions::assert_operator(deps.storage, info.sender.to_string())?;

// query current delegations
let delegations =
deps.querier.query_all_delegations(&env.contract.address)?;

let mut messages: Vec<CosmosMsg> = vec![];
for delegation in delegations.iter() {
messages.push(CosmosMsg::Distribution(
DistributionMsg::WithdrawDelegatorReward {
validator: delegation.validator.clone(),
},
));
}

Ok(Response::new()
.add_messages(messages)
.add_attribute("action", "claim_rewards"))
}

pub fn unstake(
deps: DepsMut,
_env: Env,
Expand Down
2 changes: 2 additions & 0 deletions contracts/broker-staking/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub enum ExecuteMsg {
to: Option<String>,
},

ClaimRewards {},

/// Unstake allows to unstake a given amount of tokens from a set of
/// validators. The UnstakeMsgs defines the tokens amount and address
/// of the validator.
Expand Down
81 changes: 79 additions & 2 deletions contracts/broker-staking/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::contract::{execute, query};
use crate::msg::{ExecuteMsg, StakeMsg, UnstakeMsg};
use cosmwasm_std::{self as cw_std};
use cw_std::{
coin, from_json, testing, BankMsg, Coin, CosmosMsg, Response, StakingMsg,
Uint128,
coin, from_json, testing, BankMsg, Coin, CosmosMsg, DistributionMsg,
Response, StakingMsg, Uint128,
};
use nibiru_std::errors::TestResult;
use serde::Serialize;
Expand Down Expand Up @@ -752,3 +752,80 @@ fn exec_unstake() -> TestResult {
}
Ok(())
}

#[test]
fn test_withdraw_rewards() -> TestResult {
let to_addrs: [String; 2] = ["mm_kucoin", "mm_bybit"].map(|s| s.to_string());
let opers: [String; 1] = ["valid_oper"].map(|s| s.to_string());
let test_cases: Vec<TestCaseExec> = vec![
// Success
TestCaseExec {
to_addrs: to_addrs.to_vec(),
opers: opers.to_vec(),
sender: "owner",
exec_msg: ExecuteMsg::ClaimRewards {},
err: None,
contract_funds_start: None,
resp_msgs: vec![],
},
// Success - oper can do that
TestCaseExec {
to_addrs: to_addrs.to_vec(),
opers: opers.to_vec(),
sender: "valid_oper",
exec_msg: ExecuteMsg::ClaimRewards {},
err: None,
contract_funds_start: None,
resp_msgs: vec![],
},
// Fail - non oper can't
TestCaseExec {
to_addrs: to_addrs.to_vec(),
opers: opers.to_vec(),
sender: "invalid_oper",
exec_msg: ExecuteMsg::ClaimRewards {},
err: Some("insufficient permissions"),
contract_funds_start: None,
resp_msgs: vec![],
},
];
for tc in &test_cases {
let to_addrs = &tc.to_addrs;
let opers = &tc.opers;
// instantiate smart contract from the owner
let (mut deps, env, _info) =
setup_contract(to_addrs.clone(), opers.clone())?;

if let Some(funds_start) = &tc.contract_funds_start {
// Set up a mock querier with contract balance
let contract_addr = env.contract.address.to_string();
let balances: &[(&str, &[Coin])] =
&[(contract_addr.as_str(), funds_start.as_slice())];
let querier = testing::MockQuerier::new(balances);
deps.querier = querier;
}

// send the exec msg
let info = mock_info_for_sender(tc.sender);
let res = execute(deps.as_mut(), env, info, tc.exec_msg.clone());

if let Some(want_err) = tc.err {
let got_err = res.expect_err("errors should occur in this test");
let is_contained = got_err.to_string().contains(want_err);
assert!(is_contained, "got error {}", got_err);
return Ok(());
}
assert!(res.is_ok(), "got {res:?}");

let resp = res?;
let got_resp_msgs: Vec<CosmosMsgExt> = resp
.messages
.iter()
.map(|sub_msg| CosmosMsgExt(&sub_msg.msg))
.collect();
let want_resp_msgs: Vec<CosmosMsgExt> =
tc.resp_msgs.iter().map(CosmosMsgExt).collect();
assert_eq!(want_resp_msgs, got_resp_msgs);
}
Ok(())
}

0 comments on commit e6a3a65

Please sign in to comment.