-
Notifications
You must be signed in to change notification settings - Fork 161
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
DNM: incentive module proto #1514
Conversation
Marking this R4R - since adding the proto files without hooking up module to the app does not mess with the build in main / release branch, it should be safe to merge. |
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.
- please follow the 0.46 module organization: types should be generated directly into the root package of the module, together with codec, errors and keys.
- don't use yaml tags - they are deprecated
- don't use
paramtypes.ParamSet
- new gov mechanism should be used instead when possible. - tx.go with sdk.Msg implementations should be renamed to
msg.go
Codecov Report
@@ Coverage Diff @@
## main #1514 +/- ##
==========================================
+ Coverage 55.47% 55.63% +0.15%
==========================================
Files 68 68
Lines 6725 6706 -19
==========================================
Hits 3731 3731
+ Misses 2717 2698 -19
Partials 277 277
|
Switched all block height (unbondings, durations, program ends) to unix time. Also split up where the incentive programs are stored in state and queried, so it's easier to validate them (different values should be zero/nonzero at different points in the program's lifecycle (upcoming, ongoing, completed). Additionally, only the completed programs query has pagination - that's where programs will accumulate (the upcoming and ongoing sets will always have a limited amount of programs in them) |
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.
- Usually, the best is to keep the first PR only proto oriented + generated files. This way we firstly deal with proto, without messing with validation etc... But the validation is already here, so we can go with that. So let's make the review in mulitple stage, here I firstly review the proto.
- Let's don't use
params
- it's officially deprecated. See my comment how to move forward with that. - Let's add a
create_program_fee
param to avoid a spam (maybe we can discuss it in notion). This will be paid in Umee. - Please create a notion page to specify functionality (not a design doc). Specifically:
- how the programs will work with uTokens?
- Can there be multiple programs for the same uToken with overlapping period?
- Do we support auto compounding (now, or v2?)?
- Can programs be extended or resumed?
- Can we partially fund a program?
- Maybe we should support a scenario when community fund will only partially sponsor a program? In that case we would need to add
ratio
parameter toMsgGovCreateAndSponsorProgram
// BondAmount tracks the amount of coins of one uToken denomination bonded to a | ||
// given reward tier by a single account. |
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.
// BondAmount tracks the amount of coins of one uToken denomination bonded to a | |
// given reward tier by a single account. | |
// Bond tracks the user rewards per tire and uToken coin. |
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 can simplify the name, otherwise we would need to call it UserTireBond
or UserTireCoinBond
rpc UpcomingIncentivePrograms(QueryUpcomingIncentivePrograms) | ||
returns (QueryUpcomingIncentiveProgramsResponse) { | ||
option (google.api.http).get = "/umee/incentive/v1/incentive_programs/upcoming"; | ||
} |
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 UI will usually need all programs, or both ongoing and upcoming. So, instead of having 3 queries, we can have either:
- 2 queries: past and ongoing+future (with a flag
future [default = false]
- 1 query: pas + ongoing + future (with flag
past [default = false]
)
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.
Frontend will probably just need current, and it's easier to have them stored separately in state since it reduces iterations when looking for just one type.
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.
- So you are moving the program between storage prefixes?
- My question was more related to the query, why having 3 queries if we can only have 1 or 2? That would reduce and simplify the code.
- Let's verify with the frontend. My gut feeling is that they will like to show both present and future.
rpc BeginUnbonding(MsgBeginUnbonding) returns (MsgBeginUnbondingResponse); | ||
|
||
// Sponsor defines a permissionless method for sponsoring an upcoming, not yet funded incentive program. | ||
rpc Sponsor(MsgSponsor) returns (MsgSponsorResponse); |
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 w should enable partial sponsoring, when 2 separate sponsors will like to sponsor a program. Or do it in v2.
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.
Partial sponsoring creates an edge case, where if a program is not fully sponsored by the time it starts, the module needs to either
- remember the address of any sponsor and refund the tokens
- start the program with actual rewards != governance agreed rewards
Currently, a program is either not funded, or fully funded, so such scenarios are prevented
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.
Yes, but maybe we need to support a scenario when, for example we have 2 sponsors?
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.
Something that could be useful in the future, but probably not near-term. Possible use case would be ecosystems with multiple tokens like Comdex. Maybe they want to incentivize borrowing their CMST stablecoin with CMDX, HARBOR, etc.
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.
yes, I was thinking about similar scenario. Other would be if there are two independent accounts which would sponsor only if the proposal passes (Eg: Umee DAO and Osmosis DAO).
// GovCreateProgram is used by governance proposals to create (but not fund) an incentive program. | ||
rpc GovCreateProgram(MsgGovCreateProgram) returns (MsgGovCreateProgramResponse); | ||
|
||
// GovCreateAndSponsorProgram is used by governance proposals to create and fund an incentive program. |
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.
// GovCreateAndSponsorProgram is used by governance proposals to create and fund an incentive program. | |
// GovCreateAndSponsorProgram is used by governance proposals to create an incentive program | |
// and sponsor it from the Community Fund. |
// MsgGovCreateAndSponsorProgram is used by governance to create an incentive program | ||
// and fund it in the same transaction. The sponsor address should be the community | ||
// fund or an agreed upon account - program reward funds will be taken from that address | ||
// when the incentive program passes governance. |
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.
there is no sponsor parameter in this message. Let's just write that "when passed, the program is fully sponsored by the Community Fund".
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 so, I'll need to hardcode (or add to Params
) a community fund address.
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.
Note: sponsor parameter is currently below the highlighted comment - it is the last field
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.
You check the Community Fund address during the execution. It's not a param, because it doesn't change.
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
Most of there questions are already answered in the design document. I'll copypaste the answers here but I think they'll eventually end up in a spec
Users lock and unlock `uTokens` they have enabled as collateral in `x/leverage` by sumbitting `x/incentive` message types.
Locked uTokens remain in the `x/leverage` module account.
Locking of funds is independent of active incentive programs, and can even be done in their absence. and Locked funds must be collateral-enabled uTokens. Locked funds will not leave their original place in the leverage module account. Locking will prevent withdrawal and collateral-disabling (but not liquidation) of the locked uTokens until they are successfully unlocked.
Incentive programs are created by governance. No message types to alter or halt incentive programs once voted on are planned, and any number of incentive programs should be capable of being active simultaneously regardless of parameters, including overlapping dates and denominations.
no - not mentioned in any design
Incentive programs are created by governance. No message types to alter or halt incentive programs once voted on are planned, and any number of incentive programs should be capable of being active simultaneously regardless of parameters, including overlapping dates and denominations.
currently we're requiring full funding to prevent partial -> refund edge cases.
Not planned |
This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Marking as DO NOT MERGE so I can break it up into smaller PRs
This PR contains the first step in the incentive module
Progress:
Design of gov proposals:
I have created two options for funding incentive programs:
Two step process (basic account)
If doing external incentives, we may want to let the source of the funding use a basic account. In that case,
MsgGovCreateProgram
(and governance vote) is used to set the program'smax_rewards
but NOT fund it.Then, a
MsgSponsorProgram
can be used by the basic account, which must fund the exact amount specified inmax_rewards
or the program will not start / activate.One step process (community fund)
For ordinary programs that use the community fund, or instances where external incentives are already waiting at a known address, a
MsgCreateAndSponsorProgram
is used to do it all in one step.Author Checklist
!
to the type prefix if API or client breaking changeCHANGELOG.md