Currently, withdrawals are queued in an array and processed sequentially in a for loop.
However, a user can post unlimited number of tiny (1 wei) withdrawals.
Clearing these withdrawals can be gas consuming and can delay users.
(It is gas consuming because USDC transfers require many SSLOAD and SSTORE ops)
In general, pushing withdrawal is cheaper than processing withdrawal.
1
Impact
Light DoS of USDC withdrawal system
Proof of Concept
Currently, withdrawals are queued in an array and processed sequentially in a for loop. However, a user can post unlimited number of tiny (1 wei) withdrawals. Clearing these withdrawals can be gas consuming and can delay users. (It is gas consuming because USDC transfers require many SSLOAD and SSTORE ops) In general, pushing withdrawal is cheaper than processing withdrawal.
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/VUSD.sol#L53-L67
Tools Used
Manual review
Recommended Mitigation Steps
Possible solutions: Rewrite
withdraw()
andprocessWithdrawals()
:Note: it's also gas optimized:
2
Impact
Chainlink's
latestRoundData()
might return stale or incorrect resultsProof of Concept
https://github.com/code-423n4/2022-02-hubble/blob/main/contracts/Oracle.sol#L33
There is no check if the return value indicates stale data. This could lead to stale prices according to the Chainlink documentation:
https://docs.chain.link/docs/historical-price-data/#historical-rounds https://docs.chain.link/docs/faq/#how-can-i-check-if-the-answer-to-a-round-is-being-carried-over-from-a-previous-round
Tools Used
Manual review
Recommended Mitigation Steps
Change to