1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::{Addr, Uint128};
use cw20::Cw20ReceiveMsg;
use crate::asset::Asset;
use crate::math::decimal::Decimal;
use super::interest_rate_models::InterestRateModelParams;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
/// Market configuration
pub config: CreateOrUpdateConfig,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[allow(clippy::large_enum_variant)]
pub enum ExecuteMsg {
/// Implementation of cw20 receive msg
Receive(Cw20ReceiveMsg),
/// Update contract config (only owner can call)
UpdateConfig { config: CreateOrUpdateConfig },
/// Initialize an asset on the money market (only owner can call)
InitAsset {
/// Asset related info
asset: Asset,
/// Asset parameters
asset_params: InitOrUpdateAssetParams,
/// Asset symbol to be used in maToken name and description. If non is provided,
/// denom will be used for native and token symbol will be used for cw20. Mostly
/// useful for native assets since it's denom (e.g.: uluna, uusd) does not match it's
/// user facing symbol (LUNA, UST) which should be used in maToken's attributes
/// for the sake of consistency
asset_symbol: Option<String>,
},
/// Callback sent from maToken contract after instantiated
InitAssetTokenCallback {
/// Either the denom for a terra native asset or address for a cw20 token
/// in bytes
reference: Vec<u8>,
},
/// Update an asset on the money market (only owner can call)
UpdateAsset {
/// Asset related info
asset: Asset,
/// Asset parameters
asset_params: InitOrUpdateAssetParams,
},
/// Update uncollateralized loan limit for a given user and asset.
/// Overrides previous value if any. A limit of zero means no
/// uncollateralized limit and the debt in that asset needs to be
/// collateralized (only owner can call)
UpdateUncollateralizedLoanLimit {
/// Address that receives the credit
user_address: String,
/// Asset the user receives the credit in
asset: Asset,
/// Limit for the uncolateralize loan.
new_limit: Uint128,
},
/// Deposit Terra native coins. Deposited coins must be sent in the transaction
/// this call is made
DepositNative {
/// Denom used in Terra (e.g: uluna, uusd)
denom: String,
/// Address that will receive the maTokens
on_behalf_of: Option<String>,
},
/// Withdraw an amount of the asset burning an equivalent amount of maTokens.
/// If asset is a Terra native token, the amount sent to the user
/// is selected so that the sum of the transfered amount plus the stability tax
/// payed is equal to the withdrawn amount.
Withdraw {
/// Asset to withdraw
asset: Asset,
/// Amount to be withdrawn. If None is specified, the full maToken balance will be
/// burned in exchange for the equivalent asset amount.
amount: Option<Uint128>,
/// The address where the withdrawn amount is sent
recipient: Option<String>,
},
/// Borrow Terra native coins. If borrow allowed, amount is added to caller's debt
/// and sent to the address. If asset is a Terra native token, the amount sent
/// is selected so that the sum of the transfered amount plus the stability tax
/// payed is equal to the borrowed amount.
Borrow {
/// Asset to borrow
asset: Asset,
/// Amount to borrow
amount: Uint128,
/// The address where the borrowed amount is sent
recipient: Option<String>,
},
/// Repay Terra native coins loan. Coins used to repay must be sent in the
/// transaction this call is made.
RepayNative {
/// Denom used in Terra (e.g: uluna, uusd)
denom: String,
/// Repay the funds for the user
on_behalf_of: Option<String>,
},
/// Liquidate under-collateralized native loans. Coins used to repay must be sent in the
/// transaction this call is made.
LiquidateNative {
/// Collateral asset liquidator gets from the borrower
collateral_asset: Asset,
/// Denom used in Terra (e.g: uluna, uusd) of the debt asset
debt_asset_denom: String,
/// The address of the borrower getting liquidated
user_address: String,
/// Whether the liquidator gets liquidated collateral in maToken (true) or
/// the underlying collateral asset (false)
receive_ma_token: bool,
},
/// Update (enable / disable) asset as collateral for the caller
UpdateAssetCollateralStatus {
/// Asset to update status for
asset: Asset,
/// Option to enable (true) / disable (false) asset as collateral
enable: bool,
},
/// Called by liquidity token (maToken). Validate liquidity token transfer is valid
/// and update collateral status
FinalizeLiquidityTokenTransfer {
/// Token sender. Address is trusted because it should have been verified in
/// the token contract
sender_address: Addr,
/// Token recipient. Address is trusted because it should have been verified in
/// the token contract
recipient_address: Addr,
/// Sender's balance before the token transfer
sender_previous_balance: Uint128,
/// Recipient's balance before the token transfer
recipient_previous_balance: Uint128,
/// Transfer amount
amount: Uint128,
},
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ReceiveMsg {
/// Deposit sent cw20 tokens
DepositCw20 {
/// Deposit the funds for the user
on_behalf_of: Option<String>,
},
/// Repay sent cw20 tokens
RepayCw20 {
/// Repay the funds for the user
on_behalf_of: Option<String>,
},
/// Liquidate under-collateralized cw20 loan using the sent cw20 tokens.
LiquidateCw20 {
/// Collateral asset liquidator gets from the borrower
collateral_asset: Asset,
/// The address of the borrower getting liquidated
user_address: String,
/// Whether the liquidator gets liquidated collateral in maToken (true) or
/// the underlying collateral asset (false)
receive_ma_token: bool,
},
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct CreateOrUpdateConfig {
pub owner: Option<String>,
pub address_provider_address: Option<String>,
pub ma_token_code_id: Option<u64>,
pub close_factor: Option<Decimal>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InitOrUpdateAssetParams {
/// Initial borrow rate
pub initial_borrow_rate: Option<Decimal>,
/// Portion of the borrow rate that is kept as protocol rewards
pub reserve_factor: Option<Decimal>,
/// Max uusd that can be borrowed per uusd of collateral when using the asset as collateral
pub max_loan_to_value: Option<Decimal>,
/// uusd amount in debt position per uusd of asset collateral that if surpassed makes the user's position liquidatable.
pub liquidation_threshold: Option<Decimal>,
/// Bonus amount of collateral liquidator get when repaying user's debt (Will get collateral
/// from user in an amount equal to debt repayed + bonus)
pub liquidation_bonus: Option<Decimal>,
/// Interest rate strategy to calculate borrow_rate and liquidity_rate
pub interest_rate_model_params: Option<InterestRateModelParams>,
/// If false cannot do any action (deposit/withdraw/borrow/repay/liquidate)
pub active: Option<bool>,
/// If false cannot deposit
pub deposit_enabled: Option<bool>,
/// If false cannot borrow
pub borrow_enabled: Option<bool>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
/// Get config
Config {},
/// Get asset market
Market { asset: Asset },
/// Get a list of all markets. Returns MarketsListResponse
MarketsList {},
/// Get uncollateralized limit for given asset and user.
/// Returns UncollateralizedLoanLimitResponse
UncollateralizedLoanLimit { user_address: String, asset: Asset },
/// Get all debt positions for a user. Returns UsetDebtResponse
UserDebt { user_address: String },
/// Get user debt position for a specific asset. Returns UserAssetDebtResponse
UserAssetDebt { user_address: String, asset: Asset },
/// Get info about whether or not user is using each asset as collateral.
/// Returns UserCollateralResponse
UserCollateral { user_address: String },
/// Get user position. Returns UserPositionResponse
UserPosition { user_address: String },
/// Get liquidity scaled amount for a given underlying asset amount
/// (i.e: how much maTokens will get minted if the given amount is deposited)
ScaledLiquidityAmount { asset: Asset, amount: Uint128 },
/// Get equivalent scaled debt for a given underlying asset amount.
/// (i.e: how much scaled debt is added if the given amount is borrowed)
ScaledDebtAmount { asset: Asset, amount: Uint128 },
/// Get underlying asset amount for a given maToken balance.
UnderlyingLiquidityAmount {
ma_token_address: String,
amount_scaled: Uint128,
},
/// Get underlying debt amount for a given asset and scaled amounts.
/// (i.e: How much underlying asset needs to be repaid to cancel a given scaled debt
/// amount stored in state)
UnderlyingDebtAmount {
asset: Asset,
amount_scaled: Uint128,
},
}