In this challenge, you need to call the contract through another contract, but with a twist - the calling contract must have no code at the time of the call!
The contract has a mintFlag() function that:
mintFlag() from within a constructor.
mintFlag() in its constructor:
contract CallHelper {
constructor(Challenge3 challenge3) {
challenge3.mintFlag();
}
}
Then simply deploy this contract with the Challenge3 address as a parameter.
Why this works:
- During constructor execution, the contract's code hasn't been deployed yet
- extcodesize returns 0 during this phase
- The call comes from a contract (satisfying msg.sender != tx.origin)
- The flag gets minted to your address (tx.origin)
Congratulations! You've learned about contract deployment mechanics and a common security pitfall! 🎉
Remember: Just because a contract appears to have no code doesn’t mean it can’t execute code! Always be careful when making assumptions about contract vs EOA interactions.
The extcodesize check has been historically used as a way to determine if an address belongs to a contract, but this assumption can be dangerous:
extcodesize check, airdropping tokens to the attackerThis demonstrates why using extcodesize alone is not a reliable method for determining if a caller is a contract or an EOA (Externally Owned Account).