Created
December 20, 2022 20:59
-
-
Save voith/6e70e2483a6f6184342381b923f98e8d to your computer and use it in GitHub Desktop.
Upgradeable Pattern in solidity using OZ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity 0.7.5; | |
import "forge-std/Test.sol"; | |
import "forge-std/console.sol"; | |
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; | |
import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/TransparentUpgradeableProxy.sol"; | |
contract Greeter is Ownable { | |
string greeting; | |
constructor(string memory _greeting) { | |
greeting = _greeting; | |
} | |
function greet() public view returns (string memory) { | |
return greeting; | |
} | |
function setGreeting(string memory _greeting) public virtual onlyOwner { | |
greeting = _greeting; | |
} | |
} | |
contract A { | |
bool isInitialized = false; | |
Greeter public greeter; | |
function initialize(Greeter _greeter) external { | |
require(!isInitialized, 'Contract is already initialized!'); | |
isInitialized = true; | |
greeter = _greeter; | |
} | |
function setMessage() public { | |
greeter.setGreeting("set By A"); | |
} | |
} | |
contract B { | |
bool isInitialized = false; | |
Greeter public greeter; | |
bool isInitialised = false; | |
function initialize(Greeter _greeter) external { | |
require(!isInitialised, 'Contract is already initialized!'); | |
isInitialised = true; | |
greeter = _greeter; | |
} | |
function setMessage() public { | |
greeter.setGreeting("set By B"); | |
} | |
} | |
contract ArbitrumMessages is Test { | |
address user = address(0x1); | |
TransparentUpgradeableProxy proxy; | |
Greeter greeter; | |
A a; | |
B b; | |
function setUp() public { | |
a = new A(); | |
proxy = new TransparentUpgradeableProxy(address(a), address(user), bytes("")); | |
vm.prank(address(proxy)); | |
greeter = new Greeter("Initial"); | |
assertEq(greeter.owner(), address(proxy)); | |
bytes memory data = abi.encodeWithSelector( | |
A.initialize.selector, | |
address(greeter) | |
); | |
vm.prank(user); | |
proxy.upgradeToAndCall(address(a), data); | |
} | |
function testUpgrade() public { | |
bytes memory data; | |
bytes memory message; | |
bool success; | |
string memory msg; | |
data = abi.encodeWithSelector( | |
A.setMessage.selector | |
); | |
console.log(greeter.greet()); | |
(success, message) = address(proxy).call(data); | |
assertEq(success, true); | |
console.log(greeter.greet()); | |
b = new B(); | |
data = abi.encodeWithSelector( | |
B.initialize.selector, | |
address(greeter) | |
); | |
vm.prank(user); | |
proxy.upgradeToAndCall(address(b), data); | |
data = abi.encodeWithSelector( | |
B.setMessage.selector | |
); | |
console.log(greeter.greet()); | |
(success, message) = address(proxy).call(data); | |
assertEq(success, true); | |
console.log(greeter.greet()); | |
} | |
// function testProxy() public { | |
// bytes memory data; | |
// bytes memory message; | |
// bool success; | |
// string memory msg; | |
// | |
// data = abi.encodeWithSelector( | |
// greeter.greet.selector | |
// ); | |
// (success, message) = address(proxy).call(data); | |
// assertEq(success, true); | |
// msg = abi.decode( | |
// message, | |
// (string) | |
// ); | |
// console.log(msg); | |
// | |
// data = abi.encodeWithSelector( | |
// greeter.setGreeting.selector, | |
// "New Message" | |
// ); | |
// (success, ) = address(proxy).call(data); | |
// assertEq(success, true); | |
// | |
// data = abi.encodeWithSelector( | |
// greeter.greet.selector | |
// ); | |
// (success, message) = address(proxy).call(data); | |
// assertEq(success, true); | |
// msg = abi.decode( | |
// message, | |
// (string) | |
// ); | |
// console.log(msg); | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment