This is not a walkthrough of every contract or code of the challenge. I am sharing my notes and resources I have used to complete this challenge, as well as some lessons I think are useful to take away after completing the challenge. I highly recommend you finish the challenge yourself first and only use this as additional content.
GameAssetandAssetHolderseem like normal ERC721 and ERC1155 contractsLooking at
AssetWrappercontractswrapfunction we see it immediately calls_wrapwhich mints an ERC1155 token toassetOwnerparameter without any check that it is the owner of the ERC721 token, so anyone can mint the ERC1155.Another major problem is the fact that
_wrapcalls ERC1155s_mintfunction which can be maliciously used via Reentrancy, because the_mintfunction calls an external functiononERC1155Receivedto check that a contract can receive the ERC1155 token.Wrapping tokens into ERC1155 can be dangerous because there are several functions from which we can reenter a contract if there is no
ReentrancyGuardimplementedThe vulnerable ERC1155 functions are
safeTransferFrom(),safeBatchTransferFrom(),_mint()and_mintBatch()(more on this in Resources section).This is because all of these functions implement an external function call to
msg.sendercontract, calling theonERC1155Received()function, from where an attacker can reenter.
The attack contract needs to call
wrapfor the first NFT withassetOwner = address(this)and implementonERC1155Receivedto then again callwrapfor the other NFT with the sameassetOwnerand then callunwrapon both NFTs to trap them in the wrapper contract

