function test_userCanBypassBlockByOwner() public {
address attacker = makeAddr("attacker");
vm.prank(attacker);
soulboundNFT.mintProfile("attacker", 25, "ipfs://profileImage");
assertEq(soulboundNFT.profileToToken(attacker), 1);
vm.prank(owner);
soulboundNFT.blockProfile(attacker);
assertEq(soulboundNFT.profileToToken(attacker), 0);
vm.prank(attacker);
soulboundNFT.mintProfile("attacker", 25, "ipfs://profileImage");
assertEq(soulboundNFT.profileToToken(attacker), 2);
}
Ran 1 test for test/testSoulboundProfileNFT.t.sol:SoulboundProfileNFTTest
[PASS] test_userCanBypassBlockByOwner() (gas: 262671)
Traces:
[333604] SoulboundProfileNFTTest::test_userCanBypassBlockByOwner()
├─ [0] VM::addr(<pk>) [staticcall]
│ └─ ← [Return] attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]
├─ [0] VM::label(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], "attacker")
│ └─ ← [Return]
├─ [0] VM::prank(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e])
│ └─ ← [Return]
├─ [166428] SoulboundProfileNFT::mintProfile("attacker", 25, "ipfs://profileImage")
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 1)
│ ├─ emit ProfileMinted(user: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 1, name: "attacker", age: 25, profileImage: "ipfs://profileImage")
│ └─ ← [Stop]
├─ [630] SoulboundProfileNFT::profileToToken(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]) [staticcall]
│ └─ ← [Return] 1
├─ [0] VM::assertEq(1, 1) [staticcall]
│ └─ ← [Return]
├─ [0] VM::prank(SoulboundProfileNFTTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496])
│ └─ ← [Return]
├─ [10856] SoulboundProfileNFT::blockProfile(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e])
│ ├─ emit Transfer(from: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], to: 0x0000000000000000000000000000000000000000, tokenId: 1)
│ ├─ emit ProfileBurned(user: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 1)
│ └─ ← [Stop]
├─ [630] SoulboundProfileNFT::profileToToken(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]) [staticcall]
│ └─ ← [Return] 0
├─ [0] VM::assertEq(0, 0) [staticcall]
│ └─ ← [Return]
├─ [0] VM::prank(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e])
│ └─ ← [Return]
├─ [138028] SoulboundProfileNFT::mintProfile("attacker", 25, "ipfs://profileImage")
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 2)
│ ├─ emit ProfileMinted(user: attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e], tokenId: 2, name: "attacker", age: 25, profileImage: "ipfs://profileImage")
│ └─ ← [Stop]
├─ [630] SoulboundProfileNFT::profileToToken(attacker: [0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e]) [staticcall]
│ └─ ← [Return] 2
├─ [0] VM::assertEq(2, 2) [staticcall]
│ └─ ← [Return]
└─ ← [Stop]
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 710.41µs (294.71µs CPU
mapping(address => bool) public isBlocked;
function mintProfile(string memory name, uint8 age, string memory profileImage) external {
require(!isBlocked[msg.sender], "You are blocked");
...
}
function blockProfile(address blockAddress) external onlyOwner {
...
isBlocked[blockAddress] = true;
emit ProfileBurned(blockAddress, tokenId);
}