Platform: Code4rena
Start Date: 24/07/2023
Pot Size: $100,000 USDC
Total HM: 18
Participants: 73
Period: 7 days
Judge: alcueca
Total Solo HM: 8
Id: 267
League: ETH
Rank: 15/73
Findings: 2
Award: $725.97
π Selected for report: 1
π Solo Findings: 0
π Selected for report: Aymen0909
Also found by: ABAIKUNANBAEV, Jigsaw, hals, sces60107
681.0903 USDC - $681.09
The function fastTrackProposalExecution
is supposed to be used by the TemporalGovernor
owner during periods of emergency, when the contract is paused to fast track a certain proposal (queue and execute a proposal directly without delay or voting), with gaol of ensuring the protocol safety.
But the function fastTrackProposalExecution
is missing the whenPaused
modifier which means it can be called at any time to fast track any proposal and not just when the TemporalGovernor
is paused.
I submit this issue as only Medium risk because only the TemporalGovernor
owner can call the fastTrackProposalExecution
function (and i suppose that the owner is trusted and will not execute malicious actions), but this issue still goes against the intent of the governance process in which the members of the DAO are supposed to propose, vote and execute the proposals in a permissionless and decentralized manner and where the owner should not be able to execute actions on the protocol without the agreement of the members (except for those emergency situation of course).
The issue is present in the fastTrackProposalExecution
function below :
/// @notice Allow the guardian to process a VAA when the /// Temporal Governor is paused this is only for use during /// periods of emergency when the governance on moonbeam is /// compromised and we need to stop additional proposals from going through. /// @param VAA The signed Verified Action Approval to process function fastTrackProposalExecution(bytes memory VAA) external onlyOwner { // @audit can be called when contract is not paused _executeProposal(VAA, true); /// override timestamp checks and execute }
As it can be seen the function does not contain the whenPaused
modifier and thus it can be called at any moment by the owner to fast track a proposal.
We can also notice that the function comments do mention the fact that it should only be called when the Temporal Governor is paused.
Manual review
I recommend to add the whenPaused
modifier to the fastTrackProposalExecution
function, in order to ensure that the governance process will always work as a real DAO and the owner only intervene in the emergency cases.
Governance
#0 - c4-pre-sort
2023-08-02T08:35:21Z
0xSorryNotSorry marked the issue as low quality report
#1 - c4-pre-sort
2023-08-03T13:53:34Z
0xSorryNotSorry marked the issue as duplicate of #245
#2 - c4-judge
2023-08-12T20:42:42Z
alcueca marked the issue as selected for report
π Selected for report: immeas
Also found by: 0x70C9, 0xAnah, 0xArcturus, 0xComfyCat, 0xWaitress, 0xackermann, 0xkazim, 2997ms, 33audits, Arz, Aymen0909, ChrisTina, JP_Courses, John_Femi, Jorgect, Kaysoft, LosPollosHermanos, MohammedRizwan, Nyx, Rolezn, Sathish9098, Stormreckson, T1MOH, Tendency, Topmark, Udsen, Vagner, albertwh1te, ast3ros, banpaleo5, berlin-101, catellatech, cats, codetilda, cryptonue, eeshenggoh, fatherOfBlocks, hals, jamshed, jaraxxus, josephdara, kankodu, kodyvim, kutugu, lanrebayode77, mert_eren, nadin, naman1778, niki, petrichor, ravikiranweb3, said, solsaver, souilos, twcctop, wahedtalash77
44.8793 USDC - $44.88
https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/MultiRewardDistributor/MultiRewardDistributor.sol#L564-L571 https://github.com/code-423n4/2023-07-moonwell/blob/main/src/core/MultiRewardDistributor/MultiRewardDistributor.sol#L605-L612
In the MultiRewardDistributor
contract, the _addEmissionConfig
function allow the admin (timelock) to add multiple emission config to a given MToken, each emission config corresponds to a certain emission token (ERC20).
All the emission configs are stored in a list marketConfigs[mtoken]
, and there is no limit on the number of emission config that can be added to this list, so the admin (timelock) is allowed to add multiple emission config.
This can cause an issue in some protocol functions that loops over all those emission configs in their logic, as if the number of emission configs stored in the list marketConfigs[mtoken]
get relatively big, those function can run out of gas which will make them impossible to call (cause a DOS of their functionality).
Some of the affected functions could be : updateMarketSupplyIndexAndDisburseSupplierRewards
, updateMarketBorrowIndexAndDisburseBorrowerRewards
.
This issue can occur if the number of emission configs for a given MToken become relatively big, the _addEmissionConfig
function allow the admin (timelock) to add multiple configs (if the emission token remain unique) for each MToken.
The risk of this issue causing a run out of gas denial of service is very low for the functions that only loops once over all the emission configs like the functions : updateMarketSupplyIndex
, disburseSupplierRewards
, updateMarketBorrowIndex
, disburseBorrowerRewards
. But the risk of DOS gets higher when a function run the loop twice (over all the emission configs) as it is the case in the functions : updateMarketSupplyIndexAndDisburseSupplierRewards
, updateMarketBorrowIndexAndDisburseBorrowerRewards
.
If we take for example the function updateMarketSupplyIndexAndDisburseSupplierRewards
:
function updateMarketSupplyIndexAndDisburseSupplierRewards( MToken _mToken, address _supplier, bool _sendTokens ) external onlyComptrollerOrAdmin { updateMarketSupplyIndexInternal(_mToken); disburseSupplierRewardsInternal(_mToken, _supplier, _sendTokens); }
It call both functions updateMarketSupplyIndex
and disburseSupplierRewards
and thus perform two loops over the emission config list.
The updateMarketSupplyIndexAndDisburseSupplierRewards
is used in the updateAndDistributeSupplierRewardsForToken
function inside the Comptroller
contract, the later function is implemented in many critical functions : a single time in both mintAllowed
, redeemAllowed
and twice in seizeAllowed
, transferAllowed
.
So in the case the number of emission configs becomes relatively big (not necessarily too big), the function updateMarketSupplyIndexAndDisburseSupplierRewards
will be blocked which could block those functions especially the two functions seizeAllowed
, transferAllowed
because they basically loop 4 time over the configs list (which will cost a lot of gas).
The same issue could happen with the updateAndDistributeBorrowerRewardsForToken
function which is implemented in borrowAllowed
, repayBorrowAllowed
.
If those functions are blocked, it will negatively impact the protocol as no mint, borrow, repay, redeem or transfer operation will be allowed which are among the main functionality of the protocol.
This issue is even more critical as there is no way to remove certain emission configs that were added to marketConfigs[mtoken]
list.
Manual review
I recommend to add a maximum limit on the number of emission configs associated to each MToken.
DoS
#0 - 0xSorryNotSorry
2023-08-03T08:11:49Z
A coded POC would be ideal to see the referenced edge.
#1 - c4-pre-sort
2023-08-03T13:48:13Z
0xSorryNotSorry marked the issue as primary issue
#2 - c4-sponsor
2023-08-03T18:39:22Z
ElliotFriedman marked the issue as disagree with severity
#3 - ElliotFriedman
2023-08-03T18:40:21Z
agreed this is an issue, however, governance is trusted to not add too many reward configs which would brick the system due to out of gas
#4 - ElliotFriedman
2023-08-03T22:29:30Z
disagree with severity
#5 - c4-sponsor
2023-08-07T21:49:23Z
ElliotFriedman marked the issue as sponsor acknowledged
#6 - c4-judge
2023-08-12T20:15:13Z
alcueca changed the severity to QA (Quality Assurance)
#7 - c4-judge
2023-08-12T20:15:17Z
alcueca marked the issue as grade-a