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

fix: dust left in unallocatedOffset despite allocating all LQTY #112

Merged
merged 8 commits into from
Jan 2, 2025
38 changes: 38 additions & 0 deletions test/Governance.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2477,6 +2477,7 @@ abstract contract GovernanceTest is Test {
// By waiting `initialVotingPower` seconds while having 1 wei LQTY staked,
// we accrue exactly `initialVotingPower`
vm.warp(block.timestamp + initialVotingPower);

governance.depositLQTY(583399417581888701);
Copy link
Contributor

Choose a reason for hiding this comment

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

Where dies this number come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just some random prime. Actually, there's nothing special about it, any number big enough to result in rounding error would work, even round numbers.


address[] memory initiativesToReset; // left empty
Expand All @@ -2503,6 +2504,43 @@ abstract contract GovernanceTest is Test {
);
}

function test_WhenWithdrawingTinyAmounts_VotingPowerDoesNotTurnNegativeDueToRoundingError(
uint256 initialVotingPower,
uint256 numWithdrawals
) external {
initialVotingPower = bound(initialVotingPower, 1, 20);
numWithdrawals = bound(numWithdrawals, 1, 20);

vm.startPrank(user);
{
address userProxy = governance.deriveUserProxyAddress(user);
lqty.approve(userProxy, type(uint256).max);
governance.depositLQTY(1);

// By waiting `initialVotingPower` seconds while having 1 wei LQTY staked,
// we accrue exactly `initialVotingPower`
vm.warp(block.timestamp + initialVotingPower);

governance.depositLQTY(583399417581888701);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment here


for (uint256 i = 0; i < numWithdrawals; ++i) {
governance.withdrawLQTY(1);
}
}
vm.stopPrank();

(uint256 unallocatedLQTY, uint256 unallocatedOffset,,) = governance.userStates(user);
int256 votingPower = int256(unallocatedLQTY * block.timestamp) - int256(unallocatedOffset);

// Even though we are withdrawing tiny amounts, each withdrawal
// reduces voting power by 1 (due to rounding), but not below zero
assertEq(
votingPower,
int256(initialVotingPower > numWithdrawals ? initialVotingPower - numWithdrawals : 0),
"voting power should stay non-negative"
);
}

function test_Vote_Stake_Unvote() external {
address[] memory noInitiatives;
address[] memory initiatives = new address[](1);
Expand Down
Loading