-
Notifications
You must be signed in to change notification settings - Fork 85
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
Balancer MetaStablePool Strategy #1697
Conversation
…-sfrxETH-stETH-rETH
…-sfrxETH-stETH-rETH
Codecov Report
@@ Coverage Diff @@
## master #1697 +/- ##
===========================================
- Coverage 69.98% 12.67% -57.31%
===========================================
Files 45 47 +2
Lines 2382 2556 +174
Branches 622 655 +33
===========================================
- Hits 1667 324 -1343
- Misses 712 2232 +1520
+ Partials 3 0 -3
... and 37 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
* improve documentation * add comma
* add tests for approving tokens and harvesting rewards * prettier and lint
…-sfrxETH-stETH-rETH
… decrease after the attack comaring to the middle of the attack.
…ted by withdrawing the funds
virtual | ||
returns (uint256 balancerPoolTokens) | ||
{ | ||
balancerPoolTokens = IERC20(platformAddress).balanceOf(address(this)); |
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.
Noting, I don't think the code in this function is ever used, tested, or included in a deployed 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.
This is used by the checkBalance
functions here and here and both versions (with asset parameter & without) of checkBalance are used in a few places in the fork test file
There appears to be a little behavior that's unexpected to me. It looks like an even deposit can make a unit profit. (as recorded by check balance), (but maybe that has to do with tokens getting more valuable) ![]() Similarly, it's possible for withdrawAll() to be making a tiny unit loss, which is not what I would expect. ![]() Again, when picking different withdraw mixes, it looks like after withdrawing we have a little less money than we expect. ![]() All of these point to the the result of check balance being a tiny bit high somehow. Not sure how. Possibly acceptable. But still a bit of a mismatch to what I would we would expect. I wonder where this comes from. Gist with charts: https://gist.github.com/DanielVF/885753cd1dad7bc840046f19219ec480 |
@DanielVF you've asked me about caching the decimals yesterday. I forgot that by removing the Oracles (and relying solely on VaultValueChecker) we no longer query the decimals - so no need for caching. 2 birds 1 stone :) |
@DanielVF awesome approach of testing the behaviour of checkBalance and value in vault functions. I've made a couple of adjustments:
I've rerun the Jupyter notebook and this is what the deposit profit looks like with adjustments: Link to PR with all the 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.
Great work Domen
* Removed unused imports * Generated updated contract diagram
…-sfrxETH-stETH-rETH
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.
Requirements
We are adding support for a balancer MetaStablePool strategy.
We are doing the same way of splitting checkBalances into fixed equal percentages that we used for the curve pools.
Deployment Considerations
- Monitoring needed for pool
- Strategy needed in analytics
Internal State
config only
Attack
Biggest concern with our strategy is check balance inflation. We've fork tested this, and an attacker was unable to manipulate our balance downwards via tilting the pool.
Balancer has known read-only reentrancy vectors. We have the balancer approved method on our checkBalance, and a test checking that this blocks it.
Tests
I've run my own fork test suite.
Flavor
Still rather whenNotInBalancerVaultContext
was an inline function, rather than a modifier, but can live with this.
Overflow
- Never use "+" or "-", always use safe math or have contract compile in solidity version > 0.8
- Check that all for loops use uint256
Proxy
- Make sure proxy implementation contracts don't initialize variable state on variable declaration and do it rather in initialize function.
Black magic
- Does not contain
selfdestruct
- Does not use
delegatecall
outside of proxying - Address.isContract should be treated as if could return anything at any time, because that's reality.
Dependencies
- Review any new contract dependencies thoroughly (e.g. OpenZeppelin imports) when new dependencies are added or version of dependencies changes.
- If OpenZeppelin ACL roles are use review & enumerate all of them.
- Check OpenZeppelin security vulnerabilities and see if any apply to current PR considering the version of OpenZeppelin contract used.
Deploy
- Check that any deployer permissions are removed after deploy
Authentication
- Never use tx.origin
- Check that every external/public function should actually be external
- Check that every external/public function has the correct authentication
Cryptographic code
No crypto code
Gas problems
- Contracts with for loops must have either:
- A way to remove items
- Can be upgraded to get unstuck
- Size can only controlled by admins
- Contracts with for loops must not allow end users to add unlimited items to a loop that is used by others or admins.
External calls
- Contract addresses passed in are validated
- Reentrancy guards on all state changing functions
- Malicious behaviors
- Could fail from stack depth problems (low level calls must require success)
- No slippage attacks (we need to validate expected tokens received)
- Check with vault value checker
- Oracles, one of:
- No oracles
- Oracles can't be bent
- If oracle can be bent, it won't hurt us.
- Don't call balanceOf for external contracts to determine what they will do, when they instead use internal accounting?
Ethereum
- Contract does not send or receive Ethereum.
- Contract has no payable methods.
Adds balancer Meta Stable Pool strategy. Corresponding Notion design document.
Design considerations: since we are planning to potentially also support Composable pool strategy, I've decided to make Meta stable pool contract extend Aura contract. This way Aura implementation can stay the same when/if we add the support for Composable Stable pools.
Things done ✅ :