Skip to content

Commit

Permalink
feat: started implementing ics20-transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
srdtrk committed Jun 3, 2024
1 parent 7877e67 commit a940b8d
Show file tree
Hide file tree
Showing 20 changed files with 356 additions and 8 deletions.
66 changes: 66 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ cosmwasm-std = { version = "1.5.5", features = [
] }
cw-storage-plus = "1.2.0"
cw2 = "1.1.2"
cw20 = "1.1.2"
cw20-ics20 = "1.1.2"
schemars = "0.8.16"
serde = { version = "1.0.197", default-features = false, features = ["derive"] }
thiserror = { version = "1.0.58" }
Expand Down
11 changes: 9 additions & 2 deletions contracts/ics07-tendermint/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary, ContractErro
query::check_for_misbehaviour(deps, env, msg.try_into()?)
}
QueryMsg::VerifyMembership(_) | QueryMsg::VerifyNonMembership(_) => {
query::execute_query(deps, env, msg.try_into()?)
query::sudo_query(deps, env, msg.try_into()?)
}
QueryMsg::Ownership {} => query::ownership(deps),
}
}

Expand Down Expand Up @@ -145,7 +146,7 @@ mod query {
}

#[allow(clippy::needless_pass_by_value, clippy::module_name_repetitions)]
pub fn execute_query(
pub fn sudo_query(
deps: Deps,
env: Env,
msg: ibc_client_cw::types::SudoMsg,
Expand All @@ -156,4 +157,10 @@ mod query {

ctx.sudo(msg).map_err(ContractError::from)
}

pub fn ownership(deps: Deps) -> Result<Binary, ContractError> {
Ok(cosmwasm_std::to_json_binary(&cw_ownable::get_ownership(
deps.storage,
)?)?)
}
}
16 changes: 16 additions & 0 deletions contracts/ics20-transfer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Build results
/target
/schema

# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
.cargo-ok

# Text file backups
**/*.rs.bk

# macOS
.DS_Store

# IDEs
*.iml
.idea
32 changes: 32 additions & 0 deletions contracts/ics20-transfer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "cw-ibc-lite-ics20-transfer"
description = "ICS-20 Transfer application for `cw-ibc-lite`"
version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }
repository = { workspace = true }
license = { workspace = true }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib", "rlib"]

[features]
# exclude export feature to disable all instantiate/execute/query exports
default = ["export"]
export = []

[dependencies]
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw-storage-plus = { workspace = true }
cw2 = { workspace = true }
cw20-ics20 = { workspace = true }
cw20 = { workspace = true }
schemars = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
ibc-core-host = { workspace = true }
cw-ibc-lite-shared = { workspace = true }
cw-ibc-lite-ics02-client = { workspace = true }
ibc-client-cw = { workspace = true }
3 changes: 3 additions & 0 deletions contracts/ics20-transfer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# CosmWasm IBC Lite Transfer App

This is a transfer application for `cw-ibc-lite`. It is based on [cw20-ics20](https://github.com/CosmWasm/cw-plus/tree/main/contracts/cw20-ics20) contract. It currently only works with cw20 tokens.
11 changes: 11 additions & 0 deletions contracts/ics20-transfer/src/bin/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use cosmwasm_schema::write_api;

use cw_ibc_lite_ics20_transfer::types::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};

fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg,
}
}
100 changes: 100 additions & 0 deletions contracts/ics20-transfer/src/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//! This module handles the execution logic of the contract.
use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response};

use cw_ibc_lite_shared::types::error::ContractError;

use crate::types::{
keys,
msg::{ExecuteMsg, InstantiateMsg, QueryMsg},
};

/// Instantiates a new contract.
///
/// # Errors
/// Will return an error if the instantiation fails.
#[allow(clippy::needless_pass_by_value)]
#[cosmwasm_std::entry_point]
pub fn instantiate(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
_msg: InstantiateMsg,
) -> Result<Response, ContractError> {
// NOTE: Contract admin is assumed to be the ics26-router contract.
cw2::set_contract_version(deps.storage, keys::CONTRACT_NAME, keys::CONTRACT_VERSION)?;

todo!()
}

/// Handles the execution of the contract by routing the messages to the respective handlers.
///
/// # Errors
/// Will return an error if the handler returns an error.
#[allow(clippy::needless_pass_by_value)]
#[cosmwasm_std::entry_point]
pub fn execute(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::Receive(receive_msg) => execute::receive(deps, env, info, receive_msg),
ExecuteMsg::ReceiveIbcAppCallback(callback_msg) => {
execute::receive_ibc_callback(deps, env, info, callback_msg)
}
}
}

/// Handles the query messages by routing them to the respective handlers.
///
/// # Errors
/// Will return an error if the handler returns an error.
#[allow(clippy::needless_pass_by_value)]
#[cosmwasm_std::entry_point]
pub fn query(_deps: Deps, _env: Env, _msg: QueryMsg) -> Result<Binary, ContractError> {
todo!()
}

mod execute {
use cw_ibc_lite_shared::types::{apps::callbacks::IbcAppCallbackMsg, error::TransferError};

use crate::types::{msg::TransferMsg, state};

use super::{ContractError, DepsMut, Env, MessageInfo, Response};

#[allow(clippy::needless_pass_by_value)]
pub fn receive(
_deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: cw20::Cw20ReceiveMsg,
) -> Result<Response, ContractError> {
if !info.funds.is_empty() {
return Err(TransferError::UnexpectedNativeToken.into());
}

// NOTE: We use the sender contract address as the denom.
let _denom = info.sender.as_str();
let _transfer_msg: TransferMsg = cosmwasm_std::from_json(msg.msg)?;
todo!()
}

#[allow(clippy::needless_pass_by_value)]
pub fn receive_ibc_callback(
deps: DepsMut,
env: Env,
info: MessageInfo,
msg: IbcAppCallbackMsg,
) -> Result<Response, ContractError> {
state::admin::assert_admin(&env, &deps.querier, &info.sender)?;

match msg {
IbcAppCallbackMsg::OnSendPacket { .. } => todo!(),
IbcAppCallbackMsg::OnRecvPacket { .. } => todo!(),
IbcAppCallbackMsg::OnAcknowledgementPacket { .. } => todo!(),
IbcAppCallbackMsg::OnTimeoutPacket { .. } => todo!(),
}
}
}
7 changes: 7 additions & 0 deletions contracts/ics20-transfer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![doc = include_str!("../README.md")]
#![deny(missing_docs)]
#![deny(clippy::nursery, clippy::pedantic, warnings)]

#[cfg(feature = "export")]
pub mod contract;
pub mod types;
1 change: 1 addition & 0 deletions contracts/ics20-transfer/src/types/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! `cw-ibc-lite-ics20-transfer` Event Keys
12 changes: 12 additions & 0 deletions contracts/ics20-transfer/src/types/keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! # Keys
//!
//! Contains key constants definitions for the contract such as version info for migrations.
/// `CONTRACT_NAME` is the name of the contract recorded with [`cw2`]
pub const CONTRACT_NAME: &str = "crates.io:cw-ibc-lite-ics20-transfer";
/// `CONTRACT_VERSION` is the version of the cargo package.
/// This is also the version of the contract recorded in [`cw2`]
pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

/// `ICS20_VERSION` is the version of the ICS20 module used in the contract.
pub const ICS20_VERSION: &str = "ics20-1";
7 changes: 7 additions & 0 deletions contracts/ics20-transfer/src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! This module contains the types used by the contract's execution and state logic.
pub mod events;
pub mod keys;
#[allow(clippy::module_name_repetitions)]
pub mod msg;
pub mod state;
42 changes: 42 additions & 0 deletions contracts/ics20-transfer/src/types/msg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! # Messages
//!
//! This module defines the messages that this contract receives.
use cosmwasm_schema::{cw_serde, QueryResponses};

use cw_ibc_lite_shared::types::apps::helpers::ibc_lite_app_callback;

/// The message to instantiate the contract.
#[cw_serde]
pub struct InstantiateMsg {}

/// The execute messages supported by the contract.
#[ibc_lite_app_callback]
#[cw_serde]
pub enum ExecuteMsg {
/// This accepts a properly-encoded ReceiveMsg from a cw20 contract
/// The wrapped message is expected to be [`TransferMsg`].
Receive(cw20::Cw20ReceiveMsg),
}

/// This is the message we accept via [`ExecuteMsg::Receive`].
#[cw_serde]
pub struct TransferMsg {
/// The local channel to send the packets on
pub source_channel: String,
/// The remote address to send to.
/// Don't use HumanAddress as this will likely have a different Bech32 prefix than we use
/// and cannot be validated locally
pub receiver: String,
/// How long the packet lives in seconds. If not specified, use default_timeout
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout: Option<u64>,
/// An optional memo to add to the IBC transfer
#[serde(skip_serializing_if = "Option::is_none")]
pub memo: Option<String>,
}

/// The query messages supported by the contract.
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {}
30 changes: 30 additions & 0 deletions contracts/ics20-transfer/src/types/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! This module defines the state storage of the Contract.
/// A collection of methods to access the admin of the contract.
pub mod admin {
use cosmwasm_std::{Addr, Env, QuerierWrapper};
use cw_ibc_lite_shared::types::error::ContractError;

/// Asserts that the given address is the admin of the contract.
///
/// # Errors
/// Returns an error if the given address is not the admin of the contract or the contract
/// doesn't have an admin.
#[allow(clippy::module_name_repetitions)]
pub fn assert_admin(
env: &Env,
querier: &QuerierWrapper,
addr: &Addr,
) -> Result<(), ContractError> {
let admin = querier
.query_wasm_contract_info(&env.contract.address)?
.admin
.ok_or(ContractError::Unauthorized)?;

if admin != addr.as_str() {
return Err(ContractError::Unauthorized);
}

Ok(())
}
}
Loading

0 comments on commit a940b8d

Please sign in to comment.