Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: high
Invalid

Lack of Timelock in setStakeAmounts Allows Abrupt Parameter Changes

Summary

The setStakeAmounts function in LLMOracleRegistry allows immediate changes to stake requirements without any timelock or notification period, potentially causing disruption to oracle participants and enabling unfair advantages.

Vulnerability Details

Current implementation allows instant changes to stake parameters:

function setStakeAmounts(uint256 _generatorStakeAmount, uint256 _validatorStakeAmount) public onlyOwner {
generatorStakeAmount = _generatorStakeAmount; // Immediate change
validatorStakeAmount = _validatorStakeAmount; // Immediate change
}

Problem scenarios:

Unfair Registration Prevention:

// User prepares to register with current stake amount
currentStake = registry.getStakeAmount(LLMOracleKind.Generator); // e.g., 100 tokens
user.approve(registry, currentStake);
// Owner front-runs with increased stake amount
registry.setStakeAmounts(currentStake * 2, validatorStakeAmount);
// User's transaction fails due to insufficient allowance
registry.register(LLMOracleKind.Generator); // Reverts

Impact

Disrupts oracle participation planning

Tools Used

Manual Review

Recommendations

Implement basic timelock:

contract LLMOracleRegistry {
uint256 public constant STAKE_CHANGE_DELAY = 7 days;
struct PendingStakeUpdate {
uint256 generatorStake;
uint256 validatorStake;
uint256 effectiveTime;
}
PendingStakeUpdate public pendingUpdate;
event StakeUpdateScheduled(
uint256 generatorStake,
uint256 validatorStake,
uint256 effectiveTime
);
function scheduleStakeUpdate(uint256 _generatorStake, uint256 _validatorStake)
public
onlyOwner
{
pendingUpdate = PendingStakeUpdate({
generatorStake: _generatorStake,
validatorStake: _validatorStake,
effectiveTime: block.timestamp + STAKE_CHANGE_DELAY
});
emit StakeUpdateScheduled(
_generatorStake,
_validatorStake,
pendingUpdate.effectiveTime
);
}
function executeStakeUpdate() public {
require(
block.timestamp >= pendingUpdate.effectiveTime,
"Update not ready"
);
require(pendingUpdate.effectiveTime != 0, "No pending update");
generatorStakeAmount = pendingUpdate.generatorStake;
validatorStakeAmount = pendingUpdate.validatorStake;
emit StakeAmountsUpdated(
generatorStakeAmount,
validatorStakeAmount
);
delete pendingUpdate;
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.