mars_core/
helpers.rs

1use cosmwasm_std::{
2    to_binary, Addr, Api, QuerierWrapper, QueryRequest, StdError, StdResult, Uint128, WasmQuery,
3};
4
5use crate::{error::MarsError, math::decimal::Decimal};
6use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse};
7use std::convert::TryInto;
8
9// CW20
10pub fn cw20_get_balance(
11    querier: &QuerierWrapper,
12    token_address: Addr,
13    balance_address: Addr,
14) -> StdResult<Uint128> {
15    let query: BalanceResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
16        contract_addr: token_address.into(),
17        msg: to_binary(&Cw20QueryMsg::Balance {
18            address: balance_address.into(),
19        })?,
20    }))?;
21
22    Ok(query.balance)
23}
24
25pub fn cw20_get_total_supply(querier: &QuerierWrapper, token_address: Addr) -> StdResult<Uint128> {
26    let query = cw20_get_info(querier, token_address)?;
27    Ok(query.total_supply)
28}
29
30pub fn cw20_get_symbol(querier: &QuerierWrapper, token_address: Addr) -> StdResult<String> {
31    let query = cw20_get_info(querier, token_address)?;
32    Ok(query.symbol)
33}
34
35pub fn cw20_get_info(
36    querier: &QuerierWrapper,
37    token_address: Addr,
38) -> StdResult<TokenInfoResponse> {
39    let query: TokenInfoResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
40        contract_addr: token_address.into(),
41        msg: to_binary(&Cw20QueryMsg::TokenInfo {})?,
42    }))?;
43
44    Ok(query)
45}
46
47pub fn read_be_u64(input: &[u8]) -> StdResult<u64> {
48    let num_of_bytes = std::mem::size_of::<u64>();
49    if input.len() != num_of_bytes {
50        return Err(StdError::generic_err(format!(
51            "Expected slice length to be {}, received length of {}",
52            num_of_bytes,
53            input.len()
54        )));
55    };
56    let slice_to_array_result = input[0..num_of_bytes].try_into();
57
58    match slice_to_array_result {
59        Ok(array) => Ok(u64::from_be_bytes(array)),
60        Err(err) => Err(StdError::generic_err(format!(
61            "Error converting slice to array: {}",
62            err
63        ))),
64    }
65}
66
67/// Used when unwrapping an optional address sent in a contract call by a user.
68/// Validates addreess if present, otherwise uses a given default value.
69pub fn option_string_to_addr(
70    api: &dyn Api,
71    option_string: Option<String>,
72    default: Addr,
73) -> StdResult<Addr> {
74    match option_string {
75        Some(input_addr) => api.addr_validate(&input_addr),
76        None => Ok(default),
77    }
78}
79
80pub fn decimal_param_le_one(param_value: &Decimal, param_name: &str) -> Result<(), MarsError> {
81    if !param_value.le(&Decimal::one()) {
82        Err(MarsError::InvalidParam {
83            param_name: param_name.to_string(),
84            invalid_value: param_value.to_string(),
85            predicate: "<= 1".to_string(),
86        })
87    } else {
88        Ok(())
89    }
90}
91
92pub fn zero_address() -> Addr {
93    Addr::unchecked("")
94}