Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: low
Likelihood: medium
Invalid

missing-zero-check

Root + Impact

Description

  • When a function accepts an address argument that is meant to represent a valid user, contract, or owner, it is a crucial security and robustness best practice to include a check to ensure that the provided address is not the zero address (address(0x0)).

  • Several functions across FestivalPass.sol, BeatToken.sol, and inherited OpenZeppelin contracts lack these essential zero-address checks. This omission can lead to serious issues such as accidental loss of administrative control, permanent freezing of funds, or rendering core contract functionalities unusable if a critical address is inadvertently or maliciously set to address(0).

SLITHER OUTPUT:

## missing-zero-check Impact: Low
Confidence: Medium - [ ] ID-8
[FestivalPass.setOrganizer(address)._organizer](src/FestivalPass.sol#L50) lacks a zero-check on :
- [organizer = _organizer](src/FestivalPass.sol#L51)
src/FestivalPass.sol#L50
- [ ] ID-9
[Ownable2Step.transferOwnership(address).newOwner](lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol#L43) lacks a zero-check on :
- [_pendingOwner = newOwner](lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol#L44)
lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol#L43
- [ ] ID-10 [FestivalPass.withdraw(address).target](src/FestivalPass.sol#L147) lacks a zero-check on : - [address(target).transfer(address(this).balance)](src/FestivalPass.sol#L148)
src/FestivalPass.sol#L147
- [ ] ID-11 [BeatToken.setFestivalContract(address)._festival](src/BeatToken.sol#L13) lacks a zero-check on :
- [festivalContract = _festival](src/BeatToken.sol#L15)
src/BeatToken.sol#L13
- [ ] ID-12
[FestivalPass.constructor(address,address)._beatToken](src/FestivalPass.sol#L45) lacks a zero-check on :
- [beatToken = _beatToken](src/FestivalPass.sol#L47)
src/FestivalPass.sol#L45
// Root cause in the codebase with @> marks to highlight the relevant section
// ID-8: FestivalPass.setOrganizer(address)._organizer
src/FestivalPass.sol#L50
function setOrganizer(address _organizer) public onlyOwner {
organizer = _organizer; // @> Missing zero-address check for _organizer
}
// ID-9: Ownable2Step.transferOwnership(address).newOwner
lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol#L43
function transferOwnership(address newOwner) public virtual override onlyOwner {
_transferOwnership(newOwner); // @> Missing zero-address check for newOwner
}
// ID-10: FestivalPass.withdraw(address).target
src/FestivalPass.sol#L147
function withdraw(address target) public onlyOwner {
address(target).transfer(address(this).balance); // @> Missing zero-address check for target
}
// ID-11: BeatToken.setFestivalContract(address)._festival
src/BeatToken.sol#L13
function setFestivalContract(address _festival) external onlyOwner {
festivalContract = _festival; // @> Missing zero-address check for _festival
}
// ID-12: FestivalPass.constructor(address,address)._beatToken
src/FestivalPass.sol#L45
constructor(
address _owner,
address _beatToken // @> Missing zero-address check for _beatToken
) ERC1155("") Ownable2Step(_owner) {
beatToken = _beatToken;
}

Risk

Likelihood:

  • This will occur if a user or administrator mistakenly provides address(0) as an input to any of the affected functions.

  • This will occur if an attacker intentionally passes address(0) in an attempt to disable functionality or gain control (e.g., setting owner to zero address).

Impact:

  • Loss of Control: Setting administrative roles (like owner or organizer) to address(0) effectively renders the contract unmanageable, as the zero address cannot initiate transactions.

  • Irrecoverable Funds: Sending funds to address(0) (as in the withdraw function) means the funds are permanently lost and unrecoverable.

  • Broken Functionality: If critical contract dependencies (like beatToken or festivalContract) are set to address(0), functions relying on these addresses will likely revert or behave unexpectedly.

  • Deployment Errors: If crucial constructor parameters are address(0), the contract might be deployed in an unusable or compromised state.

Proof of Concept

// Example PoC for missing-zero-check in setOrganizer
// (Illustrative - actual PoC would involve deploying and calling functions)
// Scenario: A legitimate owner accidentally or maliciously calls setOrganizer(address(0)).
// FestivalPass.setOrganizer(address(0));
// Result: The `organizer` state variable becomes `address(0)`.
// Any subsequent calls to functions protected by `onlyOrganizer` or similar checks
// that rely on a valid `organizer` address would fail or become impossible to execute,
// leading to a denial of service for administrative operations.

Recommended Mitigation

- remove this code
+ add this code
--- a/src/FestivalPass.sol
+++ b/src/FestivalPass.sol
@@ -49,5 +49,6 @@
function setOrganizer(address _organizer) public onlyOwner {
+ require(_organizer != address(0), "Organizer cannot be the zero address"); // @> Add zero-address check
organizer = _organizer;
emit OrganizerChanged(oldOrganizer, _organizer);
}
@@ -146,5 +147,6 @@
function withdraw(address target) public onlyOwner {
+ require(target != address(0), "Withdraw target cannot be the zero address"); // @> Add zero-address check
address(target).transfer(address(this).balance);
}
@@ -44,5 +45,6 @@
address _beatToken
) ERC1155("") Ownable2Step(_owner) {
+ require(_beatToken != address(0), "Beat token address cannot be zero"); // @> Add zero-address check
beatToken = _beatToken;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 25 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Zero address check

Owner/admin is trusted / Zero address check - Informational

Appeal created

deadmanxxxii Submitter
24 days ago
inallhonesty Lead Judge
24 days ago
inallhonesty Lead Judge 22 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Zero address check

Owner/admin is trusted / Zero address check - Informational

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.