-
Notifications
You must be signed in to change notification settings - Fork 79
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
WOETH: Withdraw OETH in surplus. #2119
base: sparrowDom/woeth_hack_proof
Are you sure you want to change the base?
WOETH: Withdraw OETH in surplus. #2119
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## sparrowDom/woeth_hack_proof #2119 +/- ##
===============================================================
+ Coverage 62.76% 62.78% +0.02%
===============================================================
Files 66 66
Lines 3373 3375 +2
Branches 657 873 +216
===============================================================
+ Hits 2117 2119 +2
Misses 1253 1253
Partials 3 3 ☔ View full report in Codecov by Sentry. |
WOETH: Withdraw OETH in surplus.
🚨 Report Summary
For more details view the full report in OpenZeppelin Code Inspector |
contracts/contracts/token/WOETH.sol
Outdated
// the contract, that we can let the governor transfer the excess of the token. | ||
require(asset_ != address(asset()), "Cannot collect OETH"); | ||
if (asset_ == address(asset())) { | ||
uint256 surplus = OETH(asset()).balanceOf(address(this)) - totalAssets(); |
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.
On a quick look, I'm a bit lost here. OETH is a rebasing token. wOETH's appreciation comes from the OETH yields (which are distributed during rebases with increasing balances). Won't this forgo all unrealized yields as well?
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.
Looks like it has an internal log of oethCredits (updating during wrap and unwrap) but let me check
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.
With WOETH ignore donations PR WOETH keeps the balance of the internal credits (of the OETH token) that change on mint, deposit, redeem, withdraw.
I think this approach is mathematically correct since the surplus
figures out the difference between WOETH internal credits amount and OETH internal credits (for WOETH contract) multiplied by the credits per token - in other words operating with OETH token amounts.
Surplus could also be calculated using another approach by finding the difference of internal credits tracked by WOETH and OETH and then multiplying it by the current credits per token ( to arrive to the OETH token surplus amount).
I think in either of the approaches the un-realized rebase yields aren't left on the table, since as long as we do the correct math on the underlying credits per token. The rebase will take care of correct yield distribution.
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.
Still a spot on comment @shahthepro 🙏 These are the sort of checks we need to make to be sure the math works correctly.
We could add a test for this @clement-ux, where:
- WOETH has initial supply of 100 OETH
- 2 OETH are transferred to the WOETH contract
- OETH rebases (say increases balance of OETH on WOETH contract by x2)
- governor should be able to transfer out 4 OETH and no more
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.
Thanks for the detailed explanation. Will check both PRs today to get more clarity on this.
Yeah, totally agree that we should be having unit and fork tests with different scenarios involving donations and rebases.
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.
I've added the test that @sparrowDom suggested in this commit and it passes.
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.
Surplus could also be calculated using another approach by finding the difference of internal credits tracked by WOETH and OETH and then multiplying it by the current credits per token ( to arrive to the OETH token surplus amount).
Do you mean dividing instead of multiplying maybe?
An implementation could look something like this:
(uint256 creditsBalanceHighres, uint256 creditsPerTokenHighres, ) = OETH(asset()).creditsBalanceOfHighres(address(this));
uint256 surplus = (creditsBalanceHighres - oethCreditsHighres).divPrecisely(creditsPerTokenHighres);
This could consume less gas but can lead to rounding issues IMO. But as you already mentioned, I don't think it is important enough to increase complexity.
contracts/contracts/token/WOETH.sol
Outdated
@@ -95,7 +97,8 @@ contract WOETH is ERC4626, Governable, Initializable { | |||
* @return amount of OETH credits the OETH amount corresponds to | |||
*/ | |||
function _creditsPerAsset(uint256 oethAmount) | |||
internal | |||
internal | |||
view |
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.
nice catch 👍
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.
Left a couple of comments, some minor changes and this PR is good to go.
Great job with it @clement-ux 🙏
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.
LGTM
Allow the governor to withdraw the OETH that has been sent in surplus to the wrapper.
Code Change Checklist
To be completed before internal review begins:
Internal review:
Deploy checklist
Two reviewers complete the following checklist: