Skip to content

Instantly share code, notes, and snippets.

@voith
Created December 20, 2022 20:59
Show Gist options
  • Save voith/6e70e2483a6f6184342381b923f98e8d to your computer and use it in GitHub Desktop.
Save voith/6e70e2483a6f6184342381b923f98e8d to your computer and use it in GitHub Desktop.
Upgradeable Pattern in solidity using OZ
// 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