| title |
Sandbox Public Burn |
| description |
Destroying anyone's NFTs through flawed burn logic |
| type |
Exploit |
| network |
|
| date |
2022-02-08 |
| returned_usd |
0 |
| tags |
|
| subcategory |
|
| vulnerable_contracts |
0x50f5474724e0Ee42D9a4e711ccFB275809Fd6d4a |
|
| tokens_lost |
|
| attacker_addresses |
0x6FB0B915D0e10c3B2ae42a5DD879c3D995377A2C |
|
| malicious_token |
|
| attack_block |
|
| reproduction_command |
forge test --match-contract Exploit_SandBox -vvv |
| attack_txs |
0x34516ee081c221d8576939f68aee71e002dd5557180d45194209d6692241f7b1 |
|
| sources |
|
- Find a player you don't like
- Call
_burn with (enemyAddress, enemyAddress, id)
- You have destroyed your enemy NFT
The Sandbox Land contract has a _burn method that destroys an NFT.
function _burn(address from, address owner, uint256 id) public {
require(from == owner, "not owner");
_owners[id] = 2**160; // cannot mint it again
_numNFTPerAddress[from]--;
emit Transfer(from, address(0), id);
}
The method apparently intends to authenticate the burn, but does so using
parameters to the function instead of msg.sender. This leads to the attack being
quite trivial: the attacker just sends from == owner.
- Use
msg.sender instead of the function parameter from
- Rikkei Oracle Replace - Unprotected public function allows critical state changes
- MBC Token - Public function that should have been restricted
- Bad Guys NFT - Insufficient input validation on user-supplied parameters