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

Introduce compounder cap #220

Merged
merged 15 commits into from
Jan 29, 2025
Merged

Conversation

dusan-maksimovic
Copy link
Contributor

Description

This PR introduces the "compounder cap" which reserves certain amount of tokens (out of the total number of tokens allowed to be locked) and allows users that had voting power in previous round to exclusively lock in this cap, for a certain time frame. The "compounder cap" is meant to be active for some time at the beginning of the round. After this time has expired, any amount of tokens that wasn't locked by the compunders will be at disposal to any other user to freely lock, up to the limit of total cap, that is enforced at any time. Implementation also supports re-activation of "compunders cap" at any time during the round, which is controlled by the contract governance and handled by the update_config() action (as it is the case with initial activation).

Techinical Details

Updated contract stores:

  • CONSTANTS are converted into Map, to allow different configurations activation depending on the time. This allows us to e.g. prepare 2 configurations- one that increases total_cap and activates the compunder cap, and the other one that is activated some time after and sets the compounder cap to zero.
  • LOCKS_MAP converted to SnapshotMap so that we can compute users voting power at a given height. This goes along with newly added storage USER_LOCKS which allows us to know which lockups user had at a given height, since we can not iterate over LOCKS_MAP at desired height in the past.

Newly added stores:

  • EXTRA_LOCKED_TOKENS_ROUND_TOTAL and EXTRA_LOCKED_TOKENS_CURRENT_USERS allow us to track how many tokens were locked in compunder cap and enforce the maximum limit per user and in total.
  • TOTAL_VOTING_POWER_PER_ROUND stores total voting power for current and all future rounds in which there is at least some voting power. It gets updated each time user locks/relocks as well as on validator power ratio changes. This store will be more useful for governance but it is introduced together with user voting power snapshot map. For compunder cap PR, we could compute this value for past rounds on the fly since we store locked shares and validator power ratios per round, but this is also a bit more performant.
  • ROUND_TO_HEIGHT_RANGE and HEIGHT_TO_ROUND are introduced to be able to this conversion, where for the compounder cap we need round->height, while for the governance we will need the other direction. Both stores are updated on each transaction that gets executed against the smart contract. The function for getting round for height will be implemented in governance PR.

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • Targeted the correct branch
  • Included the necessary unit tests
  • Added/adjusted the necessary interchain tests
  • Added a changelog entry in .changelog
  • Compiled the contracts by using make compile and included content of the artifacts directory into the PR
  • Regenerated front-end schema by using make schema and included generated files into the PR
  • Updated the relevant documentation or specification
  • Reviewed "Files changed" and left comments if necessary
  • Confirmed all CI checks have passed

@dusan-maksimovic dusan-maksimovic self-assigned this Jan 23, 2025
@dusan-maksimovic dusan-maksimovic requested a review from a team as a code owner January 23, 2025 12:57
@dusan-maksimovic dusan-maksimovic changed the title Introduce compunder cap Introduce compounder cap Jan 23, 2025
@dusan-maksimovic dusan-maksimovic force-pushed the dusan/introduce-participant-cap branch from 85fc37e to 917e2e4 Compare January 27, 2025 15:06
Copy link
Member

@p-offtermatt p-offtermatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed:

  • Time-adjustment for constants
  • Keeping historical values for user locks and total power

To-do:

  • Compounder cap itself

contracts/hydro/src/state.rs Show resolved Hide resolved
contracts/hydro/src/testing_utils.rs Outdated Show resolved Hide resolved
contracts/hydro/src/utils.rs Outdated Show resolved Hide resolved
contracts/hydro/src/state.rs Show resolved Hide resolved
contracts/hydro/src/testing_snapshoting.rs Show resolved Hide resolved
contracts/hydro/src/utils.rs Outdated Show resolved Hide resolved
contracts/hydro/src/utils.rs Show resolved Hide resolved
Copy link
Member

@p-offtermatt p-offtermatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to check my understanding of the migration:

  • USER_LOCKS will only be populated from the height of the migration onwards, and empty for earlier rounds (thus get_user_voting_power_for_past_rounds will be unpopulated)
  • TOTAL_VOTING_POWER_PER_ROUND will be populated correctly for all rounds
  • round height mappings will be populated only for future heights, and empty for earlier rounds

Do you think it's worth storing the height of the migration and erroring out when querying these if the asked-for height was before the migration height?

Pro: harder to mess up when calling these
Con: might make testing harder

Maybe we can do this just in the outward-facing queries. I think that would not impact testing too much, but assure us a bit more that noone will build on this and have it silently fail in a weird way.

@dusan-maksimovic
Copy link
Contributor Author

Just to check my understanding of the migration:

  • USER_LOCKS will only be populated from the height of the migration onwards, and empty for earlier rounds (thus get_user_voting_power_for_past_rounds will be unpopulated)
  • TOTAL_VOTING_POWER_PER_ROUND will be populated correctly for all rounds
  • round height mappings will be populated only for future heights, and empty for earlier rounds

That is correct.

  1. Just a clarification on this item, get_user_voting_power_for_past_round() will be used in compounder cap and governance. For compounder cap, we will migrate the contract before e.g. the round 4 is finished, and starting from round 5 we can introduce the compounder cap. So we will not need it for past rounds. For the governance, we only care to have this info at the height first proposal is submitted, which will be in the future, so we are good there as well.

I agree with storing the info during the migration and checking it later. Currently we only need this for the mentioned function, even though it doesn't get called from the outside (yet).

contracts/hydro/src/utils.rs Outdated Show resolved Hide resolved
contracts/hydro/src/utils.rs Show resolved Hide resolved
contracts/hydro/src/utils.rs Outdated Show resolved Hide resolved
contracts/hydro/src/utils.rs Show resolved Hide resolved
Copy link
Member

@p-offtermatt p-offtermatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed everything except the tests for now.
Great work!

@p-offtermatt
Copy link
Member

Ok, LGTM! Just a reminder to do the admin things (recompile & add changelog). We can do a separate PR for the queries.

@dusan-maksimovic dusan-maksimovic merged commit 82c43c3 into main Jan 29, 2025
4 checks passed
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

Successfully merging this pull request may close these issues.

2 participants