code-423n4 / 2024-02-althea-liquid-infrastructure-findings

3 stars 1 forks source link

`LiquidInfrastructureERC20::distributeToAllHolders()` - Gas griefing combo DoS attack vector: Due to lack of access control and/or lack of throttling/frequency-limiting mechanisms, an attacker can repeatedly call this function manually or via mempool bots and DoS contract/protocol functionality. #728

Closed c4-bot-10 closed 8 months ago

c4-bot-10 commented 9 months ago

Lines of code

https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/3adc34600561077ad4834ee9621060afd9026f06/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L161-L169 https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/3adc34600561077ad4834ee9621060afd9026f06/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L178 https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/3adc34600561077ad4834ee9621060afd9026f06/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L289

Vulnerability details

An attacker can repeatedly call this function manually or via mempool bots (with higher gas prices if necessary) to effectively gobble up block gas limits quickly and thereby make it difficult for any other function calls to be included into current block during the ongoing attack, effectively DoS-ing any other contract/protocol functionalities for as long a the attack continues.

This attack will be more effective when the holders array length is large enough. However, due to the existing gas gobbling implementation of the distribute() function, holders.length doesn't need to be that large at all.

Should either add access control here so only owner can call this function, or implement mechanisms to throttle or limit the frequency at which this function can be called, to help mitigate this attack vector. This should be the primary mitigation approach. Secondary measures would be to gas optimize the hell out of the distribute() function.

IMPACT:

Ideal scenario for attacker: If the attacker repeatedly calls distributeToAllHolders() or burnAndDistribute() when the holders.length is too large for the function call to succeed before running out of gas, then the attacker could exploit this to guzzle up the block gas limit quickly, which would potentially prevent anyone from successfully calling the distribute() function directly where the holders.length value can be controlled, effectively DoS-ing critical distribution functionality of the contract, including any other function calls.

This DoS attack can keep going for as long as the attacker can maintain it, which could also DoS any attempts to change the holders.length value via onlyOwner function call approveHolder().

Since the attacker can increase their gas price to prioritize their transactions over the contract owner's or normal users' function calls, ensuring that attacker's function calls are included first in the block(s), the attacker can additionally do this:

Attacker could leverage mempool bots to monitor for protocol mitigation attempts like increasing gas price for direct distribute() calls, and then he immediately calls the gas-guzzling functions distributeToAllHolders() or burnAndDistribute() with a higher gas price to ensure his function calls get prioritized for inclusion into the block(s), potentially intensifying the impact of the gas-based DoS attack, via bots.

Alternatively, the attacker could call distribute() directly as per below explanation:

Attacker could call this function directly in quick succession with parameter numDistributions = 1 each time, which should guzzle up the block gas limit really quickly because this uses more gas overall, compared to calling either of the other two functions just once for the full holders array, but this might not be as long-lasting as the attack via the other two functions, but it could DoS contract functionality for at least one block.

Mitigation/Recommendation:

Assessed type

DoS

0xRobocop commented 9 months ago

Spam

c4-pre-sort commented 9 months ago

0xRobocop marked the issue as insufficient quality report

c4-judge commented 8 months ago

0xA5DF marked the issue as unsatisfactory: Invalid