Chinmay - An Oracle Signer can never be removed even if he becomes malicious
sherlock-admin opened this issue · comments
Chinmay
high
An Oracle Signer can never be removed even if he becomes malicious
Summary
The call flow of removeOracleSIgner incorrectly compares the hash of ("removeOracleSigner", account) with the hash of ("addOracleSigner", account) for validating that an action is actually initiated. This validation always fails because the hashes can never match.
Vulnerability Detail
The process of removing oracle signers is 2 stage. First function signalRemoveOracleSigner
is called by the TimelockAdmin which stores a time-delayed timestamp corresponding to the keccak256 hash of ("removeOracleSigner", account) - a bytes32 value called actionKey in the pendingActions mapping.
Then the Admin needs to call function removeOracleSignerAfterSignal
but this function calls _addOracleSignerActionKey
instead of _removeOracleSignerActionKey
for calculating the bytes32 action key value. Now the actionKey is calculated as keccak256 hash of ("addOracleSigner", account) and this hash is used for checking if this action is actually pending by ensuring its timestamp is not zero inside the _validateAction
function called via _validateAndClearAction
function at Line 122. The hash of ("removeOracleSigner", account) can never match hash of ("addOracleSigner", account) and thus this validation will fail.
function removeOracleSignerAfterSignal(address account) external onlyTimelockAdmin nonReentrant {
bytes32 actionKey = _addOracleSignerActionKey(account);
_validateAndClearAction(actionKey, "removeOracleSigner");
oracleStore.removeSigner(account);
EventUtils.EventLogData memory eventData;
eventData.addressItems.initItems(1);
eventData.addressItems.setItem(0, "account", account);
eventEmitter.emitEventLog1(
"RemoveOracleSigner",
actionKey,
eventData
);
}
Impact
The process of removing an Oracle Signer will always revert and this breaks an important safety measure if a certain oracle signer becomes malicious the TimelockAdmin could do nothing(these functions are meant for this). Hence, important functionality is permanently broken.
Code Snippet
Tool used
Manual Review
Recommendation
Replace the call to _addOracleSignerActionKey at Line 118 by call to _removeOracleSignerActionKey
fixed in gmx-io/gmx-synthetics@3ef1161
gmx-io/gmx-synthetics@3ef1161
The commit correctly implements the suggested fix of using the correct function (_removeOracleSignerActionKey()
) for looking up the action key for oracle removal
done