vegaprotocol / specs

Specs, designs and requirements 🦔
MIT License
7 stars 2 forks source link

MVP fund accounts ("vaults") #2377

Open barnabee opened 1 month ago

barnabee commented 1 month ago

Vaults/fund accounts

Overview

This ticket describes the key points of an MVP fund account (hereafter: "vault") implementation in the protocol.

The functionality enabled by this would be the ability to create trading vaults in which many users can fund another user's trading.

The funds sent to a vault will be segregated and can only be used to enter and exit positions, not transferred or withdrawn. Users can redeem their share of the vault, based on their share of its value when they sent funds. Redemptions may be subject to delays and per-period maximums to allow the vault owner notice to exit positions. Vault owners will be able to specify management and performance fees, and optionally require funding keys to be whiutelisted.

Theory of operation

Key algorithms

Updating share

When a user funds the vault their share must be calculated and other users' shares must be updated.

existing_shares = [ ... ]

new_share = amount_invested / (total_value_of_all_vault_accounts_before_investment + new_funds_added)
existing_shares[i] = (existing_shares[i] * total_value_of_all_vault_accounts_before_investment) / (total_value_of_all_vault_accounts_before_investment + new_funds_added)

New gains

New gains are the amount of new value created since the last assessment (i.e. the end of the last fee period). If the relative performance of the vault is below its all time high, new gains will be zero. The algorithm below will allow correct calculation of new gains even in the presence of new subscriptions and redemptions.

A state variable high_water_mark is set to 1 at vault creation.

The "invested amount" is tracked as follows:

At the end of each fee period:

new_high_water_mark = max(high_water mark, total_balance_in_all_vault_accounts / invested_amount)
new_gains = min(0, new_high_water_mark - high_water_mark) * invested_amount
high_water_mark = new_high_water_mark
barnabee commented 1 month ago

Open question: does there need to be a way to resterict the rate of adding funds?

Could be:

If we do nothing I worry about the impact on returns if a vault grows too fast…

0xfatman commented 1 month ago

I think everything looks great, except I would handle redemptions differently. This is how I envisaged them working:

Let's say someone has 1% share in a vault, and the vault has 100k in it, with 10k in the margin account and 90k in the general account, then...

I see this as beneficial because we don't need to require vault owners to define arbitrary delays, and we also don't need to handle the edge case where redemptions are not processed on time by the vault owner.

Oh lastly, I don't think it's a huge problem if vaults grow quickly, but maybe you have some common/likely use cases in mind that you think we should be concerned about?

0xfatman commented 1 month ago

I suppose we could also have a network-wide restriction that means each user can only do one redemption per epoch. That would limit the user from the example above to 180 USDT in epoch 1, giving the rest of the vault depositors an opportunity to make redemptions from the available balance before this user is able to redeem again in the next epoch.

This would prevent a whale depositor from draining the available margin, while everyone else's money gets tied up supporting open orders and/or open interest.

davidsiska-vega commented 1 month ago
  • When fees are paid, this is done by increasing the share of the vault's total assets attributed to the vault owner and decreasing the shares held by everyone else pro rata, meaning funds do not need to be available or moved between accounts to pay fees

Will need enough decimal precision not to lose this, especially if fee period is short.

davidsiska-vega commented 1 month ago
  • The owner can update, close, or change the owning key of a vault

I am not sure we should allow updates to withdrawal delays, fractions, fees... only metadata. To "update" a vault, close it and open a new one - and advertise this in the metadata of the old one.

davidsiska-vega commented 1 month ago

Needs anti-spam parameter of minimum vault investment quantum multiple or some such.

OR we may want a minimum for the party setting up the vault (as a quantum multiple) and then a minimum vault investment as a fraction of the total vault capital e.g. 1%.

barnabee commented 1 month ago

Let's say someone has 1% share in a vault, and the vault has 100k in it, with 10k in the margin account and 90k in the general account, then...

  • This user's maximum redeemable amount would be 1k (e.g. if no funds are held on margin)

  • The vault owner can set the max redemption amount to be N% of the available funds in general account

I think limiting redemptions to the general account amount is potentially quite problematic.

The example is perhaps quite misleading because there's no reason in general that 90% of the funds in the vault would be in the general account. If this was somewhat guaranteed then obviously using only general account balance for redemptions would be more reasonable, but that's not a assumption we can generally make.

The current design trades off safety for pragmatism somewhat, by not enforcing liquidations for late redemptions in the MVP but it would still ensure that as funds became available, redemptions are processed, and provide some incentive to do them on time in order to earn fees.

Happy to consider compromises or other alternatives if you really want to avoid a redemption period, but as it stands I'm not very comfortable forcing the size of redemptions to be bounded by the general account balance.

NB: the proposed design does include a maximum fraction of the vault that can be redeemed per period, and we could udpate that to be more like your proposed formula (e.g. x% times users share times vault value), and a user would be free to set this quite low and use a very short or zero delay if they wished.

davidsiska-vega commented 1 month ago

One thing that I am not sure how I'd do but it would be nice if someone can certify their identity as a manager of the vault somehow. E.g. a Ethereum name service registered key can sign something that they can then add to the vault metadata to say hey, we here at fund X, it's really us and we're running the vault.

barnabee commented 1 month ago

The example is perhaps quite misleading because there's no reason in general that 90% of the funds in the vault would be in the general account. If this was somewhat guaranteed then obviously using only general account balance for redemptions would be more reasonable, but that's not a assumption we can generally make.

@0xfatman the other option to make something like your proposal workable would be to specify a minimum % of the vault value that must be in the general account and prevent new orders that take the account below that.

I don't feel like it's a great solution. It'd need a mechanism to incentivise keeping to that minimum in the face of MTM losses (or to partially liquidate to do so) and would feel a bit hacky, and possibly be a pain to test, but it would be possible.

barnabee commented 1 month ago

One thing that I am not sure how I'd do but it would be nice if someone can certify their identity as a manager of the vault somehow. E.g. a Ethereum name service registered key can sign something that they can then add to the vault metadata to say hey, we here at fund X, it's really us and we're running the vault.

Someone could sign a message with a Vega key and put it on their website / socials. The well-known repo could be used to track where these have been verified (it already is used for this for oracles) and then dapps like Console could query the repo to put a verification mark on vaults.

barnabee commented 1 month ago

I am not sure we should allow updates to withdrawal delays, fractions, fees... only metadata. To "update" a vault, close it and open a new one - and advertise this in the metadata of the old one.

I believe amending withdrawal rules can be desirable as it may be hard to get these right ahead of time, particularly if the vault is going to do things where there may be low liquidity (e.g. be the only market maker on a market).

@davidsiska-vega what are your thoughts on allowing such changes but with certain rules, such changes only applying after a minimum time period?

Another option would be to specify specific redemption dates. For example if someone provided liquidity on futures they could allow redemptions after each settlement date.

0xfatman commented 1 month ago

@barnabee okay I didn't think about the scenario where a vault owner engineers a low general balance, in which case my suggestion doesn't work.

I think that leaves us with your original proposal being the most viable option, so would say let's proceed on that basis. However, I thought of another drawback with your original summary:

It doesn't work particularly well for illiquid markets, where e.g. >80% of the liquidity is provided by one vault. You assume that the vault owner is able to liquidate its exposure to facilitate withdrawals, which might not always be possible. I suppose in this scenario the vault owner will need to configure the vault to have very long redemption delays, but I just wanted to flag that this is a consequence of this design approach and see if anything else can be done to mitigate the impact this has on the UX for vault depositors.

0xfatman commented 1 month ago

The example is perhaps quite misleading because there's no reason in general that 90% of the funds in the vault would be in the general account. If this was somewhat guaranteed then obviously using only general account balance for redemptions would be more reasonable, but that's not a assumption we can generally make.

@0xfatman the other option to make something like your proposal workable would be to specify a minimum % of the vault value that must be in the general account and prevent new orders that take the account below that.

I don't feel like it's a great solution. It'd need a mechanism to incentivise keeping to that minimum in the face of MTM losses (or to partially liquidate to do so) and would feel a bit hacky, and possibly be a pain to test, but it would be possible.

I'm not keen on this solution. I'd go in the direction of your original proposal.

barnabee commented 1 month ago

It doesn't work particularly well for illiquid markets, where e.g. >80% of the liquidity is provided by one vault. You assume that the vault owner is able to liquidate its exposure to facilitate withdrawals, which might not always be possible. … see if anything else can be done to mitigate the impact this has on the UX for vault depositors.

The issue here seems to be the existence of two very differerent types of vault. Roughly speaking they can be seen as analagous to:

  1. A liquid tradiing fund or ETF, in which it is possible to fairly easily allow buying into and out of the fund, because the assumption is that positions can always be exited or increaed easily. This is covered nicely by the redemption period design IMO.

  2. A more "venture-like" fund. In this case there may be no liquidity to exit positions outside of a defined schedule or some kind of liquidity event. This is not covered well yet.

To better cover the second type of vault, I propose modifying the model described above to a kind of hybrid design. Instead of a redemption waiting period starting at the time of the request (i.e. "continuous redemptions", there would be set redemption dates.

I believe this design would satisfy both type of vault.

For a liquid vault, regular "normal" redemption dates would allow freely coming and going under most circumstances (with the max. fraction acting as a limit to avoid forcing painful liquidations to happen too quickly).

For a less liquid vault, dates for "normal" redemptions could be aligned with liquidity events and/or a long-dated "end date" for the vault (which could also be moved), and regular partial/free cash only dates would allow people to redeem more often if and when the cash is available.

@0xfatman @davidsiska-vega I'd be interested to know whether you think this model would work better?

0xfatman commented 1 month ago

Looks good to me

cdummett commented 1 month ago

Regarding APIs does the following sound like it gives users the ability to query everything they need @0xfatman @barnabee @davidsiska-vega

A vaults endpoint, exposing

A redemptions endpoint, exposing

davidsiska-vega commented 4 weeks ago

It may be nice to have access to vault balance across all accounts for each asset, so the vault general + margin over markets with same asset + bonds over markets with same asset… so people can see at a quick glance how much their 3% (or whatever) of a given vault is actually worth.

davidsiska-vega commented 4 weeks ago

Spam: