Skip to content

Commit

Permalink
refactor: using upcoming_reward_bucket when filling rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
kerber0x committed May 13, 2024
1 parent 3c915d8 commit 9743e5e
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 223 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub(crate) fn bond(
asset: Coin,
) -> Result<Response, ContractError> {
println!("----bond----");
helpers::validate_buckets(&deps)?;
helpers::validate_buckets_not_empty(&deps)?;
helpers::validate_claimed(&deps, &info)?;
helpers::validate_bonding_for_current_epoch(&deps)?;

Expand Down
103 changes: 19 additions & 84 deletions contracts/liquidity_hub/bonding-manager/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use cosmwasm_std::{ensure, entry_point, from_json, Addr, Coin, Order, Reply, Uint128};
use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cw2::{get_contract_version, set_contract_version};
use cw_utils::parse_reply_execute_data;

use white_whale_std::bonding_manager::{Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use white_whale_std::pool_network::asset;

use crate::error::ContractError;
use crate::helpers::{self, validate_growth_rate};
use crate::state::{BONDING_ASSETS_LIMIT, CONFIG, REWARD_BUCKETS};
use crate::state::{BONDING_ASSETS_LIMIT, CONFIG, UPCOMING_REWARD_BUCKET};
use crate::{bonding, commands, queries, rewards};
use cosmwasm_std::{ensure, entry_point, Addr, Reply};
use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response};
use cw2::{get_contract_version, set_contract_version};
use white_whale_std::bonding_manager::{
Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, UpcomingRewardBucket,
};

// version info for migration info
const CONTRACT_NAME: &str = "white_whale-bonding_manager";
Expand Down Expand Up @@ -45,6 +43,9 @@ pub fn instantiate(
CONFIG.save(deps.storage, &config)?;
cw_ownable::initialize_owner(deps.storage, deps.api, Some(info.sender.as_str()))?;

// Initialize the upcoming reward bucket
UPCOMING_REWARD_BUCKET.save(deps.storage, &UpcomingRewardBucket::default())?;

Ok(Response::default().add_attributes(vec![
("action", "instantiate".to_string()),
("owner", info.sender.to_string()),
Expand All @@ -55,6 +56,15 @@ pub fn instantiate(
]))
}

// Reply entrypoint handling LP withdraws from fill_rewards
#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
match msg.id {
LP_WITHDRAWAL_REPLY_ID => rewards::commands::handle_lp_withdrawal_reply(deps, msg),
_ => Err(ContractError::Unauthorized),
}
}

#[entry_point]
pub fn execute(
deps: DepsMut,
Expand Down Expand Up @@ -158,81 +168,6 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<Binary, ContractErr
}
}

// Reply entrypoint handling LP withdraws from fill_rewards
#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
match msg.id {
LP_WITHDRAWAL_REPLY_ID => {
// Read the epoch sent by the fee collector through the ForwardFeesResponse
let execute_contract_response = parse_reply_execute_data(msg.clone()).unwrap();
let data = execute_contract_response
.data
.ok_or(ContractError::Unauthorized)?;

let coins: Vec<Coin> = from_json(data.as_slice())?;
let config = CONFIG.load(deps.storage)?;
let distribution_denom = config.distribution_denom.clone();
let mut messages = vec![];

// Search received coins funds for the coin that is not the distribution denom
// This will be swapped for
let mut to_be_distribution_asset = coins
.iter()
.find(|coin| coin.denom.ne(distribution_denom.as_str()))
.unwrap_or(&Coin {
denom: config.distribution_denom.clone(),
amount: Uint128::zero(),
})
.to_owned();
println!("reply");
// Swap other coins to the distribution denom
helpers::swap_coins_to_main_token(
coins,
&deps,
config,
&mut to_be_distribution_asset,
&distribution_denom,
&mut messages,
)?;

// if the swap was successful and the to_be_distribution_asset.denom is the
// distribution_denom, update the upcoming epoch with the new funds
if to_be_distribution_asset.denom == distribution_denom {
// Finding the upcoming EpochID
let upcoming_epoch_id = match REWARD_BUCKETS
.keys(deps.storage, None, None, Order::Descending)
.next()
{
Some(epoch_id) => epoch_id?,
None => return Err(ContractError::Unauthorized),
};

REWARD_BUCKETS.update(
deps.storage,
upcoming_epoch_id,
|epoch| -> StdResult<_> {
let mut upcoming_epoch = epoch.unwrap_or_default();
upcoming_epoch.available = asset::aggregate_coins(
upcoming_epoch.available,
vec![to_be_distribution_asset.clone()],
)?;
upcoming_epoch.total = asset::aggregate_coins(
upcoming_epoch.total,
vec![to_be_distribution_asset.clone()],
)?;
Ok(upcoming_epoch)
},
)?;
}

Ok(Response::new()
.add_messages(messages)
.add_attribute("total_withdrawn", msg.id.to_string()))
}
_ => Err(ContractError::Unauthorized),
}
}

#[cfg(not(tarpaulin_include))]
#[entry_point]
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
Expand Down
21 changes: 10 additions & 11 deletions contracts/liquidity_hub/bonding-manager/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use cosmwasm_std::{
StdResult, SubMsg, WasmMsg,
};
use cw_utils::PaymentError;

use white_whale_std::bonding_manager::{ClaimableRewardBucketsResponse, Config};
use white_whale_std::constants::LP_SYMBOL;
use white_whale_std::epoch_manager::epoch_manager::EpochResponse;
Expand Down Expand Up @@ -84,7 +85,7 @@ pub fn validate_bonding_for_current_epoch(deps: &DepsMut) -> Result<(), Contract

// Used in FillRewards to search the funds for LP tokens and withdraw them
// If we do get some LP tokens to withdraw they could be swapped to whale in the reply
pub fn handle_lp_tokens(
pub fn handle_lp_tokens_rewards(
funds: &Vec<Coin>,
config: &Config,
submessages: &mut Vec<SubMsg>,
Expand Down Expand Up @@ -163,16 +164,14 @@ pub fn swap_coins_to_main_token(
for coin in coins_to_swap {
println!("Swapping {} to {}", coin.denom, distribution_denom);

let swap_route_query = white_whale_std::pool_manager::QueryMsg::SwapRoute {
offer_asset_denom: coin.denom.to_string(),
ask_asset_denom: distribution_denom.to_string(),
};

println!("he");
// Query for the routes and pool
let swap_routes_response: StdResult<SwapRouteResponse> = deps
.querier
.query_wasm_smart(config.pool_manager_addr.to_string(), &swap_route_query);
let swap_routes_response: StdResult<SwapRouteResponse> = deps.querier.query_wasm_smart(
config.pool_manager_addr.to_string(),
&white_whale_std::pool_manager::QueryMsg::SwapRoute {
offer_asset_denom: coin.denom.to_string(),
ask_asset_denom: distribution_denom.to_string(),
},
);

println!("swap_routes_response: {:?}", swap_routes_response);
let swap_routes = match swap_routes_response {
Expand Down Expand Up @@ -247,7 +246,7 @@ pub fn swap_coins_to_main_token(

/// Validates that there are reward buckets in the state. If there are none, it means the system has just
/// been started and the epoch manager has still not created any epochs yet.
pub(crate) fn validate_buckets(deps: &DepsMut) -> Result<(), ContractError> {
pub(crate) fn validate_buckets_not_empty(deps: &DepsMut) -> Result<(), ContractError> {
let reward_buckets = REWARD_BUCKETS
.keys(deps.storage, None, None, Order::Descending)
.collect::<StdResult<Vec<_>>>()?;
Expand Down
12 changes: 5 additions & 7 deletions contracts/liquidity_hub/bonding-manager/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,12 @@ pub fn query_global_index(deps: Deps, epoch_id: Option<u64>) -> StdResult<Global
/// after creating a new epoch is created.
pub fn get_expiring_reward_bucket(deps: Deps) -> Result<Option<RewardBucket>, ContractError> {
let config = CONFIG.load(deps.storage)?;
// Adding 1 because we store the future bucket in the map also, so grace_period + 1
let grace_period_plus_future_bucket = Uint64::new(config.grace_period)
.checked_add(Uint64::one())?
.u64();
// Take grace_period + 1 and then slice last one off
let grace_period = config.grace_period;

// Take grace_period
let buckets = REWARD_BUCKETS
.range(deps.storage, None, None, Order::Descending)
.take(grace_period_plus_future_bucket as usize)
.take(grace_period as usize)
.map(|item| {
let (_, bucket) = item?;
Ok(bucket)
Expand All @@ -282,7 +280,7 @@ pub fn get_expiring_reward_bucket(deps: Deps) -> Result<Option<RewardBucket>, Co

// if the buckets vector's length is the same as the grace period it means there is one bucket that
// is expiring once the new one is created i.e. the last bucket in the vector
if buckets.len() == grace_period_plus_future_bucket as usize {
if buckets.len() == grace_period as usize {
let expiring_reward_bucket: RewardBucket = buckets.into_iter().last().unwrap_or_default();
Ok(Some(expiring_reward_bucket))
} else {
Expand Down
Loading

0 comments on commit 9743e5e

Please sign in to comment.