From 49b5b2b365a5e2a6c2a8ae3f59e6eb070a84e996 Mon Sep 17 00:00:00 2001 From: "E. Fynn" Date: Mon, 11 Apr 2022 10:35:53 -0300 Subject: [PATCH 1/3] Add metrics for deposit and withdrawals --- anker/src/instruction.rs | 4 +-- anker/src/metrics.rs | 54 +++++++++++++++++++++++++++++++++++++++- anker/src/processor.rs | 6 +++-- anker/src/state.rs | 2 +- 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/anker/src/instruction.rs b/anker/src/instruction.rs index 8d9e9f26d..917f51e08 100644 --- a/anker/src/instruction.rs +++ b/anker/src/instruction.rs @@ -166,7 +166,7 @@ accounts_struct! { DepositAccountsMeta, DepositAccountsInfo { pub anker { is_signer: false, - is_writable: false, + is_writable: true, // We update metrics. }, // For reading the stSOL/SOL exchange rate. pub solido { @@ -222,7 +222,7 @@ accounts_struct! { WithdrawAccountsMeta, WithdrawAccountsInfo { pub anker { is_signer: false, - is_writable: false, + is_writable: true, // Needed to update metrics. }, // For reading the stSOL/SOL exchange rate. pub solido { diff --git a/anker/src/metrics.rs b/anker/src/metrics.rs index 041d582e3..e417a035c 100644 --- a/anker/src/metrics.rs +++ b/anker/src/metrics.rs @@ -2,7 +2,7 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; use lido::token::StLamports; use serde::Serialize; -use crate::token::{self, MicroUst}; +use crate::token::{self, BLamports, MicroUst}; #[repr(C)] #[derive( @@ -16,13 +16,41 @@ pub struct Metrics { /// Total amount of UST received through swaps. #[serde(rename = "swapped_rewards_ust_total_microust")] pub swapped_rewards_ust_total: MicroUst, + + /// Metric for deposits. + pub deposit_metric: DepositWithdrawMetric, + + /// Metrics for withdrawals. + pub withdraw_metric: DepositWithdrawMetric, +} + +#[repr(C)] +#[derive( + Clone, Debug, Default, BorshDeserialize, BorshSerialize, BorshSchema, Eq, PartialEq, Serialize, +)] +pub struct DepositWithdrawMetric { + /// Total amount of StSOL. + pub st_sol_total: StLamports, + + /// Total amount of bSol. + pub b_sol_total: BLamports, + + /// Total number of times the metric was called. + pub count: u64, } impl Metrics { pub fn new() -> Self { + let empty_metric = DepositWithdrawMetric { + st_sol_total: StLamports(0), + b_sol_total: BLamports(0), + count: 0, + }; Metrics { swapped_rewards_st_sol_total: StLamports(0), swapped_rewards_ust_total: MicroUst(0), + deposit_metric: empty_metric.clone(), + withdraw_metric: empty_metric, } } @@ -36,4 +64,28 @@ impl Metrics { Ok(()) } + + pub fn observe_deposit( + &mut self, + st_sol_amount: StLamports, + b_sol_amount: BLamports, + ) -> token::Result<()> { + self.deposit_metric.st_sol_total = (self.deposit_metric.st_sol_total + st_sol_amount)?; + self.deposit_metric.b_sol_total = (self.deposit_metric.b_sol_total + b_sol_amount)?; + self.deposit_metric.count += 1; + + Ok(()) + } + + pub fn observe_withdraw( + &mut self, + st_sol_amount: StLamports, + b_sol_amount: BLamports, + ) -> token::Result<()> { + self.withdraw_metric.st_sol_total = (self.withdraw_metric.st_sol_total + st_sol_amount)?; + self.withdraw_metric.b_sol_total = (self.withdraw_metric.b_sol_total + b_sol_amount)?; + self.withdraw_metric.count += 1; + + Ok(()) + } } diff --git a/anker/src/processor.rs b/anker/src/processor.rs index 78cb003fa..33c0f005a 100644 --- a/anker/src/processor.rs +++ b/anker/src/processor.rs @@ -211,7 +211,7 @@ fn process_deposit( return Err(ProgramError::InvalidArgument); } - let (solido, anker) = deserialize_anker(program_id, accounts.anker, accounts.solido)?; + let (solido, mut anker) = deserialize_anker(program_id, accounts.anker, accounts.solido)?; anker.check_st_sol_reserve_address( program_id, accounts.anker.key, @@ -249,6 +249,7 @@ fn process_deposit( amount, b_sol_amount, ); + anker.metrics.observe_deposit(amount, b_sol_amount)?; Ok(()) } @@ -402,7 +403,7 @@ fn process_withdraw( ) -> ProgramResult { let accounts = WithdrawAccountsInfo::try_from_slice(accounts_raw)?; - let (solido, anker) = deserialize_anker(program_id, accounts.anker, accounts.solido)?; + let (solido, mut anker) = deserialize_anker(program_id, accounts.anker, accounts.solido)?; anker.check_is_st_sol_account(&solido, accounts.reserve_account)?; anker.check_mint(accounts.b_sol_mint)?; @@ -484,6 +485,7 @@ fn process_withdraw( )?; msg!("Anker: Withdrew {} for {}.", amount, st_sol_amount,); + anker.metrics.observe_withdraw(st_sol_amount, amount)?; Ok(()) } diff --git a/anker/src/state.rs b/anker/src/state.rs index 55a30ef14..0e2bdcf1d 100644 --- a/anker/src/state.rs +++ b/anker/src/state.rs @@ -25,7 +25,7 @@ use spl_token_swap::state::SwapV1; use crate::token::{self, BLamports, MicroUst}; /// Size of the serialized [`Anker`] struct, in bytes. -pub const ANKER_LEN: usize = 322; +pub const ANKER_LEN: usize = 370; pub const ANKER_VERSION: u8 = 0; // Next are three constants related to stored stSOL/UST prices. Because Anker is From 1e8a63b954e865aa5f18deb08ce7adea96143aa2 Mon Sep 17 00:00:00 2001 From: "E. Fynn" Date: Mon, 11 Apr 2022 10:49:46 -0300 Subject: [PATCH 2/3] Save Anker --- anker/src/processor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anker/src/processor.rs b/anker/src/processor.rs index 33c0f005a..8b0c2125d 100644 --- a/anker/src/processor.rs +++ b/anker/src/processor.rs @@ -251,7 +251,7 @@ fn process_deposit( ); anker.metrics.observe_deposit(amount, b_sol_amount)?; - Ok(()) + anker.save(accounts.anker) } /// Sample the current pool price, used later to limit slippage in `sell_rewards`. @@ -487,7 +487,7 @@ fn process_withdraw( msg!("Anker: Withdrew {} for {}.", amount, st_sol_amount,); anker.metrics.observe_withdraw(st_sol_amount, amount)?; - Ok(()) + anker.save(accounts.anker) } /// Change the Terra rewards destination. From 69d63f35bf92265fac696c1ee8ba98b55e3ee54c Mon Sep 17 00:00:00 2001 From: "E. Fynn" Date: Mon, 11 Apr 2022 10:50:02 -0300 Subject: [PATCH 3/3] Test metrics --- anker/tests/tests/deposit.rs | 10 ++++++++++ anker/tests/tests/withdraw.rs | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/anker/tests/tests/deposit.rs b/anker/tests/tests/deposit.rs index 658004bc4..19b725c06 100644 --- a/anker/tests/tests/deposit.rs +++ b/anker/tests/tests/deposit.rs @@ -27,6 +27,16 @@ async fn test_successful_deposit_during_first_epoch() { // so the amounts in SOL, stSOL, and bSOL are all equal. assert_eq!(reserve_balance, TEST_DEPOSIT_AMOUNT); assert_eq!(recipient_balance, BLamports(TEST_DEPOSIT_AMOUNT.0)); + let anker = context.get_anker().await; + assert_eq!( + anker.metrics.deposit_metric.st_sol_total, + TEST_DEPOSIT_AMOUNT + ); + assert_eq!( + anker.metrics.deposit_metric.b_sol_total, + BLamports(TEST_DEPOSIT_AMOUNT.0) + ); + assert_eq!(anker.metrics.deposit_metric.count, 1); } #[tokio::test] diff --git a/anker/tests/tests/withdraw.rs b/anker/tests/tests/withdraw.rs index 8e3729b7c..9c8e6bc49 100644 --- a/anker/tests/tests/withdraw.rs +++ b/anker/tests/tests/withdraw.rs @@ -50,6 +50,10 @@ async fn test_withdraw_single_epoch() { .get_st_sol_balance(context.st_sol_reserve) .await; assert_eq!(reserve_st_sol, StLamports(0)); + let anker = context.get_anker().await; + assert_eq!(anker.metrics.withdraw_metric.st_sol_total, st_sol_balance); + assert_eq!(anker.metrics.withdraw_metric.b_sol_total, b_sol_balance); + assert_eq!(anker.metrics.withdraw_metric.count, 1); } #[tokio::test]