From 4c749e879d579487af24967db2c5dbcd89e86d87 Mon Sep 17 00:00:00 2001 From: 8ball030 <8baller@station.codes> Date: Mon, 14 Jul 2025 21:03:35 +0100 Subject: [PATCH 1/3] audit:feedback-3 --- src/DerolasAuction.sol | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/DerolasAuction.sol b/src/DerolasAuction.sol index a02bac2..38a4115 100644 --- a/src/DerolasAuction.sol +++ b/src/DerolasAuction.sol @@ -307,8 +307,10 @@ contract DerolasAuction { uint256 curRound = currentRound; require(msg.value >= roundPoints[curRound].minDonation, "Donation amount is less than the minimum donation"); + uint256 allocatedRewards = this.getAllocatedIncentives(); require( - IToken(incentiveTokenAddress).balanceOf(address(this)) >= roundPoints[curRound].availableRewards, + IToken(incentiveTokenAddress).balanceOf(address(this)) + >= roundPoints[curRound].availableRewards + allocatedRewards, "Not enough rewards to play the game" ); @@ -417,11 +419,33 @@ contract DerolasAuction { /// @dev withdraws the incentive token balance. /// @notice This function allows the owner to withdraw the incentive token balance from the contract. function withdrawIncentiveTokenBalance() external { + if (_locked != 1) { + revert("ReentrancyGuard"); + } + _locked = 2; + // check what is promised to participants in the current round and the claim round + uint256 allocatedRewards = this.getAllocatedIncentives(); + require(msg.sender == owner, "Unauthorized account"); - uint256 incentiveBalance = IToken(incentiveTokenAddress).balanceOf(address(this)); + uint256 incentiveBalance = IToken(incentiveTokenAddress).balanceOf(address(this)) - allocatedRewards; require(incentiveBalance > 0, "No incentive token balance to withdraw"); SafeTransferLib.safeTransfer(incentiveTokenAddress, owner, incentiveBalance); emit TopUpIncentiveWithdrawn(incentiveBalance); + _locked = 1; + } + + /// @dev gets allocated Incentives + /// @return allocatedRewards Allocated rewards. + function getAllocatedIncentives() external view returns (uint256 allocatedRewards) { + uint256 curRound = currentRound; + uint256 claimRound = curRound - 1; + + if (roundPoints[claimRound].totalDonated > 0) { + allocatedRewards += roundPoints[claimRound].availableRewards; + } + if (roundPoints[curRound].totalDonated > 0) { + allocatedRewards += roundPoints[curRound].availableRewards; + } } /// @dev Gets service multisig nonces. From 8f0bc1bce09f46779f5065d0cd0189024adeaba4 Mon Sep 17 00:00:00 2001 From: 8ball030 <8baller@station.codes> Date: Fri, 18 Jul 2025 16:28:13 +0100 Subject: [PATCH 2/3] feat:improve-errors --- src/DerolasAuction.sol | 8 ++++---- test/DerolasAuction.t.sol | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/DerolasAuction.sol b/src/DerolasAuction.sol index 38a4115..b3409ca 100644 --- a/src/DerolasAuction.sol +++ b/src/DerolasAuction.sol @@ -8,6 +8,8 @@ import {IBalancerVaultAdmin} from "./interfaces/IBalancerVaultAdmin.sol"; import {SafeTransferLib} from "./libraries/SafeTransferLib.sol"; +error NoAvailableIncentiveBalance(); + /// @dev Round point struct. /// @notice Stores information about a specific round struct RoundPoint { @@ -419,16 +421,14 @@ contract DerolasAuction { /// @dev withdraws the incentive token balance. /// @notice This function allows the owner to withdraw the incentive token balance from the contract. function withdrawIncentiveTokenBalance() external { - if (_locked != 1) { - revert("ReentrancyGuard"); - } + require(_locked == 1, "ReentrancyGuard"); _locked = 2; // check what is promised to participants in the current round and the claim round uint256 allocatedRewards = this.getAllocatedIncentives(); require(msg.sender == owner, "Unauthorized account"); uint256 incentiveBalance = IToken(incentiveTokenAddress).balanceOf(address(this)) - allocatedRewards; - require(incentiveBalance > 0, "No incentive token balance to withdraw"); + if (incentiveBalance == 0) revert NoAvailableIncentiveBalance(); SafeTransferLib.safeTransfer(incentiveTokenAddress, owner, incentiveBalance); emit TopUpIncentiveWithdrawn(incentiveBalance); _locked = 1; diff --git a/test/DerolasAuction.t.sol b/test/DerolasAuction.t.sol index ff0f8af..b2d243c 100644 --- a/test/DerolasAuction.t.sol +++ b/test/DerolasAuction.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.30; import {Test} from "lib/forge-std/src/Test.sol"; -import {DerolasAuction, GameState} from "src/DerolasAuction.sol"; +import {DerolasAuction, GameState, NoAvailableIncentiveBalance} from "src/DerolasAuction.sol"; import {IToken} from "src/interfaces/IToken.sol"; import {IBalancerVaultAdmin} from "src/interfaces/IBalancerVaultAdmin.sol"; @@ -321,7 +321,7 @@ contract TestDerolasAuctionContract is Test { function testCanWithdrawIncentiveBalance() public { // Check that the owner can withdraw incentives - vm.expectRevert("No incentive token balance to withdraw"); + vm.expectRevert(NoAvailableIncentiveBalance.selector); c.withdrawIncentiveTokenBalance(); this.testTopupIncentivesBalance(); // Ensure incentives are topped up From dc4eecf90bf773e8cba17f56e799d05a23d878f8 Mon Sep 17 00:00:00 2001 From: 8ball030 <8baller@station.codes> Date: Fri, 18 Jul 2025 16:52:28 +0100 Subject: [PATCH 3/3] refactor:confusing-maths --- src/DerolasAuction.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DerolasAuction.sol b/src/DerolasAuction.sol index b3409ca..abfef66 100644 --- a/src/DerolasAuction.sol +++ b/src/DerolasAuction.sol @@ -277,9 +277,11 @@ contract DerolasAuction { } // Calculate rewards - uint256 amount = (donation * roundPoints[claimRound].availableRewards) / totalRoundDonations; + uint256 claimedAmount = roundToClaimed[claimRound][account]; - return amount - claimedAmount; + if (claimedAmount > 0) return 0; // Already claimed + uint256 amount = (donation * roundPoints[claimRound].availableRewards) / totalRoundDonations; + return amount; } /// @dev Estimates ticket percentage.