Skip to content

Commit 100445f

Browse files
all done
1 parent 3f00715 commit 100445f

4 files changed

Lines changed: 314 additions & 14 deletions

File tree

the-guild-smart-contracts/script/FullDeploymentScript.s.sol

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {AttestationRequestData, AttestationRequest} from "eas-contracts/IEAS.sol
77
import {SchemaRegistry} from "eas-contracts/SchemaRegistry.sol";
88
import {TheGuildActivityToken} from "../src/TheGuildActivityToken.sol";
99
import {TheGuildAttestationResolver} from "../src/TheGuildAttestationResolver.sol";
10+
import {TheGuildInternalResolver} from "../src/TheGuildInternalResolver.sol";
1011
import {TheGuildBadgeRegistry} from "../src/TheGuildBadgeRegistry.sol";
1112
import {TheGuildBadgeRanking} from "../src/TheGuildBadgeRanking.sol";
1213
import {EASUtils} from "./utils/EASUtils.s.sol";
@@ -50,23 +51,23 @@ contract FullDeploymentScript is Script {
5051
EASUtils.getSchemaRegistryAddress(vm)
5152
);
5253
bytes32 schemaId = schemaRegistry.register(schema, resolver, true);
53-
console.logString("Schema ID:");
54+
console.logString("Badge Attestation Schema ID:");
5455
console.logBytes32(schemaId);
5556

56-
// Create some badges
57-
badgeRegistry.createBadge(
58-
bytes32("Rust"),
59-
bytes("Know how to code in Rust")
60-
);
61-
badgeRegistry.createBadge(
62-
bytes32("Solidity"),
63-
bytes("Know how to code in Solidity")
64-
);
65-
badgeRegistry.createBadge(
66-
bytes32("TypeScript"),
67-
bytes("Know how to code in TypeScript")
68-
);
57+
// Deploy Internal Resolver via CREATE2
58+
TheGuildInternalResolver internalResolver = new TheGuildInternalResolver{
59+
salt: salt
60+
}(eas, deployer);
6961

62+
// Register Skill Badge Schema
63+
string memory skillSchema = "string skillDescription, bytes32[] linkedBadges";
64+
bytes32 skillSchemaId = schemaRegistry.register(
65+
skillSchema,
66+
internalResolver,
67+
true
68+
);
69+
console.logString("Skill Badge Schema ID:");
70+
console.logBytes32(skillSchemaId);
7071
// Deploy or attach to existing badge ranking via CREATE2
7172
new TheGuildBadgeRanking{salt: salt}(badgeRegistry);
7273

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.13;
3+
4+
import {Script} from "forge-std/Script.sol";
5+
import {IEAS} from "eas-contracts/IEAS.sol";
6+
import {SchemaRegistry} from "eas-contracts/SchemaRegistry.sol";
7+
import {TheGuildInternalResolver} from "../src/TheGuildInternalResolver.sol";
8+
import {EASUtils} from "./utils/EASUtils.s.sol";
9+
import {console} from "forge-std/console.sol";
10+
11+
contract TheGuildInternalResolverScript is Script {
12+
function run() public {
13+
address eas;
14+
eas = EASUtils.getEASAddress(vm);
15+
16+
uint256 pk = vm.envUint("PRIVATE_KEY");
17+
address deployer = vm.addr(pk);
18+
vm.startBroadcast(pk);
19+
20+
TheGuildInternalResolver resolver = new TheGuildInternalResolver(
21+
IEAS(eas),
22+
deployer
23+
);
24+
25+
// Register Skill Badge Schema
26+
SchemaRegistry schemaRegistry = SchemaRegistry(
27+
EASUtils.getSchemaRegistryAddress(vm)
28+
);
29+
string memory schema = "string skillDescription, bytes32[] linkedBadges";
30+
bytes32 schemaId = schemaRegistry.register(schema, resolver, true);
31+
32+
console.logString("Internal Resolver deployed at:");
33+
console.logAddress(address(resolver));
34+
console.logString("Skill Badge Schema ID:");
35+
console.logBytes32(schemaId);
36+
37+
vm.stopBroadcast();
38+
}
39+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.13;
3+
4+
import {SchemaResolver} from "eas-contracts/resolver/SchemaResolver.sol";
5+
import {IEAS, Attestation} from "eas-contracts/IEAS.sol";
6+
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
7+
8+
/// @title
9+
/// @notice
10+
contract TheGuildInternalResolver is SchemaResolver, Ownable {
11+
mapping(address => bool) private _authorizedAttesters;
12+
13+
event AttesterAuthorized(address indexed attester, bool authorized);
14+
15+
constructor(IEAS eas, address initialOwner) SchemaResolver(eas) Ownable(initialOwner) {
16+
_authorizedAttesters[initialOwner] = true;
17+
emit AttesterAuthorized(initialOwner, true);
18+
}
19+
20+
/// @notice
21+
function setAuthorizedAttester(address attester, bool authorized) external onlyOwner {
22+
_authorizedAttesters[attester] = authorized;
23+
emit AttesterAuthorized(attester, authorized);
24+
}
25+
26+
/// @notice
27+
function isAuthorizedAttester(address attester) public view returns (bool) {
28+
return _authorizedAttesters[attester];
29+
}
30+
31+
/// @inheritdoc
32+
function onAttest(
33+
Attestation calldata attestation,
34+
uint256
35+
) internal view override returns (bool) {
36+
return _authorizedAttesters[attestation.attester];
37+
}
38+
39+
/// @inheritdoc SchemaResolver
40+
function onRevoke(
41+
Attestation calldata attestation,
42+
uint256
43+
) internal view override returns (bool) {
44+
return _authorizedAttesters[attestation.attester];
45+
}
46+
}
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.13;
3+
4+
import {Test} from "forge-std/Test.sol";
5+
import {TheGuildInternalResolver} from "../src/TheGuildInternalResolver.sol";
6+
7+
8+
import {EAS} from "eas-contracts/EAS.sol";
9+
import {SchemaRegistry} from "eas-contracts/SchemaRegistry.sol";
10+
import {IEAS, AttestationRequest, AttestationRequestData, Attestation, RevocationRequestData, RevocationRequest} from "eas-contracts/IEAS.sol";
11+
12+
contract TheGuildInternalResolverTest is Test {
13+
TheGuildInternalResolver private resolver;
14+
SchemaRegistry private schemaRegistry;
15+
EAS private eas;
16+
17+
address private owner = address(this);
18+
address private authorizedAttester = address(0xA11CE);
19+
address private unauthorizedAttester = address(0xBEEF);
20+
address private recipient = address(0xCAFE);
21+
22+
function setUp() public {
23+
24+
schemaRegistry = new SchemaRegistry();
25+
eas = new EAS(schemaRegistry);
26+
27+
28+
resolver = new TheGuildInternalResolver(
29+
IEAS(address(eas)),
30+
owner
31+
);
32+
}
33+
34+
function _registerSchema() internal returns (bytes32) {
35+
36+
string memory schema = "string skillDescription, bytes32[] linkedBadges";
37+
38+
bytes32 schemaId = schemaRegistry.register(schema, resolver, true);
39+
return schemaId;
40+
}
41+
42+
function test_AttestationByOwnerSucceeds() public {
43+
bytes32 schemaId = _registerSchema();
44+
45+
bytes32[] memory linkedBadges = new bytes32[](2);
46+
linkedBadges[0] = bytes32("Solidity");
47+
linkedBadges[1] = bytes32("Rust");
48+
49+
AttestationRequestData memory data = AttestationRequestData({
50+
recipient: recipient,
51+
expirationTime: 0,
52+
revocable: true,
53+
refUID: bytes32(0),
54+
data: abi.encode("Master of Smart Contracts", linkedBadges),
55+
value: 0
56+
});
57+
58+
AttestationRequest memory request = AttestationRequest({
59+
schema: schemaId,
60+
data: data
61+
});
62+
63+
64+
eas.attest(request);
65+
66+
}
67+
68+
function test_AttestationByAuthorizedAttesterSucceeds() public {
69+
bytes32 schemaId = _registerSchema();
70+
resolver.setAuthorizedAttester(authorizedAttester, true);
71+
72+
bytes32[] memory linkedBadges = new bytes32[](1);
73+
linkedBadges[0] = bytes32("Solidity");
74+
75+
AttestationRequestData memory data = AttestationRequestData({
76+
recipient: recipient,
77+
expirationTime: 0,
78+
revocable: true,
79+
refUID: bytes32(0),
80+
data: abi.encode("Solidity Dev", linkedBadges),
81+
value: 0
82+
});
83+
84+
AttestationRequest memory request = AttestationRequest({
85+
schema: schemaId,
86+
data: data
87+
});
88+
89+
vm.prank(authorizedAttester);
90+
eas.attest(request);
91+
92+
}
93+
94+
function test_AttestationByUnauthorizedAttesterFails() public {
95+
bytes32 schemaId = _registerSchema();
96+
97+
bytes32[] memory linkedBadges = new bytes32[](1);
98+
linkedBadges[0] = bytes32("Solidity");
99+
100+
AttestationRequestData memory data = AttestationRequestData({
101+
recipient: recipient,
102+
expirationTime: 0,
103+
revocable: true,
104+
refUID: bytes32(0),
105+
data: abi.encode("Solidity Dev", linkedBadges),
106+
value: 0
107+
});
108+
109+
AttestationRequest memory request = AttestationRequest({
110+
schema: schemaId,
111+
data: data
112+
});
113+
114+
vm.prank(unauthorizedAttester);
115+
vm.expectRevert();
116+
eas.attest(request);
117+
}
118+
119+
function test_RevocationByAuthorizedAttesterSucceeds() public {
120+
bytes32 schemaId = _registerSchema();
121+
resolver.setAuthorizedAttester(authorizedAttester, true);
122+
123+
bytes32[] memory linkedBadges = new bytes32[](1);
124+
linkedBadges[0] = bytes32("Solidity");
125+
126+
AttestationRequestData memory data = AttestationRequestData({
127+
recipient: recipient,
128+
expirationTime: 0,
129+
revocable: true,
130+
refUID: bytes32(0),
131+
data: abi.encode("Solidity Dev", linkedBadges),
132+
value: 0
133+
});
134+
135+
AttestationRequest memory request = AttestationRequest({
136+
schema: schemaId,
137+
data: data
138+
});
139+
140+
vm.prank(authorizedAttester);
141+
bytes32 uid = eas.attest(request);
142+
143+
vm.prank(authorizedAttester);
144+
eas.revoke(
145+
RevocationRequest({
146+
schema: schemaId,
147+
data: RevocationRequestData({uid: uid, value: 0})
148+
})
149+
);
150+
// success == no revert
151+
}
152+
153+
function test_RevocationByUnauthorizedAttesterFails() public {
154+
bytes32 schemaId = _registerSchema();
155+
resolver.setAuthorizedAttester(authorizedAttester, true);
156+
157+
bytes32[] memory linkedBadges = new bytes32[](1);
158+
linkedBadges[0] = bytes32("Solidity");
159+
160+
AttestationRequestData memory data = AttestationRequestData({
161+
recipient: recipient,
162+
expirationTime: 0,
163+
revocable: true,
164+
refUID: bytes32(0),
165+
data: abi.encode("Solidity Dev", linkedBadges),
166+
value: 0
167+
});
168+
169+
AttestationRequest memory request = AttestationRequest({
170+
schema: schemaId,
171+
data: data
172+
});
173+
174+
vm.prank(authorizedAttester);
175+
bytes32 uid = eas.attest(request);
176+
177+
vm.prank(unauthorizedAttester);
178+
vm.expectRevert();
179+
eas.revoke(
180+
RevocationRequest({
181+
schema: schemaId,
182+
data: RevocationRequestData({uid: uid, value: 0})
183+
})
184+
);
185+
}
186+
187+
function test_DeauthorizeAttester() public {
188+
bytes32 schemaId = _registerSchema();
189+
resolver.setAuthorizedAttester(authorizedAttester, true);
190+
assertTrue(resolver.isAuthorizedAttester(authorizedAttester));
191+
192+
resolver.setAuthorizedAttester(authorizedAttester, false);
193+
assertFalse(resolver.isAuthorizedAttester(authorizedAttester));
194+
195+
bytes32[] memory linkedBadges = new bytes32[](1);
196+
linkedBadges[0] = bytes32("Solidity");
197+
198+
AttestationRequest memory request = AttestationRequest({
199+
schema: schemaId,
200+
data: AttestationRequestData({
201+
recipient: recipient,
202+
expirationTime: 0,
203+
revocable: true,
204+
refUID: bytes32(0),
205+
data: abi.encode("Solidity Dev", linkedBadges),
206+
value: 0
207+
})
208+
});
209+
210+
vm.prank(authorizedAttester);
211+
vm.expectRevert();
212+
eas.attest(request);
213+
}
214+
}

0 commit comments

Comments
 (0)