After attempting (so far unsuccessfully) to implement the UUPS pattern in the Synthetix FuturesMarket contract, this repo was created to help diagnose and solve the issue(s).
-
Extract the contracts relevant to Synthetix FuturesMarket from OpenZeppelin upgradeable contracts.
-
Add the contracts to the Synthetix codebase.
-
Change the compiler version in the OZ contracts from
^0.8.0
to^0.5.16
and go about changing the solidity code in those contracts so the contracts compile and function in the same way before the changes. -
Modify the FuturesMarket.sol contract to use UUPS and not the old/current proxy pattern.
-
Modify the Synthetix test deployment scripts and test cases to interact with the contract via UUPS instead of the old proxy.
-
Ensure that all the pre-existing tests pass.
-
Add a new test to deploy and then immediately upgrade the proxy. Observe that the deploy succeeds but the upgrade fails.
-
Proceed to fix as many issues as possible with the solidity UUPS contracts.
-
A stubborn error was encountered when attempting an upgrade:
Error: VM Exception while processing transaction: reverted with reason string 'Function must be called through active proxy'
-
This test harness was created to help isolate the issue and ensure that no Synthetix contract was actually causing the problems experienced. The modified open-zeppelin contracts from the Synthetix repo were extracted and added to this repo. and some simple UUPS-compatible token contracts (
MyTokenV1
andMyTokenV2
) were created along with a simple test case. -
The contracts were then upgraded to v0.8.0 (changing as little as possible) to get them working again. It was at this point we discovered at that the modification to the this line in the
UUPSUpgradeable
contract causes upgrades to break. This line was changed from:address private immutable __self = address(this);
to
address private __self = address(this);
The cause is that the value for
__self
is always0x0
when read through the proxy. The result is the above error.It actually contains a valid address when the contract is deployed and referenced without a proxy - so we know the code works.
-
Removing the keyword
immutable
causes the upgrade to fail in exactly the same way as with the Synthetix contracts using Solidity0.5.16
.Since the modifier
immutable
isn't available in solidity version0.5.16
, and the upgrade instruction fails without it, it's not immediately clear how we can proceed with the downgraded versions of the0.5.16
UUPS contracts.
This branch contains a downgraded version of the contracts for comparison. v0.8.0 --> v0.5.16
. The test to deploy succeeds but the upgrade fails.