Helper library for interacting with Terra assets (SDK coins and CW20 tokens)

Overview

terra-asset

Helpers for interacting with Terra assets, including native coins and CW20 tokens

Usage

This crate contains two struct types:

  • AssetInfo stores key information of an asset type – for CW20 tokens, the contract address; for native coins, the denomination

  • Asset represents an asset of specific amount

Instances of AssetInfo and Asset can be created as follows:

use terra_asset::{AssetInfo, Asset};

// native coin
let coin_info = AssetInfo::native("uusd");

let coin = Asset::new(&coin_info, 69420);
// or
let coin = Asset::native("uusd", 69420);

// CW20 token
let token_addr = deps.api.addr_validate("token_contract_address")?;
let token_info = AssetInfo::cw20(&token_addr);

let token = Asset::new(&token_info, 12345);
// or
let token = Asset::cw20(&token_addr, 12345);

Checked and unchecked types

AssetInfo and Asset contain contract addresses of cosmwasm_std::Addr type. Additionally, they each comes with an "unchecked" counterpart where the addresses are in String type. Both the unchecked and chekced types can be serialized to / deserialized from JSON format. The checked type is intended to be saved in contract storage, while the unchecked type is intended to be passed between contracts in messages.

The following code snippets show common usage of the AssetInfo type. However, the same methods are also implemented for Asset type.

Save the checked type in storage

use cw_storage_plus::Item;

const TOKEN_INFO: Item<AssetInfo> = Item::new("token_info");

let token_info = AssetInfo::cw20(&token_addr);
TOKEN_INFO.save(deps.storage, &token_info)?;

Using the unchecked type in messages

use terra_asset::AssetInfoUnchecked;

pub struct InstantiateMsg {
    token_info: AssetInfoUnchecked,
}

Conversions between checked and unchecked types

// cast checked to unchecked type
let token_info_unchecked: AssetInfoUnchecked = token_info.into();

// cast unchecked to checked type
let token_info = token_info_unchecked.check(deps.api)?;

Tax handling

Stability fee (a.k.a. "tax") is a fees charged on Terra stablecoin transfers and considered by many developers to be a pain in the arse to work with, just as the real world tax.

Tax works as follows. Suppose Alice sends Bob 100 UST when the tax rate is 0.1%. The tax amount is 100 * 0.1% = 0.1 UST. After the transfer is executed, Bob's balance increases by 100 UST, while Alice's balance is deducted by 100.1 UST.

Note that tax is paid by whoever sends the BankMsg::Send message, not the transaction's initiator. If Alice holds some funds in a smart contract, and invokes a functions on the contract to send 100 UST. The resulting 0.1 UST tax is deducted from the contract's balance, not Alice's.

An implication of this is that if the contract only has 100 UST balance, it is impossible for it to send all 100 UST out, because it needs to reserve some funds to pay tax. In fact, at 0.1% tax rate, the maximum amount the contract can send is 99900099uusd, with 99900uusd needed for tax. After this transfer, the contract will have exactly 1uusd left, which cannot be transferred out.

The Asset type implements two helper functions for handling taxes:

deduct_tax

Calculates the deliverable amount (tax deducted) when sending an asset:

let coin = Asset::native("uusd", 100000000);
let coin_after_tax = coin.deduct_tax(&deps.querier)?;
// at 0.1% tax rate, `coin_after_tax.amount` should be 99900099

add_tax

Calculates the total cost (including tax) for sending an asset:

let coin = Asset::native("uusd", 99900099);
let coin_with_tax = coin.add_tax(&deps.querier)?;
// at 0.1% tax rate, `coin_with_tax.amount` should be 99999999

Message generation

The Asset type also comes with helper functions for generating messages:

transfer_msg

The following example creates a message for transferring 100 UST to Bob. Note that we first deduct tax before generating the message:

let coin = Asset::native("uusd", 100000000);
let msg = coin.deduct_tax(&deps.querier)?.transfer_msg("bob_address")?;
let res = Response::new().add_message(msg);

transfer_from_msg

The following example creates a message that draws 100 MIR tokens from Alice's wallet to Bob's. Note that:

  • Alice must have approved Bob to spend her tokens using CW20's IncreaseAllowance command

  • Invoking transfer_from_msg on an native coin will result in error, as native coins don't have the TransferFrom method

let token = Asset::cw20("mirror_token", 100000000);
let msg = token.transfer_from_msg("alice", "bob")?;
let res = Response::new().add_message(msg);

License

Contents of this repository are open source under GNU General Public License v3 or later versions.

You might also like...
A CosmWasm Tutorial by Terra Academy.

CosmWasm Starter Pack This is a template to build smart contracts in Rust to run inside a Cosmos SDK module on all chains that enable it. To understan

Terra liquid staking derivative

Terra liquid staking derivative. Of the community, by the community, for the community.

Outp0st is an open-source UI tool to enable next-level team collaboration on dApp development over Terra blockchain
Outp0st is an open-source UI tool to enable next-level team collaboration on dApp development over Terra blockchain

Outp0st is an open-source UI tool to enable next-level team collaboration on dApp development over Terra blockchain

This monorepository contains the source code for the smart contracts implementing bAsset Protocol on the Terra blockchain.

Crll bAsset Contracts This monorepository contains the source code for the smart contracts implementing bAsset Protocol on the Terra blockchain. You c

Uniswap V2 / constant-product AMM implemented in Solana's Anchor -- add and remove liquidity, swap tokens, earn fees

Uniswap V2 AMM implemented in Anchor programs/ammv2/src/draft.rs: outline of program with comments -- drafted before implementation Supported Instruct

nAssets are Nova Finance’s framework for building programmable assets.
nAssets are Nova Finance’s framework for building programmable assets.

nAssets are Nova Finance’s framework for building programmable assets. nAssets can be used to tokenize and store collective forms of value while also instructing assets to yield, exchange or rebalance.

Tradechain is an open source blockchain designed for fast trading & interoperability for new, existing assets

Tradechain is an open source blockchain designed for fast trading & interoperability for new, existing assets. Help build the future of trading with other Tradians.

The implementation of the chain extension for `pallet-assets`

Pallet assets chain extension ⚠️ Chain extension contains vulnerabilities: Don't use it in the production. Fixing vulnerabilities requires changes on

An HTTP proxy for assets (mainly images) to route requests through an always-encrypted connection.

camo-rs camo-rs is a frontend-compatible Rust-re-implementation of the now archived NodeJS-based atmos/camo - an HTTP proxy for assets (mainly images)

Releases(v0.2.2)
Owner
larry
smart contract developer
larry
Rust SDK for interacting with the Nile.

Nile API Rust Client This is a POC Rust client for the Nile API. Usage Source the Nile environment variables into your environment. export NILE_DEVELO

coredb-io 4 Jan 12, 2023
A cw20 based DAO.

cw20 DAO NOT PRODUCTION READY This builds on cw3-flex-multisig and instead has the voting set maintained by cw20 tokens. This allows for the cw20s to

Jake Hartnell 115 Jan 1, 2023
A cw20 based DAO.

cw20 DAO NOT PRODUCTION READY This builds on cw3-flex-multisig and instead has the voting set maintained by cw20 tokens. This allows for the cw20s to

DAO DAO 114 Dec 28, 2022
Examples of cw20 usage, extracted from cw-plus, maintained by the community

CosmWasm Tokens This is a collection of cw20-related contracts extracted from cw-plus. These serve as examples of what is possible to build and as sta

CosmWasm 59 Jan 2, 2023
Blue Terra is a decentralized protocol for the global democratization of stable and accessible property rights.

??️ The official Blue Terra KYC program. Blue Terra holders interact with this program to activate the leases embedded in their NFTs.

Blue Terra 1 Jan 31, 2022
A gRPC-based scripting library for interacting with CosmWasm smart-contracts.

Cosmos Rust Script Smart contract scripting library to ease CosmWasm smart contract development and deployment. cosm-script is inspired by terra-rust-

null 11 Nov 3, 2022
The NFT smart contract powering xyz on Terra

xyz NFT Contract This repository contains the core NFT smart contract that implements xyz, a base layer for metaverses on the Terra blockchain. The xy

null 16 Sep 25, 2022
My code for the terra.academy course on CosmWasm smart contracts

CosmWasm Starter Pack This is a template to build smart contracts in Rust to run inside a Cosmos SDK module on all chains that enable it. To understan

Alex Incerti 0 Nov 7, 2021
Smart Contract for Terra Name Service

TERRA NAME SERVICE CONTRACTS Terra Name Service is to create easy-to-remember names for your Terra address like ‘dokwon.ust’ instead of ‘terra1...whez

null 12 Nov 23, 2022
Smart contracts powering Spectrum Protocol on Terra

Spectrum Core Contracts This monorepository contains the source code for the core smart contracts implementing Spectrum Protocol on the Terra blockcha

Spectrum Protocol 38 Dec 19, 2022