-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Marinade LP: implement extract yield and update epoch record
- Loading branch information
1 parent
b789822
commit 4dcdb89
Showing
26 changed files
with
846 additions
and
199 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "marinade-common" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
anchor-lang = '0.29.0' | ||
marinade-cpi = { git = "https://github.com/sunrise-stake/anchor-gen", branch = "update/anchor-v0.29" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
pub mod vault_authority_seed; | ||
|
||
use anchor_lang::prelude::*; | ||
use marinade_cpi::state::State as MarinadeState; | ||
use std::num::TryFromIntError; | ||
|
||
/// calculate amount*numerator/denominator | ||
/// as value = shares * share_price where share_price=total_value/total_shares | ||
/// or shares = amount_value / share_price where share_price=total_value/total_shares | ||
/// => shares = amount_value * 1/share_price where 1/share_price=total_shares/total_value | ||
pub fn proportional( | ||
amount: u64, | ||
numerator: u64, | ||
denominator: u64, | ||
) -> std::result::Result<u64, TryFromIntError> { | ||
if denominator == 0 { | ||
return Ok(amount); | ||
} | ||
u64::try_from((amount as u128) * (numerator as u128) / (denominator as u128)) | ||
} | ||
|
||
// All lifted from https://github.com/marinade-finance/liquid-staking-program/blob/447f9607a8c755cac7ad63223febf047142c6c8f/programs/marinade-finance/src/state.rs#L227 | ||
pub fn calc_msol_from_lamports( | ||
marinade_state: &MarinadeState, | ||
stake_lamports: u64, | ||
) -> std::result::Result<u64, TryFromIntError> { | ||
msg!("calc_msol_from_lamports"); | ||
msg!("stake_lamports: {}", stake_lamports); | ||
msg!("marinade_state.msol_supply: {}", marinade_state.msol_supply); | ||
msg!( | ||
"total_virtual_staked_lamports: {}", | ||
total_virtual_staked_lamports(marinade_state) | ||
); | ||
proportional( | ||
stake_lamports, | ||
marinade_state.msol_supply, | ||
total_virtual_staked_lamports(marinade_state), | ||
) | ||
} | ||
pub fn calc_lamports_from_msol_amount( | ||
marinade_state: &MarinadeState, | ||
msol_amount: u64, | ||
) -> std::result::Result<u64, TryFromIntError> { | ||
proportional( | ||
msol_amount, | ||
total_virtual_staked_lamports(marinade_state), | ||
marinade_state.msol_supply, | ||
) | ||
} | ||
|
||
fn total_cooling_down(marinade_state: &MarinadeState) -> u64 { | ||
marinade_state | ||
.stake_system | ||
.delayed_unstake_cooling_down | ||
.checked_add(marinade_state.emergency_cooling_down) | ||
.expect("Total cooling down overflow") | ||
} | ||
|
||
fn total_lamports_under_control(marinade_state: &MarinadeState) -> u64 { | ||
marinade_state | ||
.validator_system | ||
.total_active_balance | ||
.checked_add(total_cooling_down(marinade_state)) | ||
.expect("Stake balance overflow") | ||
.checked_add(marinade_state.available_reserve_balance) // reserve_pda.lamports() - self.rent_exempt_for_token_acc | ||
.expect("Total SOLs under control overflow") | ||
} | ||
|
||
fn total_virtual_staked_lamports(marinade_state: &MarinadeState) -> u64 { | ||
// if we get slashed it may be negative but we must use 0 instead | ||
total_lamports_under_control(marinade_state) | ||
.saturating_sub(marinade_state.circulating_ticket_balance) //tickets created -> cooling down lamports or lamports already in reserve and not claimed yet | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use anchor_lang::prelude::{Account, Key}; | ||
use anchor_lang::{AccountDeserialize, AccountSerialize}; | ||
|
||
// NOTE: this must match the constant used by the programs themselves | ||
const VAULT_AUTHORITY: &[u8] = b"vault-authority"; | ||
|
||
pub struct VaultAuthoritySeed<'a> { | ||
state_address: Vec<u8>, | ||
vault_authority: &'a [u8], | ||
bump: Vec<u8>, | ||
} | ||
|
||
pub trait HasVaultAuthority: AccountSerialize + AccountDeserialize + Clone { | ||
fn vault_authority_bump(&self) -> u8; | ||
} | ||
|
||
impl<'a> VaultAuthoritySeed<'a> { | ||
pub fn new<'info>(state: &'a Account<'info, impl HasVaultAuthority>) -> Self { | ||
let state_address = state.key().to_bytes().to_vec(); | ||
let vault_authority = VAULT_AUTHORITY; | ||
let bump = vec![state.vault_authority_bump()]; | ||
|
||
VaultAuthoritySeed { | ||
state_address, | ||
vault_authority, | ||
bump, | ||
} | ||
} | ||
|
||
pub fn as_slices(&self) -> [&[u8]; 3] { | ||
[&self.state_address, self.vault_authority, &self.bump] | ||
} | ||
} |
Oops, something went wrong.