Attackathon _ Fuel Network 33039 - [Smart Contract - High] The subtraction function is not correctly
Submitted on Tue Jul 09 2024 20:44:32 GMT-0400 (Atlantic Standard Time) by @Schnilch for Attackathon | Fuel Network
Report ID: #33039
Report type: Smart Contract
Report severity: High
Target: https://github.com/FuelLabs/sway-libs/tree/0f47d33d6e5da25f782fc117d4be15b7b12d291b
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
In the subtraction functions for signed integers in the Sway libraries, the case when the other
parameter is negative is handled incorrectly. When the other
parameter is negative, it is still simply subtracted instead of being added, as would be mathematically correct.
Vulnerability Details
In the sway-libs, within the signed integer library, every signed integer has a subtraction function (see 1. reference. I have linked to the I64 subtraction function as an example, but the subtraction functions of all signed integers have the same bug). The parts of the function that handle cases where the other
parameter is negative are incorrectly implemented (see 2nd and 3rd references). When the other
parameter is negative, it is subtracted, but it should actually be added.
This part of the code is responsible for when self
is positive and other
is negative. Here you can see that self
and other
are being added, but the problem is that other
is added as a negative value. Therefore, other
is subtracted from self
. For the result to be calculated correctly, the absolute value of other (so it is no longer negative) should be added to self. It would look like this:
A similar error occurs when self and other both are negative:
This part could be fixed like this:
An Example
self = 9223372036854775908 (which is 100 when you subtract 2^63); other = 9223372036854775608 (which is -200 when you subtract 2^63). This means the result should be 9223372036854776108 because 100 - (-200) = 300 and 300 + 2^63 = 9223372036854776108. However, the error occurs because instead of adding 200 as in the example, it is subtracted. And the resulting value would be 9223372036854775708 (which is -100).
Impact Details
This bug can have various consequences depending on what the signed integer subtraction is used for. If this subtraction function is used to calculate token amounts on which transfers are then based, it can lead to a loss of tokens because the calculated amount may be incorrect. A user could lose money this way, or in the worst case, an attacker could deliberately exploit this vulnerability to steal money if he controls the other
parameter.
References
https://github.com/FuelLabs/sway-libs/blob/2a869c583d2ab9fbe8de17a3301d928b224062c7/libs/src/signed_integers/i256.sw#L375-L406
https://github.com/FuelLabs/sway-libs/blob/2a869c583d2ab9fbe8de17a3301d928b224062c7/libs/src/signed_integers/i64.sw#L310-L318
https://github.com/FuelLabs/sway-libs/blob/2a869c583d2ab9fbe8de17a3301d928b224062c7/libs/src/signed_integers/i64.sw#L302-L305
Proof of concept
Proof of Concept
For the POC of this bug, a sway project is required. This can be created with this command: forc new substraction-bug
After that, this dependency needs to be added to the Forc.toml: sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.22.0" }
Then the following code for the PoC must be inserted into the main.sw file:
The PoC can then be started with forc test
. This PoC demonstrates that the subtraction function of the signed integer library does not work. Although this is only a minimal PoC, if this function is used for the calculation of token amounts, it can easily lead to a loss of tokens.
Last updated