Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

_requireIsKeeper Access Control Bypass

Summary

The _requireIsKeeper function allows any caller to pass the keeper check if the keeper address is set to address(0), effectively disabling access control.

Vulnerability Details

The _requireIsKeeper function in the SettlementBranch contract is designed to enforce access control by ensuring only designated keepers can execute certain functions, such as fillMarketOrder and fillOffchainOrders but the function permits any caller to pass the keeper check if the keeper address is set to address(0). This oversight disables the access control mechanism, allowing unauthorized users to execute restricted functions.

The logical mistake is in the condition used to enforce the keeper check. The function was written as:

if (sender != keeper && keeper != address(0)) {
revert Errors.OnlyKeeper(sender, keeper);
}

This meansif the keeper is set to address(0), the second part of the condition (keeper != address(0)) evaluates to false. As a result, the entire condition is false—even if sender is not equal to address(0)—and the function does not revert. In other words, when keeper is address(0), the access control is effectively bypassed, allowing any caller to pass the check.

Impact

I'm rating this as MEDIUM because it allows unauthorized users to execute functions that should be restricted to designated keepers.

Tools Used

Manual Review

An attacker exploits this by setting the keeper address to address(0) and executing restricted functions. For example: The attacker calls a function like fillMarketOrder, bypassing the access control check.

function exploit() external {
// Assume keeper is set to address(0)
settlementBranch.fillMarketOrder(tradingAccountId, marketId, priceData);
}

Recommendations

Make sure the keeper address is never set to address(0) or modify the _requireIsKeeper function to handle address(0) as an invalid keeper.

function _requireIsKeeper(address sender, address keeper) internal pure {
// Treat address(0) as an invalid keeper
if (keeper == address(0) || sender != keeper) {
revert Errors.OnlyKeeper(sender, keeper);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!