Skip to content

Commit e77777a

Browse files
committed
chore: add Bundler deploy script
1 parent ee445c6 commit e77777a

File tree

2 files changed

+360
-0
lines changed

2 files changed

+360
-0
lines changed

script/UpgradeBundler.s.sol

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity 0.8.21;
3+
4+
import {Test} from "forge-std/Test.sol";
5+
import {StorageRegistry} from "../src/StorageRegistry.sol";
6+
import {IdRegistry} from "../src/IdRegistry.sol";
7+
import {IdGateway} from "../src/IdGateway.sol";
8+
import {KeyRegistry, IKeyRegistry} from "../src/KeyRegistry.sol";
9+
import {KeyGateway} from "../src/KeyGateway.sol";
10+
import {SignedKeyRequestValidator} from "../src/validators/SignedKeyRequestValidator.sol";
11+
import {Bundler, IBundler} from "../src/Bundler.sol";
12+
import {RecoveryProxy} from "../src/RecoveryProxy.sol";
13+
import {console, ImmutableCreate2Deployer} from "./abstract/ImmutableCreate2Deployer.sol";
14+
15+
contract UpgradeBundler is ImmutableCreate2Deployer, Test {
16+
struct Salts {
17+
bytes32 bundler;
18+
}
19+
20+
struct DeploymentParams {
21+
Salts salts;
22+
}
23+
24+
struct Addresses {
25+
address storageRegistry;
26+
address idRegistry;
27+
address idGateway;
28+
address keyRegistry;
29+
address keyGateway;
30+
address signedKeyRequestValidator;
31+
address bundler;
32+
address recoveryProxy;
33+
}
34+
35+
struct Contracts {
36+
StorageRegistry storageRegistry;
37+
IdRegistry idRegistry;
38+
IdGateway idGateway;
39+
KeyRegistry keyRegistry;
40+
KeyGateway keyGateway;
41+
SignedKeyRequestValidator signedKeyRequestValidator;
42+
Bundler bundler;
43+
RecoveryProxy recoveryProxy;
44+
}
45+
46+
function run() public {
47+
runSetup(runDeploy(loadDeploymentParams()));
48+
}
49+
50+
function runDeploy(
51+
DeploymentParams memory params
52+
) public returns (Contracts memory) {
53+
return runDeploy(params, true);
54+
}
55+
56+
function runDeploy(DeploymentParams memory params, bool broadcast) public returns (Contracts memory) {
57+
Addresses memory addrs;
58+
59+
// No changes
60+
addrs.storageRegistry = address(0x00000000fcCe7f938e7aE6D3c335bD6a1a7c593D);
61+
addrs.idRegistry = address(0x00000000Fc6c5F01Fc30151999387Bb99A9f489b);
62+
addrs.idGateway = payable(address(0x00000000Fc25870C6eD6b6c7E41Fb078b7656f69));
63+
addrs.keyRegistry = address(0x00000000Fc1237824fb747aBDE0FF18990E59b7e);
64+
addrs.keyGateway = address(0x00000000fC56947c7E7183f8Ca4B62398CaAdf0B);
65+
addrs.signedKeyRequestValidator = address(0x00000000FC700472606ED4fA22623Acf62c60553);
66+
addrs.recoveryProxy = address(0x00000000FcB080a4D6c39a9354dA9EB9bC104cd7);
67+
68+
// Deploy new Bundler
69+
addrs.bundler = register(
70+
"Bundler", params.salts.bundler, type(Bundler).creationCode, abi.encode(addrs.idGateway, addrs.keyGateway)
71+
);
72+
deploy(broadcast);
73+
74+
return Contracts({
75+
storageRegistry: StorageRegistry(addrs.storageRegistry),
76+
idRegistry: IdRegistry(addrs.idRegistry),
77+
idGateway: IdGateway(payable(addrs.idGateway)),
78+
keyRegistry: KeyRegistry(addrs.keyRegistry),
79+
keyGateway: KeyGateway(payable(addrs.keyGateway)),
80+
signedKeyRequestValidator: SignedKeyRequestValidator(addrs.signedKeyRequestValidator),
81+
bundler: Bundler(payable(addrs.bundler)),
82+
recoveryProxy: RecoveryProxy(addrs.recoveryProxy)
83+
});
84+
}
85+
86+
function runSetup(Contracts memory contracts, DeploymentParams memory, bool) public {
87+
if (deploymentChanged()) {
88+
console.log("Running setup");
89+
90+
// Check bundler deploy parameters
91+
assertEq(address(contracts.bundler.idGateway()), address(contracts.idGateway));
92+
assertEq(address(contracts.bundler.keyGateway()), address(contracts.keyGateway));
93+
} else {
94+
console.log("No changes, skipping setup");
95+
}
96+
}
97+
98+
function runSetup(
99+
Contracts memory contracts
100+
) public {
101+
DeploymentParams memory params = loadDeploymentParams();
102+
runSetup(contracts, params, true);
103+
}
104+
105+
function loadDeploymentParams() internal returns (DeploymentParams memory) {
106+
return DeploymentParams({salts: Salts({bundler: vm.envOr("BUNDLER_CREATE2_SALT", bytes32(0))})});
107+
}
108+
}

test/Deploy/UpgradeBundler.t.sol

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity 0.8.21;
3+
4+
import "forge-std/console.sol";
5+
import {
6+
UpgradeBundler,
7+
StorageRegistry,
8+
IdRegistry,
9+
IdGateway,
10+
KeyRegistry,
11+
IKeyRegistry,
12+
KeyGateway,
13+
SignedKeyRequestValidator,
14+
Bundler,
15+
RecoveryProxy,
16+
IBundler
17+
} from "../../script/UpgradeBundler.s.sol";
18+
19+
/* solhint-disable state-visibility */
20+
21+
contract UpgradeBundlerTest is UpgradeBundler {
22+
StorageRegistry internal storageRegistry;
23+
IdRegistry internal idRegistry;
24+
IdGateway internal idGateway;
25+
KeyRegistry internal keyRegistry;
26+
KeyGateway internal keyGateway;
27+
SignedKeyRequestValidator internal validator;
28+
Bundler internal bundler;
29+
RecoveryProxy internal recoveryProxy;
30+
31+
address internal alice;
32+
uint256 internal alicePk;
33+
34+
address internal bob;
35+
uint256 internal bobPk;
36+
37+
address internal app;
38+
uint256 internal appPk;
39+
40+
address internal alpha = address(0x53c6dA835c777AD11159198FBe11f95E5eE6B692);
41+
address internal beta = address(0xD84E32224A249A575A09672Da9cb58C381C4837a);
42+
address internal vault = address(0x53c6dA835c777AD11159198FBe11f95E5eE6B692);
43+
address internal relayer = address(0x2D93c2F74b2C4697f9ea85D0450148AA45D4D5a2);
44+
address internal migrator = relayer;
45+
46+
address internal deployer = address(0x6D2b70e39C6bc63763098e336323591eb77Cd0C6);
47+
48+
address internal warpcastWallet = address(0x2cd85a093261f59270804A6EA697CeA4CeBEcafE);
49+
50+
function setUp() public {
51+
vm.createSelectFork("l2_mainnet", 136433938);
52+
53+
(alice, alicePk) = makeAddrAndKey("alice");
54+
(bob, bobPk) = makeAddrAndKey("bob");
55+
(app, appPk) = makeAddrAndKey("app");
56+
57+
vm.deal(alice, 0.5 ether);
58+
vm.deal(bob, 0.5 ether);
59+
vm.deal(app, 0.5 ether);
60+
61+
UpgradeBundler.DeploymentParams memory params =
62+
UpgradeBundler.DeploymentParams({salts: UpgradeBundler.Salts({bundler: 0})});
63+
64+
vm.startPrank(deployer);
65+
UpgradeBundler.Contracts memory contracts = runDeploy(params, false);
66+
runSetup(contracts, params, false);
67+
vm.stopPrank();
68+
69+
storageRegistry = contracts.storageRegistry;
70+
idRegistry = contracts.idRegistry;
71+
idGateway = contracts.idGateway;
72+
keyRegistry = contracts.keyRegistry;
73+
keyGateway = contracts.keyGateway;
74+
validator = contracts.signedKeyRequestValidator;
75+
bundler = contracts.bundler;
76+
recoveryProxy = contracts.recoveryProxy;
77+
}
78+
79+
function test_deploymentParams() public {
80+
// Check bundler deploy parameters
81+
assertEq(address(bundler.idGateway()), address(idGateway));
82+
assertEq(address(bundler.keyGateway()), address(keyGateway));
83+
}
84+
85+
function test_e2e() public {
86+
// Register an app fid
87+
uint256 idFee = idGateway.price();
88+
vm.prank(app);
89+
(uint256 requestFid,) = idGateway.register{value: idFee}(address(0));
90+
uint256 deadline = block.timestamp + 60;
91+
IBundler.SignerParams[] memory emptySigners = new IBundler.SignerParams[](0);
92+
93+
// Register FID to alice through Bundler
94+
bytes memory registerSig = _signRegister(alicePk, alice, address(recoveryProxy), deadline);
95+
uint256 price = bundler.price(1);
96+
97+
vm.prank(bob);
98+
uint256 fid = bundler.register{value: price}(
99+
IBundler.RegistrationParams({
100+
to: alice,
101+
recovery: address(recoveryProxy),
102+
deadline: deadline,
103+
sig: registerSig
104+
}),
105+
emptySigners,
106+
0
107+
);
108+
109+
IBundler.SignerParams[] memory signers = new IBundler.SignerParams[](2);
110+
_generateKeys(signers, deadline, requestFid);
111+
112+
// Register app/auth keys to Alice through bundler
113+
vm.prank(bob);
114+
bundler.addKeys(alice, signers);
115+
116+
// Alice's fid is registered
117+
assertEq(idRegistry.idOf(alice), fid);
118+
119+
// Alice's keys are registered
120+
assertEq(keyRegistry.totalKeys(fid, IKeyRegistry.KeyState.ADDED), 2);
121+
for (uint256 i; i < signers.length; i++) {
122+
assertEq(uint8(keyRegistry.keyDataOf(fid, signers[i].key).state), uint8(IKeyRegistry.KeyState.ADDED));
123+
assertEq(keyRegistry.keyDataOf(fid, signers[i].key).keyType, signers[i].keyType);
124+
}
125+
}
126+
127+
function _generateKeys(IBundler.SignerParams[] memory signers, uint256 deadline, uint256 requestFid) internal {
128+
_generateAppKey(signers, deadline, requestFid);
129+
_generateAuthKey(signers, deadline, requestFid);
130+
}
131+
132+
function _generateAppKey(IBundler.SignerParams[] memory signers, uint256 deadline, uint256 requestFid) internal {
133+
// Generate app key
134+
bytes memory appKey = bytes.concat("appKey", bytes26(0));
135+
bytes memory appKeySig = _signMetadata(appPk, requestFid, appKey, deadline);
136+
bytes memory appKeyMetadata = abi.encode(
137+
SignedKeyRequestValidator.SignedKeyRequestMetadata({
138+
requestFid: requestFid,
139+
requestSigner: app,
140+
signature: appKeySig,
141+
deadline: deadline
142+
})
143+
);
144+
signers[0] = IBundler.SignerParams({
145+
keyType: 1,
146+
key: appKey,
147+
metadataType: 1,
148+
metadata: appKeyMetadata,
149+
deadline: deadline,
150+
sig: _signAdd(alicePk, alice, 1, appKey, 1, appKeyMetadata, deadline)
151+
});
152+
}
153+
154+
function _generateAuthKey(IBundler.SignerParams[] memory signers, uint256 deadline, uint256 requestFid) internal {
155+
// Generate auth key
156+
bytes memory authKey = bytes.concat(bytes12(uint96(0)), bytes20(address(warpcastWallet)));
157+
bytes memory authKeySig = _signMetadata(appPk, requestFid, authKey, deadline);
158+
bytes memory authKeyMetadata = abi.encode(
159+
SignedKeyRequestValidator.SignedKeyRequestMetadata({
160+
requestFid: requestFid,
161+
requestSigner: app,
162+
signature: authKeySig,
163+
deadline: deadline
164+
})
165+
);
166+
signers[1] = IBundler.SignerParams({
167+
keyType: 2,
168+
key: authKey,
169+
metadataType: 1,
170+
metadata: authKeyMetadata,
171+
deadline: deadline,
172+
sig: _signAdd(alicePk, alice, 2, authKey, 1, authKeyMetadata, keyGateway.nonces(alice) + 1, deadline)
173+
});
174+
}
175+
176+
function _signRegister(
177+
uint256 pk,
178+
address to,
179+
address recovery,
180+
uint256 deadline
181+
) internal returns (bytes memory signature) {
182+
address signer = vm.addr(pk);
183+
bytes32 digest = idGateway.hashTypedDataV4(
184+
keccak256(abi.encode(idGateway.REGISTER_TYPEHASH(), to, recovery, idGateway.nonces(signer), deadline))
185+
);
186+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, digest);
187+
signature = abi.encodePacked(r, s, v);
188+
assertEq(signature.length, 65);
189+
}
190+
191+
function _signAdd(
192+
uint256 pk,
193+
address owner,
194+
uint32 keyType,
195+
bytes memory key,
196+
uint8 metadataType,
197+
bytes memory metadata,
198+
uint256 deadline
199+
) internal returns (bytes memory signature) {
200+
return _signAdd(pk, owner, keyType, key, metadataType, metadata, keyGateway.nonces(owner), deadline);
201+
}
202+
203+
function _signAdd(
204+
uint256 pk,
205+
address owner,
206+
uint32 keyType,
207+
bytes memory key,
208+
uint8 metadataType,
209+
bytes memory metadata,
210+
uint256 nonce,
211+
uint256 deadline
212+
) internal returns (bytes memory signature) {
213+
bytes32 digest = keyGateway.hashTypedDataV4(
214+
keccak256(
215+
abi.encode(
216+
keyGateway.ADD_TYPEHASH(),
217+
owner,
218+
keyType,
219+
keccak256(key),
220+
metadataType,
221+
keccak256(metadata),
222+
nonce,
223+
deadline
224+
)
225+
)
226+
);
227+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, digest);
228+
signature = abi.encodePacked(r, s, v);
229+
assertEq(signature.length, 65);
230+
}
231+
232+
function _signMetadata(
233+
uint256 pk,
234+
uint256 requestFid,
235+
bytes memory signerPubKey,
236+
uint256 deadline
237+
) internal returns (bytes memory signature) {
238+
bytes32 digest = validator.hashTypedDataV4(
239+
keccak256(
240+
abi.encode(
241+
keccak256("SignedKeyRequest(uint256 requestFid,bytes key,uint256 deadline)"),
242+
requestFid,
243+
keccak256(signerPubKey),
244+
deadline
245+
)
246+
)
247+
);
248+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, digest);
249+
signature = abi.encodePacked(r, s, v);
250+
assertEq(signature.length, 65);
251+
}
252+
}

0 commit comments

Comments
 (0)