@@ -384,6 +384,13 @@ fn check_allowances(
384384 allowances : Vec < Allowance > ,
385385 assets : & AssetMap ,
386386) -> InterpreterResult < Option < u128 > > {
387+ let mut earliest_violation: Option < u128 > = None ;
388+ let mut record_violation = |candidate : u128 | {
389+ if earliest_violation. is_none_or ( |current| candidate < current) {
390+ earliest_violation = Some ( candidate) ;
391+ }
392+ } ;
393+
387394 // Elements are (index in allowances, amount)
388395 let mut stx_allowances: Vec < ( usize , u128 ) > = Vec :: new ( ) ;
389396 // Map assets to a vector of (index in allowances, amount)
@@ -428,34 +435,30 @@ fn check_allowances(
428435
429436 // Check STX movements
430437 if let Some ( stx_moved) = assets. get_stx ( owner) {
431- // If there are no allowances for STX, any movement is a violation
432438 if stx_allowances. is_empty ( ) {
433- return Ok ( Some ( MAX_ALLOWANCES as u128 ) ) ;
434- }
435-
436- // Check against the STX allowances
437- for ( index, allowance) in & stx_allowances {
438- if stx_moved > * allowance {
439- return Ok ( Some ( u128:: try_from ( * index) . map_err ( |_| {
440- InterpreterError :: Expect ( "failed to convert index to u128" . into ( ) )
441- } ) ?) ) ;
439+ // If there are no allowances for STX, any movement is a violation
440+ record_violation ( MAX_ALLOWANCES as u128 ) ;
441+ } else {
442+ for ( index, allowance) in & stx_allowances {
443+ if stx_moved > * allowance {
444+ record_violation ( * index as u128 ) ;
445+ break ;
446+ }
442447 }
443448 }
444449 }
445450
446451 // Check STX burns
447452 if let Some ( stx_burned) = assets. get_stx_burned ( owner) {
448- // If there are no allowances for STX, any burn is a violation
449453 if stx_allowances. is_empty ( ) {
450- return Ok ( Some ( MAX_ALLOWANCES as u128 ) ) ;
451- }
452-
453- // Check against the STX allowances
454- for ( index, allowance) in & stx_allowances {
455- if stx_burned > * allowance {
456- return Ok ( Some ( u128:: try_from ( * index) . map_err ( |_| {
457- InterpreterError :: Expect ( "failed to convert index to u128" . into ( ) )
458- } ) ?) ) ;
454+ // If there are no allowances for STX, any burn is a violation
455+ record_violation ( MAX_ALLOWANCES as u128 ) ;
456+ } else {
457+ for ( index, allowance) in & stx_allowances {
458+ if stx_burned > * allowance {
459+ record_violation ( * index as u128 ) ;
460+ break ;
461+ }
459462 }
460463 }
461464 }
@@ -479,17 +482,13 @@ fn check_allowances(
479482
480483 if merged. is_empty ( ) {
481484 // No allowance for this asset, any movement is a violation
482- return Ok ( Some ( MAX_ALLOWANCES as u128 ) ) ;
485+ record_violation ( MAX_ALLOWANCES as u128 ) ;
486+ continue ;
483487 }
484488
485- // Sort by allowance index so we check allowances in order
486- merged. sort_by_key ( |( idx, _) | * idx) ;
487-
488489 for ( index, allowance) in merged {
489490 if * amount_moved > allowance {
490- return Ok ( Some ( u128:: try_from ( index) . map_err ( |_| {
491- InterpreterError :: Expect ( "failed to convert index to u128" . into ( ) )
492- } ) ?) ) ;
491+ record_violation ( index as u128 ) ;
493492 }
494493 }
495494 }
@@ -512,20 +511,13 @@ fn check_allowances(
512511
513512 if merged. is_empty ( ) {
514513 // No allowance for this asset, any movement is a violation
515- return Ok ( Some ( MAX_ALLOWANCES as u128 ) ) ;
514+ record_violation ( MAX_ALLOWANCES as u128 ) ;
515+ continue ;
516516 }
517517
518- // Sort by allowance index so we check allowances in order
519- merged. sort_by_key ( |( idx, _) | * idx) ;
520-
521518 for ( index, allowance_vec) in merged {
522- // Check against the NFT allowances
523- for id_moved in ids_moved {
524- if !allowance_vec. contains ( id_moved) {
525- return Ok ( Some ( u128:: try_from ( index) . map_err ( |_| {
526- InterpreterError :: Expect ( "failed to convert index to u128" . into ( ) )
527- } ) ?) ) ;
528- }
519+ if ids_moved. iter ( ) . any ( |id| !allowance_vec. contains ( id) ) {
520+ record_violation ( index as u128 ) ;
529521 }
530522 }
531523 }
@@ -535,20 +527,18 @@ fn check_allowances(
535527 if let Some ( stx_stacked) = assets. get_stacking ( owner) {
536528 // If there are no allowances for stacking, any stacking is a violation
537529 if stacking_allowances. is_empty ( ) {
538- return Ok ( Some ( MAX_ALLOWANCES as u128 ) ) ;
539- }
540-
541- // Check against the stacking allowances
542- for ( index, allowance) in & stacking_allowances {
543- if stx_stacked > * allowance {
544- return Ok ( Some ( u128:: try_from ( * index) . map_err ( |_| {
545- InterpreterError :: Expect ( "failed to convert index to u128" . into ( ) )
546- } ) ?) ) ;
530+ record_violation ( MAX_ALLOWANCES as u128 ) ;
531+ } else {
532+ for ( index, allowance) in & stacking_allowances {
533+ if stx_stacked > * allowance {
534+ record_violation ( * index as u128 ) ;
535+ break ;
536+ }
547537 }
548538 }
549539 }
550540
551- Ok ( None )
541+ Ok ( earliest_violation )
552542}
553543
554544/// Handles all allowance functions, always returning an error, since these are
0 commit comments