From 9b95c4691faf81f3f13ecc69acda845ebbd410f1 Mon Sep 17 00:00:00 2001 From: Sarfaraz Nawaz Date: Wed, 19 Aug 2026 21:09:00 +0530 Subject: [PATCH 1/5] feat: Raise Delegation & Commit Fees 10x --- dlp-api/src/consts.rs | 10 +-- src/processor/fast/commit_state.rs | 6 +- src/processor/fast/delegate.rs | 9 ++- src/processor/fast/delegate_with_actions.rs | 11 +++- src/processor/fast/request_undelegation.rs | 9 ++- src/processor/fast/undelegate.rs | 6 +- .../fast/undelegate_confined_account.rs | 4 +- src/processor/fast/utils/pda.rs | 61 ++++++++++++++++--- tests/test_delegate.rs | 16 ++++- 9 files changed, 103 insertions(+), 29 deletions(-) diff --git a/dlp-api/src/consts.rs b/dlp-api/src/consts.rs index db940329..5b277b3c 100644 --- a/dlp-api/src/consts.rs +++ b/dlp-api/src/consts.rs @@ -2,17 +2,17 @@ use pinocchio::Address; use crate::compat::{pubkey, Pubkey}; -/// The delegation session fees (extracted in percentage from the delegation PDAs rent on closure). +/// Legacy rent-fee percentage kept for API compatibility. pub const RENT_FEES_PERCENTAGE: u8 = 10; /// The fees extracted from the validator earnings (extracted in percentage from the validator fees claims). pub const PROTOCOL_FEES_PERCENTAGE: u8 = 10; -/// Fixed fee per commit (charged for each commit after the first). -pub const COMMIT_FEE_LAMPORTS: u64 = 100_000; +/// Fixed fee per commit after the first. +pub const COMMIT_FEE_LAMPORTS: u64 = 1_000_000; -/// Fixed fee per delegation session (0.0003 SOL). -pub const SESSION_FEE_LAMPORTS: u64 = 300_000; +/// Fixed fee per delegation session. +pub const SESSION_FEE_LAMPORTS: u64 = 3_000_000; /// Default and minimum timeout for requested undelegation. /// Assuming 1 slot is roughly 400ms, then 9000 slots = 60min. diff --git a/src/processor/fast/commit_state.rs b/src/processor/fast/commit_state.rs index 5c1ee4db..3152e2c9 100644 --- a/src/processor/fast/commit_state.rs +++ b/src/processor/fast/commit_state.rs @@ -11,7 +11,7 @@ use crate::{ args::CommitStateArgs, error::DlpError, merge_diff_copy, pda, - processor::fast::utils::pda::create_pda, + processor::fast::utils::pda::{create_pda, AccountFunding}, requires::{ require_initialized_delegation_metadata, require_initialized_delegation_record, @@ -283,7 +283,7 @@ pub(crate) fn process_commit_state_internal( create_pda( args.commit_state_account, &crate::fast::ID, - args.commit_state_bytes.data_len(), + AccountFunding::Current(args.commit_state_bytes.data_len()), &[Signer::from(&seeds!( pda::COMMIT_STATE_TAG, args.delegated_account.address().as_ref(), @@ -296,7 +296,7 @@ pub(crate) fn process_commit_state_internal( create_pda( args.commit_record_account, &crate::fast::ID, - CommitRecord::size_with_discriminator(), + AccountFunding::Current(CommitRecord::size_with_discriminator()), &[Signer::from(&seeds!( pda::COMMIT_RECORD_TAG, args.delegated_account.address().as_ref(), diff --git a/src/processor/fast/delegate.rs b/src/processor/fast/delegate.rs index b768a22d..d76ad2d3 100644 --- a/src/processor/fast/delegate.rs +++ b/src/processor/fast/delegate.rs @@ -15,7 +15,10 @@ use crate::{ error::DlpError, pda, processor::{ - fast::{to_pinocchio_program_error, utils::pda::create_pda}, + fast::{ + to_pinocchio_program_error, + utils::pda::{create_pda, AccountFunding}, + }, utils::curve::is_on_curve_fast, }, requires::{ @@ -215,7 +218,7 @@ fn process_delegate_inner( create_pda( delegation_record_account, &crate::fast::ID, - DelegationRecord::size_with_discriminator(), + AccountFunding::Legacy(DelegationRecord::size_with_discriminator()), &[Signer::from(&[ Seed::from(pda::DELEGATION_RECORD_TAG), Seed::from(delegated_account.address().as_ref()), @@ -250,7 +253,7 @@ fn process_delegate_inner( create_pda( delegation_metadata_account, &crate::fast::ID, - delegation_metadata.serialized_size(), + AccountFunding::Legacy(delegation_metadata.serialized_size()), &[Signer::from(&[ Seed::from(pda::DELEGATION_METADATA_TAG), Seed::from(delegated_account.address().as_ref()), diff --git a/src/processor/fast/delegate_with_actions.rs b/src/processor/fast/delegate_with_actions.rs index d78bfd0d..45fc2190 100644 --- a/src/processor/fast/delegate_with_actions.rs +++ b/src/processor/fast/delegate_with_actions.rs @@ -15,7 +15,10 @@ use crate::{ error::DlpError, pda, processor::{ - fast::{to_pinocchio_program_error, utils::pda::create_pda}, + fast::{ + to_pinocchio_program_error, + utils::pda::{create_pda, AccountFunding}, + }, utils::curve::is_on_curve_fast, }, require_n_accounts_with_optionals, @@ -217,7 +220,9 @@ pub fn process_delegate_with_actions( create_pda( delegation_record_account, &crate::fast::ID, - DelegationRecord::size_with_discriminator() + action_data.len(), + AccountFunding::Legacy( + DelegationRecord::size_with_discriminator() + action_data.len(), + ), &[Signer::from(&[ Seed::from(pda::DELEGATION_RECORD_TAG), Seed::from(delegated_account.address().as_ref()), @@ -262,7 +267,7 @@ pub fn process_delegate_with_actions( create_pda( delegation_metadata_account, &crate::fast::ID, - delegation_metadata.serialized_size(), + AccountFunding::Legacy(delegation_metadata.serialized_size()), &[Signer::from(&[ Seed::from(pda::DELEGATION_METADATA_TAG), Seed::from(delegated_account.address().as_ref()), diff --git a/src/processor/fast/request_undelegation.rs b/src/processor/fast/request_undelegation.rs index a7538b72..3b2bb405 100644 --- a/src/processor/fast/request_undelegation.rs +++ b/src/processor/fast/request_undelegation.rs @@ -12,7 +12,10 @@ use super::to_pinocchio_program_error; use crate::{ error::DlpError, pda, - processor::{fast::utils::pda::create_pda, utils::curve::is_on_curve_fast}, + processor::{ + fast::utils::pda::{create_pda, AccountFunding}, + utils::curve::is_on_curve_fast, + }, require, require_eq_keys, require_n_accounts, requires::{ is_uninitialized_account, require_initialized_delegation_metadata, @@ -125,7 +128,9 @@ pub fn process_request_undelegation( create_pda( undelegation_request_account, &crate::fast::ID, - UndelegationRequest::size_with_discriminator(), + AccountFunding::Current( + UndelegationRequest::size_with_discriminator(), + ), &[Signer::from(&seeds!( pda::UNDELEGATION_REQUEST_TAG, delegated_account.address().as_ref(), diff --git a/src/processor/fast/undelegate.rs b/src/processor/fast/undelegate.rs index f5dcfdfe..bc44fafe 100644 --- a/src/processor/fast/undelegate.rs +++ b/src/processor/fast/undelegate.rs @@ -20,7 +20,9 @@ use crate::{ }, error::DlpError, pda, - processor::fast::utils::pda::{close_pda, close_pda_with_fees, create_pda}, + processor::fast::utils::pda::{ + close_pda, close_pda_with_fees, create_pda, AccountFunding, + }, require_n_accounts_with_optionals, requires::{ require_initialized_delegation_metadata, @@ -256,7 +258,7 @@ pub fn process_undelegate( create_pda( undelegate_buffer_account, &crate::fast::ID, - delegated_account.data_len(), + AccountFunding::Current(delegated_account.data_len()), &[Signer::from(&seeds!( pda::UNDELEGATE_BUFFER_TAG, delegated_account.address().as_ref(), diff --git a/src/processor/fast/undelegate_confined_account.rs b/src/processor/fast/undelegate_confined_account.rs index 52879fe9..4bde845b 100644 --- a/src/processor/fast/undelegate_confined_account.rs +++ b/src/processor/fast/undelegate_confined_account.rs @@ -7,7 +7,7 @@ use super::{process_undelegation_with_cpi, to_pinocchio_program_error}; use crate::{ error::DlpError, pda, - processor::fast::utils::pda::{close_pda, create_pda}, + processor::fast::utils::pda::{close_pda, create_pda, AccountFunding}, require_eq_keys, requires::{ require_authorization, require_initialized_delegation_metadata, @@ -116,7 +116,7 @@ pub fn process_undelegate_confined_account( create_pda( undelegate_buffer_account, &crate::fast::ID, - delegated_account.data_len(), + AccountFunding::Current(delegated_account.data_len()), &[Signer::from(&seeds!( pda::UNDELEGATE_BUFFER_TAG, delegated_account.address().as_ref(), diff --git a/src/processor/fast/utils/pda.rs b/src/processor/fast/utils/pda.rs index c08b67ed..ba8b67fe 100644 --- a/src/processor/fast/utils/pda.rs +++ b/src/processor/fast/utils/pda.rs @@ -1,30 +1,66 @@ use pinocchio::{ cpi::Signer, + error::ProgramError, sysvars::{rent::Rent, Sysvar}, AccountView, Address, ProgramResult, }; use pinocchio_system::instructions as system; -use crate::consts::PROTOCOL_FEES_PERCENTAGE; +use crate::{consts::PROTOCOL_FEES_PERCENTAGE, error::DlpError}; + +const LEGACY_RENT_EXEMPT_LAMPORTS_PER_BYTE: u64 = 6_960; +const LEGACY_RENT_ACCOUNT_STORAGE_OVERHEAD: u64 = 128; + +pub(crate) enum AccountFunding { + Current(usize), + Legacy(usize), +} + +impl AccountFunding { + fn space(&self) -> usize { + match self { + Self::Current(space) | Self::Legacy(space) => *space, + } + } + + fn minimum_balance(&self) -> Result { + let current_rent = Rent::get()?.try_minimum_balance(self.space())?; + match self { + Self::Current(_) => Ok(current_rent), + Self::Legacy(_) => Ok(current_rent.max(legacy_rent(self.space())?)), + } + } +} + +fn legacy_rent(space: usize) -> Result { + let space = u64::try_from(space).map_err(|_| DlpError::Overflow)?; + space + .checked_add(LEGACY_RENT_ACCOUNT_STORAGE_OVERHEAD) + .and_then(|bytes| { + bytes.checked_mul(LEGACY_RENT_EXEMPT_LAMPORTS_PER_BYTE) + }) + .ok_or(DlpError::Overflow.into()) +} /// Creates a new pda #[inline(always)] pub(crate) fn create_pda( target_account: &AccountView, owner: &Address, - space: usize, + funding: AccountFunding, pda_signers: &[Signer], payer: &AccountView, ) -> ProgramResult { // Create the account manually or using the create instruction - let rent = Rent::get()?; + let space = funding.space(); + let minimum_balance = funding.minimum_balance()?; if target_account.lamports().eq(&0) { // If balance is zero, create account system::CreateAccount { from: payer, to: target_account, - lamports: rent.try_minimum_balance(space)?, + lamports: minimum_balance, space: space as u64, owner, } @@ -33,9 +69,8 @@ pub(crate) fn create_pda( // Otherwise, if balance is nonzero: // 1) transfer sufficient lamports for rent exemption - let rent_exempt_balance = rent - .try_minimum_balance(space)? - .saturating_sub(target_account.lamports()); + let rent_exempt_balance = + minimum_balance.saturating_sub(target_account.lamports()); if rent_exempt_balance > 0 { system::Transfer { from: payer, @@ -115,3 +150,15 @@ pub(crate) fn close_pda_with_fees( target_account.resize(0) } + +#[cfg(test)] +mod tests { + use super::legacy_rent; + + #[test] + fn legacy_rent_uses_pre_reduction_rent_exempt_formula() { + assert_eq!(legacy_rent(96).unwrap(), 1_559_040); + assert_eq!(legacy_rent(53).unwrap(), 1_259_760); + assert_eq!(legacy_rent(65).unwrap(), 1_343_280); + } +} diff --git a/tests/test_delegate.rs b/tests/test_delegate.rs index 40e61964..9b96825e 100644 --- a/tests/test_delegate.rs +++ b/tests/test_delegate.rs @@ -76,23 +76,35 @@ async fn test_delegate() { .unwrap() .unwrap(); assert!(delegation_metadata_account.owner.eq(&dlp_api::id())); + assert_eq!( + delegation_metadata_account.lamports, + legacy_rent(delegation_metadata_account.data.len()) + ); // Assert that the delegation record exists and can be parsed - let delegation_record = banks + let delegation_record_account = banks .get_account(delegation_record_pda_from_delegated_account( &DELEGATED_PDA_ID, )) .await .unwrap() .unwrap(); + assert_eq!( + delegation_record_account.lamports, + legacy_rent(delegation_record_account.data.len()) + ); let delegation_record = DelegationRecord::try_from_bytes_with_discriminator( - &delegation_record.data, + &delegation_record_account.data, ) .unwrap(); assert_eq!(delegation_record.owner, DELEGATED_PDA_OWNER_ID); } +fn legacy_rent(space: usize) -> u64 { + (space as u64 + 128) * 6_960 +} + async fn setup_program_test_env() -> (BanksClient, Keypair, Keypair, Hash) { let mut program_test = ProgramTest::new("dlp", dlp_api::ID, None); From 712794c124d66649d5617a2dd9c5514ba591c222 Mon Sep 17 00:00:00 2001 From: Sarfaraz Nawaz Date: Thu, 20 Aug 2026 00:41:10 +0530 Subject: [PATCH 2/5] Document legacy rent constant source --- src/processor/fast/utils/pda.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/processor/fast/utils/pda.rs b/src/processor/fast/utils/pda.rs index ba8b67fe..e4bcc782 100644 --- a/src/processor/fast/utils/pda.rs +++ b/src/processor/fast/utils/pda.rs @@ -8,9 +8,15 @@ use pinocchio_system::instructions as system; use crate::{consts::PROTOCOL_FEES_PERCENTAGE, error::DlpError}; -const LEGACY_RENT_EXEMPT_LAMPORTS_PER_BYTE: u64 = 6_960; +// Legacy rent math follows SIMD-0194, which defines the 6,960 +// lamports-per-byte value used by the simplified rent-exemption formula. +// +// ref: +// https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0194-deprecate-rent-exemption-threshold.md +const LEGACY_RENT_EXEMPT_LAMPORTS_PER_BYTE: u64 = 6960; const LEGACY_RENT_ACCOUNT_STORAGE_OVERHEAD: u64 = 128; +// usize stores the space required by an account pub(crate) enum AccountFunding { Current(usize), Legacy(usize), @@ -32,6 +38,8 @@ impl AccountFunding { } } +// ref: +// https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0194-deprecate-rent-exemption-threshold.md fn legacy_rent(space: usize) -> Result { let space = u64::try_from(space).map_err(|_| DlpError::Overflow)?; space From ba42bb61842e5f7e8cbfedcd592cc181ed8961b2 Mon Sep 17 00:00:00 2001 From: Sarfaraz Nawaz Date: Thu, 20 Aug 2026 00:48:29 +0530 Subject: [PATCH 3/5] Rename account funding policy to account space --- src/processor/fast/commit_state.rs | 6 ++--- src/processor/fast/delegate.rs | 6 ++--- src/processor/fast/delegate_with_actions.rs | 6 ++--- src/processor/fast/request_undelegation.rs | 4 ++-- src/processor/fast/undelegate.rs | 4 ++-- .../fast/undelegate_confined_account.rs | 4 ++-- src/processor/fast/utils/pda.rs | 24 ++++++++++--------- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/processor/fast/commit_state.rs b/src/processor/fast/commit_state.rs index 3152e2c9..408552eb 100644 --- a/src/processor/fast/commit_state.rs +++ b/src/processor/fast/commit_state.rs @@ -11,7 +11,7 @@ use crate::{ args::CommitStateArgs, error::DlpError, merge_diff_copy, pda, - processor::fast::utils::pda::{create_pda, AccountFunding}, + processor::fast::utils::pda::{create_pda, AccountSpace}, requires::{ require_initialized_delegation_metadata, require_initialized_delegation_record, @@ -283,7 +283,7 @@ pub(crate) fn process_commit_state_internal( create_pda( args.commit_state_account, &crate::fast::ID, - AccountFunding::Current(args.commit_state_bytes.data_len()), + AccountSpace::CurrentRent(args.commit_state_bytes.data_len()), &[Signer::from(&seeds!( pda::COMMIT_STATE_TAG, args.delegated_account.address().as_ref(), @@ -296,7 +296,7 @@ pub(crate) fn process_commit_state_internal( create_pda( args.commit_record_account, &crate::fast::ID, - AccountFunding::Current(CommitRecord::size_with_discriminator()), + AccountSpace::CurrentRent(CommitRecord::size_with_discriminator()), &[Signer::from(&seeds!( pda::COMMIT_RECORD_TAG, args.delegated_account.address().as_ref(), diff --git a/src/processor/fast/delegate.rs b/src/processor/fast/delegate.rs index d76ad2d3..bc5e2209 100644 --- a/src/processor/fast/delegate.rs +++ b/src/processor/fast/delegate.rs @@ -17,7 +17,7 @@ use crate::{ processor::{ fast::{ to_pinocchio_program_error, - utils::pda::{create_pda, AccountFunding}, + utils::pda::{create_pda, AccountSpace}, }, utils::curve::is_on_curve_fast, }, @@ -218,7 +218,7 @@ fn process_delegate_inner( create_pda( delegation_record_account, &crate::fast::ID, - AccountFunding::Legacy(DelegationRecord::size_with_discriminator()), + AccountSpace::LegacyRent(DelegationRecord::size_with_discriminator()), &[Signer::from(&[ Seed::from(pda::DELEGATION_RECORD_TAG), Seed::from(delegated_account.address().as_ref()), @@ -253,7 +253,7 @@ fn process_delegate_inner( create_pda( delegation_metadata_account, &crate::fast::ID, - AccountFunding::Legacy(delegation_metadata.serialized_size()), + AccountSpace::LegacyRent(delegation_metadata.serialized_size()), &[Signer::from(&[ Seed::from(pda::DELEGATION_METADATA_TAG), Seed::from(delegated_account.address().as_ref()), diff --git a/src/processor/fast/delegate_with_actions.rs b/src/processor/fast/delegate_with_actions.rs index 45fc2190..6e659a36 100644 --- a/src/processor/fast/delegate_with_actions.rs +++ b/src/processor/fast/delegate_with_actions.rs @@ -17,7 +17,7 @@ use crate::{ processor::{ fast::{ to_pinocchio_program_error, - utils::pda::{create_pda, AccountFunding}, + utils::pda::{create_pda, AccountSpace}, }, utils::curve::is_on_curve_fast, }, @@ -220,7 +220,7 @@ pub fn process_delegate_with_actions( create_pda( delegation_record_account, &crate::fast::ID, - AccountFunding::Legacy( + AccountSpace::LegacyRent( DelegationRecord::size_with_discriminator() + action_data.len(), ), &[Signer::from(&[ @@ -267,7 +267,7 @@ pub fn process_delegate_with_actions( create_pda( delegation_metadata_account, &crate::fast::ID, - AccountFunding::Legacy(delegation_metadata.serialized_size()), + AccountSpace::LegacyRent(delegation_metadata.serialized_size()), &[Signer::from(&[ Seed::from(pda::DELEGATION_METADATA_TAG), Seed::from(delegated_account.address().as_ref()), diff --git a/src/processor/fast/request_undelegation.rs b/src/processor/fast/request_undelegation.rs index 3b2bb405..4d045216 100644 --- a/src/processor/fast/request_undelegation.rs +++ b/src/processor/fast/request_undelegation.rs @@ -13,7 +13,7 @@ use crate::{ error::DlpError, pda, processor::{ - fast::utils::pda::{create_pda, AccountFunding}, + fast::utils::pda::{create_pda, AccountSpace}, utils::curve::is_on_curve_fast, }, require, require_eq_keys, require_n_accounts, @@ -128,7 +128,7 @@ pub fn process_request_undelegation( create_pda( undelegation_request_account, &crate::fast::ID, - AccountFunding::Current( + AccountSpace::CurrentRent( UndelegationRequest::size_with_discriminator(), ), &[Signer::from(&seeds!( diff --git a/src/processor/fast/undelegate.rs b/src/processor/fast/undelegate.rs index bc44fafe..6a4d7ca6 100644 --- a/src/processor/fast/undelegate.rs +++ b/src/processor/fast/undelegate.rs @@ -21,7 +21,7 @@ use crate::{ error::DlpError, pda, processor::fast::utils::pda::{ - close_pda, close_pda_with_fees, create_pda, AccountFunding, + close_pda, close_pda_with_fees, create_pda, AccountSpace, }, require_n_accounts_with_optionals, requires::{ @@ -258,7 +258,7 @@ pub fn process_undelegate( create_pda( undelegate_buffer_account, &crate::fast::ID, - AccountFunding::Current(delegated_account.data_len()), + AccountSpace::CurrentRent(delegated_account.data_len()), &[Signer::from(&seeds!( pda::UNDELEGATE_BUFFER_TAG, delegated_account.address().as_ref(), diff --git a/src/processor/fast/undelegate_confined_account.rs b/src/processor/fast/undelegate_confined_account.rs index 4bde845b..c44affb2 100644 --- a/src/processor/fast/undelegate_confined_account.rs +++ b/src/processor/fast/undelegate_confined_account.rs @@ -7,7 +7,7 @@ use super::{process_undelegation_with_cpi, to_pinocchio_program_error}; use crate::{ error::DlpError, pda, - processor::fast::utils::pda::{close_pda, create_pda, AccountFunding}, + processor::fast::utils::pda::{close_pda, create_pda, AccountSpace}, require_eq_keys, requires::{ require_authorization, require_initialized_delegation_metadata, @@ -116,7 +116,7 @@ pub fn process_undelegate_confined_account( create_pda( undelegate_buffer_account, &crate::fast::ID, - AccountFunding::Current(delegated_account.data_len()), + AccountSpace::CurrentRent(delegated_account.data_len()), &[Signer::from(&seeds!( pda::UNDELEGATE_BUFFER_TAG, delegated_account.address().as_ref(), diff --git a/src/processor/fast/utils/pda.rs b/src/processor/fast/utils/pda.rs index e4bcc782..b906560f 100644 --- a/src/processor/fast/utils/pda.rs +++ b/src/processor/fast/utils/pda.rs @@ -16,24 +16,26 @@ use crate::{consts::PROTOCOL_FEES_PERCENTAGE, error::DlpError}; const LEGACY_RENT_EXEMPT_LAMPORTS_PER_BYTE: u64 = 6960; const LEGACY_RENT_ACCOUNT_STORAGE_OVERHEAD: u64 = 128; -// usize stores the space required by an account -pub(crate) enum AccountFunding { - Current(usize), - Legacy(usize), +// usize stores the space required by an account. +pub(crate) enum AccountSpace { + CurrentRent(usize), + LegacyRent(usize), } -impl AccountFunding { +impl AccountSpace { fn space(&self) -> usize { match self { - Self::Current(space) | Self::Legacy(space) => *space, + Self::CurrentRent(space) | Self::LegacyRent(space) => *space, } } fn minimum_balance(&self) -> Result { let current_rent = Rent::get()?.try_minimum_balance(self.space())?; match self { - Self::Current(_) => Ok(current_rent), - Self::Legacy(_) => Ok(current_rent.max(legacy_rent(self.space())?)), + Self::CurrentRent(_) => Ok(current_rent), + Self::LegacyRent(_) => { + Ok(current_rent.max(legacy_rent(self.space())?)) + } } } } @@ -55,14 +57,14 @@ fn legacy_rent(space: usize) -> Result { pub(crate) fn create_pda( target_account: &AccountView, owner: &Address, - funding: AccountFunding, + account_space: AccountSpace, pda_signers: &[Signer], payer: &AccountView, ) -> ProgramResult { // Create the account manually or using the create instruction - let space = funding.space(); - let minimum_balance = funding.minimum_balance()?; + let space = account_space.space(); + let minimum_balance = account_space.minimum_balance()?; if target_account.lamports().eq(&0) { // If balance is zero, create account system::CreateAccount { From 2aeaeb1f641fcb5d1579bae67b355c37db21c4f4 Mon Sep 17 00:00:00 2001 From: Sarfaraz Nawaz Date: Thu, 20 Aug 2026 00:56:30 +0530 Subject: [PATCH 4/5] Clarify legacy rent funding behavior --- src/processor/fast/utils/pda.rs | 38 +++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/processor/fast/utils/pda.rs b/src/processor/fast/utils/pda.rs index b906560f..95eed020 100644 --- a/src/processor/fast/utils/pda.rs +++ b/src/processor/fast/utils/pda.rs @@ -16,7 +16,8 @@ use crate::{consts::PROTOCOL_FEES_PERCENTAGE, error::DlpError}; const LEGACY_RENT_EXEMPT_LAMPORTS_PER_BYTE: u64 = 6960; const LEGACY_RENT_ACCOUNT_STORAGE_OVERHEAD: u64 = 128; -// usize stores the space required by an account. +// AccountSpace represents the account allocation size. +// Its variant lets the caller choose how rent funding should be computed for that size. pub(crate) enum AccountSpace { CurrentRent(usize), LegacyRent(usize), @@ -33,6 +34,9 @@ impl AccountSpace { let current_rent = Rent::get()?.try_minimum_balance(self.space())?; match self { Self::CurrentRent(_) => Ok(current_rent), + // Legacy rent is a fee-budget floor, not a substitute for current + // rent exemption. Keep live rent as the lower bound if it ever + // exceeds the legacy formula. Self::LegacyRent(_) => { Ok(current_rent.max(legacy_rent(self.space())?)) } @@ -63,15 +67,13 @@ pub(crate) fn create_pda( ) -> ProgramResult { // Create the account manually or using the create instruction - let space = account_space.space(); - let minimum_balance = account_space.minimum_balance()?; if target_account.lamports().eq(&0) { // If balance is zero, create account system::CreateAccount { from: payer, to: target_account, - lamports: minimum_balance, - space: space as u64, + lamports: account_space.minimum_balance()?, + space: account_space.space() as u64, owner, } .invoke_signed(pda_signers) @@ -79,8 +81,9 @@ pub(crate) fn create_pda( // Otherwise, if balance is nonzero: // 1) transfer sufficient lamports for rent exemption - let rent_exempt_balance = - minimum_balance.saturating_sub(target_account.lamports()); + let rent_exempt_balance = account_space + .minimum_balance()? + .saturating_sub(target_account.lamports()); if rent_exempt_balance > 0 { system::Transfer { from: payer, @@ -93,7 +96,7 @@ pub(crate) fn create_pda( // 2) allocate space for the account system::Allocate { account: target_account, - space: space as u64, + space: account_space.space() as u64, } .invoke_signed(pda_signers)?; @@ -164,11 +167,24 @@ pub(crate) fn close_pda_with_fees( #[cfg(test)] mod tests { use super::legacy_rent; + use crate::{ + state::{DelegationMetadata, DelegationRecord, UndelegationRequester}, + Pubkey, + }; #[test] fn legacy_rent_uses_pre_reduction_rent_exempt_formula() { - assert_eq!(legacy_rent(96).unwrap(), 1_559_040); - assert_eq!(legacy_rent(53).unwrap(), 1_259_760); - assert_eq!(legacy_rent(65).unwrap(), 1_343_280); + let metadata = DelegationMetadata { + last_commit_id: 0, + undelegation_requester: UndelegationRequester::None, + seeds: vec![b"test-pda".to_vec()], + rent_payer: Pubkey::default(), + }; + + let delegation_rent = + legacy_rent(DelegationRecord::size_with_discriminator()).unwrap() + + legacy_rent(metadata.serialized_size()).unwrap(); + + assert_eq!(delegation_rent, 2_902_320); } } From 4ae062a468fb18b917c77dfeec3070d66ad7e817 Mon Sep 17 00:00:00 2001 From: Sarfaraz Nawaz Date: Thu, 20 Aug 2026 01:12:52 +0530 Subject: [PATCH 5/5] Remove unused rent fee percentage constant --- dlp-api/src/consts.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/dlp-api/src/consts.rs b/dlp-api/src/consts.rs index 5b277b3c..852d083f 100644 --- a/dlp-api/src/consts.rs +++ b/dlp-api/src/consts.rs @@ -2,9 +2,6 @@ use pinocchio::Address; use crate::compat::{pubkey, Pubkey}; -/// Legacy rent-fee percentage kept for API compatibility. -pub const RENT_FEES_PERCENTAGE: u8 = 10; - /// The fees extracted from the validator earnings (extracted in percentage from the validator fees claims). pub const PROTOCOL_FEES_PERCENTAGE: u8 = 10;