Skip to content

Commit

Permalink
Merge pull request #145 from hadronlabs-org/feat/fix-undelegation-limit
Browse files Browse the repository at this point in the history
wrap undelegations/claiming into msgExec
  • Loading branch information
oldremez authored Aug 7, 2024
2 parents dfd51db + 342a38a commit 98d1a47
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 31 deletions.
65 changes: 44 additions & 21 deletions contracts/puppeteer/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ use crate::proto::{
},
},
};
use cosmos_sdk_proto::cosmos::distribution::v1beta1::MsgSetWithdrawAddress;
use cosmos_sdk_proto::cosmos::{
authz::v1beta1::{GenericAuthorization, Grant, MsgGrant, MsgGrantResponse},
bank::v1beta1::{MsgSend, MsgSendResponse},
base::{abci::v1beta1::TxMsgData, v1beta1::Coin},
staking::v1beta1::MsgUndelegate,
};
use cosmos_sdk_proto::{
cosmos::{authz::v1beta1::MsgExec, distribution::v1beta1::MsgSetWithdrawAddress},
traits::MessageExt,
};
use cosmwasm_std::{
attr, ensure_eq, to_json_binary, Addr, Attribute, CosmosMsg, Deps, Order, Reply, StdError,
Expand Down Expand Up @@ -678,16 +680,26 @@ fn execute_claim_rewards_and_optionaly_transfer(
"/cosmos.bank.v1beta1.MsgSend",
)?);
}

let mut claim_msgs = vec![];
for val in validators.clone() {
let withdraw_msg = MsgWithdrawDelegatorReward {
delegator_address: ica.to_string(),
validator_address: val,
};
any_msgs.push(prepare_any_msg(
withdraw_msg,
"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
)?);
claim_msgs.push(cosmos_sdk_proto::Any {
type_url: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward".to_string(),
value: MsgWithdrawDelegatorReward {
delegator_address: ica.to_string(),
validator_address: val,
}
.to_bytes()?,
})
}

let grant_msg = MsgExec {
grantee: ica.to_string(),
msgs: claim_msgs,
};

any_msgs.push(prepare_any_msg(grant_msg, "/cosmos.authz.v1beta1.MsgExec")?);

let submsg = compose_submsg(
deps.branch(),
config.clone(),
Expand Down Expand Up @@ -718,18 +730,29 @@ fn execute_undelegate(
validate_sender(&config, &info.sender)?;
puppeteer_base.validate_tx_idle_state(deps.as_ref())?;
let delegator = puppeteer_base.ica.get_address(deps.storage)?;
let any_msgs = items
.iter()
.map(|(validator, amount)| MsgUndelegate {
delegator_address: delegator.to_string(),
validator_address: validator.to_string(),
amount: Some(Coin {
denom: config.remote_denom.to_string(),
amount: amount.to_string(),
}),
let mut undelegation_msgs = vec![];
for (validator, amount) in items.iter() {
undelegation_msgs.push(cosmos_sdk_proto::Any {
type_url: "/cosmos.staking.v1beta1.MsgUndelegate".to_string(),
value: cosmos_sdk_proto::cosmos::staking::v1beta1::MsgUndelegate {
delegator_address: delegator.to_string(),
validator_address: validator.to_string(),
amount: Some(cosmos_sdk_proto::cosmos::base::v1beta1::Coin {
denom: config.remote_denom.to_string(),
amount: amount.to_string(),
}),
}
.to_bytes()?,
})
.map(|msg| prepare_any_msg(msg, "/cosmos.staking.v1beta1.MsgUndelegate"))
.collect::<NeutronResult<Vec<ProtobufAny>>>()?;
}

let grant_msg = MsgExec {
grantee: delegator,
msgs: undelegation_msgs,
};

let any_msgs: Vec<neutron_sdk::bindings::types::ProtobufAny> =
vec![prepare_any_msg(grant_msg, "/cosmos.authz.v1beta1.MsgExec")?];

let submsg = compose_submsg(
deps.branch(),
Expand Down
32 changes: 22 additions & 10 deletions contracts/puppeteer/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::contract::Puppeteer;
use cosmos_sdk_proto::traits::MessageExt;
use cosmwasm_schema::schemars;
use cosmwasm_std::{
coin, coins, from_json,
Expand Down Expand Up @@ -387,18 +388,29 @@ fn test_execute_undelegate() {
msg,
)
.unwrap();
let msg = cosmos_sdk_proto::cosmos::staking::v1beta1::MsgUndelegate {
delegator_address: "ica_address".to_string(),
validator_address: "valoper1".to_string(),
amount: Some(cosmos_sdk_proto::cosmos::base::v1beta1::Coin {
denom: "remote_denom".to_string(),
amount: "1000".to_string(),
}),

let msg = cosmos_sdk_proto::Any {
type_url: "/cosmos.staking.v1beta1.MsgUndelegate".to_string(),
value: cosmos_sdk_proto::cosmos::staking::v1beta1::MsgUndelegate {
delegator_address: "ica_address".to_string(),
validator_address: "valoper1".to_string(),
amount: Some(cosmos_sdk_proto::cosmos::base::v1beta1::Coin {
denom: "remote_denom".to_string(),
amount: "1000".to_string(),
}),
}
.to_bytes()
.unwrap(),
};
let mut buf = Vec::with_capacity(msg.encoded_len());
msg.encode(&mut buf).unwrap();

let grant_msg = cosmos_sdk_proto::cosmos::authz::v1beta1::MsgExec {
grantee: "ica_address".to_string(),
msgs: vec![msg],
};
let mut buf = Vec::with_capacity(grant_msg.encoded_len());
grant_msg.encode(&mut buf).unwrap();
let any_msg = neutron_sdk::bindings::types::ProtobufAny {
type_url: "/cosmos.staking.v1beta1.MsgUndelegate".to_string(),
type_url: "/cosmos.authz.v1beta1.MsgExec".to_string(),
value: Binary::from(buf),
};
assert_eq!(
Expand Down
4 changes: 4 additions & 0 deletions packages/puppeteer-base/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use cosmwasm_std::{OverflowError, StdError};
use cw_ownable::OwnershipError;
use neutron_sdk::NeutronError;
use prost::EncodeError;
use thiserror::Error;

#[derive(Error, Debug, PartialEq)]
Expand All @@ -14,6 +15,9 @@ pub enum ContractError {
#[error("{0}")]
OverflowError(#[from] OverflowError),

#[error("{0}")]
EncodeError(#[from] EncodeError),

#[error("ICA is not registered")]
IcaNotRegistered {},

Expand Down

0 comments on commit 98d1a47

Please sign in to comment.