Attackathon _ Fuel Network 32275 - [Smart Contract - Medium] Various Sway Libs Bugs
Last updated
Was this helpful?
Last updated
Was this helpful?
Submitted on Mon Jun 17 2024 08:57:19 GMT-0400 (Atlantic Standard Time) by @anatomist for
Report ID: #32275
Report type: Smart Contract
Report severity: Medium
Target: https://github.com/FuelLabs/sway-libs/tree/0f47d33d6e5da25f782fc117d4be15b7b12d291b
Impacts:
Incorrect library function behaviors
provides a lot of utility functions to help contract development. Thus its correctness is important to ensure developers don't suffer from hidden vulnerabilities. We've identified a large amount of bugs within the libraries, and will go through each bug class in this report.
signed_integers
and fixed_point
The i256::bits
is incorrectly set to 128.
Strictly speaking, ifp64
has ~33 bits and not 64 bits. Similarly ifp128
has ~64 bits and ifp256
has ~129 bits
signed_integers
The twos complement currently doesn't make sense. For instance, two's complement for -1i8 should be 0xff, but the implementation returns 0x81
i128
and i256
i128
indent should be 1<<127
, and i256
indent should be 1<<255
UFP32::fract
The subtraction of u32::max
in UFP32::fract
will lead to underflow and panic
IFP::from
IFP::from
treats input as raw underlying instead of integers (different from signed_integer
). It is misused in several places
IFP::ceil
overflow on values close to min
IFP::ceil takes
ceilof underlying and then adjusts the values. Thus values near to
min` might suffer from incorrect overflow
fixed_point::round
fixed_point::round
takes both ceil
/ floor
and use them to derive the rounded values. Thus even if the final result falls within the valid range, function would still panic
if either ceil
of floor
does.
UFP128::sqrt
and UFP32::sqrt
The denominator for UFP128::sqrt
should be 1<<32
instead of 2<<32
The denominator for UFP32::sqrt
should be 1<<8
instead of 1<<16
UFP::sqrt
precision lossThe implementation of UFP::sqrt
loses 1/4 of precision in terms of its size.
UFP::pow
directly calls pow
on the underlying value, which will easily overflow for values >= 1.
fixed_point::exp
precision lossUFP::exp
is wildly inaccurate. We haven't properly estimated to amount of precision lost. But the PoC attached should demonstrate the idea.
UFP32::exp
and IFP256::exp
uses incorrect taylor seriesUFP32::exp
uses the taylor series for UFP64::exp
IFP256::exp
uses the taylor series for IFP128::exp
min
for IFP
min
for IFP
should use type::MAX
as underlying value
IFP
compare functionsIFP::gt
and IFP::lt
doesn't consider negative zeros. This might lead to incorrect results.
IFP::non_negative
doesn't consider negative zeroes. And might return false
for those.
IFP::ceil
IFP::ceil
increases underlying
when the value is negative, while the correct implementation should be to decrease underlying
.
It is hard to provide a concrete impact for library functions. But let's just say users may not be able to predict its behavior and might be caught of guard when those functions do unexpected stuff. And given the abundance of bugs, it seems extremely likely that users would run into those.
signed_integers
and fixed_point
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i256.sw#L88
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L46
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L46
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L46
signed_integers
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i8.sw#L398
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i16.sw#L399
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i32.sw#L398
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i64.sw#L399
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i128.sw#L423
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i256.sw#L419
i128
and i256
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i128.sw#L38
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/signed_integers/i256.sw#L39
UFP32::fract
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L391
IFP::from
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L416
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L475
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L476
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L416
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L475
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L476
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L554
IFP::ceil
overflow on values close to min
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L473
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L473
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L473
fixed_point::round
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L443
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp64.sw#L437
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp128.sw#L383
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L515
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L515
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L515
UFP128::sqrt
and UFP32::sqrt
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp128.sw#L443
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L462
UFP::sqrt
precision losshttps://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L462
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp64.sw#L456
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp128.sw#L442
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L492
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L497
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp64.sw#L487
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp128.sw#L450
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp128.sw#L452
fixed_point::exp
precision losshttps://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L471
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp64.sw#L465
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp128.sw#L469
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L533
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L533
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L533
UFP32::exp
and IFP256::exp
uses incorrect taylor serieshttps://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ufp32.sw#L475
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L537
min
for IFP
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L87
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L87
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L87
IFP
compare functionshttps://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L208
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L220
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L208
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L220
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L208
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L220
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L193
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L193
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L193
IFP::ceil
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp64.sw#L475
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp128.sw#L475
https://github.com/FuelLabs/sway-libs/blob/0f47d33d6e5da25f782fc117d4be15b7b12d291b/libs/src/fixed_point/ifp256.sw#L475
signed_integers
and fixed_point
signed_integers
i128
and i256
UFP32::fract
IFP::from
IFP::ceil
overflow on values close to min
fixed_point::round
UFP128::sqrt
and UFP32::sqrt
UFP::sqrt
precision lossfixed_point::exp
precision lossUFP32::exp
and IFP256::exp
uses incorrect taylor seriesmin
for IFP
IFP
compare functionsIFP::ceil