I'm looking at the code of some smart contracts and I've seen somewhere where the code is something like...
I've only ever seen this type of snippet in a decompiled contract, rather than a "human coded" one.
msg.sender == storage[0x00]
This part is checking that the address stored in slot 0 of the stack matches the sender of the current transaction. I'd guess that what it's really checking is (probably) msg.sender == owner, where the contract owner was set in the contract's constructor, and set as the first private variable in the contract (i.e. slot 0). (Again, I think what you're looking at is probably a decompiled version.)
From my limited understanding, 0xfffff is always true
In this case, 0xffffffffffffffffffffffffffffffffffffffff is a 20-byte long bitmask.
...& 0xffffffffffffffffffffffffffffffffffffffff
This is a bitwise AND operation (single &), not a logical AND (double &&).
Noting that addresses are also 20 bytes (160 bits) long, this mask allows the address to be type-checked. This effectively coerces whatever you're &ing into a 160-bit integer (which it should be anyway), as the EVM explicitly requires addresses to be 160 bits.
Edit - A bit more detail:
- Order or operations
Considering the two operations, bitwise & has a higher precedence than the equality operator ==, meaning we mask the value and then check it matches the address in slot0. (See the docs.)
- Why we actually need the mask
The EVM word size is 32 bytes (256 bits). But an address is only 20 bytes long, meaning we have to pad the remaining 12 bytes. The other thing to note is that byte types are all left-aligned, meaning the address is stored as the following:
0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF000000000000000000000000
^ 20 bytes ^^ 12 bytes ^
+----------------------------------------++----------------------+
We want to remove the padding. To do this, we use the mask (also of type bytes):
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000
&ing them together gives us:
0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF