Skip to content

Commit

Permalink
feat: Cross Chain Rates Recipient (#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
joemonem authored Nov 27, 2024
1 parent 54284fa commit f02960c
Show file tree
Hide file tree
Showing 8 changed files with 356 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

3 changes: 1 addition & 2 deletions contracts/modules/andromeda-rates/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ fn execute_set_rate(
ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?,
ContractError::Unauthorized {}
);
// Validate the local rate's value
rate.value.validate(deps.as_ref())?;
rate.validate(deps.as_ref())?;

RATES.save(deps.storage, &action, &rate)?;

Expand Down
1 change: 0 additions & 1 deletion contracts/os/andromeda-kernel/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,6 @@ impl MsgHandler {
gas_limit: None,
reply_on: cosmwasm_std::ReplyOn::Always,
});

Ok(resp
.add_attribute(format!("method:{sequence}"), "execute_transfer_funds")
.add_attribute(format!("channel:{sequence}"), channel)
Expand Down
2 changes: 1 addition & 1 deletion packages/std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "andromeda-std"
version = "1.4.0"
version = "1.5.0"
edition = "2021"
rust-version = "1.75.0"
description = "The standard library for creating an Andromeda Digital Object"
Expand Down
92 changes: 75 additions & 17 deletions packages/std/src/ado_base/rates.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use crate::{
ado_contract::ADOContract,
amp::{AndrAddr, Recipient},
amp::{
messages::{AMPMsg, AMPMsgConfig},
AndrAddr, Recipient,
},
common::{deduct_funds, denom::validate_native_denom, Funds},
error::ContractError,
os::{adodb::ADOVersion, aos_querier::AOSQuerier},
};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{
ensure, has_coins, to_json_binary, Coin, Decimal, Deps, Event, Fraction, QueryRequest, SubMsg,
WasmQuery,
ensure, has_coins, to_json_binary, Addr, Coin, Decimal, Deps, Event, Fraction, QueryRequest,
ReplyOn, SubMsg, WasmMsg, WasmQuery,
};
use cw20::{Cw20Coin, Cw20QueryMsg, TokenInfoResponse};

Expand Down Expand Up @@ -80,6 +83,20 @@ pub enum LocalRateValue {
Flat(Coin),
}
impl LocalRateValue {
/// Used to see if the denom is potentially a cw20 address, if it is, it cannot be paired with a cross-chain recipient
pub fn is_valid_address(&self, deps: Deps) -> Result<bool, ContractError> {
match self {
LocalRateValue::Flat(coin) => {
let denom = coin.denom.clone();
let is_valid_address = deps.api.addr_validate(denom.as_str());
match is_valid_address {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
LocalRateValue::Percent(_) => Ok(false),
}
}
pub fn validate(&self, deps: Deps) -> Result<(), ContractError> {
match self {
// If it's a coin, make sure it's non-zero
Expand Down Expand Up @@ -131,6 +148,18 @@ pub struct LocalRate {
pub value: LocalRateValue,
pub description: Option<String>,
}
impl LocalRate {
pub fn validate(&self, deps: Deps) -> Result<(), ContractError> {
if self.recipient.is_cross_chain() {
ensure!(
!self.value.is_valid_address(deps)?,
ContractError::InvalidCw20CrossChainRate {}
);
}
self.value.validate(deps)?;
Ok(())
}
}
// Created this because of the very complex return value warning.
type LocalRateResponse = (Vec<SubMsg>, Vec<Event>, Vec<Coin>);

Expand Down Expand Up @@ -160,24 +189,54 @@ impl LocalRate {
event = event.add_attribute(
"payment",
PaymentAttribute {
receiver: self.recipient.address.get_raw_address(&deps)?.to_string(),
receiver: self
.recipient
.address
.get_raw_address(&deps)
.unwrap_or(Addr::unchecked(self.recipient.address.to_string()))
.to_string(),
amount: fee.clone(),
}
.to_string(),
);

let msg = if is_native {
self.recipient
.generate_direct_msg(&deps, vec![fee.clone()])?
} else {
self.recipient.generate_msg_cw20(
&deps,
Cw20Coin {
amount: fee.amount,
address: fee.denom.to_string(),
let msg = if self.recipient.is_cross_chain() {
ensure!(is_native, ContractError::InvalidCw20CrossChainRate {});
// Create a cross chain message to be sent to the kernel
let kernel_address = ADOContract::default().get_kernel_address(deps.storage)?;
let kernel_msg = crate::os::kernel::ExecuteMsg::Send {
message: AMPMsg {
recipient: self.recipient.address.clone(),
message: self.recipient.msg.clone().unwrap_or_default(),
funds: vec![fee.clone()],
config: AMPMsgConfig {
reply_on: ReplyOn::Always,
exit_at_error: false,
gas_limit: None,
direct: true,
ibc_config: None,
},
},
)?
};
SubMsg::new(WasmMsg::Execute {
contract_addr: kernel_address.to_string(),
msg: to_json_binary(&kernel_msg)?,
funds: vec![fee.clone()],
})
} else {
if is_native {
self.recipient
.generate_direct_msg(&deps, vec![fee.clone()])?
} else {
self.recipient.generate_msg_cw20(
&deps,
Cw20Coin {
amount: fee.amount,
address: fee.denom.to_string(),
},
)?
}
};

msgs.push(msg);

events.push(event);
Expand Down Expand Up @@ -215,8 +274,7 @@ impl Rate {
}
}
Rate::Local(local_rate) => {
// Validate the local rate value
local_rate.value.validate(deps)?;
local_rate.validate(deps)?;
Ok(())
}
}
Expand Down
8 changes: 8 additions & 0 deletions packages/std/src/amp/recipient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ impl Recipient {
self.msg.clone()
}

pub fn is_cross_chain(&self) -> bool {
let protocol = self.address.get_protocol();
match protocol {
Some("ibc") => true,
_ => false,
}
}

/// Generates a direct sub message for the given recipient.
pub fn generate_direct_msg(
&self,
Expand Down
3 changes: 3 additions & 0 deletions packages/std/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ pub enum ContractError {
#[error("NoDenomInfoProvided")]
NoDenomInfoProvided {},

#[error("Cannot assign cw20 rate to cross-chain recipient")]
InvalidCw20CrossChainRate {},

#[error("InvalidAmount: {msg}")]
InvalidAmount { msg: String },

Expand Down
Loading

0 comments on commit f02960c

Please sign in to comment.