Appearance
S1C11: Who Can Call Me?
1. Problem
The contract only allows mintFlag to be called from a specific caller address. You need to deploy a contract at that specific address, then initiate the call from this "permitted" address.
2. Cause
The contract checks whether msg.sender equals a certain precomputed address. This address is determined by deterministic deployment via CREATE2 or CREATE — you need to find the appropriate salt so the deployment address matches the requirement.
3. Solution
- Analyze how the contract computes the permitted caller address
- Use
CREATE2salt grinding to find the right salt - Deploy the attack contract to the permitted address
- Call
mintFlagfrom that contract
solidity
// Grinding salt in Foundry
for (uint256 salt = 0; salt < MAX; salt++) {
address predicted = computeCreate2Address(deployer, salt, initCodeHash);
if (predicted == targetAddress) {
// Found it!
break;
}
}
4. Pitfalls Encountered
Salt Grinding Computation: If the target address constraint is strong, you may need to grind millions or even billions of salts.
5. Why the Pitfall Occurred
CREATE2 address = keccak256(0xff ++ deployer ++ salt ++ keccak256(initCode)). To match a specific address prefix or exact address, it takes 2^n attempts on average (n being the number of constrained bits).
6. How to Resolve
Use Rust or an optimized Solidity script for salt grinding. Foundry's vm.computeCreate2Address can assist with prediction. If the constraint is not strong (e.g., matching only the first few bytes), it can be found in a reasonable time.
7. Technical Takeaways
| Point | Explanation |
|---|---|
| CREATE2 | Deterministic contract deployment, address determined by sender + salt + initCodeHash |
| Salt Grinding | Brute-force searching salt values to obtain a target address |
| Address Constraint | More precise address matching (more bytes) requires more computation |