The Standard

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

Remaining tokens from division

Summary

Due to rounding down during division, undistributed tokens appear

Vulnerability Details

in for loop, rewards are distributed to users by calculating their share of tokens from the total number of staked tokens.

I'll give you an example. Maybe I didn’t choose the numbers very well, but I think the meaning will be clear

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8;
import "hardhat/console.sol";
contract POC {
struct Position { address holder; uint256 TST; uint256 EUROs; }
struct PendingStake { address holder; uint256 createdAt; uint256 TST; uint256 EUROs; }
mapping(address => Position) public positions;
function distributeFees() external {
address[4] memory holders;
holders[0] = address(1);
holders[1] = address(2);
holders[2] = address(3);
holders[3] = address(4);
positions[holders[0]].TST = 3033;
positions[holders[1]].TST = 225;
positions[holders[2]].TST = 527;
positions[holders[3]].TST = 326;
PendingStake[4] memory pendingStakes;
pendingStakes[0].TST = 3033;
pendingStakes[1].TST = 225;
pendingStakes[2].TST = 527;
pendingStakes[3].TST = 326;
uint _amount = 2000;
uint256 tstTotal = 3033 + 225 +527 + 326 + 3033 +225 +527 + 326; // 8222
if (tstTotal > 0) {
//IERC20(EUROs).safeTransferFrom(msg.sender, address(this), _amount);
for (uint256 i = 0; i < holders.length; i++) {
address _holder = holders[i];
positions[_holder].EUROs += _amount * positions[_holder].TST / tstTotal;
}
for (uint256 i = 0; i < pendingStakes.length; i++) {
pendingStakes[i].EUROs += _amount * pendingStakes[i].TST / tstTotal;
console.log(_amount * pendingStakes[i].TST / tstTotal);
}
}
uint distrubuted = positions[holders[0]].EUROs +
positions[holders[1]].EUROs +
positions[holders[2]].EUROs +
positions[holders[3]].EUROs +
pendingStakes[0].EUROs +
pendingStakes[1].EUROs +
pendingStakes[2].EUROs +
pendingStakes[3].EUROs;
console.log('distrubuted - ', distrubuted);
console.log('tstTotal - ', tstTotal);
console.log(_amount - distrubuted);
}
}

console.log shows:
distrubuted - 1996
tstTotal - 8222
4 <-----

Due to rounding down, which is present in solidity, tokens appear that are not distributed (4) among users and they remain on the contract balance.

Impact

Undistributed tokens will accumulate in the contract and no one can take them away

Tools Used

Manual review

Recommendations

Send not distributed tokens back to LiquidationPoolManager contract

Updates

Lead Judging Commences

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

precision-distributeFees

Support

FAQs

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