This repository has been archived by the owner on Jan 18, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
STIP 006 - Trade Rebates #12
Open
richardliang
wants to merge
10
commits into
main
Choose a base branch
from
richard/trade-v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
697c13d
Checkpoint 1 Trade Rebates
richardliang 1fe9b92
Add open question
richardliang 89d5b7a
Fix timeline
richardliang 14c9596
Add additional context
richardliang 1e0bdd2
Update STIP
richardliang 6a61535
Update STIP with new architecture
richardliang 9bf49db
Add checkpoint 2
richardliang 3ad5310
Add checkpoint 3
richardliang 18e0a57
Fix typo
richardliang 1cf9bfa
Address checkpoint 3 comments
richardliang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
# STIP-005 | ||
# STIP-006 | ||
*Using template v0.1* | ||
## Abstract | ||
The current TradeModule and GeneralIndexModule do not support volume based fees or rebates for the manager. This is in contrast to the issuance module. There is demand for additional fee types that managers can charge, specifically to be on par with exchanges where there are rebate / volume fee discounts. | ||
|
||
## Motivation | ||
This feature is a new version of a TradeModule (and GeneralIndexModule) that allows the manager to charge a volume fee from their followers. This will be denominated in the output token similar to the protocol fee assessed. In contrast to centralized exchanges, the fee rebates will be automatic per trade. | ||
This feature is a new version of a TradeModule (and GeneralIndexModule) that allows governance to specify a protocol fee and rebate split percentage which is sent to the manager's address. This will be denominated in the output token similar to the protocol fee assessed. The fee rebates will be automatic per trade. | ||
|
||
TradeModuleV2 will be used in upcoming TokenSets deployments on other chains, and can replace the existing on Polygon and Mainnet. GeneralIndexModuleV2 can be used by index coop products to generate additional revenue | ||
|
||
|
@@ -16,6 +16,7 @@ We have previously implemented the TradeModule and GeneralIndexModule. This will | |
- No, we can encourage in the UI instead for retail managers. This would also break for cases where the manager is a smart contract | ||
- [ ] Should we name this TradeModuleV2 or TradeModuleWithRebates (GeneralIndexModuleV2 or GeneralIndexModuleWithRebates)? | ||
- [ ] How do we prevent managers charging an 100% fee and rugging the Set on a trade? | ||
- We will only allow governance to change rebate %s | ||
|
||
## Feasibility Analysis | ||
|
||
|
@@ -28,26 +29,23 @@ uint256 protocolFeeTotal = getModuleFee(TRADE_MODULE_PROTOCOL_FEE_INDEX, _exchan | |
``` | ||
|
||
#### Option 2 | ||
Adding a managerFee and a protocol feeSplit % (similar to DebtIssuanceModule). This will make TradeModule and GeneralIndexModule fees variable in the protocol (if a manager charges 0 fees here, then protocol will always make 0) which is a departure from TradeModule V1 | ||
Governance specifies a protocol fee % and a rebate split %. The split gives the manager a rebate on a percentage of protocol fees. Manager has no say and cannot rug. | ||
|
||
``` | ||
uint256 protocolFeeSplit = controller.getModuleFee(address(this), ISSUANCE_MODULE_PROTOCOL_FEE_SPLIT_INDEX); | ||
uint256 totalFeeRate = _isIssue ? setIssuanceSettings.managerIssueFee : setIssuanceSettings.managerRedeemFee; | ||
uint256 protocolFeeSplit = controller.getModuleFee(address(this), PROTOCOL_FEE_SPLIT_INDEX); | ||
|
||
uint256 totalFee = totalFeeRate.preciseMul(_quantity); | ||
protocolFee = totalFee.preciseMul(protocolFeeSplit); | ||
managerFee = totalFee.sub(protocolFee); | ||
uint256 protocolDirectFee = controller.getModuleFee(address(this), PROTOCOL_DIRECT_FEE_SPLIT_INDEX); | ||
protocolFee = protocolDirectFee.preciseMul(protocolFeeSplit); | ||
rebateFee = protocolDirectFee.sub(protocolFee); | ||
``` | ||
|
||
#### Option 3 | ||
Manager charges a managerFee that is split with the protocol based on a feeSplit % determined by governance. Additionally, the protocol can charge a direct fee % (similar to NAVIssuanceModule). This will be a superset of TradeModule fees charged | ||
#### Recommendation | ||
Option 4 gives us protection against rugging while providing us a base rebate mechanism. This means we will charge a protocol fee to start in order to activate rebates. E.g. start with a 10 bps protocol fee and 5 bps rebate. | ||
|
||
``` | ||
uint256 protocolDirectFeePercent = controller.getModuleFee(address(this), _protocolDirectFeeIndex); | ||
``` | ||
Because the rebate % is fixed by governance across all Sets, the only variable is AUM of the Set. The more user AUM vs manager AUM the more rebates managers receive (which eventually will become negative). | ||
|
||
#### Recommendation | ||
Option 1 will require the least code changes while giving us the ability to emulate fee rebates. The maxManagerFee can be enforced either on initialization (still susceptible to manager rugging by removing and reinitializing) or stored on the Controller by governance | ||
#### Future work | ||
Tiered rebates: With this base rebate mechanism, manager contracts can be built on top in the future. Individual managers will always have the ability to specify a fee recipient address as their own, but manager contracts for a specific product (e.g. social trading) can abstract away the fee recipient to a shared peripheral contract. This central trading contract tracks cumulative volume done through trading all the Sets that are linked, and perform calculations that split the rebates collected. This way, at the base module level, rebates are flat across Sets but at the manager contract level, rebates can be tiered | ||
|
||
## Timeline | ||
- Spec + review: 2 days | ||
|
@@ -59,16 +57,40 @@ Option 1 will require the least code changes while giving us the ability to emul | |
- Write docs: 1 day | ||
|
||
## Checkpoint 1 | ||
Before more in depth design of the contract flows lets make sure that all the work done to this point has been exhaustive. It should be clear what we're doing, why, and for who. All necessary information on external protocols should be gathered and potential solutions considered. At this point we should be in alignment with product on the non-technical requirements for this feature. It is up to the reviewer to determine whether we move onto the next step. | ||
|
||
**Reviewer**: | ||
|
||
## Proposed Architecture Changes | ||
A diagram would be helpful here to see where new feature slot into the system. Additionally a brief description of any new contracts is helpful. | ||
|
||
### TradeModuleV2 | ||
- Inherit TradeModule | ||
- Override `trade` | ||
- Add `virtual` to TradeModule V1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't think you have to do this. Would rather not touch the V1 code. |
||
- Add `_accrueManagerFee` | ||
- Override constructor to add `managerRebateRecipient` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean |
||
|
||
### GeneralIndexModuleV2 | ||
- Inherit GeneralIndexModule | ||
- Override `trade` and `tradeRemainingWETH` | ||
- Add `virtual` to GeneralIndexModule trade functions | ||
- Add `_accrueManagerFee` | ||
- Override constructor to add `managerRebateRecipient` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comments here as above |
||
|
||
## Requirements | ||
These should be a distillation of the previous two sections taking into account the decided upon high-level implementation. Each flow should have high level requirements taking into account the needs of participants in the flow (users, managers, market makers, app devs, etc) | ||
- GeneralIndexModule requires no changes to the IC extension contracts except a redeployment | ||
- External trading interfaces stay exactly the same | ||
- Manager fee recipient automatically receives the rebate in their wallet | ||
|
||
## User Flows | ||
- Highlight *each* external flow enabled by this feature. It's helpful to use diagrams (add them to the `assets` folder). Examples can be very helpful, make sure to highlight *who* is initiating this flow, *when* and *why*. A reviewer should be able to pick out what requirements are being covered by this flow. | ||
![flow diagram](../assets/tradeModuleRebates.png) | ||
### A manager is looking to trade 10 ETH to USDC. | ||
1. Manager calls trade() on `TradeModule` passing in the input tokens, output tokens, path, slippage tolerance, and `SushiswapExchangeAdapter` as the exchange | ||
2. `TradeModule` gets approval and trade calldata via `SushiswapExchangeAdapter` | ||
3. `TradeModule` calls invoke on the SetToken, with the calldata to execute an approval and trade transaction. | ||
4. The trade is executed on Sushiswap and USDC is returned to the SetToken and validated | ||
5. The `TradeModuleV2` calculates the protocol fee % and sends the protocol's share to the Controller fee recipient | ||
6. The `TradeModuleV2` calculates the rebate fee % and sends the manager's share to the manager fee recipient | ||
|
||
## Checkpoint 2 | ||
Before we spec out the contract(s) in depth we want to make sure that we are aligned on all the technical requirements and flows for contract interaction. Again the who, what, when, why should be clearly illuminated for each flow. It is up to the reviewer to determine whether we move onto the next step. | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
One more thing I'd add here as potential future feature is potentially updating the TradeModule to allow each Set to have its own rebate percentage (instead of a global one for now). This could be negotiated with large managers/applications that use the protocol.