sherlock-audit / 2023-04-gmx-judging

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

https://github.com/sherlock-audit/2023-04-gmx/blob/06ccd8c7ee4cadc46e3ac412dcf141eefdced42f/gmx-synthetics/contracts/config/Timelock.sol#L117

Tool used

Manual Review

Recommendation

Replace the call to _addOracleSignerActionKey at Line 118 by call to _removeOracleSignerActionKey

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