1use cosmwasm_std::{to_binary, Addr, BankMsg, Coin, CosmosMsg, Deps, StdResult, Uint128, WasmMsg};
2use cw20::Cw20ExecuteMsg;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use crate::helpers::cw20_get_balance;
7use crate::tax::deduct_tax;
8use astroport::asset::AssetInfo as AstroportAssetInfo;
9
10#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
13#[serde(rename_all = "snake_case")]
14pub enum Asset {
15 Cw20 { contract_addr: String },
16 Native { denom: String },
17}
18
19impl Asset {
20 pub fn get_attributes(&self) -> (String, Vec<u8>, AssetType) {
24 match &self {
25 Asset::Native { denom } => {
26 let asset_reference = denom.as_bytes().to_vec();
27 (denom.clone(), asset_reference, AssetType::Native)
28 }
29 Asset::Cw20 { contract_addr } => {
30 let lower_case_contract_addr = contract_addr.to_lowercase();
31 let asset_reference = lower_case_contract_addr.as_bytes().to_vec();
32 (lower_case_contract_addr, asset_reference, AssetType::Cw20)
33 }
34 }
35 }
36
37 pub fn get_reference(&self) -> Vec<u8> {
39 match &self {
40 Asset::Native { denom } => denom.as_bytes().to_vec(),
41 Asset::Cw20 { contract_addr } => contract_addr.to_lowercase().as_bytes().to_vec(),
42 }
43 }
44}
45
46impl From<&AstroportAssetInfo> for Asset {
48 fn from(info: &AstroportAssetInfo) -> Self {
49 match info {
50 AstroportAssetInfo::Token { contract_addr } => Asset::Cw20 {
51 contract_addr: contract_addr.to_string(),
52 },
53 AstroportAssetInfo::NativeToken { denom } => Asset::Native {
54 denom: denom.clone(),
55 },
56 }
57 }
58}
59
60#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, JsonSchema)]
61#[serde(rename_all = "snake_case")]
62pub enum AssetType {
63 Cw20,
64 Native,
65}
66
67pub fn build_send_asset_with_tax_deduction_msg(
72 deps: Deps,
73 recipient_address: Addr,
74 asset_label: String,
75 asset_type: AssetType,
76 amount: Uint128,
77) -> StdResult<CosmosMsg> {
78 match asset_type {
79 AssetType::Native => Ok(build_send_native_asset_with_tax_deduction_msg(
80 deps,
81 recipient_address,
82 asset_label,
83 amount,
84 )?),
85 AssetType::Cw20 => build_send_cw20_token_msg(recipient_address, asset_label, amount),
86 }
87}
88
89pub fn build_send_native_asset_with_tax_deduction_msg(
94 deps: Deps,
95 recipient_address: Addr,
96 denom: String,
97 amount: Uint128,
98) -> StdResult<CosmosMsg> {
99 Ok(CosmosMsg::Bank(BankMsg::Send {
100 to_address: recipient_address.into(),
101 amount: vec![deduct_tax(deps, Coin { denom, amount })?],
102 }))
103}
104
105pub fn build_send_cw20_token_msg(
106 recipient_address: Addr,
107 token_contract_address_unchecked: String,
108 amount: Uint128,
109) -> StdResult<CosmosMsg> {
110 Ok(CosmosMsg::Wasm(WasmMsg::Execute {
111 contract_addr: token_contract_address_unchecked,
112 msg: to_binary(&Cw20ExecuteMsg::Transfer {
113 recipient: recipient_address.into(),
114 amount,
115 })?,
116 funds: vec![],
117 }))
118}
119
120pub fn get_asset_balance(
122 deps: Deps,
123 address: Addr,
124 asset_label: String,
125 asset_type: AssetType,
126) -> StdResult<Uint128> {
127 match asset_type {
128 AssetType::Native => {
129 let balance_query = deps.querier.query_balance(address, asset_label.as_str())?;
130 Ok(balance_query.amount)
131 }
132 AssetType::Cw20 => {
133 let token_addr = deps.api.addr_validate(&asset_label)?;
134 cw20_get_balance(&deps.querier, token_addr, address)
135 }
136 }
137}