Relevant Links
Summary
Usually whenever there is a state change within a contract, it is good practice to emit an event. There are multiple places within both the CharityRegistry
and GivingThanks
contracts where a state change occurs, and an event is not present.
Impact
Likelihood: Medium
Severity: Low
While events are not necessary to the internal functionality, if any front-end infrustructure or other smart contracts listening to this platform where to be implemented, event emission would be important.
Tools Used
Recommendations
Please define and add the following events as follows in GivingThank.sol
:
contract GivingThanks is ERC721URIStorage {
CharityRegistry public registry;
uint256 public tokenCounter;
address public owner;
+ event UserDonated(address indexed donor, address indexed charity, uint256 date, uint256 amount);
+ event RegistryUpdated(address owner, address indexed oldRegistry, address indexed newRegistry);
constructor(address _registry) ERC721("DonationReceipt", "DRC") {
registry = CharityRegistry(msg.sender);
owner = msg.sender;
tokenCounter = 0;
}
function donate(address charity) public payable {
require(registry.isVerified(charity), "Charity not verified");
(bool sent,) = charity.call{value: msg.value}("");
require(sent, "Failed to send Ether");
_mint(msg.sender, tokenCounter);
// Create metadata for the tokenURI
string memory uri = _createTokenURI(msg.sender, block.timestamp, msg.value);
_setTokenURI(tokenCounter, uri);
tokenCounter += 1;
+ emit UserDonated(msg.sender, charity, block.timestamp, msg.value);
}
...
function updateRegistry(address _registry) public {
+ CharityRegistry oldRegistry = registry;
registry = CharityRegistry(_registry);
+ emit RegistryUpdated(owner, oldRegistry, _registry);
}
Then define and add the following events as follows in CharityRegistry.sol
:
contract CharityRegistry {
address public admin;
mapping(address => bool) public verifiedCharities;
mapping(address => bool) public registeredCharities;
+ event CharityRegistered(address indexed charity);
+ event CharityVerified(address indexed charity);
+ event AdminChanged(address indexed oldAdmin, address indexed newAdmin);
constructor() {
admin = msg.sender;
}
function registerCharity(address charity) public {
registeredCharities[charity] = true;
+ emit CharityRegistered(charity);
}
function verifyCharity(address charity) public {
require(msg.sender == admin, "Only admin can verify");
require(registeredCharities[charity], "Charity not registered");
verifiedCharities[charity] = true;
+ emit CharityVerified(charity);
}
function isVerified(address charity) public view returns (bool) {
return registeredCharities[charity];
}
function changeAdmin(address newAdmin) public {
require(msg.sender == admin, "Only admin can change admin");
+ address oldAdmin = admin;
admin = newAdmin;
+ emit AdminChanged(oldAdmin, newAdmin);
}