Skip to content

Commit 0823295

Browse files
committed
Harden rollover fee accumulation
1 parent 5d58e11 commit 0823295

3 files changed

Lines changed: 41 additions & 4 deletions

File tree

programs/system/src/context.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,36 @@ impl<'info> SystemContext<'info> {
147147
}
148148
}
149149

150-
pub fn set_rollover_fee(&mut self, ix_data_index: u8, fee: u64) {
150+
pub fn set_rollover_fee(&mut self, ix_data_index: u8, fee: u64) -> Result<()> {
151151
let payment = self
152152
.rollover_fee_payments
153153
.iter_mut()
154154
.find(|a| a.0 == ix_data_index);
155155
match payment {
156-
Some(payment) => payment.1 += fee,
156+
Some(payment) => {
157+
payment.1 = payment
158+
.1
159+
.checked_add(fee)
160+
.ok_or(ProgramError::ArithmeticOverflow)?;
161+
}
157162
None => self.rollover_fee_payments.push((ix_data_index, fee)),
158163
};
164+
Ok(())
165+
}
166+
167+
#[cfg(test)]
168+
fn new_for_test() -> SystemContext<'static> {
169+
SystemContext {
170+
account_indices: Vec::new(),
171+
accounts: Vec::new(),
172+
account_infos: Vec::new(),
173+
hashed_pubkeys: Vec::new(),
174+
addresses: Vec::new(),
175+
rollover_fee_payments: Vec::new(),
176+
network_fee_is_set: false,
177+
legacy_merkle_context: Vec::new(),
178+
invoking_program_id: None,
179+
}
159180
}
160181

161182
/// Network fee distribution (fees read from tree metadata as `network_fee`):
@@ -182,6 +203,22 @@ impl<'info> SystemContext<'info> {
182203
}
183204
}
184205

206+
#[cfg(test)]
207+
mod tests {
208+
use super::*;
209+
210+
#[test]
211+
fn set_rollover_fee_accumulates_checked() {
212+
let mut context = SystemContext::new_for_test();
213+
214+
context.set_rollover_fee(3, u64::MAX).unwrap();
215+
let err = context.set_rollover_fee(3, 1).unwrap_err();
216+
217+
assert_eq!(err, ProgramError::ArithmeticOverflow);
218+
assert_eq!(context.rollover_fee_payments, vec![(3, u64::MAX)]);
219+
}
220+
}
221+
185222
#[derive(Debug)]
186223
pub struct WrappedInstructionData<'a, T: InstructionData<'a>> {
187224
instruction_data: T,

programs/system/src/processor/create_address_cpi_data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub fn derive_new_addresses<'info, 'a, 'b: 'a, const ADDRESS_ASSIGNMENT: bool>(
123123
}
124124
cpi_ix_data.addresses[i].address = address;
125125

126-
context.set_rollover_fee(new_address_params.address_queue_index(), rollover_fee);
126+
context.set_rollover_fee(new_address_params.address_queue_index(), rollover_fee)?;
127127
}
128128
cpi_ix_data.num_address_queues = accounts
129129
.iter()

programs/system/src/processor/create_outputs_cpi_data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ pub fn create_outputs_cpi_data<'a, 'info, T: InstructionData<'a>>(
221221
.map_err(ProgramError::from)?;
222222
}
223223
}
224-
context.set_rollover_fee(current_index as u8, rollover_fee);
224+
context.set_rollover_fee(current_index as u8, rollover_fee)?;
225225
}
226226

227227
cpi_ix_data.num_output_queues = index_merkle_tree_account as u8;

0 commit comments

Comments
 (0)