diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 08831f6cb..6344668e9 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -269,7 +269,7 @@ mod test { attr, coin, coins, AllBalanceResponse, BankMsg, BankQuery, Event, Reply, SubMsg, WasmMsg, }; - use crate::test_helpers::contracts::{payout, reflect}; + use crate::test_helpers::contracts::{hackatom, payout, reflect}; use crate::test_helpers::{CustomMsg, EmptyMsg}; use crate::transactions::StorageTransaction; use crate::BankKeeper; @@ -776,4 +776,45 @@ mod test { let committed = query_app(&app, &rcpt); assert_eq!(coins(37, "eth"), committed); } + + #[test] + fn sent_funds_properly_visible_on_execution() { + // Testing if funds on contract are properly visible on contract. + // Hackatom contract is initialized with 10btc. Then, the contract is executed, with + // additional 20btc. Then beneficiary balance is checked - expeced value is 30btc. 10btc + // would mean that sending tokens with message is not visible for this very message, and + // 20btc means, that only such just send funds are visible. + let mut app = mock_app(); + + let owner = Addr::unchecked("owner"); + let beneficiary = Addr::unchecked("beneficiary"); + app.init_bank_balance(&owner, coins(30, "btc")).unwrap(); + + let contract_id = app.store_code(hackatom::contract()); + let contract = app + .instantiate_contract( + contract_id, + owner.clone(), + &hackatom::InitMsg { + beneficiary: beneficiary.as_str().to_owned(), + }, + &coins(10, "btc"), + "Hackatom", + ) + .unwrap(); + + app.execute_contract( + owner.clone(), + contract.clone(), + &EmptyMsg {}, + &coins(20, "btc"), + ) + .unwrap(); + + // Check balance of all accounts to ensure no tokens where burned or created, and they are + // in correct places + assert_eq!(get_balance(&app, &owner), &[]); + assert_eq!(get_balance(&app, &contract), &[]); + assert_eq!(get_balance(&app, &beneficiary), coins(30, "btc")); + } } diff --git a/packages/multi-test/src/test_helpers/contracts.rs b/packages/multi-test/src/test_helpers/contracts.rs index a7a11077f..4c843873e 100644 --- a/packages/multi-test/src/test_helpers/contracts.rs +++ b/packages/multi-test/src/test_helpers/contracts.rs @@ -1,5 +1,6 @@ //! Module for simple contracts to be used in tests pub mod error; +pub mod hackatom; pub mod payout; pub mod reflect; diff --git a/packages/multi-test/src/test_helpers/contracts/hackatom.rs b/packages/multi-test/src/test_helpers/contracts/hackatom.rs new file mode 100644 index 000000000..b28511c99 --- /dev/null +++ b/packages/multi-test/src/test_helpers/contracts/hackatom.rs @@ -0,0 +1,52 @@ +//! Simplified contract which when executed releases the funds to beneficiary + +use cosmwasm_std::{ + to_binary, BankMsg, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdError, +}; +use cw_storage_plus::Item; +use serde::{Deserialize, Serialize}; + +use crate::{test_helpers::EmptyMsg, Contract, ContractWrapper}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InitMsg { + pub beneficiary: String, +} + +const HACKATOM: Item = Item::new("hackatom"); + +fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InitMsg, +) -> Result { + HACKATOM.save(deps.storage, &msg)?; + Ok(Response::default()) +} + +fn execute( + deps: DepsMut, + env: Env, + _info: MessageInfo, + _msg: EmptyMsg, +) -> Result { + let init = HACKATOM.load(deps.storage)?; + let balance = deps.querier.query_all_balances(env.contract.address)?; + + let resp = Response::new().add_message(BankMsg::Send { + to_address: init.beneficiary.clone(), + amount: balance, + }); + + Ok(resp) +} + +fn query(_deps: Deps, _env: Env, msg: EmptyMsg) -> Result { + to_binary(&msg) +} + +pub fn contract() -> Box> { + let contract = ContractWrapper::new(execute, instantiate, query); + Box::new(contract) +}