Skip to content

Commit

Permalink
fix(warp): consideration of igp (#56)
Browse files Browse the repository at this point in the history
* fix: merkle tree

* fix(warp): gas issue

* fix(warp): use transfer from

* feat(warp): enable migration

* clippy

* feat: scripts

* feat(hook): enable migrate

* build: new code

* chore: addr converter

* fix: inherit ism

* build: migrate

* feat: inheritable ism receiver interface

* fix: hide important files

* rc6

* feat: migratable

* migrate

* fix: remove feature & deploy codes
  • Loading branch information
byeongsu-hong committed Oct 27, 2023
1 parent 67d0c7f commit ac8cd58
Show file tree
Hide file tree
Showing 19 changed files with 441 additions and 232 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ panic = "abort"
rpath = false

[workspace.package]
version = "0.0.6-rc5"
version = "0.0.6-rc6"
authors = [
"byeongsu-hong <hong@byeongsu.dev>",
"Eric <hashableric@gmail.com>",
Expand All @@ -42,7 +42,7 @@ keywords = ["hyperlane", "cosmos", "cosmwasm"]

[workspace.dependencies]
# cosmwasm
cosmwasm-std = { version = "1.2.7", features = ["stargate", "cosmwasm_1_2"] }
cosmwasm-std = { version = "1.2.7", features = ["stargate"] }
cosmwasm-storage = "1.2.7"
cosmwasm-schema = "1.2.7"
cosmwasm-crypto = "1.2.7"
Expand Down
7 changes: 6 additions & 1 deletion contracts/core/mailbox/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Deps, DepsMut, Env, MessageInfo, QueryResponse, Response};
use cosmwasm_std::{Deps, DepsMut, Empty, Env, MessageInfo, QueryResponse, Response};

use hpl_interface::{
core::mailbox::{ExecuteMsg, InstantiateMsg, MailboxHookQueryMsg, MailboxQueryMsg, QueryMsg},
Expand Down Expand Up @@ -87,6 +87,11 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<QueryResponse, Contr
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
Ok(Response::default())
}

#[cfg(test)]
mod test {
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
Expand Down
7 changes: 5 additions & 2 deletions contracts/core/mailbox/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,12 @@ mod tests {
fn test_process_query_handler(query: &WasmQuery) -> QuerierResult {
match query {
WasmQuery::Smart { contract_addr, msg } => {
if let Ok(req) = cosmwasm_std::from_binary::<ism::IsmSpecifierQueryMsg>(msg) {
if let Ok(req) = cosmwasm_std::from_binary::<ism::ExpectedIsmSpecifierQueryMsg>(msg)
{
match req {
ism::IsmSpecifierQueryMsg::InterchainSecurityModule() => {
hpl_interface::ism::ExpectedIsmSpecifierQueryMsg::IsmSpecifier(
ism::IsmSpecifierQueryMsg::InterchainSecurityModule(),
) => {
return SystemResult::Ok(
cosmwasm_std::to_binary(&ism::InterchainSecurityModuleResponse {
ism: Some(addr("default_ism")),
Expand Down
14 changes: 12 additions & 2 deletions contracts/hooks/merkle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
ensure_eq, Addr, Deps, DepsMut, Env, Event, MessageInfo, QueryResponse, Response, StdError,
ensure_eq, Addr, Deps, DepsMut, Empty, Env, Event, MessageInfo, QueryResponse, Response,
StdError,
};
use cw_storage_plus::Item;
use hpl_interface::{
Expand Down Expand Up @@ -181,10 +182,19 @@ fn get_tree_checkpoint(deps: Deps) -> Result<merkle::CheckPointResponse, Contrac

Ok(merkle::CheckPointResponse {
root: tree.root()?,
count: tree.count as u32,
count: if tree.count == 0 {
0
} else {
tree.count as u32 - 1
},
})
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
Ok(Response::new())
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
32 changes: 17 additions & 15 deletions contracts/mocks/mock-msg-receiver/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use cosmwasm_schema::cw_serde;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
attr, to_binary, Deps, DepsMut, Env, Event, MessageInfo, QueryResponse, Response, StdResult,
attr, to_binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, QueryResponse, Response,
StdResult,
};
use cw2::set_contract_version;
use cw_storage_plus::Item;
Expand All @@ -15,9 +16,6 @@ pub struct InstantiateMsg {
pub hrp: String,
}

#[cw_serde]
pub struct MigrateMsg {}

#[cw_serde]
pub struct ExecuteMsg {}

Expand All @@ -38,11 +36,6 @@ pub fn instantiate(
Ok(Response::new().add_attribute("method", "instantiate"))
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> {
Ok(Response::default())
}

/// Handling contract execution
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
Expand All @@ -67,12 +60,21 @@ pub fn execute(

/// Handling contract query
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(_deps: Deps, _env: Env, msg: ism::IsmSpecifierQueryMsg) -> StdResult<QueryResponse> {
pub fn query(
_deps: Deps,
_env: Env,
msg: ism::ExpectedIsmSpecifierQueryMsg,
) -> StdResult<QueryResponse> {
match msg {
ism::IsmSpecifierQueryMsg::InterchainSecurityModule() => {
Ok(to_binary(&ism::InterchainSecurityModuleResponse {
ism: None,
})?)
}
ism::ExpectedIsmSpecifierQueryMsg::IsmSpecifier(
ism::IsmSpecifierQueryMsg::InterchainSecurityModule(),
) => Ok(to_binary(&ism::InterchainSecurityModuleResponse {
ism: None,
})?),
}
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> StdResult<Response> {
Ok(Response::default())
}
120 changes: 47 additions & 73 deletions contracts/warp/cw20/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
ensure_eq, from_binary, CosmosMsg, Deps, DepsMut, Env, HexBinary, MessageInfo, QueryResponse,
Reply, Response, SubMsg, Uint256, WasmMsg,
ensure_eq, wasm_execute, CosmosMsg, Deps, DepsMut, Env, HexBinary, MessageInfo, QueryResponse,
Reply, Response, SubMsg, Uint128, Uint256, WasmMsg,
};

use cw20::Cw20ReceiveMsg;
use cw20::Cw20ExecuteMsg;
use hpl_interface::{
core::mailbox,
ism::{InterchainSecurityModuleResponse, IsmSpecifierQueryMsg},
to_binary,
types::bech32_encode,
warp::{
self,
cw20::{ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg},
cw20::{ExecuteMsg, InstantiateMsg, QueryMsg},
TokenMode, TokenModeMsg, TokenModeResponse, TokenTypeResponse,
},
};
Expand Down Expand Up @@ -92,20 +93,11 @@ pub fn execute(
Ownable(msg) => Ok(hpl_ownable::handle(deps, env, info, msg)?),
Router(msg) => Ok(hpl_router::handle(deps, env, info, msg)?),
Handle(msg) => mailbox_handle(deps, info, msg),
Receive(msg) => {
ensure_eq!(
info.sender,
TOKEN.load(deps.storage)?,
ContractError::Unauthorized
);

match from_binary::<ReceiveMsg>(&msg.msg)? {
ReceiveMsg::TransferRemote {
dest_domain,
recipient,
} => transfer_remote(deps, msg, dest_domain, recipient),
}
}
TransferRemote {
dest_domain,
recipient,
amount,
} => transfer_remote(deps, env, info, dest_domain, recipient, amount),
}
}

Expand Down Expand Up @@ -173,9 +165,11 @@ fn mailbox_handle(

fn transfer_remote(
deps: DepsMut,
receive_msg: Cw20ReceiveMsg,
env: Env,
info: MessageInfo,
dest_domain: u32,
recipient: HexBinary,
transfer_amount: Uint128,
) -> Result<Response, ContractError> {
let token = TOKEN.load(deps.storage)?;
let mode = MODE.load(deps.storage)?;
Expand All @@ -187,9 +181,23 @@ fn transfer_remote(

let mut msgs: Vec<CosmosMsg> = vec![];

// push token transfer msg
msgs.push(
wasm_execute(
&token,
&Cw20ExecuteMsg::TransferFrom {
owner: info.sender.to_string(),
recipient: env.contract.address.to_string(),
amount: transfer_amount,
},
vec![],
)?
.into(),
);

if mode == TokenMode::Bridged {
// push token burn msg if token is bridged
msgs.push(conv::to_burn_msg(&token, receive_msg.amount)?.into());
msgs.push(conv::to_burn_msg(&token, transfer_amount)?.into());
}

// push mailbox dispatch msg
Expand All @@ -199,21 +207,22 @@ fn transfer_remote(
dest_router,
warp::Message {
recipient: recipient.clone(),
amount: Uint256::from_uint128(receive_msg.amount),
amount: Uint256::from_uint128(transfer_amount),
metadata: HexBinary::default(),
}
.into(),
None,
None,
info.funds,
)?);

Ok(Response::new().add_messages(msgs).add_event(
new_event("transfer-remote")
.add_attribute("sender", receive_msg.sender)
.add_attribute("sender", info.sender)
.add_attribute("dest_domain", dest_domain.to_string())
.add_attribute("recipient", recipient.to_hex())
.add_attribute("token", token)
.add_attribute("amount", receive_msg.amount),
.add_attribute("amount", transfer_amount),
))
}

Expand All @@ -228,6 +237,9 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<QueryResponse, Contr
TokenType {} => to_binary(get_token_type(deps)),
TokenMode {} => to_binary(get_token_mode(deps)),
},
QueryMsg::IsmSpecifier(IsmSpecifierQueryMsg::InterchainSecurityModule()) => Ok(
cosmwasm_std::to_binary(&InterchainSecurityModuleResponse { ism: None })?,
),
}
}

Expand Down Expand Up @@ -413,46 +425,16 @@ mod test {
}
}

enum Method {
Handle,
Receive,
}

fn default_cw20_receive_msg() -> Cw20ReceiveMsg {
Cw20ReceiveMsg {
sender: Default::default(),
amount: Default::default(),
msg: Default::default(),
}
}

#[rstest]
#[case(MAILBOX, 1, gen_bz(32), token_mode_bridged())]
#[case(MAILBOX, 1, gen_bz(32), token_mode_collateral())]
#[should_panic(expected = "unauthorized")]
#[case(MAILBOX, Method::Receive)]
#[should_panic(expected = "unauthorized")]
#[case(TOKEN, Method::Handle)]
fn test_execute_authority(
deps: (TestDeps, Response),
#[case] sender: &str,
#[case] method: Method,
) {
let (mut deps, _) = deps;

let msg = match method {
Method::Handle => ExecuteMsg::Handle(HandleMsg::default()),
Method::Receive => ExecuteMsg::Receive(default_cw20_receive_msg()),
};

test_execute(deps.as_mut(), &addr(sender), msg, vec![]);
}

#[rstest]
#[case(1, gen_bz(32), token_mode_bridged())]
#[case(1, gen_bz(32), token_mode_collateral())]
#[case(TOKEN, 1, gen_bz(32), token_mode_collateral())]
#[should_panic(expected = "route not found")]
#[case(2, gen_bz(32), token_mode_collateral())]
#[case(MAILBOX, 2, gen_bz(32), token_mode_collateral())]
fn test_mailbox_handle(
#[values("osmo", "neutron")] hrp: &str,
#[case] sender: &str,
#[case] domain: u32,
#[case] route: HexBinary,
#[case] token_mode: Cw20TokenMode,
Expand All @@ -464,8 +446,6 @@ mod test {
token_mode.clone(),
);

let sender = MAILBOX;

let warp_msg = warp::Message {
recipient: gen_bz(32),
amount: Uint256::from_u128(100),
Expand Down Expand Up @@ -539,20 +519,14 @@ mod test {
let sender = addr("sender");
let recipient = gen_bz(32);

let receive_msg = Cw20ReceiveMsg {
sender: sender.to_string(),
amount: Uint128::new(100),
msg: cosmwasm_std::to_binary(&ReceiveMsg::TransferRemote {
dest_domain: domain,
recipient: recipient.clone(),
})
.unwrap(),
};

let res = test_execute(
deps.as_mut(),
&addr(TOKEN),
ExecuteMsg::Receive(receive_msg),
&sender,
ExecuteMsg::TransferRemote {
dest_domain: domain,
recipient: route.clone(),
amount: Uint128::new(100),
},
vec![],
);
let msgs = res.messages.into_iter().map(|v| v.msg).collect::<Vec<_>>();
Expand All @@ -564,7 +538,7 @@ mod test {
};

let dispatch_msg =
mailbox::dispatch(MAILBOX, domain, route, warp_msg.into(), None, None).unwrap();
mailbox::dispatch(MAILBOX, domain, route, warp_msg.into(), None, None, vec![]).unwrap();

match token_mode {
TokenModeMsg::Bridged(_) => {
Expand Down
Loading

0 comments on commit ac8cd58

Please sign in to comment.