Skip to content

Commit

Permalink
chore: add minimum collectable and aggregable balances when creating …
Browse files Browse the repository at this point in the history
…epochs (#289)
  • Loading branch information
kerber0x authored Mar 8, 2024
1 parent 43601d4 commit 78597cf
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 45 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contracts/liquidity_hub/fee_collector/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fee_collector"
version = "1.1.4"
version = "1.1.5"
authors = ["Kerber0x <[email protected]>"]
edition.workspace = true
description = "Contract to collect the fees accrued by the pools and vaults in the liquidity hub"
Expand Down
14 changes: 8 additions & 6 deletions contracts/liquidity_hub/fee_collector/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn collect_fees(deps: DepsMut, collect_fees_for: FeesFor) -> Result<Response
}
}

Ok(Response::new()
Ok(Response::default()
.add_attribute("action", "collect_fees")
.add_messages(collect_fees_messages))
}
Expand Down Expand Up @@ -153,9 +153,11 @@ pub fn update_config(
}

CONFIG.save(deps.storage, &config)?;
Ok(Response::new().add_attribute("action", "update_config"))
Ok(Response::default().add_attribute("action", "update_config"))
}

const MINIMUM_AGGREGABLE_BALANCE: Uint128 = Uint128::new(1_000u128);

/// Aggregates the fees collected into the given asset_info.
pub fn aggregate_fees(
mut deps: DepsMut,
Expand Down Expand Up @@ -255,8 +257,8 @@ pub fn aggregate_fees(
}
};

// if the balance is greater than zero, swap the asset to the ask_asset
if balance > Uint128::zero() {
// if the balance is greater than the minimum aggregable balance, swap the asset to the ask_asset
if balance > MINIMUM_AGGREGABLE_BALANCE {
// query swap route from router
let operations_res: StdResult<Vec<SwapOperation>> =
deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
Expand Down Expand Up @@ -309,7 +311,7 @@ pub fn aggregate_fees(
}
}

Ok(Response::new()
Ok(Response::default()
.add_attribute("action", "aggregate_fees")
.add_messages(aggregate_fees_messages))
}
Expand Down Expand Up @@ -416,7 +418,7 @@ pub fn forward_fees(
// saving the epoch and the asset info to forward the fees as in temp storage
TMP_EPOCH.save(deps.storage, &epoch)?;

Ok(Response::new()
Ok(Response::default()
.add_attribute("action", "forward_fees")
.add_submessages(messages))
}
54 changes: 30 additions & 24 deletions contracts/liquidity_hub/fee_collector/src/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3770,7 +3770,7 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
}
println!(" -> weights after each bonding 1000 whale: {:?}", weights);

// Create EPOCH 1 with 100 whale
// Create EPOCH 1 with over 1000 whale
// whale -> native
app.execute_contract(
creator.sender.clone(),
Expand All @@ -3780,15 +3780,15 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
info: AssetInfo::NativeToken {
denom: "usdc".to_string(),
},
amount: Uint128::new(2_010u128),
amount: Uint128::new(21_100u128),
},
belief_price: None,
max_spread: None,
max_spread: Some(Decimal::percent(30u64)),
to: None,
},
&[Coin {
denom: "usdc".to_string(),
amount: Uint128::new(2_010u128),
amount: Uint128::new(21_100u128),
}],
)
.unwrap();
Expand Down Expand Up @@ -3834,14 +3834,14 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
assert_eq!(epoch_1.epoch.id, Uint64::one());
assert_eq!(epoch_1.epoch.available, epoch_1.epoch.total);
assert!(epoch_1.epoch.claimed.is_empty());
// Verify expiring_epoch_res.epoch.available, has 100 whale as an Asset
// Verify expiring_epoch_res.epoch.available, has 1_012 whale as an Asset
assert_eq!(
epoch_1.epoch.available,
vec![Asset {
info: AssetInfo::NativeToken {
denom: "uwhale".to_string(),
},
amount: Uint128::new(100u128),
amount: Uint128::new(1_012u128),
}]
);

Expand Down Expand Up @@ -3872,15 +3872,15 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
info: AssetInfo::NativeToken {
denom: "usdc".to_string(),
},
amount: Uint128::new(2_050u128),
amount: Uint128::new(25_000u128),
},
belief_price: None,
max_spread: None,
max_spread: Some(Decimal::percent(30u64)),
to: None,
},
&[Coin {
denom: "usdc".to_string(),
amount: Uint128::new(2_050u128),
amount: Uint128::new(25_000u128),
}],
)
.unwrap();
Expand Down Expand Up @@ -3931,10 +3931,11 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
.query_balance(creator.sender.clone(), "uwhale")
.unwrap()
.amount;

// Verify amount
assert_eq!(
uwhale_balance_after_claiming,
uwhale_balance_before_claiming + Uint128::new(50u128)
uwhale_balance_before_claiming + Uint128::new(506u128)
);
user_1_claims.push(uwhale_balance_after_claiming - uwhale_balance_before_claiming);

Expand Down Expand Up @@ -4125,7 +4126,7 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
// // Verify amount
assert_eq!(
uwhale_balance_after_claiming - uwhale_balance_before_claiming,
Uint128::new(60u128)
Uint128::new(660u128)
);
user_1_claims.push(uwhale_balance_after_claiming - uwhale_balance_before_claiming);

Expand Down Expand Up @@ -4288,12 +4289,17 @@ fn collect_and_dist_fees_where_one_bonder_is_increasing_weight_no_claims_until_e
// It should be 50 + 60 + 80 = 190
// and for user two it should be the remaining 50 + remaining 40 + remaining 20 = 110
// TODO: Currently its 50 + 60 + 60 = 170 and 50 + 40 + 40 = 130
// TODO the values here were adjusted after adding the restriction of the minimum aggregable/collectable amount.
//the numbers in the comments might not reflect the ones used in the test

// Print claims
println!("User 1 claims: {:?}", user_1_claims);
println!("User 2 claims: {:?}", user_2_claims);
assert_eq!(user_1_claims.iter().sum::<Uint128>(), Uint128::new(170u128));
assert_eq!(user_2_claims.iter().sum::<Uint128>(), Uint128::new(130u128));
assert_eq!(
user_1_claims.iter().sum::<Uint128>(),
Uint128::new(1_166u128)
);
assert_eq!(user_2_claims.iter().sum::<Uint128>(), Uint128::new(946u128));

assert_ne!(user_2_whale_received, user_1_whale_received);

Expand Down Expand Up @@ -8825,7 +8831,7 @@ fn collect_distribute_with_unbonders() {

// Create some epochs, for the first one all good but for the second we will have an unbonding

// Create EPOCH 1 with 100 whale
// Create EPOCH 1 with over 1000 whale
// whale -> native
app.execute_contract(
creator.sender.clone(),
Expand All @@ -8835,15 +8841,15 @@ fn collect_distribute_with_unbonders() {
info: AssetInfo::NativeToken {
denom: "usdc".to_string(),
},
amount: Uint128::new(2_010u128),
amount: Uint128::new(21_100u128),
},
belief_price: None,
max_spread: None,
max_spread: Some(Decimal::percent(30u64)),
to: None,
},
&[Coin {
denom: "usdc".to_string(),
amount: Uint128::new(2_010u128),
amount: Uint128::new(21_100u128),
}],
)
.unwrap();
Expand Down Expand Up @@ -8879,14 +8885,14 @@ fn collect_distribute_with_unbonders() {
expiring_epoch_res.epoch.total
);
assert!(expiring_epoch_res.epoch.claimed.is_empty());
// Verify expiring_epoch_res.epoch.available, has 100 whale as an Asset
// Verify expiring_epoch_res.epoch.available, has 1_012 whale as an Asset
assert_eq!(
expiring_epoch_res.epoch.available,
vec![Asset {
info: AssetInfo::NativeToken {
denom: "uwhale".to_string(),
},
amount: Uint128::new(100u128),
amount: Uint128::new(1_012u128),
}]
);

Expand Down Expand Up @@ -8917,15 +8923,15 @@ fn collect_distribute_with_unbonders() {
info: AssetInfo::NativeToken {
denom: "usdc".to_string(),
},
amount: Uint128::new(2_050u128),
amount: Uint128::new(25_000u128),
},
belief_price: None,
max_spread: None,
max_spread: Some(Decimal::percent(30u64)),
to: None,
},
&[Coin {
denom: "usdc".to_string(),
amount: Uint128::new(2_050u128),
amount: Uint128::new(25_000u128),
}],
)
.unwrap();
Expand Down Expand Up @@ -9222,8 +9228,8 @@ fn collect_distribute_with_unbonders() {
// No claims happened
// User 2 should have received more than user 1 as user 1 halfed their bond and thus their weight
// User 1 should not get an even share anymore considering all else stays the same
assert_eq!(user_2_whale_received, Uint128::new(133u128));
assert_eq!(user_1_whale_received, Uint128::new(66u128));
assert_eq!(user_2_whale_received, Uint128::new(704u128));
assert_eq!(user_1_whale_received, Uint128::new(352u128));

assert_ne!(user_2_whale_received, user_1_whale_received);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stableswap-3pool"
version = "1.2.3"
version = "1.2.4"
authors = ["Adam J. Weigold <[email protected]>"]
edition.workspace = true
license.workspace = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ use crate::state::{
CONFIG, TRIO_INFO,
};

const MINIMUM_COLLECTABLE_BALANCE: Uint128 = Uint128::new(1_000u128);

/// Receives cw20 tokens. Used to swap and withdraw from the pool.
pub fn receive_cw20(
deps: DepsMut,
Expand Down Expand Up @@ -649,13 +651,13 @@ pub fn collect_protocol_fees(deps: DepsMut) -> Result<Response, ContractError> {

let mut messages: Vec<CosmosMsg> = Vec::new();
for protocol_fee in protocol_fees {
// prevents trying to send 0 coins, which errors
if protocol_fee.amount != Uint128::zero() {
// prevents sending protocol fees if the amount is less than the minimum collectable balance
if protocol_fee.amount > MINIMUM_COLLECTABLE_BALANCE {
messages.push(protocol_fee.into_msg(config.fee_collector_addr.clone())?);
}
}

Ok(Response::new()
Ok(Response::default()
.add_attribute("action", "collect_protocol_fees")
.add_messages(messages))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "terraswap-pair"
version = "1.3.5"
version = "1.3.6"
authors = [
"Terraform Labs, PTE.",
"DELIGHT LABS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ use crate::state::{
CONFIG, PAIR_INFO,
};

const MINIMUM_COLLECTABLE_BALANCE: Uint128 = Uint128::new(1_000u128);

/// Receives cw20 tokens. Used to swap and withdraw from the pool.
/// If the Cw20HookMsg is Swap, the user must call IncreaseAllowance on the cw20 token first to allow
/// the contract to spend the tokens and perform the swap operation.
Expand Down Expand Up @@ -614,13 +616,13 @@ pub fn collect_protocol_fees(deps: DepsMut) -> Result<Response, ContractError> {

let mut messages: Vec<CosmosMsg> = Vec::new();
for protocol_fee in protocol_fees {
// prevents trying to send 0 coins, which errors
if protocol_fee.amount != Uint128::zero() {
// prevents sending protocol fees if the amount is less than the minimum collectable balance
if protocol_fee.amount > MINIMUM_COLLECTABLE_BALANCE {
messages.push(protocol_fee.into_msg(config.fee_collector_addr.clone())?);
}
}

Ok(Response::new()
Ok(Response::default()
.add_attribute("action", "collect_protocol_fees")
.add_messages(messages))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ fn test_collect_protocol_fees_successful_1_fee_only() {
let total_share = Uint128::from(300_000_000_000u128);
let asset_pool_amount = Uint128::from(200_000_000_000u128);
let collateral_pool_amount = Uint128::from(300_000_000_000u128);
let offer_amount = Uint128::from(1_500_000u128);
let offer_amount = Uint128::from(15_000_000u128);

let mut deps = mock_dependencies(&[Coin {
denom: "uusd".to_string(),
Expand Down Expand Up @@ -522,8 +522,8 @@ fn test_collect_protocol_fees_successful_1_fee_only() {
execute(deps.as_mut(), env.clone(), info, msg).unwrap();

// ask_amount = (ask_pool * offer_amount / (offer_pool + offer_amount))
// 9.995002 = 20000 * 15 / (30000 + 15) - swap_fee - protocol_fee
let expected_ret_amount = Uint128::from(999000u128);
// 99.5002 = 20000 * 150 / (30000 + 150) - swap_fee - protocol_fee
let expected_ret_amount = Uint128::from(9999000u128);
let expected_protocol_fee_token_amount = expected_ret_amount.multiply_ratio(1u128, 1000u128); // 0.1%

// as did only one swap from native -> token, we should have collected fees in token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ use white_whale_std::pool_network::pair::{
SimulationResponse,
};

#[cfg(feature = "osmosis")]
use anybuf::Anybuf;

use crate::contract::{execute, instantiate, query, reply};
use crate::error::ContractError;
use crate::helpers::compute_swap;
Expand Down

0 comments on commit 78597cf

Please sign in to comment.