Open c4-bot-2 opened 7 months ago
bytes032 marked the issue as sufficient quality report
bytes032 marked the issue as primary issue
tserg (sponsor) confirmed
The Warden has demonstrated how the "hidden" operations of multiplication and division that are performed as part of the overloaded Wad
data type primitive operators can result in loss of precision for assets with less than 18
decimals which are explicitly meant to be supported by the Opus system per the onboarding guidelines.
I consider a high-risk rating appropriate given that the truncation will be greater the lower the decimals of the token and the higher the value per unit of the token is.
alex-ppg marked the issue as satisfactory
alex-ppg marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2024-01-opus/blob/4720e9481a4fb20f4ab4140f9cc391a23ede3817/src/core/gate.cairo#L220
Vulnerability details
Vulnerability details
in
gate.cairo
When the user callsdeposit()
, it calculates the corresponding shares throughconvert_to_yang_helper()
. The code is as follows:The calculation formula is:
(asset_amt.into() * total_yang) / get_total_assets_helper(asset).into()
The actual calculation of converting Wad to pure numbers is:
(asset_amt * total_yang / 1e18) * 1e18 / total_assets
The above formula
(asset_amt * total_yang / 1e18)
will lose precision, especially when the asset's decimals are less than 18.Assume btc as an example, decimals = 8 after
add_yang(btc)
INITIAL_DEPOSIT_AMT = 1000 so: total_assets = 1000 total_yang = 1000e10 = 1e13If the user deposits 0.0009e8 BTC, according to the formula = (asset_amt total_yang / 1e18) = 0.0009e8 1e13 /1e18 = 0.9e5 * 1e13 /1e18 = 0
With BTC's price at 40,000 USD, 0.0009e8 = 36 USD
The user will lose 36 USD
We should cancel dividing by 1e18 and then multiplying by 1e18, and calculate directly shares =
asset_amt.into() * total_yang.into() / total_assets.into()
shares = 0.0009e8 * 1e13 / 1000 = 0.0009e18 = 900000000000000Due to the premature division by
1e18
, precision is lost, and the user loses a portion of their funds.Proof of Concept
add to test_abbot.cairo
Recommended Mitigation
Assessed type
Decimal