Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add badge check script #55

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/badges.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ This repo also contains some [examples](src/badge/examples):

We recommend going through the [requirements](#overview-of-requirements) before your badge is published.

Once your badge has been deployed on Scroll, you can auto-check some of these requirements by running `yarn check-badge`.

If your badge minting transaction reverts, we recommend debugging using `cast`:

```sh
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"main": "",
"scripts": {
"build": "forge build",
"test": "forge test -vvv"
"test": "forge test -vvv",
"fmt": "forge fmt",
"check-badge": "forge script --rpc-url https://rpc.scroll.io script/CheckBadge.s.sol --skip-simulation"
},
"author": "",
"license": "MIT",
Expand Down
137 changes: 137 additions & 0 deletions script/CheckBadge.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";

import {AttesterProxy} from "../src/AttesterProxy.sol";
import {ScrollBadge} from "../src/badge/ScrollBadge.sol";
import {ScrollBadgeEligibilityCheck} from "../src/badge/extensions/ScrollBadgeEligibilityCheck.sol";
import {ScrollBadgeAccessControl} from "../src/badge/extensions/ScrollBadgeAccessControl.sol";

contract CheckBadge is Script {
uint256 SCROLL_CHAIN_ID = 534_352;
address SCROLL_BADGE_RESOLVER_CONTRACT_ADDRESS = 0x4560FECd62B14A463bE44D40fE5Cfd595eEc0113;

function run() external {
address badge = vm.promptAddress("Please provide your badge address");
address attesterProxy = promptAddressOpt("Please provide your attester proxy address (leave empty if none)");
address signer = promptAddressOpt("Please provide your backend signer address (leave empty if none)");

run(badge, attesterProxy, signer);
}

function run(address badge, address attesterProxy, address signer) public {
console.log(
string(
abi.encodePacked(
"Checking badge ",
vm.toString(badge),
" with attester proxy ",
vm.toString(attesterProxy),
" and signer ",
vm.toString(signer)
)
)
);

// check chain id
if (block.chainid != SCROLL_CHAIN_ID) {
revert("Wrong chain, make sure to run this script with --rpc-url https://rpc.scroll.io");
}

// check if badge exists
if (badge.code.length == 0) {
revert(unicode"❌ Badge contract not deployed");
} else {
console.log(unicode"✅ Badge contract deployed");
}

// check if attester proxy exists
if (attesterProxy != address(0) && attesterProxy.code.length == 0) {
revert(unicode"❌ Attester proxy contract not deployed");
} else {
console.log(unicode"✅ Attester proxy contract deployed");
}

// check resolver
try ScrollBadge(badge).resolver() returns (address resolver) {
if (resolver != SCROLL_BADGE_RESOLVER_CONTRACT_ADDRESS) {
console.log(
unicode"❌ Incorrect resolver, make sure that you pass the correct constructor argument to ScrollBadge"
);
} else {
console.log(unicode"✅ Badge resolver configured");
}
} catch {
console.log(unicode"❌ Failed to call badge.resolver(), make sure that your badge implements ScrollBadge");
}

// check default badgeTokenURI
try ScrollBadge(badge).badgeTokenURI(bytes32("")) returns (string memory defaultUri) {
if (bytes(defaultUri).length == 0) {
console.log(
unicode"❌ Missing default badge URI, make sure that your badge implements ScrollBadgeDefaultURI"
);
} else {
console.log(unicode"✅ Default badge URI is configured");
}
} catch {
console.log(
unicode"❌ Missing default badge URI, make sure that your badge implements ScrollBadgeDefaultURI"
);
}

// on-chain eligibility check
if (attesterProxy == address(0)) {
try ScrollBadgeEligibilityCheck(badge).isEligible(address(1)) {
console.log(unicode"✅ On-chain eligibility check is configured");
} catch {
console.log(
unicode"❌ Missing on-chain eligibility check, make sure that your badge implements ScrollBadgeEligibilityCheck"
);
}
}

// authorization
if (attesterProxy != address(0)) {
try ScrollBadgeAccessControl(badge).isAttester(attesterProxy) returns (bool isAttester) {
if (!isAttester) {
console.log(
unicode"❌ Attester proxy is not whitelisted, please call badge.toggleAttester(attesterProxy, true)"
);
} else {
console.log(unicode"✅ Attester proxy is whitelisted");
}
} catch {
console.log(
unicode"❌ Missing access control, make sure that your badge implements ScrollBadgeAccessControl"
);
}
}

if (attesterProxy != address(0) && signer != address(0)) {
try AttesterProxy(attesterProxy).isAttester(signer) returns (bool isAttester) {
if (!isAttester) {
console.log(
unicode"❌ Your signer is not whitelisted, please call attesterProxy.toggleAttester(signer, true)"
);
} else {
console.log(unicode"✅ Signer is whitelisted");
}
} catch {
console.log(
unicode"❌ Failed to query attester proxy, make sure this contract is an instance of AttesterProxy"
);
}
}
}

function promptAddressOpt(string memory promptText) private returns (address addr) {
string memory str = vm.prompt(promptText);

if (bytes(str).length > 0) {
addr = vm.parseAddress(str);
}
}
}
Loading