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 ScrollBadgeDefaultURI extension #40

Merged
merged 2 commits into from
Apr 16, 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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ See [badges](./docs/badges.md) for details.
This repo contains some useful [extensions](src/badge/extensions):
- `ScrollBadgeAccessControl` restricts who can create and revoke this badge.
- `ScrollBadgeCustomPayload` adds custom payload support to the badge.
- `ScrollBadgeDefaultURI` sets a default badge token URI.
- `ScrollBadgeEligibilityCheck` adds a standard on-chain eligibility check interface.
- `ScrollBadgeNoExpiry` disables expiration for the badge.
- `ScrollBadgeNonRevocable` disables revocation for the badge.
- `ScrollBadgeEligibilityCheck` adds a standard on-chain eligibility check interface.
- `ScrollBadgeSBT` attaches an SBT token to each badge attestation.
- `ScrollBadgeSelfAttest` ensures that only the recipient of the badge can create the badge.
- `ScrollBadgeSingleton` ensures that each user can only have at most one of the badge.
Expand Down
16 changes: 10 additions & 6 deletions src/badge/examples/ScrollBadgeLevels.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

import {ScrollBadgeAccessControl} from "../extensions/ScrollBadgeAccessControl.sol";
import {ScrollBadgeCustomPayload} from "../extensions/ScrollBadgeCustomPayload.sol";
import {ScrollBadgeDefaultURI} from "../extensions/ScrollBadgeDefaultURI.sol";
import {ScrollBadge} from "../ScrollBadge.sol";

string constant SCROLL_BADGE_LEVELS_SCHEMA = "uint8 scrollLevel";
Expand All @@ -19,15 +20,18 @@ function decodePayloadData(bytes memory data) pure returns (uint8) {

/// @title ScrollBadgeLevels
/// @notice A simple badge that represents the user's level.
contract ScrollBadgeLevels is ScrollBadgeAccessControl, ScrollBadgeCustomPayload {
constructor(address resolver_) ScrollBadge(resolver_) {
contract ScrollBadgeLevels is ScrollBadgeAccessControl, ScrollBadgeCustomPayload, ScrollBadgeDefaultURI {
constructor(address resolver_, string memory _defaultBadgeURI)
ScrollBadge(resolver_)
ScrollBadgeDefaultURI(_defaultBadgeURI)
{
// empty
}

/// @inheritdoc ScrollBadge
function onIssueBadge(Attestation calldata attestation)
internal
override (ScrollBadgeAccessControl, ScrollBadgeCustomPayload)
override (ScrollBadge, ScrollBadgeAccessControl, ScrollBadgeCustomPayload)
returns (bool)
{
return super.onIssueBadge(attestation);
Expand All @@ -36,14 +40,14 @@ contract ScrollBadgeLevels is ScrollBadgeAccessControl, ScrollBadgeCustomPayload
/// @inheritdoc ScrollBadge
function onRevokeBadge(Attestation calldata attestation)
internal
override (ScrollBadgeAccessControl, ScrollBadgeCustomPayload)
override (ScrollBadge, ScrollBadgeAccessControl, ScrollBadgeCustomPayload)
returns (bool)
{
return super.onRevokeBadge(attestation);
}

/// @inheritdoc ScrollBadge
function badgeTokenURI(bytes32 uid) public view override returns (string memory) {
/// @inheritdoc ScrollBadgeDefaultURI
function getBadgeTokenURI(bytes32 uid) internal view override returns (string memory) {
uint8 level = getCurrentLevel(uid);
string memory name = string(abi.encode("Scroll Level #", Strings.toString(level)));
string memory description = "Scroll Level Badge";
Expand Down
29 changes: 29 additions & 0 deletions src/badge/extensions/ScrollBadgeDefaultURI.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import {ScrollBadge} from "../ScrollBadge.sol";

/// @title ScrollBadgeDefaultURI
/// @notice This contract sets a default badge URI.
abstract contract ScrollBadgeDefaultURI is ScrollBadge {
string public defaultBadgeURI;

constructor(string memory _defaultBadgeURI) {
defaultBadgeURI = _defaultBadgeURI;
}

/// @inheritdoc ScrollBadge
function badgeTokenURI(bytes32 uid) public view override returns (string memory) {
if (uid == bytes32(0)) {
return defaultBadgeURI;
}

return getBadgeTokenURI(uid);
}

/// @notice Returns the token URI corresponding to a certain badge UID.
/// @param uid The badge UID.
/// @return The badge token URI (same format as ERC721).
function getBadgeTokenURI(bytes32 uid) internal view virtual returns (string memory);
}
37 changes: 37 additions & 0 deletions test/ScrollBadgeDefaultURI.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.19;

import {ScrollBadgeTestBase} from "./ScrollBadgeTestBase.sol";

import {ScrollBadge} from "../src/badge/ScrollBadge.sol";
import {ScrollBadgeDefaultURI} from "../src/badge/extensions/ScrollBadgeDefaultURI.sol";

contract TestContract is ScrollBadgeDefaultURI {
constructor(address resolver_) ScrollBadge(resolver_) ScrollBadgeDefaultURI("default") {}

function getBadgeTokenURI(bytes32 /*uid*/ ) internal pure override returns (string memory) {
return "not-default";
}
}

contract ScrollBadgeDefaultURITest is ScrollBadgeTestBase {
TestContract internal badge;

function setUp() public virtual override {
super.setUp();

badge = new TestContract(address(resolver));
resolver.toggleBadge(address(badge), true);
}

function testGetBadgeTokenURI() external {
bytes32 uid = _attest(address(badge), "", alice);

string memory uri = badge.badgeTokenURI(uid);
assertEq(uri, "not-default");

uri = badge.badgeTokenURI(bytes32(0));
assertEq(uri, "default");
}
}
Loading