Skip to content
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

[Long Term] Balancer V3 Wishlist/Brainstorm #2210

Open
gerrrg opened this issue Feb 7, 2023 · 9 comments
Open

[Long Term] Balancer V3 Wishlist/Brainstorm #2210

gerrrg opened this issue Feb 7, 2023 · 9 comments

Comments

@gerrrg
Copy link
Contributor

gerrrg commented Feb 7, 2023

I know @nventuro has his own list, so I'll let him chime in first before I put thoughts out there

@nventuro
Copy link
Contributor

nventuro commented Feb 8, 2023

Small things to add:

  • add chainid to poolid
  • expose reentrancy guard status
  • store timestamp instead of blocknumber in pool balances
  • make joinPool and exitPool return the amounts of tokens in/out

Things to remove:

  • forced handling of protocol fees
  • authorizer database (become SingletonAuthentication instead)

Things to maybe remove (potentially to make space):

  • native asset wrapping (weth)
  • two token pools

Large things to maybe add:

  • optional pre/after swap/join/exit callbacks, outside of reeentrancy guard
  • make the Vault BPT aware

@gerrrg
Copy link
Contributor Author

gerrrg commented Feb 8, 2023

  • asset manager callbacks (likely the same as the pre/post swap/join/exit callback mentioned above)
  • ERC-3156 compliant (single-asset) flashloan interface would be nice, though I expect there would still be a desire for multi-asset flashloans

@markusbkoch
Copy link
Member

Expand PoolRegistered event to include as an optional argument the factory address (allows us to create a registry of pools be able to differentiate between different types without having to listen for pool creation events on each factory)

@brunoguerios
Copy link
Member

  • Add ability to set toInternalBalance on JoinPoolRequest
  • Add ability to set fromInternalBalance on ExitPoolRequest

This would be helpful in the context of composability and chaining several join/exit/swap transactions using internal balances. Right now we have to keep moving balances out of internal balances when chaining several joins/exits together, which increases gas cost.

@nventuro
Copy link
Contributor

@brunoguerios I'm not sure I follow, are you suggesting the minted BPT be deposited as user balance in a join, and burnt from user balance during an exit?

@brunoguerios
Copy link
Member

No - actually I'd like for the user to be able to choose if the BPT they get from a join transaction is kept as internal balance or if it's sent to the recipient's address.
In other words, I'd like to add a boolean toInternalBalance to the JoinPoolRequest - like this:

struct JoinPoolRequest {
    IAsset[] assets;
    uint256[] maxAmountsIn;
    bytes userData;
    bool fromInternalBalance;
    bool toInternalBalance;
}

Giving a bit more context, being able to set toInternalBalance=true on a join, will allow me to perform a second join within a multicall with fromInternalBalance=true.
The way it's currently implemented, whenever I perform 2 sequential joins on a multicall, I'm forced to use fromInternalBalance=false on the second join because the first will always behave as toInternalBalance=false.

@ejmahler
Copy link

ejmahler commented Feb 16, 2023

I'd love to see a feature in the vault swap functions, where the vault optionally calls a hypothetical IVaultSwapCallback(msg.sender).swapCallback() after it sends the output assets to the configured recipient, and gives that callback a chance to pay the vault, before it does its own transfers.

This would be helpful for making SwapKind.GIVEN_OUT swaps from third-party contracts. The external contracts might not have the source asset in their possession at the time of the call, and the assets are being acquired on the fly (such as an arbitrage contract where there are planned downstream swaps). In this situation, with the current vault implementation, the external contract needs to replicate the swap math in order to know how much the vault is going to demand, and then acquire them before the swap call. Replicating swap math is obviously a problem because that swap math is different depending on the pool.

For a reference for how this is implemented well, Uniswap V3 pools have this feature. It is equally (or more) difficult to predict beforehand what the expected amount in will be for an exact-out uniswap V3 pool swap, but external contracts don't need to do that math themselves, because the callback tells you exactly how much the pool is expecting.

The most useful parameters to this callback would be, imo:

  • an address that the external contract should pay assets to (this can be omitted if it's guaranteed to be the vault contract itself aka msg.sender)
  • an array of IAsset, and a corresponding array of int256 indicating how much of each asset must be paid
  • a bytes calldata forwarded from the swap/batchSwap function that the callback can decode to do any downstream work

Other advantages include the external contract not needing ERC20 approvals, because the external contract could voluntarily send the assets, rather than the vault trying to transferFrom.

Note that even if the "paying the vault" half of this is out of scope or nonviable, purely knowing how much the vault expects, without having to replicate that math, would be incredibly helpful.

@nventuro
Copy link
Contributor

nventuro commented Feb 22, 2023

No - actually I'd like for the user to be able to choose if the BPT they get from a join transaction is kept as internal balance or if it's sent to the recipient's address.

Yes, that is sort of what I meant except using different language. This is not currently possible because a) the Vault does not know about BPT (which is why toInternalBalance doesn't even exist in joinPool), and b) the Pool is unable to deposit said BPT as internal balance for the recipient because of the reentrancy guard.


@ejmahler that's a very interesting feature request, thank you very much. As noted, that currently does not exist in V2, but we do have a tool to let you predict exact swap amounts without having to replicate any of the math yourself.

The BalancerQueries contract lets you simulate a swap, join or exit by passing the same arguments you'd pass in a real call, and you'll get an exact answer back. With this, you won't need to do any of the math or token accounting yourself - it's all automatic and guaranteed to be correct. You can find the address of this contract in each network here, and the interface here (or as part of the @balancer-labs/v2-interfaces npm package). You can see an example of the query mechanism being used in production code here.

What the queries do under the hood is actually perform the swap/join/exit operation and then revert it, but critically without requiring that you hold the tokens to begin with in order to simulate. This uses built-in query capabilities in the Vault and Pools, but these are relatively involved and are out of scope of this discussion. If you want to learn more, take a look at this article by @0xSkly.

@gerrrg
Copy link
Contributor Author

gerrrg commented Jun 20, 2023

Doesn't necessarily need to wait for v3, but it seems that people would really appreciate pools having view functions for pricing

  • spot price
  • spot price w/ fees
  • outGivenIn
  • inGivenOut

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants