Attackathon _ Fuel Network 33227 - [Smart Contract - High] Lack of overflow protection in the pow fu
Submitted on Mon Jul 15 2024 12:05:53 GMT-0400 (Atlantic Standard Time) by @Schnilch for Attackathon | Fuel Network
Report ID: #33227
Report type: Smart Contract
Report severity: High
Target: https://github.com/FuelLabs/sway/tree/v0.61.2
Impacts:
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
For the data types u8, u16, and u32, there is no overflow protection in the pow function implemented in the standard library. If the pow function is used to calculate coin amounts, it can result in the loss of coins.
Vulnerability Details
For the data types u8 u16, u32, u64, and u256, the pow function is implemented in the standard library in math.sw. However, the pow function for the data types u8, u16, and u32 does not have overflow protections. An overflow of a u64 and a u256 is handled by the VM. Overflow protection for the other three data types would need to be implemented directly in the pow function in the standard library because the VM does not handle it. Due to the lack of these protections, the pow function of these data types are susceptible to overflow (see 1. reference). For u16 and u32, the result would simply be larger than the data type as long as it still fits into a u64, since the VM converts u16 and u32 into u64's. For u8, there would be a simple wraparound, and once the result exceeds 255, it would start back at 0.
Impact Details
This bug can have many different impacts based on what is calculated with the pow function. Especially if a coin amount is calculated with the pow function or if the result is further used to calculate a coin amount, it can easily lead to a loss of coins. Additionally, with the data types u16 and u32, if the result exceeds the maximum of the data type, the value is still stored without wrapping. If this number is then returned and further used in the Rust SDK, it would wrap there, resulting in an incorrect value. This can again lead to a loss of coins if tokens are transfers based on this value.
References
https://github.com/FuelLabs/sway/blob/ebc2ee6bf5d488e0ff693bfc8680707d66cd5392/sway-lib-std/src/math.sw#L114-L139
Proof of concept
Proof of Concept
For the PoC of this bug, a new fuel project with a Rust test suite is needed. This can be created with the following commands:
forc new pow-bugcd pow-bugcargo generate --init fuellabs/sway templates/sway-test-rs --name pow-bug --forceNow the following code needs to be inserted into themain.swfile:
Now the following code needs to be inserted into harness.rs:
The PoC can be started with the following command: cargo test pow_bug -- --nocapture
In the PoC, only the overflow of u8 and u32 is shown because the overflow behavior of u16 is certainly the same as that of u32.
Last updated
Was this helpful?