Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Milestone 3 completion #390

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ fn main() -> io::Result<()> {
admin_auth: RawContract::example(),
owner: Some(Addr::owner()),
fee_recipient: Addr::recipient(),
query_auth: RawContract::example(),

recover_staking_funds_receiver: Addr::funds_recipient(),
};
Expand Down
2 changes: 2 additions & 0 deletions contracts/liquidity_book/lb_factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub fn instantiate(
admin_auth: msg.admin_auth.into_valid(deps.api)?,
staking_contract_implementation: ContractInstantiationInfo::default(),
recover_staking_funds_receiver: msg.recover_staking_funds_receiver,
query_auth: msg.query_auth.into_valid(deps.api)?,
};

STATE.save(deps.storage, &config)?;
Expand Down Expand Up @@ -424,6 +425,7 @@ fn try_create_lb_pair(
entropy,
protocol_fee_recipient: config.fee_recipient,
admin_auth: config.admin_auth.into(),
query_auth: config.query_auth.into(),
total_reward_bins: Some(staking_preset.total_reward_bins),
rewards_distribution_algorithm: staking_preset.rewards_distribution_algorithm,
staking_contract_implementation: config.staking_contract_implementation,
Expand Down
1 change: 1 addition & 0 deletions contracts/liquidity_book/lb_factory/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub struct State {
pub lb_token_implementation: ContractInstantiationInfo,
pub staking_contract_implementation: ContractInstantiationInfo,
pub admin_auth: Contract,
pub query_auth: Contract,
pub recover_staking_funds_receiver: Addr,
}

Expand Down
6 changes: 5 additions & 1 deletion contracts/liquidity_book/lb_pair/src/bin/secretcli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use shade_protocol::{
types::{ContractInstantiationInfo, StaticFeeParameters},
},
liquidity_book::lb_pair::{
ContractStatus, InvokeMsg, LiquidityParameters, RemoveLiquidity,
ContractStatus,
InvokeMsg,
LiquidityParameters,
RemoveLiquidity,
RewardsDistributionAlgorithm,
},
swap::core::{TokenAmount, TokenType},
Expand Down Expand Up @@ -117,6 +120,7 @@ fn main() -> io::Result<()> {
viewing_key: String::from("viewing_key"),
entropy: String::from("entropy"),
protocol_fee_recipient: Addr::funds_recipient(),
query_auth: RawContract::example(),
};

writeln!(file, "## Instantiate Message\n")?;
Expand Down
149 changes: 81 additions & 68 deletions contracts/liquidity_book/lb_pair/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,29 @@ use serde::Serialize;
use shade_protocol::{
admin::helpers::{validate_admin, AdminPermissions},
c_std::{
from_binary, shd_entry_point, to_binary, Addr, Attribute, Binary, ContractInfo, CosmosMsg,
Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult, SubMsg,
SubMsgResult, Timestamp, Uint128, Uint256, WasmMsg,
from_binary,
shd_entry_point,
to_binary,
Addr,
Attribute,
Binary,
ContractInfo,
CosmosMsg,
Decimal,
Deps,
DepsMut,
Env,
MessageInfo,
Reply,
Response,
StdError,
StdResult,
SubMsg,
SubMsgResult,
Timestamp,
Uint128,
Uint256,
WasmMsg,
},
contract_interfaces::{
liquidity_book::{lb_pair::*, lb_staking, lb_token},
Expand Down Expand Up @@ -40,7 +60,8 @@ use shade_protocol::{
types::{Bytes32, MintArrays},
viewing_keys::{register_receive, set_viewing_key_msg, ViewingKey},
},
snip20, Contract,
snip20,
Contract,
};
use std::{collections::HashMap, ops::Sub, vec};

Expand Down Expand Up @@ -165,10 +186,10 @@ pub fn instantiate(
protocol_fees_recipient: msg.protocol_fee_recipient,
admin_auth: msg.admin_auth.into_valid(deps.api)?,
last_swap_timestamp: env.block.time,
rewards_epoch_id: 0,
rewards_epoch_index: 1,
base_rewards_bins: msg.total_reward_bins,
toggle_distributions_algorithm: false,
//TODO: set using the setter function and instantiate msg
max_bins_per_swap: 100, // TODO: do this by message
};

let tree: TreeUint24 = TreeUint24::new();
Expand All @@ -180,30 +201,24 @@ pub fn instantiate(
ORACLE.save(deps.storage, &oracle)?;
CONTRACT_STATUS.save(deps.storage, &ContractStatus::Active)?;
BIN_TREE.save(deps.storage, &tree)?;
FEE_MAP_TREE.save(deps.storage, 0, &tree)?;
REWARDS_STATS_STORE.save(
deps.storage,
0,
&RewardStats {
cumm_value: Uint256::zero(),
cumm_value_mul_bin_id: Uint256::zero(),
rewards_distribution_algorithm: msg.rewards_distribution_algorithm,
},
)?;
FEE_MAP_TREE.save(deps.storage, state.rewards_epoch_index, &tree)?;
REWARDS_STATS_STORE.save(deps.storage, state.rewards_epoch_index, &RewardStats {
cumm_value: Uint256::zero(),
cumm_value_mul_bin_id: Uint256::zero(),
rewards_distribution_algorithm: msg.rewards_distribution_algorithm,
})?;

EPHEMERAL_STORAGE.save(
deps.storage,
&NextTokenKey {
lb_token_code_hash: msg.lb_token_implementation.code_hash,
staking_contract: msg.staking_contract_implementation,
token_x_symbol,
token_y_symbol,
epoch_index: msg.epoch_staking_index,
epoch_duration: msg.epoch_staking_duration,
expiry_duration: msg.expiry_staking_duration,
recover_funds_receiver: msg.recover_staking_funds_receiver,
},
)?;
EPHEMERAL_STORAGE.save(deps.storage, &EphemeralStruct {
lb_token_code_hash: msg.lb_token_implementation.code_hash,
staking_contract: msg.staking_contract_implementation,
token_x_symbol,
token_y_symbol,
epoch_index: state.rewards_epoch_index,
epoch_duration: msg.epoch_staking_duration,
expiry_duration: msg.expiry_staking_duration,
recover_funds_receiver: msg.recover_staking_funds_receiver,
query_auth: msg.query_auth,
})?;

response = response.add_messages(messages);

Expand Down Expand Up @@ -409,10 +424,11 @@ fn try_swap(

let mut params = state.pair_parameters;
let bin_step = state.bin_step;
let mut reward_stats = REWARDS_STATS_STORE.load(deps.storage, state.rewards_epoch_id)?;
let mut reward_stats = REWARDS_STATS_STORE.load(deps.storage, state.rewards_epoch_index)?;

let mut active_id = params.get_active_id();

// updating the volatility
params.update_references(&env.block.time)?;
if reward_stats.rewards_distribution_algorithm == RewardsDistributionAlgorithm::TimeBasedRewards
{
Expand All @@ -423,7 +439,8 @@ fn try_swap(
reward_stats.cumm_value_mul_bin_id += time_difference * (Uint256::from(active_id));
}

loop {
// Allowing max 100 bins crossed per swap
for _ in 0..state.max_bins_per_swap {
let bin_reserves = BIN_MAP
.load(deps.storage, active_id)
.map_err(|_| Error::ZeroBinReserve { active_id })?;
Expand Down Expand Up @@ -471,7 +488,7 @@ fn try_swap(
reward_stats.cumm_value += swap_value_uint256;
FEE_MAP_TREE.update(
deps.storage,
state.rewards_epoch_id,
state.rewards_epoch_index,
|fee_tree| -> Result<_> {
Ok(match fee_tree {
Some(mut t) => {
Expand Down Expand Up @@ -529,7 +546,7 @@ fn try_swap(
}
}

REWARDS_STATS_STORE.save(deps.storage, state.rewards_epoch_id, &reward_stats)?;
REWARDS_STATS_STORE.save(deps.storage, state.rewards_epoch_index, &reward_stats)?;

if amounts_out == [0u8; 32] {
return Err(Error::InsufficientAmountOut);
Expand Down Expand Up @@ -655,8 +672,6 @@ pub fn add_liquidity_internal(

let state = STATE.load(deps.storage)?;

// TODO - we are initializing the vector of empty values, and populating them in a
// loop later. I think this could be refactored.
let mut liquidity_configs = vec![
LiquidityConfigurations {
distribution_x: 0,
Expand Down Expand Up @@ -1032,7 +1047,6 @@ fn _update_bin(
price,
total_supply,
)?;
println!("id {:?}, shares: {:?}", id, shares);

let amounts_in_to_bin = amounts_in;

Expand Down Expand Up @@ -1519,10 +1533,9 @@ fn try_calculate_rewards_distribution(
&state.admin_auth,
)?;

// loop through the fee_logs uptil a maximum iterations
// save the results in temporary storage

let reward_stats = REWARDS_STATS_STORE.load(deps.storage, state.rewards_epoch_id)?;
let reward_stats = REWARDS_STATS_STORE.load(deps.storage, state.rewards_epoch_index)?;
let distribution = if !reward_stats.cumm_value.is_zero() {
match reward_stats.rewards_distribution_algorithm {
RewardsDistributionAlgorithm::TimeBasedRewards => {
Expand All @@ -1540,8 +1553,20 @@ fn try_calculate_rewards_distribution(
calculate_default_distribution(rewards_bins, state.pair_parameters.get_active_id())?
};

REWARDS_DISTRIBUTION.save(deps.storage, state.rewards_epoch_id, &distribution)?;
state.rewards_epoch_id += 1;
REWARDS_DISTRIBUTION.save(deps.storage, state.rewards_epoch_index, &distribution)?;

//distribution algorithm
let res = lb_staking::ExecuteMsg::EndEpoch {
rewards_distribution: distribution,
epoch_index: state.rewards_epoch_index,
}
.to_cosmos_msg(
state.staking_contract.code_hash.to_owned(),
state.staking_contract.address.to_string(),
None,
)?;

state.rewards_epoch_index += 1;
let toggle = state.toggle_distributions_algorithm;
state.last_swap_timestamp = env.block.time;
state.toggle_distributions_algorithm = false;
Expand All @@ -1559,30 +1584,16 @@ fn try_calculate_rewards_distribution(
};
}

REWARDS_STATS_STORE.save(
deps.storage,
state.rewards_epoch_id,
&RewardStats {
cumm_value: Uint256::zero(),
cumm_value_mul_bin_id: Uint256::zero(),
rewards_distribution_algorithm: distribution_algorithm.clone(),
},
)?;
REWARDS_STATS_STORE.save(deps.storage, state.rewards_epoch_index, &RewardStats {
cumm_value: Uint256::zero(),
cumm_value_mul_bin_id: Uint256::zero(),
rewards_distribution_algorithm: distribution_algorithm.clone(),
})?;

if distribution_algorithm == &RewardsDistributionAlgorithm::VolumeBasedRewards {
let tree: TreeUint24 = TreeUint24::new();
FEE_MAP_TREE.save(deps.storage, state.rewards_epoch_id, &tree)?;
}

//distribution algorithm
let res = lb_staking::ExecuteMsg::EndEpoch {
rewards_distribution: distribution,
FEE_MAP_TREE.save(deps.storage, state.rewards_epoch_index, &tree)?;
}
.to_cosmos_msg(
state.staking_contract.code_hash,
state.staking_contract.address.to_string(),
None,
)?;

Ok(Response::default().add_message(res))
}
Expand Down Expand Up @@ -1641,12 +1652,13 @@ fn calculate_volume_based_rewards_distribution(
let mut ids: Vec<u32> = Vec::new();
let mut weightages: Vec<u16> = Vec::new();

let fee_tree: TreeUint24 = FEE_MAP_TREE.load(deps.storage, state.rewards_epoch_id)?;
let fee_tree: TreeUint24 = FEE_MAP_TREE.load(deps.storage, state.rewards_epoch_index)?;
let mut id: u32 = 0;
let basis_point_max: Uint256 = Uint256::from(BASIS_POINT_MAX);
let mut total_weight = 0;

loop {
// TODO: Decide a reasonable value with shade's consultation
for _ in 0..U24::MAX {
id = fee_tree.find_first_left(id);
if id == U24::MAX || id == 0 {
break;
Expand Down Expand Up @@ -1694,7 +1706,7 @@ fn try_reset_rewards_config(
info.sender.to_string(),
&state.admin_auth,
)?;
let reward_stats = REWARDS_STATS_STORE.load(deps.storage, state.rewards_epoch_id)?;
let reward_stats = REWARDS_STATS_STORE.load(deps.storage, state.rewards_epoch_index)?;

//Eventhough the distribution was changes mid epoch the effects of change will occur after the epoch.
match rewards_distribution_algorithm {
Expand Down Expand Up @@ -2104,9 +2116,10 @@ fn query_all_bins_reserves(
page_size
};

let state = STATE.load(deps.storage)?;
let mut counter: u32 = 0;

loop {
for _ in 0..state.max_bins_per_swap {
let next_id = tree.find_first_left(id);
id = next_id;

Expand Down Expand Up @@ -2589,7 +2602,7 @@ fn query_swap_in(deps: Deps, env: Env, amount_out: u128, swap_for_y: bool) -> Re

params.update_references(&env.block.time)?;

loop {
for _ in 0..state.max_bins_per_swap {
let bin_reserves = BIN_MAP
.load(deps.storage, id)
.unwrap_or_default()
Expand Down Expand Up @@ -2677,7 +2690,7 @@ fn query_swap_out(deps: Deps, env: Env, amount_in: u128, swap_for_y: bool) -> Re

params.update_references(&env.block.time)?;

loop {
for _ in 0..state.max_bins_per_swap {
let bin_reserves = BIN_MAP.load(deps.storage, id).unwrap_or_default();
if !BinHelper::is_empty(bin_reserves, !swap_for_y) {
let price = PriceHelper::get_price_from_id(id, bin_step)?;
Expand Down Expand Up @@ -2749,7 +2762,7 @@ fn query_total_supply(deps: Deps, id: u32) -> Result<Binary> {
fn query_rewards_distribution(deps: Deps, epoch_id: Option<u64>) -> Result<Binary> {
let (epoch_id) = match epoch_id {
Some(id) => id,
None => STATE.load(deps.storage)?.rewards_epoch_id - 1,
None => STATE.load(deps.storage)?.rewards_epoch_index - 1,
};

to_binary(&RewardsDistributionResponse {
Expand Down Expand Up @@ -2785,7 +2798,7 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> StdResult<Response> {
amm_pair: env.contract.address.to_string(),
lb_token: state.lb_token.to_owned().into(),
admin_auth: state.admin_auth.into(),
query_auth: None,
query_auth: emp_storage.query_auth.into(),
epoch_index: emp_storage.epoch_index,
epoch_duration: emp_storage.epoch_duration,
expiry_duration: emp_storage.expiry_duration,
Expand Down
9 changes: 6 additions & 3 deletions contracts/liquidity_book/lb_pair/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
liquidity_book::lb_pair::{ContractStatus, RewardsDistribution, RewardsDistributionAlgorithm},
secret_storage_plus::{AppendStore, Bincode2, Item, Json, Map},
swap::core::TokenType,
utils::asset::RawContract,
Contract,
};

Expand All @@ -19,7 +20,7 @@
pub const BIN_MAP: Map<u32, Bytes32> = Map::new("bins_map"); //
pub const BIN_TREE: Item<TreeUint24, Bincode2> = Item::new("bin_tree"); //?
pub const ORACLE: Item<Oracle, Bincode2> = Item::new("oracle"); //?
pub const EPHEMERAL_STORAGE: Item<NextTokenKey> = Item::new("ephemeral_storage");
pub const EPHEMERAL_STORAGE: Item<EphemeralStruct> = Item::new("ephemeral_storage");

pub const FEE_APPEND_STORE: AppendStore<FeeLog> = AppendStore::new("fee_logs"); //?
pub const REWARDS_STATS_STORE: Map<u64, RewardStats> = Map::new("rewards_stats"); //
Expand Down Expand Up @@ -64,14 +65,16 @@
pub protocol_fees_recipient: Addr,
pub admin_auth: Contract,
pub last_swap_timestamp: Timestamp,
pub rewards_epoch_id: u64,
pub rewards_epoch_index: u64,
pub base_rewards_bins: Option<u32>,
pub toggle_distributions_algorithm: bool,
pub max_bins_per_swap: u32,
}

#[cw_serde]
pub struct NextTokenKey {
pub struct EphemeralStruct {

Check warning on line 75 in contracts/liquidity_book/lb_pair/src/state.rs

View check run for this annotation

Codecov / codecov/patch

contracts/liquidity_book/lb_pair/src/state.rs#L75

Added line #L75 was not covered by tests
pub lb_token_code_hash: String,
pub query_auth: RawContract,
pub staking_contract: ContractInstantiationInfo,
pub token_x_symbol: String,
pub token_y_symbol: String,
Expand Down
Loading
Loading