When using delegate call I was under the impression that storage slots declared in the proxy will be overwritten by the implementation.

Unstructured storage implementations declare bytes32 variables that indicate the storage position within the proxy to find owners, implementations etc.

Why aren't these bytes32 variables being overwritten when a transaction is delegated to the implementing contract? The examples of implementing contracts don't seem to take into account these variables already declared.

contract OwnedUpgradeabilityProxy is Proxy {
 bytes32 private constant ownerPosition = keccak256("org.zeppelinos.proxy.owner");
 bytes32 private constant implementationPosition = keccak256("org.zeppelinos.proxy.implementation");

 function upgradeTo(address newImplementation) public onlyProxyOwner {
   address currentImplementation = implementation();

 function implementation() public view returns (address impl) {
   bytes32 position = implementationPosition;
   assembly { impl := sload(position) }

The variables are declared constant which means they are hard-coded into the bytecode. As such, they don't occupy storage slots.

The computed hashes are easily reproducible in implementation contracts given that the data to hash is known. The computed hashes amount to pseudo-random storage locations that are unlikely to be overwritten by implementation contracts.

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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