Summary
The Solidity contract defines multiple events with unnamed parameters. While functional, this approach can lead to readability issues, tooling incompatibility, and difficulties in off-chain event decoding. Proper naming of parameters in event declarations is essential for clarity and maintaining best practices in Solidity development.
Vulnerability Details
The following events are declared without parameter names:
event NewHost(address indexed);
event NewSignup(address indexed, uint256 indexed, bool indexed);
event GenerousAdditionalContribution(address indexed, uint256 indexed);
event ChangedParticipation(address indexed, bool indexed);
event Refunded(address indexed);
event DeadlineSet(uint256 indexed);
The parameters are correctly marked as indexed
where required, which allows filtering of logs. However, the omission of parameter names introduces the following issues:
ABI Generation: Unnamed parameters are represented as empty strings (""
) in the ABI, reducing its usability for event parsing and debugging.
Readability: Future developers may find it challenging to understand the purpose of each parameter without proper names.
Tooling Compatibility: Some tools, such as off-chain log parsers or SDKs (e.g., ethers.js
), may encounter issues when interacting with unnamed event parameters.
ABI:
[
{
"inputs": [],
"name": "BeyondDeadline",
"type": "error"
},
{
"inputs": [],
"name": "DeadlineAlreadySet",
"type": "error"
},
{
"inputs": [],
"name": "NotHost",
"type": "error"
},
{
"inputs": [],
"name": "NotSupportedToken",
"type": "error"
},
{
"inputs": [],
"name": "OnlyParticipantsCanBeHost",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "",
"type": "address"
},
{
"indexed": true,
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"name": "ChangedParticipation",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "DeadlineSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "GenerousAdditionalContribution",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "NewHost",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"name": "NewSignup",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "Refunded",
"type": "event"
}
]
Impact
While the contract is functional, the lack of descriptive names in event parameters:
Reduces maintainability and readability of the contract.
Makes it harder to decode events using automated tools, impacting off-chain integration.
Risks potential misinterpretation of the contract's intent and structure.
Tools Used
Recommendations
To address the issues, parameter names should be added to all events. For example, update the events as follows:
event NewHost(address indexed _addr);
event NewSignup(address indexed _addr, uint256 indexed _value, bool indexed _status);
event GenerousAdditionalContribution(address indexed _addr, uint256 indexed _amount);
event ChangedParticipation(address indexed _addr, bool indexed _isActive);
event Refunded(address indexed _addr);
event DeadlineSet(uint256 indexed _timestamp);
This update will:
Improve the contract's readability and maintainability.
Ensure compatibility with off-chain tools and SDKs.
Provide clarity for future developers working with the contract.