bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation.
* @return Address of the current implementation
*/
function _implementation() internal view returns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
impl := sload(slot)
}
}
由此解决了储存冲突。
Proxy
Impl
Note
Slot 0
<- bool var1
Slot 1
<- bool var2
Slot 2
<- uint256 var3
Slot 3
...
Slot Custom
address impl
No collison!
Audius中的情况
There were a customized variable proxyAdmin in its multiple proxy contracts, which caused the Initalized and Initializing variables in Impl that marked the initialization state to conflict with the proxyAdmin storage.
contract AudiusAdminUpgradeabilityProxy is UpgradeabilityProxy {
address private proxyAdmin;
string private constant ERROR_ONLY_ADMIN = (
"AudiusAdminUpgradeabilityProxy: Caller must be current proxy admin"
);
/**
* @notice Sets admin address for future upgrades
* @param _logic - address of underlying logic contract.
* Passed to UpgradeabilityProxy constructor.
* @param _proxyAdmin - address of proxy admin
* Set to governance contract address for all non-governance contracts
* Governance is deployed and upgraded to have own address as admin
* @param _data - data of function to be called on logic contract.
* Passed to UpgradeabilityProxy constructor.
*/
constructor(
address _logic,
address _proxyAdmin,
bytes memory _data
)
UpgradeabilityProxy(_logic, _data) public payable
{
proxyAdmin = _proxyAdmin;
}
//...
}