Recently I see a smart contract ( upgradable proxy.sol) in which developer use this :

contract UpgradableProxy is Proxy {
    event ProxyUpdated(address indexed _new, address indexed _old);
    event ProxyOwnerUpdate(address _new, address _old);

    bytes32 constant IMPLEMENTATION_SLOT =
    bytes32 constant OWNER_SLOT = keccak256("HelloWorld.proxy.owner");

    constructor(address _proxyTo) {

Here Developer not perform keccak256(("HelloWorld.proxy.implementation") -1 ), just like in case of Original EIP-1967: Standard Proxy Storage Slots


         bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1))

In My Code


So is this Mandatory in Every time you perform -1 after conversation to Keccak256 ?

Please Clear my Query

Thank You


1 Answer 1


It's an additional security check.

When calculating the value of the slot that will contain the implementation address of the proxy, we are applying a keccak256 function on this "eip1967.proxy.implementation" value. This should work well, but removing 1 after doing the hash makes it impossible to calculate a pre-image of this implementation slot.

From the "Rationale" of the EIP-1967, this is what is written: "Vyper seems to follow the same strategy as Solidity. Note that contracts written in other languages, or directly in assembly, may incur in clashes. They are chosen in such a way so they are guaranteed to not clash with state variables allocated by the compiler, since they depend on the hash of a string that does not start with a storage index. Furthermore, a -1 offset is added so the preimage of the hash cannot be known, further reducing the chances of a possible attack."

Not the answer you're looking for? Browse other questions tagged or ask your own question.