-
Notifications
You must be signed in to change notification settings - Fork 85
WOETH - Fixed yield rate each day #2421
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
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## sparrowDom/woeth_hack_proof #2421 +/- ##
==============================================================
Coverage ? 14.22%
==============================================================
Files ? 100
Lines ? 4900
Branches ? 1294
==============================================================
Hits ? 697
Misses ? 4199
Partials ? 4 ☔ View full report in Codecov by Sentry. |
contracts/contracts/token/WOETH.sol
Outdated
|
||
import { StableMath } from "../utils/StableMath.sol"; | ||
import { Governable } from "../governance/Governable.sol"; | ||
import { Initializable } from "../utils/Initializable.sol"; | ||
import { OETH } from "./OETH.sol"; | ||
|
||
/** | ||
* @title OETH Token Contract |
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.
OETH -> WOETH
Code Review - WOETHRequirementsWe want to ensure that no donations can instantly affect the exchange rate used by lending platforms. This is because an instantly changing exchange rate on a redeemable asset can be fatal to a lending platform that uses it for borrows. The approach we chose here controls the exchange rate by slowly streaming out additional assets over time. Asset yield streamingBy controlling the extra asset amounts, rather than the rate, we avoids the easy critical bugs around fixed exchange rate changes in the face of changing asset amounts. 🟣 However a fixed asset per second yield does mean that the exchange rate can change over the yield period, as the total supply changes. If we assume that the standard attack requires a 2x donation, if an attacker perfectly time this around the end of a yield period, once they redeemed their half of funds, the rate of change of the exchange rate would double. However this still spreads their donation out over 23 hours, which still cancels out the attack. No flash loansA core defense of this contract is that donations can only affect subsequent blocks. It is impossible to use a flash loan and see even the slightest change in exchange rate inside the same block. 🟣 However, a whale attacker can reduce the cost of their donation by coming back into woeth after the attack has landed, and collecting a portion of the streaming yield. While this reduces the cost of the attack, it does not reduce the massively increased size of the donation needed. Sample attacks: For each attack, we will assume that an attacker needs a 50% price instant increase for the attack to land. It might be less, but it’s what we have seen in past attacks. It must be one block, because otherwise liquidations would rekt the attacker. Assuming 5 million wOETH supply. 10 million wOETH supply. Required donation sizes: Old WOETH: 5 million A flash loan cannot be used to help with this. Having a scheduled future yield does allow others to join the contract only when this contracts yield is known to be higher than other opportunities. This does however require them to already hold OETH, or the conversion fees or redeem time would probably preclude profitability. Easy ChecksAuthentication
Ethereum
Cryptographic code
Gas problemsNo for loops Black magicNo magic Overflow
Proxy
Events
Medium ChecksRounding and casts
Dependencies
External calls
Tests
Deploy
LogicLooks good. Deployment ConsiderationsNo Internal State
AttackThis code controls 30%-50% of our our assets. It’s widely used. A critical failure could allow these assets to be stolen. This code is also used by lending platforms or other DeFi systems, and wrong values from the exchange rate could result in losses there beyond just our token. The two primary attacks against this kind of contract are rounding errors and donation attacks. We think we’ve blocked both of these. FlavorThis code errs on the side of simplicity, using if statements to clearly define edge case behavior, as well as named intermediate variables to keep things easy to understand.
|
RequirementsThis PR prepares the WOETH contract to be safe to use on lending platforms by preventing the possibility of rapid inflation / donation attack to either the WOETH contract or the OETH Vault. Easy ChecksAuthentication
Ethereum
Cryptographic code
Gas problems
Black magic
Overflow
Proxy
Events
Medium ChecksRounding and casts
Dependencies
External calls
Tests
Deploy
ThinkingLogicLooks good. Deployment ConsiderationsNo Internal State
AttackAttacks on wrapper contracts like ours will usually try either a donation attack or a rounding attack when contract balances are small. This PR addresses the possibility of a donation attack to either the WOETH contract or the OUSD Vault. FlavorThe contract needs to represent the funds entering / exiting as part of wrapping and un-wrapping the token and the other funds which are result of yield & donations. We current have Though it is easier to understand there was a lot of casting necessary making the code uglier. Yield limit 🟣There is a way to game the 5% daily yield limit the contract sets as a limitation. The steps are:
The exchange rate between OETH and WOETH still takes 23 hours to drip. That 5% daily (23 hours rather) yield limitation can be increased to any amount by paying the 0.1% in redemption fees. Considering the ~40m in WOETH TVL and a flash loan of 500m, the 5% daily rebase limit could be increased by 12.5x to a 62.5% limit. Since no yield is dripped in the first (flash loan) transaction, this makes the attack much more risky. |
"You're being let go... Your department's being downsized. You're part of an outplacement. We're going in a different direction. We're not picking up your option..." We've decided on not using this approach, and instead controlling yield inside the vault. |
Code Change Checklist
To be completed before internal review begins:
Internal review:
Deploy checklist
Two reviewers complete the following checklist: