sherlock-2025-06-symbiotic-relay-m04
[M-04] Most KeyRegistry, VotingPowerProvider functions can be DoSed
Summary
KeyRegistry.setKey 를 아무나 호출할 수 있고 등록할 수 있는 key의 수에 제한이 없었다. 다량의 key를 등록하면 모든 operator의 정보를 조회하는 getKeys 와 getKeysAt 함수를 DoS할 수 있다. VotingPowerProvider.registerOperator 역시 오퍼레이터 등록에 제한을 두지 않으므로 getOperatorsAt, getOperators 함수를 DoS 할 수 있다.
Keyword
dos, gas limit, solidity view
Vulnerability
- contracts/modules/key-registry/KeyRegistry.sol#L201
- contracts/modules/key-registry/KeyRegistry.sol#L137-L158
KeyRegistry에는 VotingPowerProvider에 오퍼레이터로 등록되지 않은 계정으로도 자유롭게 key를 등록할 수 있다.
@> function setKey(uint8 tag, bytes memory key, bytes memory signature, bytes memory extraData) public virtual {
_setKey(msg.sender, tag, key, signature, extraData);
}KeyRegistry 컨트랙트에는 등록된 모든 오퍼레이터에 대한 정보를 조회하는 getKeys 와 getKeysAt 함수가 있다. 등록할 수 있는 key 수에 제한이 없고 아무나 등록할 수 있으므로, 많은 key를 등록하면 모든 오퍼레이터에 대한 조회를 하는 함수를 DoS할 수 있다.
function getKeysAt(
uint48 timestamp
) public view virtual returns (OperatorWithKeys[] memory operatorsKeys) {
address[] memory operators = getKeysOperatorsAt(timestamp);
operatorsKeys = new IKeyRegistry.OperatorWithKeys[](operators.length);
@> for (uint256 i; i < operators.length; ++i) {
operatorsKeys[i].operator = operators[i];
operatorsKeys[i].keys = getKeysAt(operators[i], timestamp, new bytes(0));
}
}
function getKeys() public view virtual returns (OperatorWithKeys[] memory operatorsKeys) {
address[] memory operators = getKeysOperators();
operatorsKeys = new OperatorWithKeys[](operators.length);
@> for (uint256 i; i < operators.length; ++i) {
operatorsKeys[i].operator = operators[i];
operatorsKeys[i].keys = getKeys(operators[i]);
}
}마찬가지로, 누구나 VotingPowerProvider 컨트랙트의 registerOperator를 호출하여 자신을 오퍼레이터로 등록할 수 있다. getOperatorsAt, getOperators 와 같은 함수는 등록된 모든 오퍼레이터 정보를 조회하려 하므로 많은 오퍼레이터를 등록해두면 조회 함수를 DoS 할 수 있다.
function registerOperator() public virtual {
@> _registerOperatorImpl(msg.sender);
}Impact
view 함수를 DoS 할 수 있다.
Mitigation
VotingPowerProvider에 등록된 오퍼레이터만 KeyRegistry에 key를 등록할 수 있도록 제한한다. 또는 조회 함수에 페이지네이션을 사용한다.
Memo
딱히 수정되진 않았다. view 함수 DoS는 좀 비현실적이라 잘 제출하지 않는데, 그냥저냥 제출할만 한 듯. 다만 중복자가 매우 많았다. 굳이 PoC 쓸 것도 없는 듯.
tags: bughunting, symbiotic, smart contract, solidity, severity medium, dos, gas limit, solidity view