@@ -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 ) ]
186223pub struct WrappedInstructionData < ' a , T : InstructionData < ' a > > {
187224 instruction_data : T ,
0 commit comments