Skip to content

Commit 36cada6

Browse files
committed
Fix review comments
1 parent e472f45 commit 36cada6

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

sdk/src/sysvars/rent.rs

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ pub const DEFAULT_BURN_PERCENT: u8 = 50;
8888
/// added to an accounts data length when calculating [`Rent::minimum_balance`].
8989
pub 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

Comments
 (0)