templar_market_contract/
impl_token_receiver.rs

1use 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        // NEP-245: This could be an authorized account ID. We only care about
122        // the actual previous owner.
123        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}