53038 sc low distributeyield can be frontrun to sandwich rewards we can force ourselves to be the last holder and get unfairly big bonuses
Description
Brief/Intro
Vulnerability Details
function distributeYield(
uint256 amount
) external onlyRole(YIELD_DISTRIBUTOR_ROLE) nonReentrant {
......
ERC20Upgradeable yToken = ERC20Upgradeable(yieldTokenAddr);
yToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 distributedSum = 0;
uint256 holderCount = $.holders.length();
if (holderCount == 0) {
emit YieldDistributed(0, yieldTokenAddr);
return;
}
uint256 effectiveTotalSupply = 0;
for (uint256 i = 0; i < holderCount; i++) {
address holder = $.holders.at(i);
if (_isYieldAllowed(holder)) {
effectiveTotalSupply += balanceOf(holder);
}
}
if (effectiveTotalSupply == 0) {
emit YieldDistributed(0, yieldTokenAddr);
return;
}
uint256 lastProcessedIndex = holderCount > 0 ? holderCount - 1 : 0;
for (uint256 i = 0; i < lastProcessedIndex; i++) {
address holder = $.holders.at(i);
if (!_isYieldAllowed(holder)) {
continue;
}
uint256 holderBalance = balanceOf(holder);
if (holderBalance > 0) {
uint256 share = (amount * holderBalance) / effectiveTotalSupply;
if (share > 0) {
yToken.safeTransfer(holder, share);
distributedSum += share;
}
}
}
if (holderCount > 0) {
address lastHolder = $.holders.at(lastProcessedIndex);
if (_isYieldAllowed(lastHolder)) {
uint256 lastShare = amount - distributedSum;
if (lastShare > 0) {
yToken.safeTransfer(lastHolder, lastShare);
distributedSum += lastShare;
}
}
}
}Impact Details
References
Proof of Concept
Notes
Previous53039 sc high rewards and commissions accrued in the interval before a slash might be lostNext53037 sc critical commission changes can retroactively affect user rewards
Was this helpful?