Root + Impact
Description:
Expected Behavior:
Every critical state change such as minting, burning, or adjusting limits should emit an event to enhance transparency and support off-chain monitoring.
Actual Behavior:
Functions like burnFaucetTokens() and adjustDailyClaimLimit() modify significant contract states without emitting events when decreasing limits or burning tokens. This makes it harder for frontends or monitoring systems to detect these important state transitions.
function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
@> _transfer(address(this), msg.sender, balanceOf(address(this)));
@> _burn(msg.sender, amountToBurn);
}
function adjustDailyClaimLimit(uint256 by, bool increaseClaimLimit) public onlyOwner {
if (increaseClaimLimit) {
@> dailyClaimLimit += by;
} else {
if (by > dailyClaimLimit) {
revert RaiseBoxFaucet_CurrentClaimLimitIsLessThanBy();
}
@> dailyClaimLimit -= by;
}
}
Risk
Likelihood
Medium:The functions are not called often, but when they are, missing logs can lead to data inconsistencies and audit difficulties.
Impact
1.Reduces transparency and traceability of token supply and configuration changes.
2.Frontend dashboards may display outdated information.
3.Off-chain monitoring systems (e.g., alert bots) won’t know when claim limits or faucet tokens change.
Proof of Concept
Explanation:
This PoC shows that vm.expectEmit() does not detect any events when the functions are called, proving event emissions are missing.
pragma solidity ^0.8.30;
import "forge-std/Test.sol";
import "../src/RaiseBoxFaucet.sol";
contract EventTest is Test {
RaiseBoxFaucet faucet;
function setUp() public {
faucet = new RaiseBoxFaucet("RaiseBox", "RBF", 100 ether, 0.01 ether, 1 ether);
}
function testMissingEvents() public {
vm.expectEmit(false, false, false, false);
faucet.burnFaucetTokens(10 ether);
faucet.adjustDailyClaimLimit(5, true);
}
}
Recommended Mitigation
Explanation
FaucetTokensBurned logs every burn operation, providing visibility into supply reductions.
DailyClaimLimitAdjusted notifies external systems whenever the faucet’s claim rate changes.
This fix follows best-practice observability patterns: every critical change must be auditable through events.
- remove this code
+ add this code
function burnFaucetTokens(uint256 amountToBurn) public onlyOwner {
require(amountToBurn <= balanceOf(address(this)), "Faucet Token Balance: Insufficient");
_transfer(address(this), msg.sender, balanceOf(address(this)));
_burn(msg.sender, amountToBurn);
- // no event emitted
+ emit FaucetTokensBurned(msg.sender, amountToBurn);
}
function adjustDailyClaimLimit(uint256 by, bool increaseClaimLimit) public onlyOwner {
if (increaseClaimLimit) {
dailyClaimLimit += by;
} else {
if (by > dailyClaimLimit) {
revert RaiseBoxFaucet_CurrentClaimLimitIsLessThanBy();
}
dailyClaimLimit -= by;
}
- // missing event notification
+ emit DailyClaimLimitAdjusted(dailyClaimLimit);
}
+event FaucetTokensBurned(address indexed burner, uint256 amount);
+event DailyClaimLimitAdjusted(uint256 newLimit);