-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathProxy_Delegate.sol
71 lines (59 loc) · 1.81 KB
/
Proxy_Delegate.sol
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
71
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Proxy {
address public implementation;
function setImplementation(address _imp) external {
implementation = _imp;
}
function _delegate(address _imp) internal virtual {
assembly {
// calldatacopy(t, f, s)
// copy s bytes from calldata at position f to mem at position t
calldatacopy(0, 0, calldatasize())
// delegatecall(g, a, in, insize, out, outsize)
// - call contract at address a
// - with input mem[in…(in+insize))
// - providing g gas
// - and output area mem[out…(out+outsize))
// - returning 0 on error and 1 on success
let result := delegatecall(gas(), _imp, 0, calldatasize(), 0, 0)
// returndatacopy(t, f, s)
// copy s bytes from returndata at position f to mem at position t
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
// revert(p, s)
// end execution, revert state changes, return data mem[p…(p+s))
revert(0, returndatasize())
}
default {
// return(p, s)
// end execution, return data mem[p…(p+s))
return(0, returndatasize())
}
}
}
fallback() external payable {
_delegate(implementation);
}
receive() external payable {
_delegate(implementation);
}
}
contract V1 {
address public implementation;
uint public x;
function inc() external {
x += 1;
}
}
contract V2 {
address public implementation;
uint public x;
function inc() external {
x += 1;
}
function dec() external {
x -= 1;
}
}