Skip to content

Commit 918be51

Browse files
authored
feat: add auth key tests (#468)
* feat: add auth key tests * fix: CI foundry profile * chore: test cleanup
1 parent 40777f8 commit 918be51

File tree

2 files changed

+186
-0
lines changed

2 files changed

+186
-0
lines changed

foundry.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ bytecode_hash = 'none'
1616
[profile.ci]
1717
verbosity = 3
1818
fuzz = { runs = 2500 }
19+
no_match_path = "fake/"
1920
match_path = "test/*/**"
2021

2122
[fmt]

test/Deploy/AuthKeys.t.sol

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity 0.8.21;
3+
4+
import "forge-std/console.sol";
5+
import {Test} from "forge-std/Test.sol";
6+
import {
7+
UpgradeL2,
8+
StorageRegistry,
9+
IdRegistry,
10+
IIdRegistry,
11+
IdGateway,
12+
KeyRegistry,
13+
IKeyRegistry,
14+
KeyGateway,
15+
SignedKeyRequestValidator,
16+
Bundler,
17+
RecoveryProxy,
18+
IBundler,
19+
IMetadataValidator
20+
} from "../../script/UpgradeL2.s.sol";
21+
22+
/* solhint-disable state-visibility */
23+
24+
contract AuthKeysTest is Test {
25+
StorageRegistry internal storageRegistry = StorageRegistry(0x00000000fcCe7f938e7aE6D3c335bD6a1a7c593D);
26+
IdRegistry internal idRegistry = IdRegistry(0x00000000Fc6c5F01Fc30151999387Bb99A9f489b);
27+
IdGateway internal idGateway = IdGateway(payable(0x00000000Fc25870C6eD6b6c7E41Fb078b7656f69));
28+
KeyRegistry internal keyRegistry = KeyRegistry(0x00000000Fc1237824fb747aBDE0FF18990E59b7e);
29+
KeyGateway internal keyGateway = KeyGateway(0x00000000fC56947c7E7183f8Ca4B62398CaAdf0B);
30+
SignedKeyRequestValidator internal validator = SignedKeyRequestValidator(0x00000000FC700472606ED4fA22623Acf62c60553);
31+
Bundler internal bundler = Bundler(payable(0x00000000FC04c910A0b5feA33b03E0447AD0B0aA));
32+
RecoveryProxy internal recoveryProxy = RecoveryProxy(0x00000000FcB080a4D6c39a9354dA9EB9bC104cd7);
33+
34+
address internal alice;
35+
uint256 internal alicePk;
36+
37+
address internal bob;
38+
uint256 internal bobPk;
39+
40+
address internal carol;
41+
uint256 internal carolPk;
42+
43+
address internal dave;
44+
uint256 internal davePk;
45+
46+
address internal app;
47+
uint256 internal appPk;
48+
49+
address internal horsefacts = address(0x2cd85a093261f59270804A6EA697CeA4CeBEcafE);
50+
address internal warpcastWallet = address(0x2cd85a093261f59270804A6EA697CeA4CeBEcafE);
51+
52+
address internal invalid;
53+
54+
address internal alpha = address(0x53c6dA835c777AD11159198FBe11f95E5eE6B692);
55+
address internal beta = address(0xD84E32224A249A575A09672Da9cb58C381C4837a);
56+
address internal vault = address(0x53c6dA835c777AD11159198FBe11f95E5eE6B692);
57+
address internal relayer = address(0x2D93c2F74b2C4697f9ea85D0450148AA45D4D5a2);
58+
address internal migrator = relayer;
59+
60+
function setUp() public {
61+
vm.createSelectFork("l2_mainnet", 134877573);
62+
63+
(alice, alicePk) = makeAddrAndKey("alice");
64+
(bob, bobPk) = makeAddrAndKey("bob");
65+
(carol, carolPk) = makeAddrAndKey("carol");
66+
(dave, davePk) = makeAddrAndKey("dave");
67+
(app, appPk) = makeAddrAndKey("app");
68+
69+
invalid = makeAddr("invalid");
70+
71+
vm.deal(alice, 0.5 ether);
72+
vm.deal(bob, 0.5 ether);
73+
vm.deal(carol, 0.5 ether);
74+
vm.deal(dave, 0.5 ether);
75+
vm.deal(app, 0.5 ether);
76+
}
77+
78+
function test_e2e() public {
79+
// Register an app fid
80+
uint256 idFee = idGateway.price();
81+
vm.prank(app);
82+
(uint256 requestFid,) = idGateway.register{value: idFee}(address(0));
83+
uint256 deadline = block.timestamp + 60;
84+
85+
// Enable auth keys
86+
vm.prank(alpha);
87+
keyRegistry.setValidator(2, 1, IMetadataValidator(address(validator)));
88+
89+
// Register an auth key
90+
bytes memory authKey = abi.encode(address(warpcastWallet));
91+
bytes memory sig = _signMetadata(appPk, requestFid, authKey, deadline);
92+
bytes memory metadata = abi.encode(
93+
SignedKeyRequestValidator.SignedKeyRequestMetadata({
94+
requestFid: requestFid,
95+
requestSigner: app,
96+
signature: sig,
97+
deadline: deadline
98+
})
99+
);
100+
101+
vm.startPrank(horsefacts);
102+
keyGateway.add(2, authKey, 1, metadata);
103+
104+
IKeyRegistry.KeyData memory keyData = keyRegistry.keyDataOf(3621, authKey);
105+
assertEq(keyData.keyType, 2);
106+
assertEq(uint8(keyData.state), uint8(IKeyRegistry.KeyState.ADDED));
107+
108+
bytes memory invalidAuthKey = abi.encode(invalid);
109+
IKeyRegistry.KeyData memory invalidKeyData = keyRegistry.keyDataOf(3621, invalidAuthKey);
110+
111+
assertEq(invalidKeyData.keyType, 0);
112+
assertEq(uint8(invalidKeyData.state), uint8(IKeyRegistry.KeyState.NULL));
113+
114+
// Register a new app key
115+
bytes memory appKey = bytes.concat("appKey", bytes26(0));
116+
bytes memory appKeySig = _signMetadata(appPk, requestFid, appKey, deadline);
117+
bytes memory appKeyMetadata = abi.encode(
118+
SignedKeyRequestValidator.SignedKeyRequestMetadata({
119+
requestFid: requestFid,
120+
requestSigner: app,
121+
signature: appKeySig,
122+
deadline: deadline
123+
})
124+
);
125+
126+
keyGateway.add(1, appKey, 1, appKeyMetadata);
127+
128+
// Revoke auth key
129+
keyRegistry.remove(authKey);
130+
131+
keyData = keyRegistry.keyDataOf(3621, authKey);
132+
assertEq(keyData.keyType, 2);
133+
assertEq(uint8(keyData.state), uint8(IKeyRegistry.KeyState.REMOVED));
134+
135+
// Auth key is permanently revoked
136+
vm.expectRevert(IKeyRegistry.InvalidState.selector);
137+
keyGateway.add(2, authKey, 1, metadata);
138+
139+
// Revoke new app key
140+
keyRegistry.remove(appKey);
141+
142+
// App key is permanently revoked
143+
keyData = keyRegistry.keyDataOf(3621, appKey);
144+
assertEq(keyData.keyType, 1);
145+
assertEq(uint8(keyData.state), uint8(IKeyRegistry.KeyState.REMOVED));
146+
147+
vm.stopPrank();
148+
}
149+
150+
function _signTransfer(
151+
uint256 pk,
152+
uint256 fid,
153+
address to,
154+
uint256 deadline
155+
) internal returns (bytes memory signature) {
156+
address signer = vm.addr(pk);
157+
bytes32 digest = idRegistry.hashTypedDataV4(
158+
keccak256(abi.encode(idRegistry.TRANSFER_TYPEHASH(), fid, to, idRegistry.nonces(signer), deadline))
159+
);
160+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, digest);
161+
signature = abi.encodePacked(r, s, v);
162+
assertEq(signature.length, 65);
163+
}
164+
165+
function _signMetadata(
166+
uint256 pk,
167+
uint256 requestFid,
168+
bytes memory signerPubKey,
169+
uint256 deadline
170+
) internal returns (bytes memory signature) {
171+
bytes32 digest = validator.hashTypedDataV4(
172+
keccak256(
173+
abi.encode(
174+
keccak256("SignedKeyRequest(uint256 requestFid,bytes key,uint256 deadline)"),
175+
requestFid,
176+
keccak256(signerPubKey),
177+
deadline
178+
)
179+
)
180+
);
181+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(pk, digest);
182+
signature = abi.encodePacked(r, s, v);
183+
assertEq(signature.length, 65);
184+
}
185+
}

0 commit comments

Comments
 (0)