The Standard

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

`LiquidationPool::distributionFees` include `pendingStakes` array in its implementation which can lead to frontrun.

Description

In the LiquidationPool::distributionFees function, the process is as follows:

  • The function utilizes getTstTotal() to determine the total TST in the contract, including the TST in the pendingStakes array.

  • It adds EUROs proportionally based on the number of TST staked by position and pending stake.

The issue arises when any user can inject a significant amount of TST into the contract before any mint / burn / swap operation of any vault. An attacker can exploit this by frontrunning the mint / burn / swap function of any vault, injecting a substantial stake, and then strategically invoking LiquidationPoolManager::distributeFees to claim the majority of the fees.

function distributeFees(uint256 _amount) external onlyManager {
uint256 tstTotal = getTstTotal();
if (tstTotal > 0) {
.
.
.
for (uint256 i = 0; i < pendingStakes.length; i++) {
@> pendingStakes[i].EUROs +=
(_amount * pendingStakes[i].TST) /
tstTotal;
}
}
}

Impact

This vulnerability leads to a loss of rewards for all other users of the pool.

Recommended Mitigation

To address this issue, implement a function that retrieves only TST in the positions array and excludes pending stakes from the fees distribution. The example below adheres to the current implementation logic, but it's advised to create a uint256 variable to track TST in positions and avoid using a for loop on a dynamic array, which could potentially grow and result in a denial-of-service scenario.

+ function getPositionTotal() private view returns (uint256 _tst) {
+ for (uint256 i = 0; i < holders.length; i++) {
+ _tst += positions[holders[i]].TST;
+ }
+ }
function distributeFees(uint256 _amount) external onlyManager {
- uint256 tstTotal = getTstTotal();
+ uint256 tstTotal = getPositionTotal();
if (tstTotal > 0) {
.
.
.
- for (uint256 i = 0; i < pendingStakes.length; i++) {
- pendingStakes[i].EUROs +=
- (_amount * pendingStakes[i].TST) /
- tstTotal;
- }
}
}
Updates

Lead Judging Commences

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

frontrun-distrubutefees

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

frontrun-feedist-low

Support

FAQs

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