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

govstaking/src/BinaryEligibilityOracleEarningPowerCalculator.sol #19

Open
wants to merge 1 commit into
base: base
Choose a base branch
from

Conversation

sherlock-admin2
Copy link
Contributor

govstaking/src/BinaryEligibilityOracleEarningPowerCalculator.sol

STALE_ORACLE_WINDOW = _staleOracleWindow;
_setOraclePauseGuardian(_oraclePauseGuardian);
_setDelegateeScoreEligibilityThreshold(_delegateeScoreEligibilityThreshold);
_setUpdateEligibilityDelay(_updateEligibilityDelay);
Copy link
Collaborator

@CergyK CergyK Nov 30, 2024

Choose a reason for hiding this comment

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

it seems that lastOracleUpdateTime is not set here, so it means that the oracle is created in _isOracleStale() == true state. Some users may profit off of that by checkpointing their earningPower at this moment, since it would be max, independently of quality of delegatee

Copy link
Collaborator

@jokrsec jokrsec Dec 6, 2024

Choose a reason for hiding this comment

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

Good edge case. But I think this also depends on the time it takes to update the delegatee score after creation. Even if they initially receive a higher earning power, once the first request to updateDelegateeScore is made, it will be bumped down because the all delegatees would initially be considered ineligible

Choose a reason for hiding this comment

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

Presumably, it would be updated relatively soon after deployment.

if (msg.sender != scoreOracle) {
revert BinaryEligibilityOracleEarningPowerCalculator__Unauthorized("not oracle", msg.sender);
}
if (delegateeScoreLockStatus[_delegatee]) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

INFO: If all delegatees are locked (to zero for example), the oracle is forced into stale mode, potentially unlocking max earningPower again

emit DelegateeEligibilityThresholdScoreSet(
delegateeEligibilityThresholdScore, _newDelegateeScoreEligibilityThreshold
);
delegateeEligibilityThresholdScore = _newDelegateeScoreEligibilityThreshold;
Copy link
Collaborator

Choose a reason for hiding this comment

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

If delegatees get ineligible due to an increase of eligibilityThreshold, they also get instantly bumpable, because the logic checks if previous score is greater than current eligibilityThreshold.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Additionally, after the delegatee becomes ineligible, the updateEligibilityDelay wouldn't work as expected. Because timeOfIneligibility[_delegatee] is never updated in this case. Due to this all the deposits with this delegatee could be instantly bumped down.

address _delegatee,
uint256 /* _oldEarningPower */
) external view returns (uint256, bool) {
if (_isOracleStale() || isOraclePaused) return (_amountStaked, true);
Copy link
Collaborator

Choose a reason for hiding this comment

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

As _amountStaked is returned as earning power when the oracle is stale or paused. A malicious user can bump all the deposits which are delegated to ineligible delegatees to claim tips if the oracle ever becomes stale or paused.

I think its better to return _oldEarningPower when the oracle is stale or paused.

What are your thoughts on this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a good catch and a valid concern.

Using the oldEarningPower does make sense in most scenarios. There are some tradeoffs, for example if the oracle is paused/stale for an extended period of time then a delegatee that was previously ineligible before the oracle was paused/stale, then became eligible after the oracle is paused/stale, they will still retain the previous ineligible status.

Choose a reason for hiding this comment

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

I think we want to return the amount staked mainly because in those situations the oracle could be malfunctioning or malicious. As @0xSpearmint mentions there are situations where some are worse off because we are using oldEarningPower , rather than rely on old or malicious earning power we revert to a state where only stake is considered to earn rewards.

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.

6 participants