-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathProxies.sol
More file actions
70 lines (58 loc) · 1.66 KB
/
Proxies.sol
File metadata and controls
70 lines (58 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {console} from "hardhat/console.sol";
// We need to define two different proxies so that their implementation
// storage slots are different, so we can chain them.
abstract contract BaseProxy {
fallback() external payable {
address impl = getImplementation();
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
function getImplementation() internal view virtual returns (address);
receive() external payable {}
}
contract Proxy is BaseProxy {
address implementation;
constructor(address _impl) {
// console.log("Setting implementation for Proxy:", _impl);
implementation = _impl;
}
function getImplementation() internal view override returns (address) {
// console.log("Getting implementation for Proxy:", implementation);
return implementation;
}
}
contract Proxy2 is BaseProxy {
address implementation;
address proxy1;
constructor(address _impl, address _proxy1) {
// console.log("Setting implementation for Proxy2:", _impl);
proxy1 = _proxy1;
implementation = _impl;
}
function getImplementation() internal view override returns (address) {
// console.log("Getting implementation for Proxy2:", proxy1);
return proxy1;
}
}
contract Impl1 {
function one() external returns (uint256) {
return 1;
}
}
contract Impl2 {
function two() external returns (uint256) {
return 2;
}
}