@@ -50,15 +50,20 @@ fn pool_net_asset_value(
5050 let pool_rent_exempt_reserve = rent. minimum_balance ( pool_stake_info. data_len ( ) ) ;
5151 let onramp_rent_exempt_reserve = rent. minimum_balance ( pool_onramp_info. data_len ( ) ) ;
5252
53- // NEV is all lamports in both accounts less rent
54- pool_stake_info
53+ // NAV is all lamports in both accounts less rent
54+
55+ let main_stake_value = pool_stake_info
56+ . lamports ( )
57+ . saturating_sub ( pool_rent_exempt_reserve) ;
58+
59+ let onramp_value = pool_onramp_info
5560 . lamports ( )
56- . saturating_add ( pool_onramp_info . lamports ( ) )
57- . saturating_sub ( pool_rent_exempt_reserve )
58- . saturating_sub ( onramp_rent_exempt_reserve )
61+ . saturating_sub ( onramp_rent_exempt_reserve ) ;
62+
63+ main_stake_value . saturating_add ( onramp_value )
5964}
6065
61- /// Calculate pool tokens to mint, given outstanding token supply, pool NEV , and deposit amount
66+ /// Calculate pool tokens to mint, given outstanding token supply, pool NAV , and deposit amount
6267fn calculate_deposit_amount (
6368 pre_token_supply : u64 ,
6469 pre_pool_nev : u64 ,
@@ -76,7 +81,7 @@ fn calculate_deposit_amount(
7681 }
7782}
7883
79- /// Calculate pool value to return, given outstanding token supply, pool NEV , and tokens to redeem
84+ /// Calculate pool value to return, given outstanding token supply, pool NAV , and tokens to redeem
8085fn calculate_withdraw_amount (
8186 pre_token_supply : u64 ,
8287 pre_pool_nev : u64 ,
@@ -1048,6 +1053,12 @@ impl Processor {
10481053 unreachable ! ( ) ;
10491054 } ;
10501055
1056+ // onramp must exist
1057+ match deserialize_stake ( pool_onramp_info) {
1058+ Ok ( StakeStateV2 :: Initialized ( _) ) | Ok ( StakeStateV2 :: Stake ( _, _, _) ) => ( ) ,
1059+ _ => return Err ( SinglePoolError :: OnRampDoesntExist . into ( ) ) ,
1060+ } ;
1061+
10511062 // tokens for deposit are determined off the total stakeable value of both pool-owned accounts
10521063 let pre_total_nev = pool_net_asset_value ( pool_stake_info, pool_onramp_info, rent) ;
10531064
@@ -1209,7 +1220,7 @@ impl Processor {
12091220
12101221 // note we deliberately do NOT validate the activation status of the pool account.
12111222 // neither warmup/cooldown nor validator delinquency prevent a user withdrawal.
1212- // however, because we calculate NEV from all lamports in both pool accounts,
1223+ // however, because we calculate NAV from all lamports in both pool accounts,
12131224 // but can only split stake from the main account (unless inactive), we must determine whether this is possible
12141225 let ( withdrawable_value, pool_is_fully_inactive) = {
12151226 let ( _, pool_stake_state) = get_stake_state ( pool_stake_info) ?;
@@ -1235,7 +1246,14 @@ impl Processor {
12351246 }
12361247 } ;
12371248
1238- // withdraw amount is determined off pool NEV just like deposit amount
1249+ // onramp must exist. this does not create an edge case where withdrawals may be blocked,
1250+ // because we also require the onramp to exist for deposits
1251+ match deserialize_stake ( pool_onramp_info) {
1252+ Ok ( StakeStateV2 :: Initialized ( _) ) | Ok ( StakeStateV2 :: Stake ( _, _, _) ) => ( ) ,
1253+ _ => return Err ( SinglePoolError :: OnRampDoesntExist . into ( ) ) ,
1254+ } ;
1255+
1256+ // withdraw amount is determined off pool NAV just like deposit amount
12391257 let stake_to_withdraw =
12401258 calculate_withdraw_amount ( token_supply, pre_total_nev, token_amount)
12411259 . ok_or ( SinglePoolError :: UnexpectedMathError ) ?;
0 commit comments