Platform: Code4rena
Start Date: 04/01/2022
Pot Size: $25,000 USDC
Total HM: 3
Participants: 40
Period: 3 days
Judge: Ivo Georgiev
Total Solo HM: 1
Id: 75
League: ETH
Rank: 31/40
Findings: 1
Award: $30.27
π Selected for report: 0
π Solo Findings: 0
30.2712 USDC - $30.27
gpersoon
The function updateDistribution() calls _updateXDEFIBalance() and then updates _pointsPerUnit.
Suppose XDEFI tokens are send to the XDEFIDistribution contract and before updateDistribution() is called, one of the following functions is called:
Then the function _updateXDEFIBalance() is called, without doing anything with the result (e.g. not updating _pointsPerUnit). _updateXDEFIBalance() updates distributableXDEFI , so the next time it is called (with no new XDEFI tokens), it will return 0.
So even if you call updateDistribution() now, _pointsPerUnit is still not updated so the internal administration will not be ok.
function updateDistribution() external { uint256 totalUnitsCached = totalUnits; require(totalUnitsCached > uint256(0), "NO_UNIT_SUPPLY"); uint256 newXDEFI = _toUint256Safe(_updateXDEFIBalance()); if (newXDEFI == uint256(0)) return; _pointsPerUnit += ((newXDEFI * _pointsMultiplier) / totalUnitsCached); emit DistributionUpdated(msg.sender, newXDEFI); }
function _updateXDEFIBalance() internal returns (int256 newFundsTokenBalance_) { uint256 previousDistributableXDEFI = distributableXDEFI; uint256 currentDistributableXDEFI = distributableXDEFI = IERC20(XDEFI).balanceOf(address(this)) - totalDepositedXDEFI; // updates distributableXDEFI return _toInt256Safe(currentDistributableXDEFI) - _toInt256Safe(previousDistributableXDEFI); }
function relock(uint256 tokenId_, uint256 lockAmount_, uint256 duration_, address destination_) external noReenter returns (uint256 amountUnlocked_, uint256 newTokenId_) { ... _updateXDEFIBalance(); } function unlock(uint256 tokenId_, address destination_) external noReenter returns (uint256 amountUnlocked_) { ... _updateXDEFIBalance(); } function relockBatch(uint256[] memory tokenIds_, uint256 lockAmount_, uint256 duration_, address destination_) external noReenter returns (uint256 amountUnlocked_, uint256 newTokenId_) { ... _updateXDEFIBalance(); } function unlockBatch(uint256[] memory tokenIds_, address destination_) external noReenter returns (uint256 amountUnlocked_) { ... _updateXDEFIBalance(); }
Replace the instances of _updateXDEFIBalance() with updateDistribution()
#0 - deluca-mike
2022-01-09T06:32:51Z
Technically valid, but this was expected, and we disagree with severity, as explained in the duplicate issue #30.