I'm having an issue with a simple storage example through a proxy. I've been using Remix's browser IDE.
Here's what I've done.
- Create two contracts, one is Proxy.sol other is Main.sol.
- Deploy Main.sol
- Deploy Proxy.sol with argument Main.sol address.
- In Remix, now re-deploy Main.sol At Address of proxy (Which I believe is just a way to implement a given contract at the specified address, in this case for convenience sake).
- Now transact setAppStorage(x) where x is some uint256 value
- Now transact getAppStorage() to retrieve the stored value.
I'm expecting to retrieve the stored value x, but instead I'm receiving a zero-storage slot.
In Remix's debugger I see x is stored at the zeroth address slot, but I'm not familiar enough with assembly to see where that breakdown occurs in retrieving that value from storage.
Main.sol
pragma solidity ^0.8.0;
contract Main {
uint256 internal s;
function initializer() public {
}
function setAppStorage(uint256 a) public {
s = a;
}
function getAppStorage() public returns(uint256 a) {
return s;
}
}
Proxy.sol
pragma solidity ^0.8.0;
contract Proxy {
// Code position in storage is keccak256("PROXIABLE") = "0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7"
constructor(address contractLogic) public {
// save the code address
assembly { // solium-disable-line
sstore(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7, contractLogic)
}
}
fallback() external payable {
assembly { // solium-disable-line
let contractLogic := sload(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7)
calldatacopy(0x0, 0x0, calldatasize())
let success := delegatecall(sub(gas(), 10000), contractLogic, 0x0, calldatasize(), 0, 0)
let retSz := returndatasize()
returndatacopy(0, 0, retSz)
switch success
case 0 {
revert(0, retSz)
}
default {
return(0, retSz)
}
}
}
}
Any help with this problem would be greatly appreciated.