@@ -88,6 +88,12 @@ pub const DEFAULT_BURN_PERCENT: u8 = 50;
8888/// added to an accounts data length when calculating [`Rent::minimum_balance`].
8989pub const ACCOUNT_STORAGE_OVERHEAD : u64 = 128 ;
9090
91+ /// Maximum lamports per byte for the SIMD-0194 exemption threshold.
92+ const SIMD0194_MAX_LAMPORTS_PER_BYTE : u64 = 1_759_197_129_867 ;
93+
94+ /// Maximum lamports per byte for the current exemption threshold.
95+ const CURRENT_MAX_LAMPORTS_PER_BYTE : u64 = 879_598_564_933 ;
96+
9197/// Rent sysvar data
9298#[ repr( C ) ]
9399#[ cfg_attr( feature = "copy" , derive( Copy ) ) ]
@@ -180,7 +186,8 @@ impl Rent {
180186 ///
181187 /// # Panics
182188 ///
183- /// Panics if `data_len` exceeds the maximum permitted data length.
189+ /// Panics if `data_len` exceeds the maximum permitted data length or if the
190+ /// `lamports_per_byte` is too large based on the `exemption_threshold`.
184191 #[ deprecated( since = "0.10.0" , note = "Use `Rent::try_minimum_balance` instead" ) ]
185192 #[ inline( always) ]
186193 pub fn minimum_balance ( & self , data_len : usize ) -> u64 {
@@ -194,20 +201,21 @@ impl Rent {
194201 /// This method avoids floating-point operations when the `exemption_threshold`
195202 /// is the default value.
196203 ///
204+ /// # Important
205+ ///
206+ /// The caller must ensure that `data_len` is within the permitted limit
207+ /// and the `lamports_per_byte` is within the permitted limit based on
208+ /// the `exemption_threshold` to avoid overflow.
209+ ///
197210 /// # Arguments
198211 ///
199212 /// * `data_len` - The number of bytes in the account
200213 ///
201214 /// # Returns
202215 ///
203216 /// The minimum balance in lamports for rent exemption.
204- ///
205- /// # Safety
206- ///
207- /// The caller must ensure that `data_len` is within permitted the permitted
208- /// limit to avoid overflow.
209217 #[ inline( always) ]
210- pub unsafe fn minimum_balance_unchecked ( & self , data_len : usize ) -> u64 {
218+ pub fn minimum_balance_unchecked ( & self , data_len : usize ) -> u64 {
211219 let bytes = data_len as u64 ;
212220
213221 // There are two cases where it is possible to avoid floating-point
@@ -249,17 +257,30 @@ impl Rent {
249257 ///
250258 /// # Errors
251259 ///
252- /// Returns `ProgramError::InvalidArgument` if `data_len` exceeds the maximum permitted
253- /// data length.
260+ /// Returns `ProgramError::InvalidArgument` if `data_len` exceeds the maximum
261+ /// permitted data length or if the `lamports_per_byte` is too large based on
262+ /// the `exemption_threshold`, which would cause an overflow.
263+ #[ allow( clippy:: collapsible_if) ]
254264 #[ inline( always) ]
255265 pub fn try_minimum_balance ( & self , data_len : usize ) -> Result < u64 , ProgramError > {
256266 if data_len as u64 > MAX_PERMITTED_DATA_LENGTH {
257- Err ( ProgramError :: InvalidArgument )
258- } else {
259- // SAFETY: The `data_len` is validated to be lower than the maximum permitted
260- // data length.
261- Ok ( unsafe { self . minimum_balance_unchecked ( data_len) } )
267+ return Err ( ProgramError :: InvalidArgument ) ;
262268 }
269+
270+ // Validate `lamports_per_byte` based on `exemption_threshold`
271+ // to prevent overflow.
272+
273+ if unlikely ( self . lamports_per_byte > CURRENT_MAX_LAMPORTS_PER_BYTE ) {
274+ if self . exemption_threshold == CURRENT_EXEMPTION_THRESHOLD {
275+ return Err ( ProgramError :: InvalidArgument ) ;
276+ }
277+ } else if unlikely ( self . lamports_per_byte > SIMD0194_MAX_LAMPORTS_PER_BYTE ) {
278+ if self . exemption_threshold == SIMD0194_EXEMPTION_THRESHOLD {
279+ return Err ( ProgramError :: InvalidArgument ) ;
280+ }
281+ }
282+
283+ Ok ( self . minimum_balance_unchecked ( data_len) )
263284 }
264285
265286 /// Determines if an account can be considered rent exempt.
0 commit comments