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

Cw20 kernel routing #723

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- CW20 support for kernel routing [(#723)](https://github.com/andromedaprotocol/andromeda-core/pull/723)

### Changed

- feat: Improved macros and execution flow for AMP [(#741)](https://github.com/andromedaprotocol/andromeda-core/pull/741)
Expand Down
18 changes: 10 additions & 8 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "andromeda-fixed-amount-splitter"
version = "1.2.0"
version = "1.2.1-b.1"
edition = "2021"
rust-version = "1.75.0"

Expand Down
22 changes: 14 additions & 8 deletions contracts/finance/andromeda-fixed-amount-splitter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ fn execute_send_cw20(
};

let mut msgs: Vec<SubMsg> = Vec::new();
let mut amp_funds: Vec<Coin> = Vec::new();
let mut remainder_funds = coin.amount;

let mut pkt = AMPPkt::from_ctx(ctx.amp_ctx, ctx.env.contract.address.to_string());
for recipient in splitter_recipients.clone() {
// Find the recipient's corresponding denom for the current iteration of the sent funds
let recipient_coin = recipient
Expand All @@ -167,14 +169,12 @@ fn execute_send_cw20(
let recipient_funds =
cosmwasm_std::coin(recipient_coin.amount.u128(), recipient_coin.denom);

let amp_msg = recipient.recipient.generate_msg_cw20(
&deps.as_ref(),
Cw20Coin {
address: recipient_funds.denom.clone(),
amount: recipient_funds.amount,
},
)?;
msgs.push(amp_msg);
amp_funds.push(recipient_funds.clone());

let amp_msg = recipient
.recipient
.generate_amp_msg(&deps.as_ref(), Some(vec![recipient_funds.clone()]))?;
pkt = pkt.add_message(amp_msg);
}
}

Expand All @@ -192,6 +192,12 @@ fn execute_send_cw20(
msgs.push(cw20_msg);
}

let kernel_address = ADOContract::default().get_kernel_address(deps.as_ref().storage)?;
if !pkt.messages.is_empty() && !amp_funds.is_empty() {
let distro_msg = pkt.to_sub_msg_cw20(kernel_address, amp_funds.clone(), 1)?;
msgs.push(distro_msg.clone());
}

Ok(Response::new()
.add_submessages(msgs)
.add_attribute("action", "send")
Expand Down
2 changes: 1 addition & 1 deletion contracts/finance/andromeda-splitter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "andromeda-splitter"
version = "2.3.0"
version = "2.3.1-b.1"
edition = "2021"
rust-version = "1.75.0"

Expand Down
18 changes: 10 additions & 8 deletions contracts/finance/andromeda-splitter/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ fn execute_send_cw20(
let mut amp_funds: Vec<Coin> = Vec::new();
let mut remainder_funds = coin(amount.u128(), asset.clone());

let mut pkt = AMPPkt::from_ctx(ctx.amp_ctx, ctx.env.contract.address.to_string());
for recipient_addr in splitter_recipients {
let recipient_percent = recipient_addr.percent;
let mut vec_coin: Vec<Coin> = Vec::new();
Expand All @@ -245,14 +246,10 @@ fn execute_send_cw20(
remainder_funds.amount = remainder_funds.amount.checked_sub(recip_coin.amount)?;
vec_coin.push(recip_coin.clone());
amp_funds.push(recip_coin.clone());
let amp_msg = recipient_addr.recipient.generate_msg_cw20(
&deps.as_ref(),
Cw20Coin {
address: recip_coin.denom.clone(),
amount: recip_coin.amount,
},
)?;
msgs.push(amp_msg);
let amp_msg = recipient_addr
.recipient
.generate_amp_msg(&deps.as_ref(), Some(vec_coin))?;
pkt = pkt.add_message(amp_msg);
}
}

Expand All @@ -270,6 +267,11 @@ fn execute_send_cw20(
msgs.push(cw20_msg);
}

let kernel_address = ADOContract::default().get_kernel_address(deps.as_ref().storage)?;
if !pkt.messages.is_empty() && !amp_funds.is_empty() {
let distro_msg = pkt.to_sub_msg_cw20(kernel_address, amp_funds.clone(), 1)?;
msgs.push(distro_msg.clone());
}
Ok(Response::new()
.add_submessages(msgs)
.add_attribute("action", "cw20_send")
Expand Down
3 changes: 2 additions & 1 deletion contracts/os/andromeda-kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ testing = ["cw-multi-test"]
cosmwasm-std = { workspace = true, features = ["ibc3"] }
cosmwasm-schema = { workspace = true }
cw-storage-plus = { workspace = true }

cw20 = { workspace = true }
cw-utils = { workspace = true }
serde-json-wasm = "1.0.1"
osmosis-std-derive = "0.15.3"
osmosis-std = "0.1.4"
Expand Down
2 changes: 2 additions & 0 deletions contracts/os/andromeda-kernel/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use cosmwasm_std::{
entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError,
};

use crate::execute::handle_receive_cw20;
use crate::ibc::{IBCLifecycleComplete, SudoMsg};
use crate::reply::{
on_reply_create_ado, on_reply_ibc_hooks_packet_send, on_reply_ibc_transfer,
Expand Down Expand Up @@ -91,6 +92,7 @@ pub fn execute(
execute_env.env,
packet,
),
ExecuteMsg::Receive(msg) => handle_receive_cw20(execute_env, msg),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Based on the code analysis from previous results, I can now provide the final response:

CW20 token validation needs improvement

The current implementation of handle_receive_cw20 lacks explicit validation of the CW20 token contract address. While it uses the sender address (info.sender) as the asset identifier, there's no whitelist or validation mechanism to ensure only trusted CW20 tokens are processed. Additionally:

  • The handler performs basic checks using nonpayable but lacks token-specific validation
  • CW20 over IBC is explicitly rejected with NotImplemented error
  • The handler delegates to amp_receive_cw20 which focuses on message handling rather than token validation

Suggested improvements:

  • Add a whitelist or registry of allowed CW20 token contracts
  • Implement validation of the token contract address before processing
  • Consider adding token-specific restrictions or limits
🔗 Analysis chain

Verify CW20 token validation

The new match arm correctly delegates CW20 reception to the dedicated handler. Please ensure that:

  1. The handler validates the CW20 token contract address
  2. Proper error handling is in place for failed transfers

Let's verify the CW20 token validation:


Let me gather more information about the CW20 receive handler implementation:


Let me analyze the CW20 token validation one more time by looking at the message types and error handling:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for CW20 token validation in the handler implementation
ast-grep --pattern 'fn handle_receive_cw20($_, $msg) {
  $$$
}'

# Look for error handling patterns
rg -A 5 "ContractError::" contracts/os/andromeda-kernel/src/

Length of output: 26678


Script:

#!/bin/bash
# Search for handle_receive_cw20 implementation
rg -A 10 "fn handle_receive_cw20" contracts/os/andromeda-kernel/src/

# Look for CW20 token validation patterns
rg -A 5 "cw20|Cw20" contracts/os/andromeda-kernel/src/

Length of output: 8441


Script:

#!/bin/bash
# Look for CW20 message types and error definitions
rg -A 5 "pub enum (ExecuteMsg|ContractError)" contracts/os/andromeda-kernel/src/

# Look for token validation patterns in tests
rg -A 10 "mock.*cw20" contracts/os/andromeda-kernel/src/testing/

Length of output: 149

ExecuteMsg::Send { message } => execute::send(execute_env, message),
ExecuteMsg::TriggerRelay {
packet_sequence,
Expand Down
Loading
Loading