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

Reducing complexity of voting power function #101

Merged
merged 9 commits into from
Oct 21, 2024
32 changes: 9 additions & 23 deletions src/YieldDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,39 +133,25 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable {
if (_end > block.number) revert EndAfterCurrentBlock();

/// Initialized as the checkpoint count, but later used to track checkpoint index
uint32 _currentCheckpointIndex = _sourceContract.numCheckpoints(_account);
if (_currentCheckpointIndex == 0) return 0;
uint32 _numCheckpoints = _sourceContract.numCheckpoints(_account);
if (_numCheckpoints == 0) return 0;

/// No voting power if the first checkpoint is after the end of the interval
Checkpoints.Checkpoint208 memory _currentCheckpoint = _sourceContract.checkpoints(_account, 0);
if (_currentCheckpoint._key > _end) return 0;

/// Find the latest checkpoint that is within the interval
do {
--_currentCheckpointIndex;
_currentCheckpoint = _sourceContract.checkpoints(_account, _currentCheckpointIndex);
} while (_currentCheckpoint._key > _end);
uint256 _totalVotingPower;

/// Initialize voting power with the latest checkpoint thats within the interval (or nearest to it)
uint48 _latestKey = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key;
uint256 _totalVotingPower = _currentCheckpoint._value * (_end - _latestKey);

if (_latestKey == _start) return _totalVotingPower;

for (uint32 i = _currentCheckpointIndex; i > 0;) {
/// Latest checkpoint voting power is calculated when initializing `_totalVotingPower`, so we pre-decrement the index here
for (uint32 i = _numCheckpoints; i > 0;) {
_currentCheckpoint = _sourceContract.checkpoints(_account, --i);

/// Add voting power for the sub-interval to the total
_totalVotingPower += _currentCheckpoint._value * (_latestKey - _currentCheckpoint._key);
if (_currentCheckpoint._key <= _end) {
uint48 _effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key;
_totalVotingPower += _currentCheckpoint._value * (_end - _effectiveStart);

RonTuretzky marked this conversation as resolved.
Show resolved Hide resolved
/// At the start of the interval, deduct voting power accrued before the interval and return the total
if (_currentCheckpoint._key <= _start) {
_totalVotingPower -= _currentCheckpoint._value * (_start - _currentCheckpoint._key);
break;
if (_effectiveStart == _start) break;
_end = _currentCheckpoint._key;
}

_latestKey = _currentCheckpoint._key;
}

return _totalVotingPower;
Expand Down