Hi everyone,
The Openzeppelin's contract UUPSUpgradeable has the following modifier onlyProxy
in order to guarantee that the functions of an implementation contract can't be called directly but throughth a proxy:
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
Since it's declared in the UUPS, I copy the same idea to my Upgradeable contract that follows the Transparent pattern so as I could have the same guarantee. Considering that both Transparent and UUPS follow the Standard Proxy Storage Slots (EIP-1967), it works perfectly.
However, when I tryed to do the same for a Minimal Proxy it does not. My assumption is that the minimal proxies created by @openzeppelin/contracts/proxy/Clones.sol doesn't store the implementation address at the same slot. Is that right?
Is this slot known ahead of time so as we can adapt and create a similar modifier onlyMininalProxy
or it's random or something?
Regards,