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!
mint to create an asset or burn to remove it from existence. Then, using a proof, the other chain would know whether we owned an asset on it or not.increment should occur before the call to _safeMint. This worked as follows:
function mint(address to) public returns (uint256) {
uint256 newWarriorId = tokenIds.current();
_safeMint(to, newWarriorId);
tokenIds.increment();
return newWarriorId;
}
_safeMint() function has an external function call for onERC721Received inside of it. Since the CEI pattern is not followed and the contract is not using the standard library for preventing reentrancy, there is a major problem. _mint function again, it will fail because the token id wasn't incremented and already exists. However, there are other functions within the contract that could be interesting to us.crossChainTransfer() is used to send the assets from one chain to another. Calling this with a particular token ID will send the token from one chain to another.mint() with the attacker contract as the recipient. NOTE: The ID hasn't been incremented.crossChainTransfer to transfer the new id to chain B.mint() again from the recipient contract to mint the same NFT once again.