use anchor_lang::prelude::*;
use fix::prelude::*;
use crate::error::CoreError::{
YieldHarvestAllocation, YieldHarvestConfigValidation,
};
use crate::fee_controller::FeeExtract;
#[derive(
Copy, Clone, PartialEq, InitSpace, AnchorSerialize, AnchorDeserialize,
)]
pub struct YieldHarvestConfig {
pub allocation: UFixValue64,
pub fee: UFixValue64,
}
impl YieldHarvestConfig {
pub fn init(
&mut self,
allocation: UFixValue64,
fee: UFixValue64,
) -> Result<()> {
self.allocation = allocation;
self.fee = fee;
Ok(())
}
pub fn allocation(&self) -> Result<UFix64<N4>> {
self.allocation.try_into()
}
pub fn fee(&self) -> Result<UFix64<N4>> {
self.fee.try_into()
}
pub fn apply_allocation(&self, stablecoin: UFix64<N6>) -> Result<UFix64<N6>> {
let allocation = self.allocation()?;
stablecoin
.mul_div_floor(allocation, UFix64::one())
.ok_or(YieldHarvestAllocation.into())
}
pub fn apply_fee(&self, stablecoin: UFix64<N6>) -> Result<FeeExtract<N6>> {
let fee = self.fee()?;
let extract = FeeExtract::new(fee, stablecoin)?;
Ok(extract)
}
pub fn validate(&self) -> Result<Self> {
let fee: UFix64<N4> = self.fee.try_into()?;
let allocation: UFix64<N4> = self.allocation.try_into()?;
let one = UFix64::new(10000);
let zero = UFix64::zero();
if fee > zero && fee <= one && allocation > zero && allocation <= one {
Ok(*self)
} else {
Err(YieldHarvestConfigValidation.into())
}
}
}
#[derive(Copy, Clone, InitSpace, AnchorSerialize, AnchorDeserialize)]
pub struct HarvestCache {
pub epoch: u64,
pub stability_pool_cap: UFixValue64,
pub stablecoin_to_pool: UFixValue64,
}
impl HarvestCache {
pub fn init(&mut self, epoch: u64) -> Result<()> {
self.epoch = epoch;
self.stability_pool_cap = UFix64::<N6>::zero().into();
self.stablecoin_to_pool = UFix64::<N6>::zero().into();
Ok(())
}
pub fn update(
&mut self,
stability_pool_cap: UFix64<N6>,
stablecoin_to_pool: UFix64<N6>,
epoch: u64,
) -> Result<()> {
self.epoch = epoch;
self.stability_pool_cap = stability_pool_cap.into();
self.stablecoin_to_pool = stablecoin_to_pool.into();
Ok(())
}
#[must_use]
pub fn is_stale(&self, current_epoch: u64) -> bool {
self.epoch < current_epoch
}
}