Root + Impact
Description
The contract stores IPFS URIs and rarity names as string variables (commonImageUri, rareImageUri, legendaryImageUri) instead of constants. These values are set once in the constructor and never change, wasting gas on deployment and storage. Additionally, _baseURI() is a function that could be a constant.
string private commonImageUri = "ipfs://QmSsYRx3LpDAb1GZQm7zZ1AuHZjfbPkD6J7s9r41xu1mf8";
string private rareImageUri = "ipfs://QmUPjADFGEKmfohdTaNcWhp7VGk26h5jXDA7v3VtTnTLcW";
string private legendaryImageUri = "ipfs://QmYx6GsYAKnNzZ9A6NvEKV9nf1VaDzJrqDR23Y8YSkebLU";
function _baseURI() internal pure returns (string memory) {
return "data:application/json;base64,";
}
Risk
Impact:
Unnecessary gas costs for deployment and storage. Each string storage slot costs 20,000 gas to initialize. The contract wastes approximately 60,000+ gas on deployment for storing immutable strings.
Proof of Concept
Current deployment cost includes storing 3 IPFS strings in storage. With constants, these would be embedded in bytecode, saving significant deployment gas and reducing contract storage size.
Recommended Mitigation
string private constant COMMON_IMAGE_URI = "ipfs://QmSsYRx3LpDAb1GZQm7zZ1AuHZjfbPkD6J7s9r41xu1mf8";
string private constant RARE_IMAGE_URI = "ipfs://QmUPjADFGEKmfohdTaNcWhp7VGk26h5jXDA7v3VtTnTLcW";
string private constant LEGENDARY_IMAGE_URI = "ipfs://QmYx6GsYAKnNzZ9A6NvEKV9nf1VaDzJrqDR23Y8YSkebLU";
string private constant BASE_URI = "data:application/json;base64,";
constructor(uint256 _entranceFee, address _feeAddress, uint256 _raffleDuration) ERC721("Puppy Raffle", "PR") {
rarityToUri[COMMON_RARITY] = COMMON_IMAGE_URI;
rarityToUri[RARE_RARITY] = RARE_IMAGE_URI;
rarityToUri[LEGENDARY_RARITY] = LEGENDARY_IMAGE_URI;
}