templar_market_contract/
impl_token_receiver.rs1use near_contract_standards::fungible_token::receiver::FungibleTokenReceiver;
2use near_sdk::{env, json_types::U128, near, require, AccountId, PromiseOrValue};
3#[allow(clippy::wildcard_imports)]
4use near_sdk_contract_tools::mt::*;
5use templar_common::{
6 asset::{BorrowAssetAmount, CollateralAssetAmount, ReturnStyle},
7 market::DepositMsg,
8 self_ext,
9};
10
11use crate::{Contract, ContractExt};
12
13#[near]
14impl FungibleTokenReceiver for Contract {
15 fn ft_on_transfer(
16 &mut self,
17 sender_id: AccountId,
18 amount: U128,
19 msg: String,
20 ) -> PromiseOrValue<U128> {
21 const RETURN_STYLE: ReturnStyle = ReturnStyle::Nep141FtTransferCall;
22
23 let msg = near_sdk::serde_json::from_str::<DepositMsg>(&msg)
24 .unwrap_or_else(|_| templar_common::panic_with_message("Invalid deposit msg"));
25
26 let asset_id = env::predecessor_account_id();
27
28 let use_borrow_asset = || {
29 if !self.configuration.borrow_asset.is_nep141(&asset_id) {
30 templar_common::panic_with_message("Unsupported borrow asset");
31 }
32
33 BorrowAssetAmount::new(amount.0)
34 };
35
36 let use_collateral_asset = || {
37 if !self.configuration.collateral_asset.is_nep141(&asset_id) {
38 templar_common::panic_with_message("Unsupported collateral asset");
39 }
40
41 CollateralAssetAmount::new(amount.0)
42 };
43
44 match msg {
45 DepositMsg::Supply => {
46 let amount = use_borrow_asset();
47
48 self.execute_supply(sender_id, amount);
49
50 PromiseOrValue::Value(U128(0))
51 }
52 DepositMsg::Collateralize => {
53 let amount = use_collateral_asset();
54
55 self.retrieve_price_pair()
56 .then(
57 self_ext!(Self::GAS_COLLATERALIZE_TRANSFER_CALL_01_CONSUME_PRICE)
58 .collateralize_transfer_call_01_consume_price(
59 sender_id,
60 amount,
61 RETURN_STYLE,
62 ),
63 )
64 .into()
65 }
66 DepositMsg::Repay => {
67 let amount = use_borrow_asset();
68
69 self.retrieve_price_pair()
70 .then(
71 self_ext!(Self::GAS_REPAY_TRANSFER_CALL_01_CONSUME_PRICE)
72 .repay_transfer_call_01_consume_price(sender_id, amount, RETURN_STYLE),
73 )
74 .into()
75 }
76 DepositMsg::RepayAccount(msg) => {
77 let amount = use_borrow_asset();
78
79 self.retrieve_price_pair()
80 .then(
81 self_ext!(Self::GAS_REPAY_TRANSFER_CALL_01_CONSUME_PRICE)
82 .repay_transfer_call_01_consume_price(
83 msg.account_id,
84 amount,
85 RETURN_STYLE,
86 ),
87 )
88 .into()
89 }
90 DepositMsg::Liquidate(msg) => {
91 let amount = use_borrow_asset();
92
93 self.retrieve_price_pair()
94 .then(
95 self_ext!(Self::GAS_LIQUIDATE_TRANSFER_CALL_01_CONSUME_PRICE)
96 .liquidate_transfer_call_01_consume_price(
97 sender_id,
98 amount,
99 msg,
100 RETURN_STYLE,
101 ),
102 )
103 .into()
104 }
105 }
106 }
107}
108
109#[near]
110impl Nep245Receiver for Contract {
111 fn mt_on_transfer(
112 &mut self,
113 sender_id: AccountId,
114 previous_owner_ids: Vec<AccountId>,
115 token_ids: Vec<TokenId>,
116 amounts: Vec<U128>,
117 msg: String,
118 ) -> PromiseOrValue<Vec<U128>> {
119 const RETURN_STYLE: ReturnStyle = ReturnStyle::Nep245MtTransferCall;
120
121 let _ = sender_id;
124
125 let msg = near_sdk::serde_json::from_str::<DepositMsg>(&msg)
126 .unwrap_or_else(|_| templar_common::panic_with_message("Invalid deposit msg"));
127
128 let contract_id = env::predecessor_account_id();
129
130 require!(
131 token_ids.len() == 1,
132 "This contract only accepts one token at a time."
133 );
134 require!(
135 previous_owner_ids.len() == 1 && amounts.len() == 1,
136 "Invalid input length"
137 );
138
139 let token_id = &token_ids[0];
140 let sender_id = previous_owner_ids[0].clone();
141 let amount = amounts[0];
142
143 let use_borrow_asset = || {
144 if !self
145 .configuration
146 .borrow_asset
147 .is_nep245(&contract_id, token_id)
148 {
149 templar_common::panic_with_message("Unsupported borrow asset");
150 }
151
152 BorrowAssetAmount::new(amount.0)
153 };
154
155 let use_collateral_asset = || {
156 if !self
157 .configuration
158 .collateral_asset
159 .is_nep245(&contract_id, token_id)
160 {
161 templar_common::panic_with_message("Unsupported collateral asset");
162 }
163
164 CollateralAssetAmount::new(amount.0)
165 };
166
167 match msg {
168 DepositMsg::Supply => {
169 let amount = use_borrow_asset();
170
171 self.execute_supply(sender_id, amount);
172
173 PromiseOrValue::Value(vec![U128(0)])
174 }
175 DepositMsg::Collateralize => {
176 let amount = use_collateral_asset();
177
178 self.retrieve_price_pair()
179 .then(
180 self_ext!(Self::GAS_COLLATERALIZE_TRANSFER_CALL_01_CONSUME_PRICE)
181 .collateralize_transfer_call_01_consume_price(
182 sender_id,
183 amount,
184 RETURN_STYLE,
185 ),
186 )
187 .into()
188 }
189 DepositMsg::Repay => {
190 let amount = use_borrow_asset();
191
192 self.retrieve_price_pair()
193 .then(
194 self_ext!(Self::GAS_REPAY_TRANSFER_CALL_01_CONSUME_PRICE)
195 .repay_transfer_call_01_consume_price(sender_id, amount, RETURN_STYLE),
196 )
197 .into()
198 }
199 DepositMsg::RepayAccount(msg) => {
200 let amount = use_borrow_asset();
201
202 self.retrieve_price_pair()
203 .then(
204 self_ext!(Self::GAS_REPAY_TRANSFER_CALL_01_CONSUME_PRICE)
205 .repay_transfer_call_01_consume_price(
206 msg.account_id,
207 amount,
208 RETURN_STYLE,
209 ),
210 )
211 .into()
212 }
213 DepositMsg::Liquidate(msg) => {
214 let amount = use_borrow_asset();
215
216 self.retrieve_price_pair()
217 .then(
218 self_ext!(Self::GAS_LIQUIDATE_TRANSFER_CALL_01_CONSUME_PRICE)
219 .liquidate_transfer_call_01_consume_price(
220 sender_id,
221 amount,
222 msg,
223 RETURN_STYLE,
224 ),
225 )
226 .into()
227 }
228 }
229 }
230}