In this challenge, you need to find a contract address whose last byte, when masked, matches your address’s last byte. It combines both proxy calling and bit manipulation!
The contract requires:
msg.sender != tx.origin)0x15, must match0x15 in binary is 00010101 - it only looks at specific bits
CREATE2 opcode?
The address it will deploy to is calculated as the last 20 bytes of:
```
keccak256(0xff ++ address ++ salt ++ keccak256(init_code))
```
Where:
- `0xff` is a constant **byte**
- `address` is the address of the contract deploying the new contract
- `salt` is a **uint256** that can be manipulated to get the desired address
- `init_code` is the bytecode of the contract being deployed
contract CallChallenge11 {
function callChallenge11(Challenge11 challenge11) public {
challenge11.mintFlag();
}
}
2. Get the contract's creation code and its hash:
// Get the bytecode of our contract
bytes memory callerBytecode = type(CallChallenge11).creationCode;
// Calculate the hash of the bytecode
bytes32 bytecodeHash = keccak256(callerBytecode);
3. Calculate potential addresses until we find a match:
uint256 salt = 0;
while (true) {
// Calculate the address where the contract would be deployed
bytes32 deployedAddressBytes = keccak256(
abi.encodePacked(
bytes1(0xff), // CREATE2 prefix
PLAYER, // deploying address
salt, // current salt
bytecodeHash // bytecode hash
)
);
address deployedAddress = address(uint160(uint256(deployedAddressBytes)));
// Check if the last bytes match when masked
uint8 senderLast = uint8(abi.encodePacked(deployedAddress)[19]);
uint8 originLast = uint8(abi.encodePacked(PLAYER)[19]);
if ((senderLast & 0x15) == (originLast & 0x15)) {
break;
}
salt++;
}
4. Deploy the contract using the found salt:
address addr;
assembly {
addr := create2(
0, // value to send
add(callerBytecode, 0x20), // actual bytecode
mload(callerBytecode), // length of bytecode
salt // our calculated salt
)
}
// Verify the address matches our calculation
assert(addr == deployedAddress);
5. Finally, call the challenge through our deployed contract:
CallChallenge11(addr).callChallenge11(challenge11);
Congratulations! You've mastered CREATE2 and bit manipulation! 🎉
Remember: CREATE2 is a powerful tool for deterministic contract deployment!