-
Notifications
You must be signed in to change notification settings - Fork 15
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
Vault Protocol #53
Vault Protocol #53
Conversation
… maker to profit fee
.cast::<i128>()? | ||
.safe_sub(self.total_shares.cast()?)?; | ||
|
||
protocol_fee_shares = self |
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.
think it might be better to do new_total_shares - management_fee_shares - vault.total_shares
here so that we dont get weird numerical issues for rounding in multipication?
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 should stay. switching both of your comments to that math breaks the tests.
in the first comment that protocol calc does:
let protocol_fee_payment = total_fee_payment
.min(depositor_equity.saturating_sub(1))
.safe_sub(management_fee_payment)?;
This is because if the shares are odd, then the applied fee to the manager and protocol can't divide, so one of them must lose one share. I make the protocol take the short end of the stick.
This second comment has to use the protocol_fee_shares_factor so that it has that subtraction factored in. It can't just do new_total - manager - old_total = protocol
like you suggest.
I spent a lot of time wrestling with the rounding errors when I first made this PR.
The tests with manager shares had to stay as it was, and calculating the protocol as the total - manager
never worked because of that rounding error on odd numbers.
If I make your change then the manager ends up with more shares than it should, because that rounding isn't accounted for.
So my system attempted to solve for this, so I don't think it should change as the tests would break.
Purpose
Support a third party "protocol" that represents the entity, company, or product surrounding one or more vaults. The use case is for my company which highlights multiple vaults allowing users to arbitrage between the best vaults; this is analogous to shopping for hedge funds on Wall Street.
My company, or any company that uses this feature, is the protocol which can take a fee or profit share in order to drive revenue. The manager of the vault (the trader) maintains their profit share and fee just as before.
The need for this exists because previously only the manager of the vault could take a cut, but that is only a two-party system with the investors and the manager/trader. If a company is maintaining a product surrounding these vaults and the managers/traders are the party that collects the fees, then the company/protocol needs a way to mechanism to generate revenue. This update makes the vaults a three-party system where the protocol, too, can take a fee.
That is what this
VaultProtocol
feature achieves.Changes
Adds a
vault_protocol
field in theVault
account which is a PDA for aVaultProtocol
account if defined and not the system program.This vault protocol can take an optional profit share or annual fee just as the manager, expect only >= 0 whereas the manager can be negative.
In
programs/drift_vaults/src/tests.rs
under thevault_v1_fcn
test module, there are tests that incorporates protocol fees alongside and standalone to the manager fees.The main case change in the
apply_fee
where it applies the manager or protocol annual fee and profit share, if any.These tests handle just a manager fee, both a manager and protocol fee, and just a protocol fee. All legacy tests without a protocol have been untouched and still pass, which is the main piece to review here: backwards compatibility.
In
ts/tests/driftProtocolVault.ts
there are tests that run through the following steps:Vault
with aVaultProtocol
with a manager profit share of zero and a protocol profit share of 10%. A distinct keypair for the manager is used to test signing permissions.VaultDepositor
and deposits $300 USDC.The
VaultProtocol
is passed in as the last remaining account in any instruction that needs it post-initialization.If the last rem acct deserializes into an
AccountLoader<VaultProtocol>
then it is a protocol, and if it does not then the vault protocol has not been passed in and is a legacy vault.This is backwards compatible because legacy clients won't pass this into remaining accounts, and it will fail to deserialize and return None which the instructions handle as being a legacy client. This logic can be found in
programs/drift_vaults/src/state/vault_protocol.rs
You will find these two lines in any instruction that needs the
VaultProtocol
:Side Note
Added steps to the README for Apple Silicon (Mac M1) users since I had trouble getting things to compile.