-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug in deposit
if the asset decimals are less than 18
#148
Comments
Great sleuthing @andreivladbrg. I am glad you found it. While reading your report, I stumbled upon a question for which I have created a discussion: #150 and would love like to hear your thoughts on it. If we agree to keep the 18-decimals format, then I cannot think of a better solution than what you have already proposed. We should also add two more assets, 0 decimals and 30 decimals, to the list of assets for invariant testing (related issue: #137). |
I have another idea. What if we allow deposits in native decimals instead of normalised decimals? In your solution, you will now make two conversions:
If we allow deposit with native decimals, then we only have to handle one conversion i.e.
Do you find any problem with this approach? |
Wait, I don't think I understand. Are you suggesting to make the In my proposal, if I was not clear. I am saying that in the Also, I am afraid we can’t escape the need for a second conversion because the refundable/withdrawable amounts are in an 18-decimal format, as we need to have the |
Oh that was not clear to me from the OP. Then we are on the same page. Can you explain did you add
Thats true, we will need both. But not necessary in the same function. What do you think about using the same design in |
It is in the OP, but I will paste it here again:
Ofc not in the same function. There will be a problem if you use both in the same function. Either one way, either the other way.
we could do that as it would be technically possible. but there would an inconsistency between the 2 extract operations :
in the same time, you can say there will an inconsistency between
Not sure, yet, what is the best approach. Should I proceed with creating a PR with proposed fix? |
I see. I am not in favour of reverting the deposit tx. Instead of reverting, lets just transfer the correct amount in
A reverting tx will cost a significant amount of gas. Even the UI can make such mistakes.
Yes please. Thank you. |
About
In the current version of the
deposit
function it requires a 18 decimalamount
param.This causes a bug when the asset has less than 18 decimals due to a problem here:
flow/src/SablierFlow.sol
Line 413 in aac36d5
Imagine this scenario for a 6 decimals asset:
1_000000_500000000000
)_streams[streamId].balance
will be updated to1_000000_500000000000
asset.balanceOf(flow) = 1_000000
_streams[streamId].balance
will be updated to2 * 1_000000_500000000000 = 2_000001_000000000000
asset.balanceOf(flow) = 2_000000
So, now we will have a stream balance, normalized (2_000001), greater than the actual asset balance (2_000000) assigned to the unique stream, which as you can see, it can lead to a leak of funds.
Note: For extract operations (refund and withdraw), I couldn’t find a problem because the amount is subtracted and not added, so we will not have problems with digits shifting to the left.
Test on remix
How to fix this
The fix consists of changing the amount parameter to match the asset decimals. However, the internal storage can still be in an 18-decimal format, so we will need to add a new function
_calculateDepositAmount
.For assets with decimals greater than 18, I believe we will need to restrict the last decimals to zeros (the difference between decimals and 18). For example, the transfer amount divided by$10^{18}$ must be equal to $10^{normalizingFactor}$ so that assets won’t be stuck in the contract. Yes, it is a limitation, but it wouldn’t lead to loss of funds from other streams. Also, there are almost no assets with more than 18 decimals.
@smol-ninja Please lmk if I have missed something in my proposed fix, or if you have a better idea on how address this bug. Otherwise I will open a PR with this fix.
The text was updated successfully, but these errors were encountered: