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 category #291

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
110 changes: 78 additions & 32 deletions contracts/contracts/FleekERC721.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ contract FleekERC721 is
string ipfsHash,
string logo,
uint24 color,
bool accessPointAutoApproval,
Categories category,
address indexed minter,
address indexed owner,
address verifier
Expand Down Expand Up @@ -106,14 +106,11 @@ contract FleekERC721 is
address to,
string memory name,
string memory description,
string memory externalURL,
string calldata ens,
string memory commitHash,
string memory gitRepository,
string memory ipfsHash,
string memory logo,
uint24 color,
bool accessPointAutoApproval,
Categories category,
Build memory buildParams,
address verifier
) public payable requirePayment(Billing.Mint) returns (uint256) {
if (!hasCollectionRole(CollectionRoles.Verifier, verifier))
Expand All @@ -127,35 +124,40 @@ contract FleekERC721 is
Token storage app = _apps[tokenId];
app.name = name;
app.description = description;
app.externalURL = externalURL;
app.externalURL = buildParams.domain;
app.ENS = ens;
app.logo = logo;
app.color = color;
app.category = category;

// The mint interaction is considered to be the first build of the site. Updates from now on all increment the currentBuild by one and update the mapping.
app.currentBuild = 0;
app.builds[0] = Build(commitHash, gitRepository, ipfsHash, externalURL);
app.builds[0] = Build(
buildParams.commitHash,
buildParams.gitRepository,
buildParams.ipfsHash,
buildParams.domain
);

emit NewMint(
tokenId,
name,
description,
externalURL,
buildParams.domain,
ens,
commitHash,
gitRepository,
ipfsHash,
buildParams.commitHash,
buildParams.gitRepository,
buildParams.ipfsHash,
logo,
color,
accessPointAutoApproval,
category,
msg.sender,
to,
verifier
);

_tokenVerifier[tokenId] = verifier;
_tokenVerified[tokenId] = false;
_setAccessPointAutoApproval(tokenId, accessPointAutoApproval);

return tokenId;
}
Expand Down Expand Up @@ -196,11 +198,35 @@ contract FleekERC721 is
public
view
virtual
returns (string memory, string memory, string memory, string memory, uint256, string memory, uint24)
returns (
string memory,
string memory,
string memory,
uint256,
string memory,
string memory,
string memory,
string memory,
string memory,
uint24,
Categories
)
{
_requireMinted(tokenId);
Token storage app = _apps[tokenId];
return (app.name, app.description, app.externalURL, app.ENS, app.currentBuild, app.logo, app.color);
return (
app.name,
app.description,
app.ENS,
app.currentBuild,
app.builds[app.currentBuild].commitHash,
app.builds[app.currentBuild].domain,
app.builds[app.currentBuild].gitRepository,
app.builds[app.currentBuild].ipfsHash,
app.logo,
app.color,
app.category
);
}

function getAppData(
Expand Down Expand Up @@ -387,6 +413,26 @@ contract FleekERC721 is
emit MetadataUpdate(tokenId, "color", _tokenColor, msg.sender);
}

/**
* @dev Updates the `category` metadata field of a minted `tokenId`.
*
* May emit a {NewTokenCategory} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenCategory(
uint256 tokenId,
Categories category
) public virtual requireTokenRole(tokenId, TokenRoles.Controller) {
_requireMinted(tokenId);
_apps[tokenId].category = category;
emit MetadataUpdate(tokenId, "category", category, msg.sender);
}

/**
* @dev Updates the `logo` and `color` metadata fields of a minted `tokenId`.
*
Expand Down Expand Up @@ -542,37 +588,37 @@ contract FleekERC721 is
}

/**
* @dev Remove an AccessPoint registry for an app token.
* It will also remove the AP from the app token APs list.
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
*
* May emit a {RemoveAccessPoint} event.
* May emit a {MetadataUpdate} event.
*
* Requirements:
*
* - the AP must exist.
* - must be called by the AP owner.
* - the contract must be not paused.
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function removeAccessPoint(string memory apName) public whenNotPaused {
_removeAccessPoint(apName);
function setAccessPointAutoApproval(uint256 tokenId, bool _apAutoApproval) public requireTokenOwner(tokenId) {
_requireMinted(tokenId);
_setAccessPointAutoApproval(tokenId, _apAutoApproval);
emit MetadataUpdate(tokenId, "accessPointAutoApproval", _apAutoApproval, msg.sender);
}

/**
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
* @dev Remove an AccessPoint registry for an app token.
* It will also remove the AP from the app token APs list.
*
* May emit a {MetadataUpdate} event.
* May emit a {RemoveAccessPoint} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
* - the AP must exist.
* - must be called by the AP owner.
* - the contract must be not paused.
*
*/
function setAccessPointAutoApproval(uint256 tokenId, bool _apAutoApproval) public requireTokenOwner(tokenId) {
_requireMinted(tokenId);
_setAccessPointAutoApproval(tokenId, _apAutoApproval);
emit MetadataUpdate(tokenId, "accessPointAutoApproval", _apAutoApproval, msg.sender);
function removeAccessPoint(string memory apName) public whenNotPaused {
_removeAccessPoint(apName);
}

/**
Expand Down
18 changes: 18 additions & 0 deletions contracts/contracts/IERCX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface IERCX {
event MetadataUpdate(uint256 indexed _tokenId, string key, uint24 value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, string[4] value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, bool value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, Categories value, address indexed triggeredBy);

/**
* The metadata that is stored for each build.
Expand All @@ -37,6 +38,17 @@ interface IERCX {
string domain;
}

/**
* @dev All available app category traits.
*/
enum Categories {
DeFi,
NFT,
Analytics,
Infrastructure,
Gaming
}

/**
* The properties are stored as string to keep consistency with
* other token contracts, we might consider changing for bytes32
Expand All @@ -49,6 +61,7 @@ interface IERCX {
string ENS; // ENS for the site
string logo; // Branding logo
uint24 color; // Branding color
Categories category; // The category trait associated with the token
uint256 currentBuild; // The current build number (Increments by one with each change, starts at zero)
mapping(uint256 => Build) builds; // Mapping to build details for each build number
}
Expand Down Expand Up @@ -83,6 +96,11 @@ interface IERCX {
*/
function setTokenColor(uint256 tokenId, uint24 _tokenColor) external;

/**
* @dev Sets a minted token's category.
*/
function setTokenCategory(uint256 tokenId, Categories tokenCategory) external;

/**
* @dev Sets a minted token's build.
*/
Expand Down
4 changes: 2 additions & 2 deletions contracts/contracts/util/FleekStrings.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ library FleekStrings {
'"name":"', app.name, '",',
'"description":"', app.description, '",',
'"owner":"', uint160(owner).toHexString(20), '",',
'"external_url":"', app.externalURL, '",',
'"external_url":"', app.builds[app.currentBuild].domain, '",',
'"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
'"access_point_auto_approval":', accessPointAutoApproval.toString(),',',
'"verified":',verified.toString(),',',
'"attributes": [',
'{"trait_type": "ENS", "value":"', app.ENS,'"},',
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
'{"trait_type": "Repository", "value":"', app.builds[app.currentBuild].gitRepository,'"},',
'{"trait_type": "IPFS Hash", "value":"', app.builds[app.currentBuild].ipfsHash,'"},',
'{"trait_type": "Version", "value":"', app.currentBuild.toString(),'"},',
'{"trait_type": "Color", "value":"', app.color.toColorString(),'"}',
']',
Expand Down
2 changes: 1 addition & 1 deletion contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const config: HardhatUserConfig = {
forking: MAINNET_API_KEY
? {
url: MAINNET_API_KEY,
blockNumber: 16876149,
blockNumber: undefined,
}
: undefined,
},
Expand Down
2 changes: 1 addition & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": "false",
"scripts": {
"test": "yarn test:hardhat && yarn test:foundry",
"test:foundry": "forge test -vvv --fork-url mainnet --fork-block-number 16876149",
"test:foundry": "forge test -vvv --fork-url mainnet",
"test:hardhat": "hardhat test --network hardhat",
"format": "prettier --write \"./**/*.{js,json,sol,ts}\"",
"node:hardhat": "hardhat node",
Expand Down
Loading