Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 2e5056f

Browse files
Tyera Eulbergmvines
authored andcommitted
Add Account.rent_exempt_reserve
1 parent a5c1bb4 commit 2e5056f

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

token/program/src/processor.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Processor {
4141
return Err(TokenError::AlreadyInUse.into());
4242
}
4343

44-
if mint_info.lamports() < rent.minimum_balance(mint_info_data_len) {
44+
if !rent.is_exempt(mint_info.lamports(), mint_info_data_len) {
4545
return Err(TokenError::NotRentExempt.into());
4646
}
4747

@@ -68,7 +68,7 @@ impl Processor {
6868
return Err(TokenError::AlreadyInUse.into());
6969
}
7070

71-
if new_account_info.lamports() < rent.minimum_balance(new_account_info_data_len) {
71+
if !rent.is_exempt(new_account_info.lamports(), new_account_info_data_len) {
7272
return Err(TokenError::NotRentExempt.into());
7373
}
7474

@@ -80,6 +80,7 @@ impl Processor {
8080
if *mint_info.key == crate::native_mint::id() {
8181
account.is_native = true;
8282
account.amount = new_account_info.lamports();
83+
account.rent_exempt_reserve = rent.minimum_balance(new_account_info_data_len);
8384
} else {
8485
account.is_native = false;
8586
account.amount = 0;
@@ -101,7 +102,7 @@ impl Processor {
101102
return Err(TokenError::AlreadyInUse.into());
102103
}
103104

104-
if multisig_info.lamports() < rent.minimum_balance(multisig_info_data_len) {
105+
if !rent.is_exempt(multisig_info.lamports(), multisig_info_data_len) {
105106
return Err(TokenError::NotRentExempt.into());
106107
}
107108

@@ -183,6 +184,10 @@ impl Processor {
183184
.ok_or(TokenError::Overflow)?;
184185

185186
if source_account.is_native {
187+
// Ensure that wrapped SOL accounts remain rent-exempt
188+
if source_account_info.lamports() < source_account.rent_exempt_reserve + amount {
189+
return Err(TokenError::InsufficientFunds.into());
190+
}
186191
**source_account_info.lamports.borrow_mut() -= amount;
187192
**dest_account_info.lamports.borrow_mut() += amount;
188193
}
@@ -2827,8 +2832,11 @@ mod tests {
28272832
let mut mint_account =
28282833
SolanaAccount::new(mint_minimum_balance(), size_of::<Mint>(), &program_id);
28292834
let account_key = pubkey_rand();
2830-
let mut account_account =
2831-
SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
2835+
let mut account_account = SolanaAccount::new(
2836+
account_minimum_balance() + 40,
2837+
size_of::<Account>(),
2838+
&program_id,
2839+
);
28322840
let account2_key = pubkey_rand();
28332841
let mut account2_account =
28342842
SolanaAccount::new(account_minimum_balance(), size_of::<Account>(), &program_id);
@@ -2857,7 +2865,7 @@ mod tests {
28572865
.unwrap();
28582866
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
28592867
assert!(account.is_native);
2860-
assert_eq!(account.amount, account_minimum_balance());
2868+
assert_eq!(account.amount, account_minimum_balance() + 40);
28612869

28622870
// initialize native account
28632871
do_process_instruction(
@@ -2927,8 +2935,8 @@ mod tests {
29272935

29282936
let account: &mut Account = state::unpack(&mut account_account.data).unwrap();
29292937
assert!(account.is_native);
2930-
assert_eq!(account_account.lamports, account_minimum_balance() - 40);
2931-
assert_eq!(account.amount, account_minimum_balance() - 40);
2938+
assert_eq!(account_account.lamports, account_minimum_balance());
2939+
assert_eq!(account.amount, account_minimum_balance());
29322940
let account: &mut Account = state::unpack(&mut account2_account.data).unwrap();
29332941
assert!(account.is_native);
29342942
assert_eq!(account2_account.lamports, account_minimum_balance() + 40);
@@ -2948,10 +2956,7 @@ mod tests {
29482956
assert!(account.is_native);
29492957
assert_eq!(account_account.lamports, 0);
29502958
assert_eq!(account.amount, 0);
2951-
assert_eq!(
2952-
account3_account.lamports,
2953-
2 * account_minimum_balance() - 40
2954-
);
2959+
assert_eq!(account3_account.lamports, 2 * account_minimum_balance());
29552960
}
29562961

29572962
#[test]

token/program/src/state.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub struct Account {
4646
pub delegated_amount: u64,
4747
/// Optional authority to close the account.
4848
pub close_authority: COption<Pubkey>,
49+
/// An Account is required to be rent-exempt. This value logs the reserve required to be
50+
/// rent-exempt so that wrapped SOL accounts do not drop below this threshold.
51+
pub rent_exempt_reserve: u64,
4952
}
5053
impl Account {
5154
/// Checks if account is frozen

0 commit comments

Comments
 (0)