From 12e76589ff09683dca3242d5c01a1c15579ae8c2 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Sat, 28 Sep 2024 14:03:49 +0300 Subject: [PATCH 1/8] optimization: reducing complexity of voting power function --- src/YieldDistributor.sol | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index 8128b57..a6c978a 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -140,32 +140,18 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { 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); - - /// 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; + uint256 _totalVotingPower; for (uint32 i = _currentCheckpointIndex; i > 0;) { - /// Latest checkpoint voting power is calculated when initializing `_totalVotingPower`, so we pre-decrement the index here _currentCheckpoint = _sourceContract.checkpoints(_account, --i); + if (_currentCheckpoint._key <= _end) { + uint48 effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; + _totalVotingPower += _currentCheckpoint._value * (_end - effectiveStart); - /// Add voting power for the sub-interval to the total - _totalVotingPower += _currentCheckpoint._value * (_latestKey - _currentCheckpoint._key); + if (effectiveStart == _start) break; - /// 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; + _end = _currentCheckpoint._key; } - - _latestKey = _currentCheckpoint._key; } return _totalVotingPower; From f6c61c5cdce8d6e5535067edf9ee1d9885300f68 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Sat, 28 Sep 2024 14:03:49 +0300 Subject: [PATCH 2/8] optimization: reducing complexity of voting power function --- src/YieldDistributor.sol | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index 8128b57..a6c978a 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -140,32 +140,18 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { 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); - - /// 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; + uint256 _totalVotingPower; for (uint32 i = _currentCheckpointIndex; i > 0;) { - /// Latest checkpoint voting power is calculated when initializing `_totalVotingPower`, so we pre-decrement the index here _currentCheckpoint = _sourceContract.checkpoints(_account, --i); + if (_currentCheckpoint._key <= _end) { + uint48 effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; + _totalVotingPower += _currentCheckpoint._value * (_end - effectiveStart); - /// Add voting power for the sub-interval to the total - _totalVotingPower += _currentCheckpoint._value * (_latestKey - _currentCheckpoint._key); + if (effectiveStart == _start) break; - /// 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; + _end = _currentCheckpoint._key; } - - _latestKey = _currentCheckpoint._key; } return _totalVotingPower; From 9f92e21f55443a66be0165e91df9daf75de2c391 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Sun, 29 Sep 2024 09:21:11 +0300 Subject: [PATCH 3/8] fix: renaming --- src/YieldDistributor.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index a6c978a..32e413e 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -133,8 +133,8 @@ 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); @@ -142,7 +142,7 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { uint256 _totalVotingPower; - for (uint32 i = _currentCheckpointIndex; i > 0;) { + for (uint32 i = _numCheckpoints; i > 0;) { _currentCheckpoint = _sourceContract.checkpoints(_account, --i); if (_currentCheckpoint._key <= _end) { uint48 effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; From b6c1b7703433198abbbfd1615444ab8be21b6797 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Sun, 29 Sep 2024 09:22:18 +0300 Subject: [PATCH 4/8] fix: prefix _ for internal variable --- src/YieldDistributor.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index 32e413e..daa7411 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -145,10 +145,10 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { for (uint32 i = _numCheckpoints; i > 0;) { _currentCheckpoint = _sourceContract.checkpoints(_account, --i); if (_currentCheckpoint._key <= _end) { - uint48 effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; - _totalVotingPower += _currentCheckpoint._value * (_end - effectiveStart); + uint48 _effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; + _totalVotingPower += _currentCheckpoint._value * (_end - _effectiveStart); - if (effectiveStart == _start) break; + if (_effectiveStart == _start) break; _end = _currentCheckpoint._key; } From 51931c636d77d1015ddc5203f31ac33e90e8be39 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Sun, 29 Sep 2024 09:23:15 +0300 Subject: [PATCH 5/8] fix: line break for readability --- src/YieldDistributor.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index daa7411..d055059 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -144,6 +144,7 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { for (uint32 i = _numCheckpoints; i > 0;) { _currentCheckpoint = _sourceContract.checkpoints(_account, --i); + if (_currentCheckpoint._key <= _end) { uint48 _effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; _totalVotingPower += _currentCheckpoint._value * (_end - _effectiveStart); From d87945af2d1a3ced4d2a6a752e9c618357bd15c3 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Sun, 29 Sep 2024 09:24:07 +0300 Subject: [PATCH 6/8] fix: consolidating 2 line control flow statements --- src/YieldDistributor.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index d055059..124d9f8 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -150,7 +150,6 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { _totalVotingPower += _currentCheckpoint._value * (_end - _effectiveStart); if (_effectiveStart == _start) break; - _end = _currentCheckpoint._key; } } From 5a4520c829ec3c873bf11ed8c277928ae6cae561 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Mon, 30 Sep 2024 08:45:46 +0300 Subject: [PATCH 7/8] fix: cleaning up decrementation --- src/YieldDistributor.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index 124d9f8..4f83ba9 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -142,8 +142,8 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { uint256 _totalVotingPower; - for (uint32 i = _numCheckpoints; i > 0;) { - _currentCheckpoint = _sourceContract.checkpoints(_account, --i); + for (uint32 i = _numCheckpoints - 1; --i > 0;) { + _currentCheckpoint = _sourceContract.checkpoints(_account, i); if (_currentCheckpoint._key <= _end) { uint48 _effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key; From 667aa93a9de68e37bcca5e36548004ae32654ae4 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Mon, 30 Sep 2024 09:05:46 +0300 Subject: [PATCH 8/8] Revert "fix: cleaning up decrementation" This reverts commit 5a4520c829ec3c873bf11ed8c277928ae6cae561. --- src/YieldDistributor.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/YieldDistributor.sol b/src/YieldDistributor.sol index 4f83ba9..124d9f8 100644 --- a/src/YieldDistributor.sol +++ b/src/YieldDistributor.sol @@ -142,8 +142,8 @@ contract YieldDistributor is IYieldDistributor, OwnableUpgradeable { uint256 _totalVotingPower; - for (uint32 i = _numCheckpoints - 1; --i > 0;) { - _currentCheckpoint = _sourceContract.checkpoints(_account, i); + for (uint32 i = _numCheckpoints; i > 0;) { + _currentCheckpoint = _sourceContract.checkpoints(_account, --i); if (_currentCheckpoint._key <= _end) { uint48 _effectiveStart = _currentCheckpoint._key < _start ? uint48(_start) : _currentCheckpoint._key;