Skip to content

Commit

Permalink
Zero amounts in Lend and staked_astro_lps (#421)
Browse files Browse the repository at this point in the history
* MP-2522. Filter out zero amount for staked astro lps.

* MP-2521. No error for zero lend.
  • Loading branch information
piobab authored Jul 16, 2024
1 parent e6c22e2 commit b09cf2b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 29 deletions.
26 changes: 13 additions & 13 deletions contracts/credit-manager/src/lend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use cosmwasm_std::{Coin, Deps, DepsMut, Response, Uint128};
use mars_types::credit_manager::ActionCoin;

use crate::{
error::{ContractError, ContractResult},
error::ContractResult,
state::{COIN_BALANCES, RED_BANK},
utils::{assert_coin_is_whitelisted, decrement_coin_balance},
};
Expand All @@ -15,29 +15,29 @@ pub fn lend(mut deps: DepsMut, account_id: &str, coin: &ActionCoin) -> ContractR
amount: get_lend_amount(deps.as_ref(), account_id, coin)?,
};

decrement_coin_balance(deps.storage, account_id, &amount_to_lend)?;
// Don't error if there is zero amount to lend - just return an empty response
let mut res = Response::new();
if !amount_to_lend.amount.is_zero() {
decrement_coin_balance(deps.storage, account_id, &amount_to_lend)?;

let red_bank_lend_msg = RED_BANK.load(deps.storage)?.lend_msg(&amount_to_lend, account_id)?;
let red_bank_lend_msg =
RED_BANK.load(deps.storage)?.lend_msg(&amount_to_lend, account_id)?;

Ok(Response::new()
.add_message(red_bank_lend_msg)
res = res.add_message(red_bank_lend_msg);
}

Ok(res
.add_attribute("action", "lend")
.add_attribute("account_id", account_id)
.add_attribute("coin_lent", &amount_to_lend.denom))
}

/// Queries balance to ensure passing EXACT is not too high.
/// Also asserts the amount is greater than zero.
/// Queries balance to ensure passing EXACT is not too high
fn get_lend_amount(deps: Deps, account_id: &str, coin: &ActionCoin) -> ContractResult<Uint128> {
let amount_to_lend = if let Some(amount) = coin.amount.value() {
amount
} else {
COIN_BALANCES.may_load(deps.storage, (account_id, &coin.denom))?.unwrap_or(Uint128::zero())
};

if amount_to_lend.is_zero() {
Err(ContractError::NoAmount)
} else {
Ok(amount_to_lend)
}
Ok(amount_to_lend)
}
54 changes: 39 additions & 15 deletions contracts/credit-manager/tests/tests/test_lend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ use std::ops::Add;

use cosmwasm_std::{coin, coins, Addr, Coin, OverflowError, OverflowOperation, Uint128};
use mars_credit_manager::error::ContractError;
use mars_types::credit_manager::{
Action::{Deposit, Lend},
ActionAmount, ActionCoin,
use mars_types::{
credit_manager::{
Action::{Deposit, Lend},
ActionAmount, ActionCoin, Positions,
},
health::AccountKind,
};

use super::helpers::{
Expand Down Expand Up @@ -54,20 +57,28 @@ fn can_only_lend_what_is_whitelisted() {
}

#[test]
fn lending_zero_raises() {
fn lending_zero_has_no_effect() {
let coin_info = uosmo_info();
let user = Addr::unchecked("user");
let mut mock = MockEnv::new().set_params(&[coin_info.clone()]).build().unwrap();
let account_id = mock.create_credit_account(&user).unwrap();

let res = mock.update_credit_account(
&account_id,
&user,
vec![Lend(coin_info.to_action_coin(0))],
&[],
);
mock.update_credit_account(&account_id, &user, vec![Lend(coin_info.to_action_coin(0))], &[])
.unwrap();

assert_err(res, ContractError::NoAmount)
let position = mock.query_positions(&account_id);
assert_eq!(
position,
Positions {
account_id,
account_kind: AccountKind::Default,
deposits: vec![],
debts: vec![],
lends: vec![],
vaults: vec![],
staked_astro_lps: vec![]
}
);
}

#[test]
Expand Down Expand Up @@ -104,7 +115,7 @@ fn raises_when_not_enough_assets_to_lend() {
}

#[test]
fn raises_when_attempting_to_lend_account_balance_with_no_funds() {
fn attempting_to_lend_account_balance_with_no_funds() {
let coin_info = uosmo_info();

let user_a = Addr::unchecked("user_a");
Expand All @@ -127,17 +138,30 @@ fn raises_when_attempting_to_lend_account_balance_with_no_funds() {
let red_bank_collateral = mock.query_red_bank_collateral(&account_id_a, &coin_info.denom);
assert_eq!(red_bank_collateral.amount, Uint128::zero());

let res = mock.update_credit_account(
mock.update_credit_account(
&account_id_a,
&user_a,
vec![Lend(ActionCoin {
denom: "uosmo".to_string(),
amount: ActionAmount::AccountBalance,
})],
&[],
);
)
.unwrap();

assert_err(res, ContractError::NoAmount)
let position = mock.query_positions(&account_id_a);
assert_eq!(
position,
Positions {
account_id: account_id_a,
account_kind: AccountKind::Default,
deposits: vec![],
debts: vec![],
lends: vec![],
vaults: vec![],
staked_astro_lps: vec![]
}
);
}

#[test]
Expand Down
4 changes: 3 additions & 1 deletion packages/types/src/adapters/incentives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ impl Incentives {
let response =
self.query_staked_astro_lp_positions(querier, account_id, start_after, None)?;
for item in response.data {
all_coins.push(item.lp_coin);
if !item.lp_coin.amount.is_zero() {
all_coins.push(item.lp_coin);
}
}
start_after = all_coins.last().map(|item| item.denom.clone());
has_more = response.metadata.has_more;
Expand Down

0 comments on commit b09cf2b

Please sign in to comment.