abstract_sdk/cw_helpers/
fees.rs1use cosmwasm_std::{CosmosMsg, Uint128};
5use cw_asset::Asset;
6
7use crate::{
8 std::objects::fee::{Fee, UsageFee},
9 AbstractSdkResult,
10};
11
12pub trait Chargeable {
14 fn charge_fee(&mut self, fee: Fee) -> AbstractSdkResult<Uint128>;
16 fn charge_usage_fee(&mut self, fee: UsageFee) -> AbstractSdkResult<Option<CosmosMsg>>;
18}
19
20impl Chargeable for Asset {
21 fn charge_fee(&mut self, fee: Fee) -> AbstractSdkResult<Uint128> {
22 let fee_amount = fee.compute(self.amount);
23 self.amount -= fee_amount;
24 Ok(fee_amount)
25 }
26
27 fn charge_usage_fee(&mut self, fee: UsageFee) -> AbstractSdkResult<Option<CosmosMsg>> {
29 let fee_amount = fee.compute(self.amount);
30 if fee_amount.is_zero() {
31 return Ok(None);
32 }
33 self.amount -= fee_amount;
34 Ok(Some(
35 Asset::new(self.info.clone(), fee_amount).transfer_msg(fee.recipient())?,
36 ))
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use cosmwasm_std::{Addr, Decimal};
43 use cw_asset::AssetInfo;
44
45 use super::*;
46
47 #[coverage_helper::test]
50 fn test_charge_fee() {
51 let info = AssetInfo::native("uusd");
52 let mut asset = Asset::new(info, 1000u128);
53 let fee = Fee::new(Decimal::percent(10)).unwrap();
54 let charged = asset.charge_fee(fee).unwrap();
55 assert_eq!(asset.amount.u128(), 900);
56 assert_eq!(charged.u128(), 100);
57 }
58 #[coverage_helper::test]
60 fn test_charge_transfer_fee() {
61 let info = AssetInfo::native("uusd");
62 let mut asset: Asset = Asset::new(info.clone(), 1000u128);
63 let fee = UsageFee::new(Decimal::percent(10), Addr::unchecked("recipient")).unwrap();
64 let msg = asset.charge_usage_fee(fee).unwrap();
65 assert_eq!(asset.amount.u128(), 900);
66 assert_eq!(
67 msg,
68 Some(
69 Asset::new(info, 100u128)
70 .transfer_msg(Addr::unchecked("recipient"))
71 .unwrap()
72 )
73 );
74
75 let fee = UsageFee::new(Decimal::zero(), Addr::unchecked("recipient")).unwrap();
77
78 let msg = asset.charge_usage_fee(fee).unwrap();
79 assert_eq!(asset.amount.u128(), 900);
80 assert_eq!(msg, None);
81 }
82}