-
Notifications
You must be signed in to change notification settings - Fork 4
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
fix to dust issue on unforced withdrawals under special case #247
base: main
Are you sure you want to change the base?
Conversation
const newBal = await underlying.balanceOf(alice.address); | ||
|
||
expect(prevBal.sub(newBal)).to.eq(toDeposit.sub(parseUnits('1'))); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this test failing without your changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test because of the subtraction of 1 done in line 2977 to take the dust into account. Similarly many other tests also had a +1 or -1 in the end to account for the dust. This fix, fixes that issue so now we dont have to account for dust in the tests thus also making the tests more readable and simpler. I have made the changes to the tests and they are passing now.
This change violates one of our invariants: deposits or withdrawals should not affect the price per share. |
}); | ||
|
||
it('price per share can be manipulated', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious to why was there a test for "pps can be manipulated"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a test from the 2nd audit we did. The test proved (at the time) that it could be manipulated. We just kept it as it was
@dxganta check my comment above regarding the invariant |
I assume you meant this test. It was failing due to this line where at the end 1 was subtracted from the oldBalance variable to account for the difference in test. Since the current commit, fixes this so the we can assert I thus removed the sub(1) from the test and the test is passing now. Its not violating the invariant. |
@dxganta I'm not following. There are many more tests about that. That's on purpose, and for the reason I said: no user action should manipulate the price per share. Your change breaks that rule. @fyang1024 since you opened the issue, can you jump in here? |
No I dont think it does. All the tests I changed are just removing that '1' wei dust from the assertion which was there to account for the dust which is currently solved now with this fix. For example, in this test itself, |
I'll wait for @fyang1024 to answer before I go into details. But that |
Hi @gabrielpoca , as Certora has proved, the current implementation cannot preserve exact share price when user makes withdrawals because of the possible rounding of uint division in the The changed withdraw function won't be able to preserve the share price because of the possible rounding of uint division in the |
@fyang1024 yeah, I know that you lose precision every time you change from the amount to shares or shares to the amount. But both implementations are different because on the previous one, we always rounded down, but on this one, you are rounding up. |
@gabrielpoca I get your point. let's use an example.
Neither implementations maintain the share price invariant, but I don't see why previous round down makes the Vault better. |
My issue with the rounding up is that you can only round up for some. For instance, if the vault loses funds, and everyone is in a rush to withdraw from the vault, only some people will be able to round up, and the others will have to round down since there will be no funds left. Worst case scenario, the last person to withdraw gets burned, right? A second concern is really about the price per share. While initially, we have 1 share = 1000000000000000000 underlying, that relationship will change, and if the vault really really well, the rounding up may no longer be ~0.000000000000000001 underlying, and instead turn into a bigger amount. What do you think? |
The bottom line is that the user can withdraw the full amount only if the vault is making money and the user cannot withdraw more than her/his initial deposit. In the example above, the previous implementation burned the only user slightly without benefiting anyone else. I don't think 1 wei difference will make the last person to withdraw gets burned too much in practice. When the share price rises a lot, the two implementations will most likely end up with the same. I tried to assume the step 2 of the example has 1299 Token or 1999 Token rather than 1002 Token, and the calculations of both end up with the same which both allow the user to withdraw all the initial deposit. |
You are correct that you can only withdraw total amounts if the vault didn't lose money. I mean, it's only half true since there's also the local loss, where if the vault makes a lot of money and then loses only a bit after a claim, you can't withdraw your total amount. But it still doesn't change the fact that with each deposit you are slightly decreasing the price per share, right? |
If the vault is losing money, and the user did If the vault is making a lot of money, the 2 implementations should end up with the same, even though the calculations are slightly different. The two implementations have slightly different results only when the share price rises slightly (e.g, the user deposited yesterday and withdrew today) |
But withdrawals in this solution will decrease the price per share, while in the previous solution, they would increase it even if it's only so slightly for each withdrawal. For instance, if 3 million withdrawals are happening while the vault is also losing money (not enough to get negative), the withdrawals will help the price per share go down. I can try and run some numbers on this because I'm sure I could be missing some obvious property that prevents this. |
Fix to Audit issue #13 according to recommendation