code-423n4 / 2023-12-autonolas-findings

3 stars 3 forks source link

Permanent DOS in `liquidity_lockbox` for under $10 #445

Open c4-bot-6 opened 10 months ago

c4-bot-6 commented 10 months ago

Lines of code

https://github.com/code-423n4/2023-12-autonolas/blob/main/lockbox-solana/solidity/liquidity_lockbox.sol#L54 https://github.com/code-423n4/2023-12-autonolas/blob/main/lockbox-solana/solidity/liquidity_lockbox.sol#L181-L184

Vulnerability details

Impact

The liquidity_lockbox contract in the lockbox-solana project is vulnerable to permanent DOS due to its storage limitations. The contract uses a Program Derived Address (PDA) as a data account, which is created with a maximum size limit of 10 KB.

Every time the deposit() function is called, a new element is added to positionAccounts, mapPositionAccountPdaAta, and mapPositionAccountLiquidity, which decreases the available storage by 64 + 32 + 32 = 128 bits. This means that the contract will run out of space after at most 80000 / 128 = 625 deposits.

Once the storage limit is reached, no further deposits can be made, effectively causing a permanent DoS condition. This could be exploited by an attacker to block the contract's functionality at a very small cost.

Proof of Concept

An attacker can cause a permanent DoS of the contract by calling deposit() with the minimum position size only 625 times. This will fill up the storage limit of the PDA, preventing any further deposits from being made.

Since neither the contract nor seemingly Orca's pool contracts impose a limitation on the minimum position size, this can be achieved at a very low cost of 625 * dust * transaction fees:

no min deposit in SOL/OLAS pool

Tools Used

Manual review

Recommended Mitigation Steps

The maximum size of a PDA is 10 KiB on creation, only slightly larger than the current allocated space of 10 KB. The Solana SDK does provide a method to resize a data account (source), but this functionality isn't currently implemented in Solang (source).

A potential solution to this issue is to use an externally created account as a data account, which can have a size limit of up to 10 MiB, as explained in this StackExchange post.

Alternatively, free up space by clearing the aforementioned variables in storage for withdrawn positions.

However, a more prudent security recommendation would be to leverage the Solana SDK directly, despite the potential need for contract reimplementation and the learning curve associated with Rust. The Solana SDK offers greater flexibility and is less likely to introduce unforeseen vulnerabilities. Solang, while a valuable tool, is still under active development and will usually lag behind the SDK, which could inadvertently introduce complexity and potential vulnerabilities due to compiler discrepancies.

Assessed type

DoS

c4-pre-sort commented 10 months ago

alex-ppg marked the issue as sufficient quality report

c4-sponsor commented 10 months ago

kupermind (sponsor) confirmed

c4-judge commented 10 months ago

dmvt marked the issue as selected for report