Skip to content

Commit

Permalink
Merge pull request #184 from mars-protocol/public/latest-master
Browse files Browse the repository at this point in the history
Move latest public master changes
piobab authored Dec 4, 2024
2 parents 17471d8 + 0227e68 commit c82858d
Showing 8 changed files with 471 additions and 63 deletions.
101 changes: 78 additions & 23 deletions contracts/incentives/src/astro_incentives.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,8 @@ use std::collections::HashMap;
use astroport_v5::incentives::ExecuteMsg;
use cosmwasm_std::{
ensure_eq, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, DepsMut, Env, Event, MessageInfo,
Order::Ascending, Response, StdResult, Storage, Uint128, WasmMsg,
Order::{self, Ascending},
Response, StdResult, Storage, Uint128, WasmMsg,
};
use mars_types::{
address_provider::{helpers::query_contract_addrs, MarsAddressType},
@@ -18,7 +19,10 @@ use crate::{
compute_updated_astro_incentive_states, MaybeMutStorage,
},
query::query_unclaimed_astro_lp_rewards,
state::{ASTRO_INCENTIVE_STATES, ASTRO_TOTAL_LP_DEPOSITS, ASTRO_USER_LP_DEPOSITS, CONFIG},
state::{
ASTRO_INCENTIVE_STATES, ASTRO_TOTAL_LP_DEPOSITS, ASTRO_USER_LP_DEPOSITS, CONFIG,
USER_ASTRO_INCENTIVE_STATES,
},
ContractError::{self, NoStakedLp},
};

@@ -232,29 +236,76 @@ fn decrement_staked_lp(
account_id: &str,
lp_coin: &Coin,
) -> Result<(), ContractError> {
// Update user staked lp state
ASTRO_USER_LP_DEPOSITS.update(
store,
(account_id, &lp_coin.denom),
|existing| -> StdResult<_> {
Ok(existing
.ok_or(ContractError::NoStakedLp {
account_id: account_id.to_string(),
denom: lp_coin.denom.clone(),
})?
.checked_sub(lp_coin.amount)?)
},
)?;
update_user_staked_lp(store, lp_coin, account_id)?;
update_total_staked_lp(store, lp_coin)?;

// Update total staked lp state
ASTRO_TOTAL_LP_DEPOSITS.update(store, &lp_coin.denom, |existing| -> StdResult<_> {
Ok(existing
.ok_or(ContractError::NoDeposits {
Ok(())
}

fn update_user_staked_lp(
store: &mut dyn Storage,
lp_coin: &Coin,
account_id: &str,
) -> Result<(), ContractError> {
let key = (account_id, lp_coin.denom.as_str());
let existing_amount =
ASTRO_USER_LP_DEPOSITS.may_load(store, key)?.ok_or_else(|| ContractError::NoStakedLp {
account_id: account_id.to_string(),
denom: lp_coin.denom.clone(),
})?;

let new_amount = existing_amount.checked_sub(lp_coin.amount)?;
if new_amount.is_zero() {
ASTRO_USER_LP_DEPOSITS.remove(store, key);

// Get all incentives for (user, lp_token_denom) key
let prefix = USER_ASTRO_INCENTIVE_STATES.prefix((account_id, lp_coin.denom.as_str()));

// Iterate over all reward_denom keys
let keys_to_remove =
prefix.keys(store, None, None, Order::Ascending).collect::<StdResult<Vec<String>>>()?;

// Delete each matching (account_id, lp_token_denom, reward_denom) incentive.
for incentive_denom in keys_to_remove {
USER_ASTRO_INCENTIVE_STATES
.remove(store, (account_id, lp_coin.denom.as_str(), &incentive_denom));
}
} else {
ASTRO_USER_LP_DEPOSITS.save(store, key, &new_amount)?;
}

Ok(())
}

fn update_total_staked_lp(store: &mut dyn Storage, lp_coin: &Coin) -> Result<(), ContractError> {
let lp_denom = lp_coin.denom.as_str();

let total_staked_lp_amount =
ASTRO_TOTAL_LP_DEPOSITS.may_load(store, lp_denom)?.ok_or_else(|| {
ContractError::NoDeposits {
denom: lp_coin.denom.clone(),
})?
.checked_sub(lp_coin.amount)?)
})?;
}
})?;

let new_total_staked_lp_amount = total_staked_lp_amount.checked_sub(lp_coin.amount)?;

// If the new amount is zero, remove the entry and all associated incentive states
if new_total_staked_lp_amount.is_zero() {
ASTRO_TOTAL_LP_DEPOSITS.remove(store, lp_denom);

// Get all incentive states for the lp_key
let prefix = ASTRO_INCENTIVE_STATES.prefix(lp_denom);
let keys_to_remove =
prefix.keys(store, None, None, Order::Ascending).collect::<StdResult<Vec<String>>>()?;

// Remove all incentive states related to the lp_key
for incentive_denom in keys_to_remove {
ASTRO_INCENTIVE_STATES.remove(store, (lp_denom, incentive_denom.as_str()));
}
} else {
// Save the updated staked amount if it's not zero
ASTRO_TOTAL_LP_DEPOSITS.save(store, lp_denom, &new_total_staked_lp_amount)?;
}
Ok(())
}

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

for coin in &user_claimable_rewards {
event = event
.add_attribute("denom", coin.denom.to_string())
.add_attribute("amount", coin.amount.to_string());
}
res = if !user_claimable_rewards.is_empty() {

// Check if rewards not already claimed in the same block
res = if !user_claimable_rewards.is_empty() && !total_claimed_amount.is_zero() {
// Send the claimed rewards to the credit manager
let send_rewards_to_cm_msg = CosmosMsg::Bank(BankMsg::Send {
to_address: credit_manager_addr.to_string(),
5 changes: 4 additions & 1 deletion contracts/incentives/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::string::FromUtf8Error;

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

#[error("{0}")]
OverflowError(#[from] OverflowError),

#[error("{0}")]
Std(#[from] StdError),

3 changes: 1 addition & 2 deletions contracts/incentives/src/query.rs
Original file line number Diff line number Diff line change
@@ -199,8 +199,7 @@ pub fn query_staked_astro_lp_rewards_for_coin(
)
.unwrap_or_default();

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

225 changes: 204 additions & 21 deletions contracts/incentives/tests/tests/test_claim_astro_lp_rewards.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,12 @@ use cosmwasm_std::{
testing::{mock_env, mock_info, MockApi},
Addr, Coin, Deps, DepsMut, Env, MemoryStorage, OwnedDeps, Response, Uint128,
};
use mars_incentives::{contract::execute, query, state::ASTRO_TOTAL_LP_DEPOSITS, ContractError};
use mars_incentives::{
contract::execute,
query,
state::{ASTRO_TOTAL_LP_DEPOSITS, ASTRO_USER_LP_DEPOSITS},
ContractError,
};
use mars_testing::{assert_eq_vec, MarsMockQuerier};
use mars_types::{
credit_manager::{
@@ -23,6 +28,7 @@ fn set_pending_astro_rewards(
) {
deps.querier.set_unclaimed_astroport_lp_rewards(lp_denom, mars_incentives_contract, rewards);
}

fn deposit_for_user(
deps: DepsMut,
env: Env,
@@ -96,7 +102,7 @@ fn lp_lifecycle() {
let env = mock_env();
let mut deps: OwnedDeps<MemoryStorage, MockApi, MarsMockQuerier> = th_setup();

// users
// Users
let user_a_id = "1";
let user_b_id = "2";

@@ -165,7 +171,7 @@ fn lp_lifecycle() {
unclaimed_rewards.iter().map(|asset| asset.as_coin().unwrap()).collect(),
);

// deposit new user
// Deposit new user
deposit_for_user(
deps.as_mut(),
env.clone(),
@@ -242,7 +248,7 @@ fn lp_lifecycle() {
}],
);

// claim rewards, set as null
// Claim rewards, set as null
claim_for_user(
deps.as_mut(),
env.clone(),
@@ -323,7 +329,7 @@ fn lp_lifecycle() {
}],
);

// test double stake
// Test double stake
deposit_for_user(
deps.as_mut(),
env.clone(),
@@ -367,6 +373,15 @@ fn lp_lifecycle() {
vec![],
);

// Add new unclaimed rewards
set_pending_astro_rewards(
&mut deps,
lp_denom,
mars_incentives_contract,
unclaimed_rewards.clone(),
);

// Unstake all user a
unstake_for_user(
deps.as_mut(),
env.clone(),
@@ -379,10 +394,43 @@ fn lp_lifecycle() {
)
.unwrap();

// State:
// - LP in incentives = 300 (user_a 100, user_b 200)
// - Rewards available for user_1 = 0
// - Rewards available for user_2 = 0
assert_eq!(
ASTRO_USER_LP_DEPOSITS.may_load(&deps.storage, (user_a_id, lp_denom)).unwrap(),
None
);

// Unstake all user b
unstake_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_b_id.to_string(),
ActionCoin {
denom: lp_denom.to_string(),
amount: ActionAmount::AccountBalance,
},
)
.unwrap();

assert_eq!(
ASTRO_USER_LP_DEPOSITS.may_load(&deps.storage, (user_b_id, lp_denom)).unwrap(),
None
);

// Remove rewards
set_pending_astro_rewards(&mut deps, lp_denom, mars_incentives_contract, vec![]);

// Deposit for user a
deposit_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_a_id.to_string(),
default_lp_coin.clone(),
)
.unwrap();

// User a should have no rewards after depositing
assert_user_rewards(
deps.as_ref(),
env.clone(),
@@ -584,18 +632,6 @@ fn lp_states_update_correctly() {
.amount,
Uint128::new(50u128)
);
assert_eq!(
query::query_staked_astro_lp_position(
deps.as_ref(),
env.clone(),
user_b_id.to_string(),
lp_denom.to_string()
)
.unwrap()
.lp_coin
.amount,
Uint128::new(0u128)
);

deposit_for_user(
deps.as_mut(),
@@ -638,3 +674,150 @@ fn lp_states_update_correctly() {
Uint128::new(50u128)
);
}

#[test]
fn indexes_clean_correctly_when_all_users_unstake() {
// Setup
let env = mock_env();
let mut deps: OwnedDeps<MemoryStorage, MockApi, MarsMockQuerier> = th_setup();

// Users
let user_a_id = "1";
let user_b_id = "2";

let credit_manager = Addr::unchecked("credit_manager");
let astroport_incentives_addr = Addr::unchecked("astroport_incentives");
deps.querier.set_astroport_incentives_address(astroport_incentives_addr.clone());

let lp_denom = "uusd/ubtc";
let unclaimed_rewards = vec![Asset::native("ibc/reward_1", 100u128)];

let default_lp_coin = Coin {
denom: lp_denom.to_string(),
amount: Uint128::new(100u128),
};

// State:
// - LP in incentives = 0
// - Rewards available = 0
assert_eq!(ASTRO_TOTAL_LP_DEPOSITS.may_load(&deps.storage, lp_denom).unwrap(), None);

let mars_incentives_contract = &env.contract.address.to_string();

// Deposit for user a
deposit_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_a_id.to_string(),
Coin::new(100u128, lp_denom),
)
.unwrap();

set_pending_astro_rewards(
&mut deps,
lp_denom,
mars_incentives_contract,
unclaimed_rewards.clone(),
);

// Deposit user b
deposit_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_b_id.to_string(),
Coin::new(100u128, lp_denom),
)
.unwrap();

set_pending_astro_rewards(
&mut deps,
lp_denom,
mars_incentives_contract,
unclaimed_rewards.clone(),
);

// State:
// - LP in incentives = 200
// - Rewards available for user_1 = 150
// - Rewards available for user_2 = 50

assert_user_rewards(
deps.as_ref(),
env.clone(),
astroport_incentives_addr.clone(),
user_a_id,
default_lp_coin.clone(),
vec![Coin {
denom: "ibc/reward_1".to_string(),
amount: Uint128::new(150u128),
}],
);

// User b
assert_user_rewards(
deps.as_ref(),
env.clone(),
astroport_incentives_addr.clone(),
user_b_id,
default_lp_coin.clone(),
vec![Coin {
denom: "ibc/reward_1".to_string(),
amount: Uint128::new(50u128),
}],
);

// Unstake both users
unstake_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_a_id.to_string(),
ActionCoin {
denom: lp_denom.to_string(),
amount: mars_types::credit_manager::ActionAmount::AccountBalance,
},
)
.unwrap();

unstake_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_b_id.to_string(),
ActionCoin {
denom: lp_denom.to_string(),
amount: mars_types::credit_manager::ActionAmount::AccountBalance,
},
)
.unwrap();

// State:
// - LP in incentives = 0
// - Rewards available = 0
assert_eq!(ASTRO_TOTAL_LP_DEPOSITS.may_load(&deps.storage, lp_denom).unwrap(), None);

// Set no rewards
set_pending_astro_rewards(&mut deps, lp_denom, mars_incentives_contract, vec![]);

// Stake for user a
deposit_for_user(
deps.as_mut(),
env.clone(),
credit_manager.as_str(),
user_a_id.to_string(),
Coin::new(100u128, lp_denom),
)
.unwrap();

// Assert no rewards:
assert_user_rewards(
deps.as_ref(),
env.clone(),
astroport_incentives_addr.clone(),
user_a_id,
default_lp_coin.clone(),
vec![],
);
}
63 changes: 50 additions & 13 deletions contracts/mock-astroport-incentives/src/execute.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ use cosmwasm_std::{Coin, DepsMut, Env, MessageInfo, Response, StdError, StdResul

use crate::{
query::query_rewards,
state::{ASTRO_LP_INCENTIVE_DEPOSITS, INCENTIVE_SCHEDULES},
state::{ASTRO_LP_INCENTIVE_DEPOSITS, INCENTIVE_SCHEDULES, LAST_CLAIMED_HEIGHT},
};

pub fn incentivise(
@@ -30,9 +30,7 @@ pub fn incentivise(
Ok(Response::new())
}

// We just use this as a blank to consume the deposit message. This mock assumes only the incentives contract
// will ever deposit / withdraw / interact
pub fn deposit(deps: DepsMut, _: Env, info: MessageInfo) -> StdResult<Response> {
pub fn deposit(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult<Response> {
let sender = info.sender.to_string();
let coins = info.funds;

@@ -44,28 +42,35 @@ pub fn deposit(deps: DepsMut, _: Env, info: MessageInfo) -> StdResult<Response>
.checked_add(coin.amount)
.map_err(|_| StdError::generic_err("overflow"))
})?;
// We will be claiming when depositing so we need to ensure our mock state is aware of that
LAST_CLAIMED_HEIGHT.save(
deps.storage,
(info.sender.as_ref(), &lp_token),
&env.block.height,
)?;
}

Ok(Response::new())
}

pub fn withdraw(
deps: DepsMut,
_: Env,
env: Env,
info: MessageInfo,
lp_token: String,
amount: Uint128,
) -> StdResult<Response> {
let sender = info.sender.to_string();

// Send the rewards to the user
let withdraw_lp_msg = cosmwasm_std::CosmosMsg::Bank(cosmwasm_std::BankMsg::Send {
to_address: info.sender.to_string(),
amount: vec![Coin {
amount,
denom: lp_token.clone(),
}],
});
let withdraw_lp_msg: cosmwasm_std::CosmosMsg =
cosmwasm_std::CosmosMsg::Bank(cosmwasm_std::BankMsg::Send {
to_address: info.sender.to_string(),
amount: vec![Coin {
amount,
denom: lp_token.clone(),
}],
});

ASTRO_LP_INCENTIVE_DEPOSITS.update(deps.storage, (&sender, &lp_token), |value_opt| {
value_opt
@@ -74,6 +79,9 @@ pub fn withdraw(
.map_err(|_| StdError::generic_err("overflow"))
})?;

// We will be claiming when withdrawing so we need to ensure our mock state is aware of that
LAST_CLAIMED_HEIGHT.save(deps.storage, (info.sender.as_ref(), &lp_token), &env.block.height)?;

Ok(Response::new().add_message(withdraw_lp_msg))
}

@@ -85,6 +93,17 @@ pub fn claim_rewards(
) -> StdResult<Response> {
let rewards = lp_tokens
.iter()
.filter(|lp_token| {
let last_claimed_height = LAST_CLAIMED_HEIGHT
.may_load(deps.storage, (info.sender.as_ref(), lp_token))
.unwrap_or_default();
let unclaimed = last_claimed_height.unwrap_or(0) < env.block.height;
let has_deposits = ASTRO_LP_INCENTIVE_DEPOSITS
.may_load(deps.storage, (info.sender.as_ref(), lp_token))
.unwrap_or_default()
.is_some();
unclaimed && has_deposits
})
.map(|lp_token: &String| {
query_rewards(deps.as_ref(), env.clone(), info.sender.to_string(), lp_token.to_string())
.unwrap()
@@ -100,10 +119,28 @@ pub fn claim_rewards(
return Ok(response);
}

for lp_token_denom in lp_tokens.clone() {
LAST_CLAIMED_HEIGHT.save(
deps.storage,
(info.sender.as_ref(), &lp_token_denom),
&env.block.height,
)?;
}

let coins_to_send: Vec<Coin> = rewards
.into_iter()
.filter(|asset| asset.amount > Uint128::zero())
.map(|asset| asset.as_coin().unwrap())
.collect();

if coins_to_send.is_empty() {
return Ok(response);
}

// Send the rewards to the user
let reward_msg = cosmwasm_std::CosmosMsg::Bank(cosmwasm_std::BankMsg::Send {
to_address: info.sender.to_string(),
amount: rewards.into_iter().map(|asset| asset.as_coin().unwrap()).collect(),
amount: coins_to_send,
});

Ok(response.add_message(reward_msg))
18 changes: 16 additions & 2 deletions contracts/mock-astroport-incentives/src/query.rs
Original file line number Diff line number Diff line change
@@ -3,11 +3,11 @@ use std::str::FromStr;
use astroport_v5::asset::Asset;
use cosmwasm_std::{Coin, Decimal256, Deps, Env, StdResult, Uint128};

use crate::state::{ASTRO_LP_INCENTIVE_DEPOSITS, INCENTIVE_SCHEDULES};
use crate::state::{ASTRO_LP_INCENTIVE_DEPOSITS, INCENTIVE_SCHEDULES, LAST_CLAIMED_HEIGHT};

pub fn query_rewards(
deps: Deps,
_: Env,
env: Env,
sender: String,
lp_token: String,
) -> StdResult<Vec<Asset>> {
@@ -23,6 +23,20 @@ pub fn query_rewards(
>| {
let (reward_denom, schedule) = item.unwrap();
// Note - this gives all rewards to the claimer, but in reality we would need to calculate the rewards for each user.
let current_height = env.block.height;
let last_claimed = LAST_CLAIMED_HEIGHT
.may_load(deps.storage, (&sender, &lp_token))
.unwrap()
.unwrap_or(0);

if last_claimed == current_height {
return Coin {
amount: Uint128::zero(),
denom: reward_denom,
}
.into();
}

let amount =
schedule.rps.checked_mul(Decimal256::from_str("5000").unwrap()).unwrap();
Coin {
2 changes: 2 additions & 0 deletions contracts/mock-astroport-incentives/src/state.rs
Original file line number Diff line number Diff line change
@@ -7,3 +7,5 @@ pub const INCENTIVE_SCHEDULES: Map<(&str, &str), IncentivesSchedule> =
Map::new("astro_incentive_schedules");
pub const ASTRO_LP_INCENTIVE_DEPOSITS: Map<(&str, &str), Uint128> =
Map::new("astro_incentive_lp_deposits");
pub const LAST_CLAIMED_HEIGHT: Map<(&str, &str), u64> =
Map::new("astro_incentive_last_claimed_height");
117 changes: 116 additions & 1 deletion integration-tests/tests/test_astro_lp_incentives.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,10 @@ use astroport_v5::{
incentives::InputSchedule,
};
use cosmwasm_std::{coin, Addr, Coin, Uint128};
use mars_testing::integration::mock_env::MockEnvBuilder;
use mars_testing::{
assert_eq_vec,
integration::mock_env::{MockEnv, MockEnvBuilder},
};

use crate::helpers::default_asset_params;
mod helpers;
@@ -203,3 +206,115 @@ fn unstake_claims_rewards() {
let lp_balance = mock_env.query_balance(&credit_manager, lp_denom).unwrap();
assert_eq!(lp_balance, lp_coin);
}

#[test]
fn unstake_all_positions_resets_state_correctly() {
// Params
let lp_denom = "factory/neturon1234/astroport/share";
let stake_lp_amount = 1000000;

let lp_coin = Coin {
denom: lp_denom.to_string(),
amount: Uint128::new(stake_lp_amount),
};

let helper = AstroIncentivesTestHelper::new(None, None, None, Some(lp_denom.to_string()));

let mut mock_env = helper.mock;

// Contracts
let incentives = mock_env.incentives.clone();
let astro_incentives = mock_env.astro_incentives.clone();

astro_incentives.set_incentive_schedule(
&mut mock_env,
lp_denom,
&helper.incentive_schedule,
helper.rewards.clone(),
);

let credit_manager = mock_env.credit_manager.clone();

incentives.stake_astro_lp(&mut mock_env, &credit_manager, "1".to_string(), lp_coin.clone());
incentives.stake_astro_lp(&mut mock_env, &credit_manager, "2".to_string(), lp_coin.clone());

mock_env.increment_by_blocks(1);

incentives.unstake_astro_lp(&mut mock_env, &credit_manager, "1".to_string(), lp_coin.clone());
mock_env.increment_by_blocks(1);
incentives.unstake_astro_lp(&mut mock_env, &credit_manager, "2".to_string(), lp_coin.clone());
mock_env.increment_by_blocks(1);

incentives.stake_astro_lp(&mut mock_env, &credit_manager, "1".to_string(), lp_coin.clone());

// verify incentives are still 0 - we have not progressed time (blocks) so we should not have rewards
let rewards =
incentives.query_unclaimed_astroport_rewards(&mock_env, "1".to_string(), lp_denom).unwrap();
assert_eq_vec(vec![], rewards);
}

/// Test helpers to build state for astro incentives
struct AstroIncentivesTestHelper {
rewards: Vec<Coin>,
incentive_schedule: InputSchedule,
mock: MockEnv,
}

impl AstroIncentivesTestHelper {
fn new(
owner: Option<String>,
funded_assets: Option<Vec<Coin>>,
incentive_schedule: Option<InputSchedule>,
lp_denom: Option<String>,
) -> Self {
let owner = owner.unwrap_or("owner".to_string());
let mut mock_env = MockEnvBuilder::new(None, Addr::unchecked(owner)).build();

let funded_amt = 10_000_000_000u128;
let default_reward_denom = "factory/neutron1234/rewards";
let lp_denom = lp_denom.unwrap_or("factory/neturon1234/astroport/share".to_string());

// Rewards
let default_reward_asset = Asset {
info: AssetInfo::NativeToken {
denom: default_reward_denom.to_string(),
},
amount: Uint128::new(funded_amt),
};

let default_incentives_schedule = &InputSchedule {
reward: default_reward_asset.clone(),
duration_periods: 1u64,
};

let incentive_schedule = incentive_schedule.unwrap_or(default_incentives_schedule.clone());

let rewards = vec![Coin::try_from(incentive_schedule.reward.clone()).unwrap()];

// Funded assets - required to fund our mocks
let mut default_funded_assets = rewards.clone();
default_funded_assets.push(Coin {
denom: lp_denom.clone(),
amount: funded_amt.into(),
});
let funded_assets = funded_assets.unwrap_or(default_funded_assets);

let credit_manager = mock_env.credit_manager.clone();
let params = mock_env.params.clone();

// Set asset params for lp token
let (_, asset_params) = default_asset_params(lp_denom.as_str());
params.init_params(&mut mock_env, asset_params);

// Fund accounts we need funded
mock_env.fund_account(&credit_manager, &funded_assets);
mock_env.fund_account(&mock_env.owner.clone(), &funded_assets);

AstroIncentivesTestHelper {
rewards,
incentive_schedule,
mock: mock_env,
}
}
}

0 comments on commit c82858d

Please sign in to comment.