Skip to content

Instantly share code, notes, and snippets.

@devtooligan
Created October 11, 2022 19:19
Show Gist options
  • Save devtooligan/039659a2f76612afb0fa1e8bef278b7f to your computer and use it in GitHub Desktop.
Save devtooligan/039659a2f76612afb0fa1e8bef278b7f to your computer and use it in GitHub Desktop.
// 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