Skip to content

Commit

Permalink
feat: remove ProfileRegistry mint
Browse files Browse the repository at this point in the history
  • Loading branch information
Thegaram committed Jan 15, 2025
1 parent d202680 commit ec185c2
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 62 deletions.
6 changes: 0 additions & 6 deletions src/interfaces/IProfileRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,6 @@ interface IProfileRegistry {
*
*/

/// @notice Mint a profile for caller with given username.
/// @param username The username of the profile.
/// @param referral The referral data.
/// @return The address of minted profile.
function mint(string calldata username, bytes calldata referral) external payable returns (address);

/// @notice Register an username.
/// @param username The username to register.
function registerUsername(string memory username) external;
Expand Down
101 changes: 57 additions & 44 deletions src/profile/ProfileRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ contract ProfileRegistry is OwnableUpgradeable, EIP712Upgradeable, IBeacon, IPro
/// @notice The codehash for `ClonableBeaconProxy` contract.
bytes32 public constant cloneableProxyHash = keccak256(type(ClonableBeaconProxy).creationCode);

// solhint-disable-next-line var-name-mixedcase
bytes32 private constant _REFERRAL_TYPEHASH = keccak256("Referral(address referrer,address owner,uint256 deadline)");

/**
*
* Structs *
Expand Down Expand Up @@ -151,46 +148,6 @@ contract ProfileRegistry is OwnableUpgradeable, EIP712Upgradeable, IBeacon, IPro
*
*/

/// @inheritdoc IProfileRegistry
function mint(string calldata username, bytes memory referral) external payable override returns (address) {
address receiver = treasury;
address referrer;
uint256 mintFee = MINT_FEE;
if (referral.length > 0) {
uint256 deadline;
bytes memory signature;
(receiver, deadline, signature) = abi.decode(referral, (address, uint256, bytes));
if (deadline < block.timestamp) revert ExpiredSignature();
if (!isProfileMinted[getProfile(receiver)]) {
revert InvalidReferrer();
}

bytes32 structHash = keccak256(abi.encode(_REFERRAL_TYPEHASH, receiver, _msgSender(), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address recovered = ECDSAUpgradeable.recover(hash, signature);
if (signer != recovered) revert InvalidSignature();

// half mint fee and fee goes to referral
mintFee = MINT_FEE / 2;
referrer = receiver;
}
if (msg.value != mintFee) revert MsgValueMismatchWithMintFee();
Address.sendValue(payable(receiver), mintFee);

if (isProfileMinted[getProfile(_msgSender())]) {
revert ProfileAlreadyMinted();
}

if (referrer != address(0)) {
ReferrerData memory cached = referrerData[referrer];
cached.referred += 1;
cached.earned += uint128(mintFee);
referrerData[referrer] = cached;
}

return _mintProfile(_msgSender(), username, referrer);
}

/// @inheritdoc IProfileRegistry
function registerUsername(string memory username) external override onlyProfile {
_validateUsername(username);
Expand Down Expand Up @@ -260,7 +217,7 @@ contract ProfileRegistry is OwnableUpgradeable, EIP712Upgradeable, IBeacon, IPro
/// @dev Internal function to mint a profile with given account address and username.
/// @param account The address of user to mint profile.
/// @param username The username of the profile.
function _mintProfile(address account, string calldata username, address referrer) private returns (address) {
function _mintProfile(address account, string calldata username, address referrer) internal returns (address) {
// deployment will fail and this function will revert if contract `salt` is not unique
bytes32 salt = keccak256(abi.encode(account));
address profile = address(new ClonableBeaconProxy{salt: salt}());
Expand Down Expand Up @@ -322,3 +279,59 @@ contract ProfileRegistry is OwnableUpgradeable, EIP712Upgradeable, IBeacon, IPro
}
}
}

contract ProfileRegistryMintable is ProfileRegistry {
/**
*
* Constants *
*
*/

// solhint-disable-next-line var-name-mixedcase
bytes32 private constant _REFERRAL_TYPEHASH = keccak256("Referral(address referrer,address owner,uint256 deadline)");

/**
*
* Public Mutating Functions *
*
*/

function mint(string calldata username, bytes memory referral) external payable returns (address) {
address receiver = treasury;
address referrer;
uint256 mintFee = MINT_FEE;
if (referral.length > 0) {
uint256 deadline;
bytes memory signature;
(receiver, deadline, signature) = abi.decode(referral, (address, uint256, bytes));
if (deadline < block.timestamp) revert ExpiredSignature();
if (!isProfileMinted[getProfile(receiver)]) {
revert InvalidReferrer();
}

bytes32 structHash = keccak256(abi.encode(_REFERRAL_TYPEHASH, receiver, _msgSender(), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address recovered = ECDSAUpgradeable.recover(hash, signature);
if (signer != recovered) revert InvalidSignature();

// half mint fee and fee goes to referral
mintFee = MINT_FEE / 2;
referrer = receiver;
}
if (msg.value != mintFee) revert MsgValueMismatchWithMintFee();
Address.sendValue(payable(receiver), mintFee);

if (isProfileMinted[getProfile(_msgSender())]) {
revert ProfileAlreadyMinted();
}

if (referrer != address(0)) {
ReferrerData memory cached = referrerData[referrer];
cached.referred += 1;
cached.earned += uint128(mintFee);
referrerData[referrer] = cached;
}

return _mintProfile(_msgSender(), username, referrer);
}
}
8 changes: 4 additions & 4 deletions test/Profile.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {

import {EmptyContract} from "../src/misc/EmptyContract.sol";
import {Profile} from "../src/profile/Profile.sol";
import {ProfileRegistry} from "../src/profile/ProfileRegistry.sol";
import {ProfileRegistryMintable} from "../src/profile/ProfileRegistry.sol";
import {ScrollBadge} from "../src/badge/ScrollBadge.sol";
import {ScrollBadgeResolver} from "../src/resolver/ScrollBadgeResolver.sol";

Expand Down Expand Up @@ -75,7 +75,7 @@ contract ProfileRegistryTest is Test {
ScrollBadge private badge;

Profile private profileImpl;
ProfileRegistry private profileRegistry;
ProfileRegistryMintable private profileRegistry;
Profile private profile;

receive() external payable {}
Expand All @@ -95,10 +95,10 @@ contract ProfileRegistryTest is Test {
resolver.toggleBadge(address(badge), true);

profileImpl = new Profile(address(resolver));
ProfileRegistry profileRegistryImpl = new ProfileRegistry();
ProfileRegistryMintable profileRegistryImpl = new ProfileRegistryMintable();
vm.prank(PROXY_ADMIN_ADDRESS);
ITransparentUpgradeableProxy(profileRegistryProxy).upgradeTo(address(profileRegistryImpl));
profileRegistry = ProfileRegistry(profileRegistryProxy);
profileRegistry = ProfileRegistryMintable(profileRegistryProxy);
profileRegistry.initialize(TREASURY_ADDRESS, TREASURY_ADDRESS, address(profileImpl));
profile = Profile(profileRegistry.mint{value: 0.001 ether}("xxxxx", new bytes(0)));
}
Expand Down
8 changes: 4 additions & 4 deletions test/ProfileRegistry.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {

import {EmptyContract} from "../src/misc/EmptyContract.sol";
import {Profile} from "../src/profile/Profile.sol";
import {ProfileRegistry} from "../src/profile/ProfileRegistry.sol";
import {ProfileRegistryMintable} from "../src/profile/ProfileRegistry.sol";
import {ScrollBadgeResolver} from "../src/resolver/ScrollBadgeResolver.sol";

contract ProfileRegistryTest is Test {
Expand All @@ -40,7 +40,7 @@ contract ProfileRegistryTest is Test {
VmSafe.Wallet private signer;

Profile private profileImpl;
ProfileRegistry private profileRegistry;
ProfileRegistryMintable private profileRegistry;

receive() external payable {}

Expand All @@ -58,10 +58,10 @@ contract ProfileRegistryTest is Test {
signer = vm.createWallet(10_001);

profileImpl = new Profile(address(resolver));
ProfileRegistry profileRegistryImpl = new ProfileRegistry();
ProfileRegistryMintable profileRegistryImpl = new ProfileRegistryMintable();
vm.prank(PROXY_ADMIN_ADDRESS);
ITransparentUpgradeableProxy(profileRegistryProxy).upgradeTo(address(profileRegistryImpl));
profileRegistry = ProfileRegistry(profileRegistryProxy);
profileRegistry = ProfileRegistryMintable(profileRegistryProxy);
profileRegistry.initialize(TREASURY_ADDRESS, signer.addr, address(profileImpl));
vm.warp(1_000_000);
}
Expand Down
8 changes: 4 additions & 4 deletions test/SCRHoldingBadge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {ITransparentUpgradeableProxy, TransparentUpgradeableProxy} from "@openze

import {EmptyContract} from "../src/misc/EmptyContract.sol";
import {Profile} from "../src/profile/Profile.sol";
import {ProfileRegistry} from "../src/profile/ProfileRegistry.sol";
import {ProfileRegistryMintable} from "../src/profile/ProfileRegistry.sol";
import {ScrollBadge} from "../src/badge/ScrollBadge.sol";
import {ScrollBadgeResolver} from "../src/resolver/ScrollBadgeResolver.sol";
import {SCRHoldingBadge} from "../src/badge/examples/SCRHoldingBadge.sol";
Expand All @@ -42,7 +42,7 @@ contract SCRHoldingBadgeTest is Test {
Token private token;

Profile private profileImpl;
ProfileRegistry private profileRegistry;
ProfileRegistryMintable private profileRegistry;
Profile private profile;

receive() external payable {}
Expand All @@ -64,10 +64,10 @@ contract SCRHoldingBadgeTest is Test {
resolver.updateSelfAttestedBadge(0, address(badge));

profileImpl = new Profile(address(resolver));
ProfileRegistry profileRegistryImpl = new ProfileRegistry();
ProfileRegistryMintable profileRegistryImpl = new ProfileRegistryMintable();
vm.prank(PROXY_ADMIN_ADDRESS);
ITransparentUpgradeableProxy(profileRegistryProxy).upgradeTo(address(profileRegistryImpl));
profileRegistry = ProfileRegistry(profileRegistryProxy);
profileRegistry = ProfileRegistryMintable(profileRegistryProxy);
profileRegistry.initialize(TREASURY_ADDRESS, TREASURY_ADDRESS, address(profileImpl));
profile = Profile(profileRegistry.mint{value: 0.001 ether}("xxxxx", new bytes(0)));
}
Expand Down

0 comments on commit ec185c2

Please sign in to comment.