SSSwap

First Flight #41
Beginner FriendlyRust
100 EXP
View results
Submission Details
Severity: medium
Valid

Downcasting from u128 to u64 may lead to silent truncation

Root + Impact

The protocol is downcasting u128 to u64 without any additional checks which may lead to silent truncations.

Description

  • Normally, when casting, no decimals should be truncated

  • In these cases, when downcasting, every time the value exceeds the u64 max, all leading bits will be silently truncated

//Example
let mut amount_out: u64 = numerator.div_floor(&denominator) as u64; // <- if this division exceeds u64::MAX, leading bits will be truncated

Risk

Likelihood:

  • Since most users won't be dealing with such large amounts, likelihood is low

Impact:

  • Impact is high because this leads to a direct loss of funds

Proof of Concept

This code shows an example of what happens when not downcasting correctly

fn main() {
let large_value: u128 = u64::MAX as u128 + 42; // just above u64::MAX
// Naive cast: silently truncates the upper 64 bits
let casted = large_value as u64;
println!("Original u128: {}", large_value);
println!("After naive cast to u64: {}", casted);
if casted as u128 != large_value {
println!("⚠️ Bug detected: value was truncated!");
} else {
println!("✅ Safe conversion.");
}
}
Console:
Original u128: 18446744073709551657
After naive cast to u64: 41
⚠️ Bug detected: value was truncated!

Recommended Mitigation

For every downcast, it is recommended to use this safe downcast code:

+ value.try_into().map_err(|_| "value does not fit in u64")
Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Unsafe Casting

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.