Created
October 11, 2022 19:19
-
-
Save devtooligan/039659a2f76612afb0fa1e8bef278b7f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.17; | |
import "forge-std/Test.sol"; | |
contract TestDeleteMappingInStruct is Test { | |
/// @param enabled Whether the token is enabled or not | |
/// @param balances Mapping of user address to balance | |
struct Token { | |
bool enabled; | |
mapping(address => uint256) balances; | |
} | |
/// @notice Mapping of token address to Token struct | |
mapping(address => Token) public tokens; // slot8 | |
function testDeleteMappingInStruct() external { | |
// enable the B0FFED token | |
address tkn = address(0xB0FFED); | |
tokens[tkn].enabled = true; | |
// set the balance of BADBABE to 1 milly | |
address badBabe = address(0xBADBABE); | |
uint balanceBB = 1_000_000; | |
tokens[tkn].balances[badBabe] = balanceBB; | |
// calc storage slot location addresses | |
bytes32 tokensTkn = keccak256(abi.encode(tkn, 8)); // tokens[tkn] we know slot is 8 from forge inspect | |
bytes32 tokensTknBalances = bytes32(uint256(tokensTkn) + 1); // tokens[tkn].balances | |
bytes32 tokensTknBalancesBadBabe = keccak256(abi.encode(badBabe, tokensTknBalances)); // tokens[tkn].balances[badBabe] | |
// confirm storage slot value | |
uint badBabeStoredBalance; | |
assembly { | |
badBabeStoredBalance := sload(tokensTknBalancesBadBabe) | |
} | |
assertEq(badBabeStoredBalance, balanceBB); | |
// let's delete the token, this should change `enabled` to false and delete the `balances`, right? | |
// what could go wrong? | |
delete tokens[tkn]; | |
// confirm token is not enabled | |
assertFalse(tokens[tkn].enabled); // yay! | |
// so token deleted, and we confirmed it's not enabled, but what about the balances mapping? | |
assembly { | |
badBabeStoredBalance := sload(tokensTknBalancesBadBabe) | |
} | |
assertEq(badBabeStoredBalance, balanceBB); //holy shit it's still there 😱😱😱 | |
// so let's say later we later "re-activate" the token | |
tokens[tkn].enabled = true; | |
// badBabe (and everyone else) still has her balance | |
assertEq(tokens[tkn].balances[badBabe], 1_000_000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment