Skip to content

Commit c82858d

Browse files
authored
Merge pull request #184 from mars-protocol/public/latest-master
Move latest public master changes
2 parents 17471d8 + 0227e68 commit c82858d

File tree

8 files changed

+471
-63
lines changed

8 files changed

+471
-63
lines changed

contracts/incentives/src/astro_incentives.rs

Lines changed: 78 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use std::collections::HashMap;
33
use astroport_v5::incentives::ExecuteMsg;
44
use cosmwasm_std::{
55
ensure_eq, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, DepsMut, Env, Event, MessageInfo,
6-
Order::Ascending, Response, StdResult, Storage, Uint128, WasmMsg,
6+
Order::{self, Ascending},
7+
Response, StdResult, Storage, Uint128, WasmMsg,
78
};
89
use mars_types::{
910
address_provider::{helpers::query_contract_addrs, MarsAddressType},
@@ -18,7 +19,10 @@ use crate::{
1819
compute_updated_astro_incentive_states, MaybeMutStorage,
1920
},
2021
query::query_unclaimed_astro_lp_rewards,
21-
state::{ASTRO_INCENTIVE_STATES, ASTRO_TOTAL_LP_DEPOSITS, ASTRO_USER_LP_DEPOSITS, CONFIG},
22+
state::{
23+
ASTRO_INCENTIVE_STATES, ASTRO_TOTAL_LP_DEPOSITS, ASTRO_USER_LP_DEPOSITS, CONFIG,
24+
USER_ASTRO_INCENTIVE_STATES,
25+
},
2226
ContractError::{self, NoStakedLp},
2327
};
2428

@@ -232,29 +236,76 @@ fn decrement_staked_lp(
232236
account_id: &str,
233237
lp_coin: &Coin,
234238
) -> Result<(), ContractError> {
235-
// Update user staked lp state
236-
ASTRO_USER_LP_DEPOSITS.update(
237-
store,
238-
(account_id, &lp_coin.denom),
239-
|existing| -> StdResult<_> {
240-
Ok(existing
241-
.ok_or(ContractError::NoStakedLp {
242-
account_id: account_id.to_string(),
243-
denom: lp_coin.denom.clone(),
244-
})?
245-
.checked_sub(lp_coin.amount)?)
246-
},
247-
)?;
239+
update_user_staked_lp(store, lp_coin, account_id)?;
240+
update_total_staked_lp(store, lp_coin)?;
248241

249-
// Update total staked lp state
250-
ASTRO_TOTAL_LP_DEPOSITS.update(store, &lp_coin.denom, |existing| -> StdResult<_> {
251-
Ok(existing
252-
.ok_or(ContractError::NoDeposits {
242+
Ok(())
243+
}
244+
245+
fn update_user_staked_lp(
246+
store: &mut dyn Storage,
247+
lp_coin: &Coin,
248+
account_id: &str,
249+
) -> Result<(), ContractError> {
250+
let key = (account_id, lp_coin.denom.as_str());
251+
let existing_amount =
252+
ASTRO_USER_LP_DEPOSITS.may_load(store, key)?.ok_or_else(|| ContractError::NoStakedLp {
253+
account_id: account_id.to_string(),
254+
denom: lp_coin.denom.clone(),
255+
})?;
256+
257+
let new_amount = existing_amount.checked_sub(lp_coin.amount)?;
258+
if new_amount.is_zero() {
259+
ASTRO_USER_LP_DEPOSITS.remove(store, key);
260+
261+
// Get all incentives for (user, lp_token_denom) key
262+
let prefix = USER_ASTRO_INCENTIVE_STATES.prefix((account_id, lp_coin.denom.as_str()));
263+
264+
// Iterate over all reward_denom keys
265+
let keys_to_remove =
266+
prefix.keys(store, None, None, Order::Ascending).collect::<StdResult<Vec<String>>>()?;
267+
268+
// Delete each matching (account_id, lp_token_denom, reward_denom) incentive.
269+
for incentive_denom in keys_to_remove {
270+
USER_ASTRO_INCENTIVE_STATES
271+
.remove(store, (account_id, lp_coin.denom.as_str(), &incentive_denom));
272+
}
273+
} else {
274+
ASTRO_USER_LP_DEPOSITS.save(store, key, &new_amount)?;
275+
}
276+
277+
Ok(())
278+
}
279+
280+
fn update_total_staked_lp(store: &mut dyn Storage, lp_coin: &Coin) -> Result<(), ContractError> {
281+
let lp_denom = lp_coin.denom.as_str();
282+
283+
let total_staked_lp_amount =
284+
ASTRO_TOTAL_LP_DEPOSITS.may_load(store, lp_denom)?.ok_or_else(|| {
285+
ContractError::NoDeposits {
253286
denom: lp_coin.denom.clone(),
254-
})?
255-
.checked_sub(lp_coin.amount)?)
256-
})?;
287+
}
288+
})?;
289+
290+
let new_total_staked_lp_amount = total_staked_lp_amount.checked_sub(lp_coin.amount)?;
291+
292+
// If the new amount is zero, remove the entry and all associated incentive states
293+
if new_total_staked_lp_amount.is_zero() {
294+
ASTRO_TOTAL_LP_DEPOSITS.remove(store, lp_denom);
295+
296+
// Get all incentive states for the lp_key
297+
let prefix = ASTRO_INCENTIVE_STATES.prefix(lp_denom);
298+
let keys_to_remove =
299+
prefix.keys(store, None, None, Order::Ascending).collect::<StdResult<Vec<String>>>()?;
257300

301+
// Remove all incentive states related to the lp_key
302+
for incentive_denom in keys_to_remove {
303+
ASTRO_INCENTIVE_STATES.remove(store, (lp_denom, incentive_denom.as_str()));
304+
}
305+
} else {
306+
// Save the updated staked amount if it's not zero
307+
ASTRO_TOTAL_LP_DEPOSITS.save(store, lp_denom, &new_total_staked_lp_amount)?;
308+
}
258309
Ok(())
259310
}
260311

@@ -342,13 +393,17 @@ fn claim_rewards_for_staked_lp_position(
342393
lp_denom,
343394
staked_lp_amount,
344395
)?;
396+
let total_claimed_amount =
397+
user_claimable_rewards.iter().fold(Uint128::zero(), |acc, coin| acc + coin.amount);
345398

346399
for coin in &user_claimable_rewards {
347400
event = event
348401
.add_attribute("denom", coin.denom.to_string())
349402
.add_attribute("amount", coin.amount.to_string());
350403
}
351-
res = if !user_claimable_rewards.is_empty() {
404+
405+
// Check if rewards not already claimed in the same block
406+
res = if !user_claimable_rewards.is_empty() && !total_claimed_amount.is_zero() {
352407
// Send the claimed rewards to the credit manager
353408
let send_rewards_to_cm_msg = CosmosMsg::Bank(BankMsg::Send {
354409
to_address: credit_manager_addr.to_string(),

contracts/incentives/src/error.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::string::FromUtf8Error;
22

3-
use cosmwasm_std::{Coin, StdError};
3+
use cosmwasm_std::{Coin, OverflowError, StdError};
44
use mars_owner::OwnerError;
55
use mars_types::error::MarsError;
66
use mars_utils::error::{GuardError, ValidationError};
@@ -14,6 +14,9 @@ pub enum ContractError {
1414
#[error("{0}")]
1515
Validation(#[from] ValidationError),
1616

17+
#[error("{0}")]
18+
OverflowError(#[from] OverflowError),
19+
1720
#[error("{0}")]
1821
Std(#[from] StdError),
1922

contracts/incentives/src/query.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,7 @@ pub fn query_staked_astro_lp_rewards_for_coin(
199199
)
200200
.unwrap_or_default();
201201

202-
// Update our global indexes for each reward. We only accept native tokens,
203-
// cw20 will just be swallowed by contract
202+
// Update our global indexes for each reward.
204203
let incentives_to_update =
205204
compute_updated_astro_incentive_states(deps.storage, pending_rewards, lp_denom)?;
206205

0 commit comments

Comments
 (0)