In RngRelayAuction.sol we have rngComplete():
function rngComplete(
uint256 _randomNumber,
uint256 _rngCompletedAt,
address _rewardRecipient,
uint32 _sequenceId,
AuctionResult calldata _rngAuctionResult
) external returns (bytes32) {
if (_sequenceHasCompleted(_sequenceId)) revert SequenceAlreadyCompleted();
uint64 _auctionElapsedSeconds = uint64(block.timestamp < _rngCompletedAt ? 0 : block.timestamp - _rngCompletedAt);
if (_auctionElapsedSeconds > (_auctionDurationSeconds-1)) revert AuctionExpired();
// Calculate the reward fraction and set the draw auction results
UD2x18 rewardFraction = _fractionalReward(_auctionElapsedSeconds);
_auctionResults.rewardFraction = rewardFraction;
_auctionResults.recipient = _rewardRecipient;
_lastSequenceId = _sequenceId;
AuctionResult[] memory auctionResults = new AuctionResult[](2);
auctionResults[0] = _rngAuctionResult;
auctionResults[1] = AuctionResult({
rewardFraction: rewardFraction,
recipient: _rewardRecipient
});
uint32 drawId = prizePool.closeDraw(_randomNumber);
uint256 futureReserve = prizePool.reserve() + prizePool.reserveForOpenDraw();
uint256[] memory _rewards = RewardLib.rewards(auctionResults, futureReserve);
emit RngSequenceCompleted(
_sequenceId,
drawId,
_rewardRecipient,
_auctionElapsedSeconds,
rewardFraction
);
for (uint8 i = 0; i < _rewards.length; i++) {
uint104 _reward = uint104(_rewards[i]);
if (_reward > 0) {
prizePool.withdrawReserve(auctionResults[i].recipient, _reward);
emit AuctionRewardDistributed(_sequenceId, auctionResults[i].recipient, i, _reward);
}
}
return bytes32(uint(drawId));
}
This function handles the completion of an RNG relay auction. The problem is this block of code:
for (uint8 i = 0; i < _rewards.length; i++) {
uint104 _reward = uint104(_rewards[i]);
if (_reward > 0) {
prizePool.withdrawReserve(auctionResults[i].recipient, _reward);
emit AuctionRewardDistributed(_sequenceId, auctionResults[i].recipient, i, _reward);
}
}
The variable i is declared as a uint8, which means it can only hold values from 0 to 255. If _rewards.length were to be more than 255, the function will revert.
The issue lies in the use of uint8 as the loop iterator, which can only represent values between 0 to 255. If the length of the _rewards array exceeds 255, the loop will revert.
In rngComplete() we see the _rewards is uint256:
157: uint256[] memory _rewards = RewardLib.rewards(auctionResults, futureReserve);
After this in the for loop i is uint8:
for (uint8 i = 0; i < _rewards.length; i++) {
uint104 _reward = uint104(_rewards[i]);
if (_reward > 0) {
prizePool.withdrawReserve(auctionResults[i].recipient, _reward);
emit AuctionRewardDistributed(_sequenceId, auctionResults[i].recipient, i, _reward);
}
}
But _rewards.length can be bigger than uint8. And if so the function will revert.
Visual Studio Code
I recommend changing the data type of the iterator from uint8 to uint256, as these data types can handle a much larger range of values. By making this change, the functions would be able to process any number of rewards.
Loop
The text was updated successfully, but these errors were encountered:
All reactions