use crate::common::constants::WAD;
use crate::common::errors::PoolError;
use crate::common::maths::{div_down_fixed, mul_down_fixed};
use alloy_primitives::U256;
pub fn get_normalized_weights(
project_token_index: usize,
current_time: &U256,
start_time: &U256,
end_time: &U256,
project_token_start_weight: &U256,
project_token_end_weight: &U256,
) -> Result<Vec<U256>, PoolError> {
let mut normalized_weights = vec![U256::ZERO; 2];
let reserve_token_index = if project_token_index == 0 { 1 } else { 0 };
normalized_weights[project_token_index] = get_project_token_normalized_weight(
current_time,
start_time,
end_time,
project_token_start_weight,
project_token_end_weight,
)?;
normalized_weights[reserve_token_index] = WAD - normalized_weights[project_token_index];
Ok(normalized_weights)
}
fn get_project_token_normalized_weight(
current_time: &U256,
start_time: &U256,
end_time: &U256,
start_weight: &U256,
end_weight: &U256,
) -> Result<U256, PoolError> {
let pct_progress = calculate_value_change_progress(current_time, start_time, end_time)?;
interpolate_value(start_weight, end_weight, &pct_progress)
}
fn calculate_value_change_progress(
current_time: &U256,
start_time: &U256,
end_time: &U256,
) -> Result<U256, PoolError> {
if current_time >= end_time {
return Ok(WAD); } else if current_time <= start_time {
return Ok(U256::ZERO); }
let total_seconds = end_time - start_time;
let seconds_elapsed = current_time - start_time;
div_down_fixed(&seconds_elapsed, &total_seconds)
}
fn interpolate_value(
start_value: &U256,
end_value: &U256,
pct_progress: &U256,
) -> Result<U256, PoolError> {
if pct_progress >= &WAD || start_value == end_value {
return Ok(*end_value);
}
if pct_progress == &U256::ZERO {
return Ok(*start_value);
}
if start_value > end_value {
let delta = mul_down_fixed(pct_progress, &(start_value - end_value))?;
Ok(start_value - delta)
} else {
let delta = mul_down_fixed(pct_progress, &(end_value - start_value))?;
Ok(start_value + delta)
}
}