-
Notifications
You must be signed in to change notification settings - Fork 5
/
forwardFactory.sol
85 lines (53 loc) · 2.77 KB
/
forwardFactory.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
pragma solidity ^0.4.12;
/*
--------------------------------------------------------------------------------------
A much more efficient version of the DELEGATECALL forwarder factory can be found here:
https://gist.github.com/izqui/7f904443e6d19c1ab52ec7f5ad46b3a8
--------------------------------------------------------------------------------------
This is factory for generating DELEGATECALL forwarders.
This project is the result of the following reddit thread:
https://www.reddit.com/r/ethereum/comments/6c1jui/delegatecall_forwarders_how_to_save_5098_on/
As well as the following:
https://blog.aragon.one/advanced-solidity-code-deployment-techniques-dc032665f434
https://www.reddit.com/r/ethereum/comments/6ic49q/any_assembly_programmers_willing_to_write_a/
An instance of forwardFactory can be found at 0xba9ef985D5dA61959B88577d2a392C11c8445A7f on the kovan network
forwardFactory abi: [ { "constant": false, "inputs": [ { "name": "addr", "type": "address" } ], "name": "deployForwarder", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "", "type": "address" } ], "name": "codeDeployed", "type": "event" } ]
*/
contract forwardFactory {
bytes fwdrCode = hex"602e600c600039602e6000f3366000600037611000600036600073f00df00df00df00df00df00df00df00df00df00d5af41558576110006000f3";
function deployCode(bytes _code) internal returns (address deployedAddress) {
assembly {
deployedAddress := create(0, add(_code, 0x20), mload(_code))
switch extcodesize(deployedAddress) case 0 { invalid() }
}
_code;
codeDeployed(deployedAddress);
}
function deployForwarder(address addr) public returns(address) {
for (uint i = 0; i < 20; i++) {
fwdrCode[46-i] = byte(uint8(uint(addr) >> (8*i)));
}
return deployCode(fwdrCode);
}
event codeDeployed(address);
}
contract fixedForwardFactory {
bytes fwdrCode = hex"602e600c600039602e6000f3366000600037611000600036600073f00df00df00df00df00df00df00df00df00df00d5af41558576110006000f3";
function deployCode(bytes _code) internal returns (address deployedAddress) {
assembly {
deployedAddress := create(0, add(_code, 0x20), mload(_code))
switch extcodesize(deployedAddress) case 0 { invalid() }
}
_code;
codeDeployed(deployedAddress);
}
function fixedForwardFactory(address addr) public {
for (uint i = 0; i < 20; i++) {
fwdrCode[46-i] = byte(uint8(uint(addr) >> (8*i)));
}
}
function deployForwarder() public returns(address) {
return deployCode(fwdrCode);
}
event codeDeployed(address);
}