Skip to content

Conversation

funkyenough
Copy link
Collaborator

@funkyenough funkyenough commented Jun 26, 2025

Implementation

  • New Method: updateDelegateeScores accepts an array of DelegateeScoreUpdate structs for efficient batch processing
  • Comprehensive Test Coverage: Extended all existing updateDelegateeScore test patterns to cover the batch method
  • Additional Batch-Specific Tests:
    a. Empty array handling
    b. Single delegatee, single update
    c. Single delegatee, multiple updates
    d. Multiple delegatees, single update each
    e. Multiple delegatees, multiple updates each

Design Decisions

  • Empty Array Behavior: Empty input is treated as a no-op rather than reverting. This design choice is up to further discussion.

@funkyenough funkyenough changed the title Feature/beoepc batch update delegatee score Add batch delegatee score update functionality to BinaryEligibilityOracleEarningPowerCalculator Jun 26, 2025
@funkyenough funkyenough marked this pull request as ready for review June 26, 2025 04:57
Copy link
Collaborator

@apbendi apbendi left a comment

Choose a reason for hiding this comment

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

Thanks @funkyenough. Overall this is looking great. I did request some changes to avoid duplication and to clarify one of the requirements.

}
_updateDelegateeScore(_delegatee, _newScore);
}
if (_delegateeScoreUpdates.length > 0) lastOracleUpdateTime = block.timestamp;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm how to handle this is actually an interesting question. It might actually be worthwhile to allow the oracle to call this method with 0 new scores yet have that actually update the timestamp. It could be useful as a way to "touch" the oracle and keep it fresh even if no scores need to change.

Let's switch to that: calling this method with a zero length array should update the lastOracleUpdateTime

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Makes sense!

I was initially cautious about the security implications of allowing empty arrays to update the timestamp. I took some time to think it through and realized that for any meaningful attack to succeed here, the oracle itself would need to be compromised, and at that point the entire system's security model is already broken anyways.

Change implemented in 47020f0

}
for (uint256 _i = 0; _i < _delegateeScoreUpdates.length; _i++) {
address _delegatee = _delegateeScoreUpdates[_i].delegatee;
uint256 _newScore = _delegateeScoreUpdates[_i].newScore;
Copy link

@thelostone-mc thelostone-mc Jun 26, 2025

Choose a reason for hiding this comment

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

Might be worth using memory reference for calldata array instead of accesing the array twice

 DelegateeScoreUpdate calldata update = _delegateeScoreUpdates[_i];
address _delegatee = update.delegatee;
uint256 _newScore = update.newScore;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good call! Fixed in d318e9b

}
_revertIfNotScoreOracle();
_revertIfPaused();
_revertIfDelegateeScoreLocked(_delegatee);
Copy link

@thelostone-mc thelostone-mc Jun 27, 2025

Choose a reason for hiding this comment

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

This is soo much cleaner. ❤️ nice job

_revertIfPaused();
uint256 _delegateesLength = _delegateeScoreUpdates.length;
for (uint256 _i = 0; _i < _delegateesLength; _i++) {
DelegateeScoreUpdate calldata update = _delegateeScoreUpdates[_i];
Copy link

@thelostone-mc thelostone-mc Jun 27, 2025

Choose a reason for hiding this comment

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

nit: should this be renamed to _update / _delagateScoreUpdate to be consistent (cause convention is we add _ to local vars )

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed. Fixed in 9b13507

);
}

function _boundToRealisticDelegateeScoreUpdateLength(uint256 _length)

Choose a reason for hiding this comment

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

Ah i like this naming. Will borrow this onto the project I'm working on

@thelostone-mc
Copy link

LGTM

Copy link
Collaborator

@apbendi apbendi left a comment

Choose a reason for hiding this comment

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

Left one small nit on test naming @funkyenough, if you don't mind fixing that up. Otherwise this is good to go, from my perspective, but let's avoid merging it for now, because I want to share the PR with the auditors who will be doing a security review as-is.

@github-actions
Copy link

Coverage after merging feature/beoepc-batch-update-delegatee-score into main will be

100.00%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   DelegationSurrogate.sol100%100%100%100%
   DelegationSurrogateVotes.sol100%100%100%100%
   Staker.sol100%100%100%100%
src/calculators
   BinaryEligibilityOracleEarningPowerCalculator.sol100%100%100%100%
   IdentityEarningPowerCalculator.sol100%100%100%100%
src/extensions
   StakerCapDeposits.sol100%100%100%100%
   StakerDelegateSurrogateVotes.sol100%100%100%100%
   StakerOnBehalf.sol100%100%100%100%
   StakerPermitAndStake.sol100%100%100%100%
src/notifiers
   MintRewardNotifier.sol100%100%100%100%
   RewardTokenNotifierBase.sol100%100%100%100%
   TransferFromRewardNotifier.sol100%100%100%100%
   TransferRewardNotifier.sol100%100%100%100%

@alexkeating alexkeating merged commit 96588fc into main Jul 14, 2025
6 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.

4 participants