Skip to content

Add Voting streak multiplier contract #128

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

Closed
wants to merge 7 commits into from
Closed

Add Voting streak multiplier contract #128

wants to merge 7 commits into from

Conversation

secbajor
Copy link
Collaborator

[#127]

Copy link
Collaborator Author

@secbajor secbajor left a comment

Choose a reason for hiding this comment

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

Could this be mergeable as-is or would there be other changes recommended?


/// @notice Mapping of user addresses to their multiplier validity period
mapping(address => uint256) public override userToValidity;
mapping(address => uint256) public userToValidity;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

probably add these to IMultiplier and override them here

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure we need to add them to the IMultiplier interface. It's unclear to me how they'd be used differently than the existing functions that are f(address) returns uint256 for multliplying factor and validity

Comment on lines 59 to 66
/// @notice Mapping of user addresses to their current multiplier factor
mapping(address => uint256) public userToMultiplier;
/// @notice Mapping of user addresses to their multiplier validity period
mapping(address => uint256) public userToValidity;
/// @notice The maximum multiplier incrementation
uint256 public maxVotingStreakMultiplier;
/// @notice The increment value for the multiplier
uint256 public votingStreakMultiplierIncrement;
Copy link
Collaborator

Choose a reason for hiding this comment

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

confused on why this is in the yield distributor, this should be implemented in the multiplier no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this commit was exploring a design where the yielddistributor itself knows about the voting history of addresses.

i have some feedback from bagel to integrate that will change this significantly, so ignore this for now :)


/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
constructor(address _votingStreakMultiplier) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should need to add them through a setter, not through the constructor

also because these contracts are upgradeable, we actually don't use the constructor at all

https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable

Comment on lines +208 to +218
function finalizeCycle() internal {
cycles[currentCycle].voteDistribution = projectDistributions;
cycles[currentCycle].totalVotes = currentVotes;
cycles[currentCycle].endBlock = lastClaimedBlockNumber;
currentCycle++;
}

/// @notice Initialize the new cycle
function initializeCycle() internal {
cycles[currentCycle].startBlock = lastClaimedBlockNumber;
cycles[currentCycle].projects = projects;
Copy link
Collaborator

Choose a reason for hiding this comment

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

why aren't we tracking the cycles in the multiplier itself per user instead of adding additional logic to the yd? I'm against this approach

Copy link
Contributor

@bagelface bagelface Mar 27, 2025

Choose a reason for hiding this comment

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

Can you elaborate on the solution you're proposing? Tracking the cycles in the multiplier would require updating storage, so it's not immediately clear to me how that would work with the existing implementation of the multipliers extension where all the functions are "view".

With this solution, yes, we modify the YieldDistributor contract, but we add only a single storage write or two (depending on implementation) with each cycle start/end and add additional data that can be useful to implementing other multipliers.

To be clear, I'm not necessarily endorsing this specific implementation, but this approach overall (modifying the YD vs tracking this data in the multiplier)

Copy link
Collaborator

Choose a reason for hiding this comment

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

This breaks the entire pattern and design of the multiplier spec, which is meant to not add multiplier logic to the YD but instead provide a way to add modular and decoupled voting power logic...

if we want this data on the YD in general that's another question, but as far as I can tell of those data structures can sit inside the multiplier and I can't think of other multipliers that would use this.

I'm very against adding any code to the YD in general,and I don't understand why we need all this data for the voting streak multiplier. Don't we just need a counter that goes up when the user votes?

My suggestion would be to hook into the multiplier when the user votes , update their last voted time and increment a counter. Next time they vote, we can use the CYCLE_LENGTH to determine whether they've broken their streak or not by referencing whether their last time voted is longer than CYCLE_LENGTH

Copy link
Contributor

@bagelface bagelface Mar 28, 2025

Choose a reason for hiding this comment

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

"My suggestion would be to hook into the multiplier when the user votes"
What exactly do you mean by this? How can we "hook" into the multiplier when the user votes without updating the YieldDistributor or adding an additional transaction? I guess we can add a contract that wraps the vote transaction and updates multipliers in the same transaction, but that just seems awkward. Feel free to DM me to discuss.

fwiw, this is not a suggestion to "add multiplier logic to the YD". It is a suggestion to add storage variables for data that didn't previously have a clear onchain use case (so it's emitted as an event).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

seems we'll have to align on a path forward to get this going.

@RonTuretzky from my perspective the updates here to the YD are not multiplier logic, they are just adding relevant Cycle data (meaning a YD distribution Cycle) which the new voting streak multiplier uses to implement its own functions.

if you see an alternate strategy, about hooking into the multiplier when the user votes, can you clarify how that could be implemented? the only way i can see that working is also adding logic to the YD in the castVote function 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm against adding anymore variables to the YD in general , it will require complex upgrade logic and add more variables I'm not sure are needed.

My suggestion would be to hook into the multiplier when the user votes , update their last voted time and increment a counter. Next time they vote, we can use the CYCLE_LENGTH to determine whether they've broken their streak or not by referencing whether their last time voted is longer than CYCLE_LENGTH

^ this is my suggestion

Copy link
Contributor

@bagelface bagelface Apr 21, 2025

Choose a reason for hiding this comment

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

As per my previous comment, we need clarification from you on what this means:

My suggestion would be to hook into the multiplier when the user votes"
What exactly do you mean by this? How can we "hook" into the multiplier when the user votes without updating the YieldDistributor or adding an additional transaction? I guess we can add a contract that wraps the vote transaction and updates multipliers in the same transaction, but that just seems awkward. Feel free to DM me to discuss.

@secbajor
Copy link
Collaborator Author

After some discussion and advice we are going a different direction. Closing in favor of #129

@secbajor secbajor closed this Apr 24, 2025
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.

3 participants