-
Notifications
You must be signed in to change notification settings - Fork 41
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
Using wrappedToken in CompositeLiquidityRouter in ERC4626Pool operations #1201
base: main
Are you sure you want to change the base?
Using wrappedToken in CompositeLiquidityRouter in ERC4626Pool operations #1201
Conversation
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.
First pass done. I didn't get to the tests yet, but I think there are a few things that need to be adjusted before proceeding.
Overall the idea is correct; great job. It's just that some of the edge cases should behave differently now that we're not automatically wrapping / unwrapping.
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.
Another pass done.
Changes are looking good for the most part. Just a few minor comments around names / docs / style; otherwise seems to be correct. I'll finish covering the tests in one more pass. Great job!
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 a pretty elegant solution (especially to the limits problem). I have a conceptual issue with the useWrappedTokens
name, and lots of little details.
I also think these PRs need a lot more in the description. Why do we need it? What problem does it address? What options did we consider and reject (e.g., in this case, the limits hack, replaced by splitting the wrap/unwrap functions)?
Otherwise we're not going to remember all this context when we go back and look at this in 6 months or a year.
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
…ttps://github.com/balancer/balancer-v3-monorepo into using-wrapped-amount-in-erc4626-operations-in-clr
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'd recommend changing isWrappedToken
to useWrappedToken
, it's probably clearer. Also, since the amounts out are mixing wrapped and underlying, I'd return a token array, for UX purposes. Not sure if gas is a constraint in this case.
Ohh, I just noticed it was |
I didn't have an issue with the name (also prefer Maybe reverse the sense of the name to make it clearer, like |
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 think we need to address the boolean array name (see my suggestion to use isStandardToken
or useAsStandardToken
), and returning the token addresses, which would resolve all the "sorted in ... order" comment issues.
My eyes are already lost in the description, I double checked several times, but if you can double check, I would be very grateful |
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.
Looking much better! Note the suggested language for NatSpec, which I believe is much clearer.
Sorry for the late comment, but I feel we're making up new terms here 😅 We're already dealing with wrapped and underlying, and that should be enough. I can't know which of them is The argument is consumed by a function called |
Makes sense - especially because there isn't an unwrap, so there's only one name for the set of flags. The only drawback is the "default" value would be to set everything to true (kind of annoying), but I agree that reusing standard terms is more important. |
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 looking great.
Just a few more comments; otherwise LGTM. I like the new structure much better; it reuses less code, but it's more clear and goes straight to the point.
pkg/vault/test/foundry/CompositeLiquidityRouterERC4626Pool.t.sol
Outdated
Show resolved
Hide resolved
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
Co-authored-by: EndymionJkb <[email protected]>
…ttps://github.com/balancer/balancer-v3-monorepo into using-wrapped-amount-in-erc4626-operations-in-clr
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 good now; have one last (very minor) rename suggestion, and some comments.
* @param useAsStandardToken An array indicating whether to use the token as standard or wrap it, | ||
* sorted in token registration order of wrapped tokens in the pool | ||
* @param wrapUnderlying Flags indicating whether the corresponding token should be wrapped or | ||
* use as a standard ERC20 |
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.
* use as a standard ERC20 | |
* used as a standard ERC20 |
* @param useAsStandardToken An array indicating whether to use the token as standard or wrap it, | ||
* sorted in token registration order of wrapped tokens in the pool | ||
* @param wrapUnderlying Flags indicating whether the corresponding token should be wrapped or | ||
* use as a standard ERC20 |
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.
* use as a standard ERC20 | |
* used as a standard ERC20 |
* @param useAsStandardToken An array indicating whether to use the token as standard or unwrap it, | ||
* sorted in token registration order of wrapped tokens in the pool | ||
* @param unwrapWrapper Flags indicating whether the corresponding token should be unwrapped or | ||
* use as a standard ERC20 |
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.
* use as a standard ERC20 | |
* used as a standard ERC20 |
* @param wethIsEth If true, incoming ETH will be wrapped to WETH and outgoing WETH will be unwrapped to ETH | ||
* @param userData Additional (optional) data required for removing liquidity | ||
* @return tokensOut Actual tokens received | ||
* @return amountsOut Actual amounts of tokens received | ||
*/ | ||
function removeLiquidityProportionalFromERC4626Pool( | ||
address pool, | ||
bool[] memory useAsStandardToken, | ||
bool[] memory unwrapWrapper, |
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.
bool[] memory unwrapWrapper, | |
bool[] memory unwrapWrapped, |
If we're saying "wrapped" and "underlying," this should be unwrapWrapped
* @param useAsStandardToken An array indicating whether to use the token as standard or wrap it, | ||
* sorted in token registration order of wrapped tokens in the pool | ||
* @param wrapUnderlying Flags indicating whether the corresponding token should be wrapped or | ||
* use as a standard ERC20 |
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.
* use as a standard ERC20 | |
* used as a standard ERC20 |
@@ -134,7 +134,7 @@ contract CompositeLiquidityRouter is ICompositeLiquidityRouter, BatchRouterCommo | |||
wethIsEth: wethIsEth, | |||
userData: userData | |||
}), | |||
useAsStandardToken | |||
unwrapWrapper |
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.
unwrapWrapper | |
unwrapWrapped |
@@ -303,13 +303,13 @@ contract CompositeLiquidityRouter is ICompositeLiquidityRouter, BatchRouterCommo | |||
|
|||
function removeLiquidityERC4626PoolProportionalHook( | |||
RemoveLiquidityHookParams calldata params, | |||
bool[] calldata useAsStandardToken | |||
bool[] calldata unwrapWrapper |
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.
bool[] calldata unwrapWrapper | |
bool[] calldata unwrapWrapped |
// Revert if `poolTokens` length does not match `minAmountsOut` and `unwrapWrapper`. | ||
InputHelpers.ensureInputLengthMatch(poolTokensLength, params.minAmountsOut.length, unwrapWrapper.length); |
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.
// Revert if `poolTokens` length does not match `minAmountsOut` and `unwrapWrapper`. | |
InputHelpers.ensureInputLengthMatch(poolTokensLength, params.minAmountsOut.length, unwrapWrapper.length); | |
// Revert if `poolTokens` length does not match `minAmountsOut` and `unwrapWrapped`. | |
InputHelpers.ensureInputLengthMatch(poolTokensLength, params.minAmountsOut.length, unwrapWrapped.length); |
_sendTokenOut(params.sender, erc4626PoolTokens[i], amountsOut[i], params.wethIsEth); | ||
} | ||
} else { | ||
if (unwrapWrapper[i]) { |
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.
if (unwrapWrapper[i]) { | |
if (unwrapWrapped[i]) { |
bool[] memory wrapUnderlying = new bool[](exactUnderlyingAmountsIn.length); | ||
for (uint256 i = 0; i < wrapUnderlying.length; i++) { | ||
wrapUnderlying[i] = true; | ||
} |
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.
Might be able to refactor this section of code out
Description
The current CLR implementation does not support adding mixed assets. For example, if my pool consists of two wrapped tokens, and I already have one of them and want to use it, this is not possible with the current CLR. The reason is that it treats all input tokens as underlying assets. This PR resolves the issue by introducing a new flag in the interface, allowing us to specify which type of token to use.
Type of change
Checklist:
main
, or there's a description of how to mergeIssue Resolution
Closes #1192