AirDropper

AI First Flight #5
Beginner FriendlyDeFiFoundry
EXP
View results
Submission Details
Impact: low
Likelihood: high
Invalid

Hardcoded Deployment Parameters Are Mutable Storage Instead of Constants

Hardcoded Deployment Parameters Are Mutable Storage Instead of Constants

Description

In script/Deploy.s.sol, the deployment configuration is hardcoded as state variables:

address public s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
bytes32 public s_merkleRoot = 0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;
uint256 public s_amountToAirdrop = 4 * (25 * 1e6);

These values are never updated and are only used as fixed deployment parameters.

Keeping immutable configuration as mutable storage is unnecessary and reduces clarity. It also weakens intent signaling: readers cannot immediately distinguish truly fixed constants from values that may be changed in future script flows.

Additionally, run() uses a second hardcoded USDC literal in transfer(...) instead of reusing s_zkSyncUSDC, which introduces avoidable duplication.


Risk

Likelihood: High

This is definitely present in the codebase and always affects maintainability/readability of the deployment script.

Impact: Low

The issue does not directly create an exploitable on-chain vulnerability in the deployed MerkleAirdrop contract. The impact is limited to code quality, maintainability, and configuration hygiene.


Proof of Concept

The variable declarations in Deploy.s.sol are storage-backed and non-constant:

rg -n "s_zkSyncUSDC|s_merkleRoot|s_amountToAirdrop" script/Deploy.s.sol

Output:

8: address public s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
9: bytes32 public s_merkleRoot = 0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;
11: uint256 public s_amountToAirdrop = 4 * (25 * 1e6);
16: MerkleAirdrop airdrop = deployMerkleDropper(s_merkleRoot, IERC20(s_zkSyncUSDC));
18: IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);

Thus, fixed deployment values are currently stored as mutable state variables, and the token address is duplicated in two different literals/usages.


Recommended Mitigation

Declare fixed deployment parameters as constant and reuse them consistently.

contract Deploy is Script {
- address public s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
- bytes32 public s_merkleRoot = 0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;
+ address public constant ZKSYNC_USDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
+ bytes32 public constant MERKLE_ROOT = 0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;
// 4 users, 25 USDC each
- uint256 public s_amountToAirdrop = 4 * (25 * 1e6);
+ uint256 public constant AMOUNT_TO_AIRDROP = 4 * (25 * 1e6);
function run() public {
vm.startBroadcast();
- MerkleAirdrop airdrop = deployMerkleDropper(s_merkleRoot, IERC20(s_zkSyncUSDC));
+ MerkleAirdrop airdrop = deployMerkleDropper(MERKLE_ROOT, IERC20(ZKSYNC_USDC));
// Send USDC -> Merkle Air Dropper
- IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
+ IERC20(ZKSYNC_USDC).transfer(address(airdrop), AMOUNT_TO_AIRDROP);
vm.stopBroadcast();
}
}

This improves readability, removes duplicate literals, and makes deployment intent explicit.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 7 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!