How to create a smart contract to hold and redistribute UST?


I’d like to develop a small game where people could play with UST. Basically they send 5 UST to answer a question and if it’s the good answer, they can claim a reward (eg 10 UST).

However I do not find ressources to help me develop a smart contract which hold coins and redistributes them. I looked at Cosmwasm, at Terra Academy and onto some smart contract (eg terraswap or astoport) but did not really find what I was looking for.

Where should I look ?


Sending funds to a smart contract is no different from sending funds to a regular account:

  const send = new MsgSend( 
    dest,  // <- smart contract addr
    { uusd: amount }

Retrieving funds from a smart contract will require you to encode that functionality in smart contract. e.g.

    let balance = query_balance(&deps.querier, env.contract.address.clone(), "uusd".to_string())?;
    let msg = CosmosMsg::Bank(BankMsg::Send {
        to_address: dest,
        amount: vec![deduct_tax(
            Coin {
                denom: "uusd".to_string(),
                amount: balance,

Here is a smart contract:

I highly recommend playing around in LocalTerra before doing any deployment.

receiving native coins is easy.

lines 309 - 316 is it. that will put the native coins into the contract.

as @Duncan_Idaho mentioned, sending coins is not that hard.
another example of it is here -

receiving CW20’s is more challenging. you need to send a message to the CW20 contract, with a message to yours

msg=$(base64 << CAT

this causes the CW20 to send you a message

this is an example of how that can be handled.


1 Like

I’m trying to understand the native coin example. If 309-316 never happens and you don’t retrieve the coin info into your contract, what would happen to the coins sent from the initial Msg?

You can try this on testnet.
Coins sent to a contract will sit in the contracts balance.
If the contract isn’t designed to handle it, they will just accumulate.

pub fn execute_transfer_usd(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,

)-> Result<Response, ContractError>
    let  config = TOKEN_INFO.load(;
    if config.owner != info.sender 
        return Err(ContractError::Unauthorized {}); 
    let mut messages: Vec<CosmosMsg> = vec![];
   // let balance = query_balance( env.contract.address.clone(), "uusd".to_string())?;
   messages.push(CosmosMsg::Bank(BankMsg::Send {
        to_address: info.sender.to_string(),
        amount: vec![Coin {
            amount: amount,

    let res = Response::new()
    .add_attribute("action", "transferusd")
    .add_attribute("to", info.sender)
    .add_attribute("amount", amount);


this function execute successful but not sending uluna or ussd to my wallet
and the transaction you can see there

Looks like you forgot to
add_message() the Bank:Send to the response.

1 Like

yes i forget it

Thanks a lot for your ressources.

Is there a way to sent UST to my contract and in the same message, execute a function ?
I understood that info.funds are the funds of the sender’s wallet.

Since I have to send a message to send funds, and another one to call my smart contract, is there a standard way to check if I send the correct amount of UST ? Or can it be done in one message ?

Yeah, any executable message that you handle can carry coins. Check out the MessageInfo data you get in every message handler, you’ll find references to the sender and any funds in there.

I am developing smart contract with terra-peep721 and want to send LUNA or UST or my cw20 token to other wallets.
I think I have to use Terra.js from the frontend.
I’d like to know how to send LUNA with the connected wallet with Terra.js.
And also smart contract too.