diff --git a/contracts/credit-manager/src/lend.rs b/contracts/credit-manager/src/lend.rs index d087655b..c1ef32af 100644 --- a/contracts/credit-manager/src/lend.rs +++ b/contracts/credit-manager/src/lend.rs @@ -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}, }; @@ -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 { 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) } diff --git a/contracts/credit-manager/tests/tests/test_lend.rs b/contracts/credit-manager/tests/tests/test_lend.rs index 8dfbd4fa..1652f63b 100644 --- a/contracts/credit-manager/tests/tests/test_lend.rs +++ b/contracts/credit-manager/tests/tests/test_lend.rs @@ -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::{ @@ -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] @@ -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"); @@ -127,7 +138,7 @@ 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 { @@ -135,9 +146,22 @@ fn raises_when_attempting_to_lend_account_balance_with_no_funds() { 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] diff --git a/packages/types/src/adapters/incentives.rs b/packages/types/src/adapters/incentives.rs index fa56dfc7..e9dcbbd4 100644 --- a/packages/types/src/adapters/incentives.rs +++ b/packages/types/src/adapters/incentives.rs @@ -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;