diff --git a/contracts/warp/cw20/src/contract.rs b/contracts/warp/cw20/src/contract.rs index 31268b4c..c2f8b56c 100644 --- a/contracts/warp/cw20/src/contract.rs +++ b/contracts/warp/cw20/src/contract.rs @@ -190,6 +190,11 @@ fn transfer_remote( .route .expect("route not found"); + // validate hook if present + if let Some(ref custom_hook) = hook { + let _ = deps.api.addr_validate(&custom_hook)?; + } + let mut msgs: Vec = vec![]; // push token transfer msg @@ -298,6 +303,7 @@ mod test { const OWNER: &str = "owner"; const MAILBOX: &str = "mailbox"; const TOKEN: &str = "token"; + const CUSTOM_HOOK: &str = "custom_hook"; const CW20_BRIDGED_CODE_ID: u64 = 1; const CW20_BRIDGED_NAME: &str = "cw20-created"; @@ -515,15 +521,17 @@ mod test { } #[rstest] - #[case(1, gen_bz(32), token_mode_bridged())] - #[case(1, gen_bz(32), token_mode_collateral())] + #[case(1, gen_bz(32), token_mode_bridged(), Some(CUSTOM_HOOK), None)] + #[case(1, gen_bz(32), token_mode_collateral(), None, Some(gen_bz(100)))] #[should_panic(expected = "route not found")] - #[case(2, gen_bz(32), token_mode_collateral())] + #[case(2, gen_bz(32), token_mode_collateral(), None, None)] fn test_transfer_remote( #[values("osmo", "neutron")] hrp: &str, #[case] domain: u32, #[case] route: HexBinary, #[case] token_mode: Cw20TokenMode, + #[case] custom_hook: Option<&str>, + #[case] custom_metadata: Option, ) { let (mut deps, _) = deps( vec![(1, route.clone())], @@ -542,8 +550,8 @@ mod test { dest_domain: domain, recipient: recipient.clone(), amount: Uint128::new(100), - hook: None, - metadata: None, + hook: custom_hook.map(|h| h.to_string()), + metadata: custom_metadata.clone(), }, vec![], ); @@ -566,8 +574,15 @@ mod test { metadata: HexBinary::default(), }; - let dispatch_msg = - mailbox::dispatch(MAILBOX, domain, route, warp_msg.into(), None, None, vec![]).unwrap(); + let dispatch_msg = mailbox::dispatch( + MAILBOX, + domain, + route, + warp_msg.into(), + custom_hook.map(|h| h.to_string()), + custom_metadata, + vec![], + ).unwrap(); match token_mode { TokenModeMsg::Bridged(_) => { diff --git a/contracts/warp/native/src/contract.rs b/contracts/warp/native/src/contract.rs index 6c98872e..0981bf99 100644 --- a/contracts/warp/native/src/contract.rs +++ b/contracts/warp/native/src/contract.rs @@ -217,6 +217,11 @@ fn transfer_remote( .route .expect("route not found"); + // validate hook if present + if let Some(ref custom_hook) = hook { + let _ = deps.api.addr_validate(&custom_hook)?; + } + let mut msgs: Vec = vec![]; if mode == TokenMode::Bridged { @@ -320,6 +325,7 @@ mod test { const OWNER: &str = "owner"; const MAILBOX: &str = "mailbox"; const DENOM: &str = "utest"; + const CUSTOM_HOOK: &str = "custom_hook"; #[fixture] fn metadata(#[default(true)] empty: bool) -> Option { @@ -514,20 +520,22 @@ mod test { } #[rstest] - #[case(1, gen_bz(32), gen_bz(32), vec![coin(100, DENOM)])] - #[case(1, gen_bz(32), gen_bz(32), vec![coin(100, DENOM), coin(100, "uatom")])] + #[case(1, gen_bz(32), gen_bz(32), vec![coin(100, DENOM)], Some(CUSTOM_HOOK), None)] + #[case(1, gen_bz(32), gen_bz(32), vec![coin(100, DENOM), coin(100, "uatom")], None, Some(gen_bz(100)))] #[should_panic(expected = "route not found")] - #[case(2, gen_bz(32), gen_bz(32), vec![coin(100, DENOM)])] + #[case(2, gen_bz(32), gen_bz(32), vec![coin(100, DENOM)], None, None)] #[should_panic(expected = "no funds sent")] - #[case(1, gen_bz(32), gen_bz(32), vec![])] + #[case(1, gen_bz(32), gen_bz(32), vec![], None, None)] #[should_panic(expected = "no funds sent")] - #[case(1, gen_bz(32), gen_bz(32), vec![coin(100, "uatom")])] + #[case(1, gen_bz(32), gen_bz(32), vec![coin(100, "uatom")], None, None)] fn test_transfer_remote( mut deps: TestDeps, #[case] dest_domain: u32, #[case] dest_router: HexBinary, #[case] dest_recipient: HexBinary, #[case] funds: Vec, + #[case] custom_hook: Option<&str>, + #[case] custom_metadata: Option, ) { set_route( deps.as_mut().storage, @@ -546,8 +554,8 @@ mod test { dest_domain, recipient: dest_recipient.clone(), amount: Uint128::new(50), - hook: None, - metadata: None, + hook: custom_hook.map(|h| h.to_string()), + metadata: custom_metadata.clone(), }, funds.clone(), ); @@ -567,8 +575,8 @@ mod test { metadata: HexBinary::default(), } .into(), - None, - None, + custom_hook.map(|h| h.to_string()), + custom_metadata, [ vec![coin(50, DENOM)], funds.into_iter().filter(|v| v.denom != DENOM).collect()