People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
0x01 and B being 0x0101. If we concatenate A + B together, we end up with 0x010101. However, the signed data would be the same if A was 0x0101 and B was 0x01! This violates Horton's Principle mentioned above. In the context of the smart contract, this means we can change the parameter that the bytes were signed for!calldata field to allow a callback with specific parameters. In some cases, the calldata must be mutated at the time of fulfillment. This can be done by a replacementPattern - a bitmask to alter the calldata. This is necessary for OpenSea, the address of the offer taker must be added to the calldata. calldata, the first 4 bytes are the function selector. In the context of OpenSea, we need to call transferFrom(address,address,uint256). Using the modification primitive from above, an attacker could shift bits between the callData and replacementPattern to modify the function selector! The closest selector is getApproved(uint) at only 10 bits of difference.getApproved(0) primitive, an attacker could have taken WETH from these users, despite them never approving or still owning the NFT.