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
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;
if (tstTotal > 0) {
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);
}
}
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.
Undistributed tokens will accumulate in the contract and no one can take them away