Merge pull request #34 from fleekxyz/feat/events

Update events & function header documentations
This commit is contained in:
Shredder 2022-12-19 01:46:01 +03:30 committed by GitHub
commit cc3979f3a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 253 additions and 142 deletions

View File

@ -11,17 +11,16 @@ contract FleekERC721 is ERC721, FleekAccessControl {
using Strings for uint256; using Strings for uint256;
using Counters for Counters.Counter; using Counters for Counters.Counter;
event NewBuild(uint256 indexed token, string indexed commit_hash); event NewBuild(uint256 indexed token, string indexed commitHash, address indexed triggeredBy);
event NewTokenName(uint256 indexed token, string indexed name); event NewTokenName(uint256 indexed token, string indexed name, address indexed triggeredBy);
event NewTokenDescription(uint256 indexed token, string indexed description); event NewTokenDescription(uint256 indexed token, string indexed description, address indexed triggeredBy);
event NewTokenImage(uint256 indexed token, string indexed image); event NewTokenImage(uint256 indexed token, string indexed image, address indexed triggeredBy);
event NewTokenExternalURL(uint256 indexed token, string indexed external_url); event NewTokenExternalURL(uint256 indexed token, string indexed externalURL, address indexed triggeredBy);
event NewTokenENS(uint256 indexed token, string indexed ENS); event NewTokenENS(uint256 indexed token, string indexed ENS, address indexed triggeredBy);
struct Build { struct Build {
string commit_hash; string commitHash;
string git_repository; string gitRepository;
string author;
} }
/** /**
@ -33,9 +32,9 @@ contract FleekERC721 is ERC721, FleekAccessControl {
string name; // Name of the site string name; // Name of the site
string description; // Description about the site string description; // Description about the site
string image; // Preview Image IPFS Link string image; // Preview Image IPFS Link
string external_url; // Site URL string externalURL; // Site URL
string ENS; // ENS ID string ENS; // ENS ID
uint256 current_build; // The current build number (Increments by one with each change, starts at zero) 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 mapping(uint256 => Build) builds; // Mapping to build details for each build number
} }
@ -49,16 +48,25 @@ contract FleekERC721 is ERC721, FleekAccessControl {
_; _;
} }
/**
* @dev Mints a token and returns a tokenId.
*
* If the `tokenId` has not been minted before, and the `to` address is not zero, emits a {Transfer} event.
*
* Requirements:
*
* - the caller must have ``collectionOwner``'s admin role.
*
*/
function mint( function mint(
address to, address to,
string memory name, string memory name,
string memory description, string memory description,
string memory image, string memory image,
string memory external_url, string memory externalURL,
string memory ENS, string memory ENS,
string memory commit_hash, string memory commitHash,
string memory git_repository, string memory gitRepository
string memory author
) public payable requireCollectionOwner returns (uint256) { ) public payable requireCollectionOwner returns (uint256) {
uint256 tokenId = _tokenIds.current(); uint256 tokenId = _tokenIds.current();
_mint(to, tokenId); _mint(to, tokenId);
@ -68,16 +76,26 @@ contract FleekERC721 is ERC721, FleekAccessControl {
app.name = name; app.name = name;
app.description = description; app.description = description;
app.image = image; app.image = image;
app.external_url = external_url; app.externalURL = externalURL;
app.ENS = ENS; app.ENS = ENS;
// The mint interaction is considered to be the first build of the site. Updates from now on all increment the current_build by one and update the mapping. // 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.current_build = 0; app.currentBuild = 0;
app.builds[0] = Build(commit_hash, git_repository, author); app.builds[0] = Build(commitHash, gitRepository);
return tokenId; return tokenId;
} }
/**
* @dev Returns the token metadata associated with the `tokenId`.
*
* Returns a based64 encoded string value of the URI.
*
* Requirements:
*
* - the tokenId must be minted and valid.
*
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId); _requireMinted(tokenId);
address owner = ownerOf(tokenId); address owner = ownerOf(tokenId);
@ -89,14 +107,13 @@ contract FleekERC721 is ERC721, FleekAccessControl {
'"name":"', app.name, '",', '"name":"', app.name, '",',
'"description":"', app.description, '",', '"description":"', app.description, '",',
'"owner":"', Strings.toHexString(uint160(owner), 20), '",', '"owner":"', Strings.toHexString(uint160(owner), 20), '",',
'"external_url":"', app.external_url, '",', '"external_url":"', app.externalURL, '",',
'"image":"', app.image, '",', '"image":"', app.image, '",',
'"attributes": [', '"attributes": [',
'{"trait_type": "ENS", "value":"', app.ENS,'"},', '{"trait_type": "ENS", "value":"', app.ENS,'"},',
'{"trait_type": "Commit Hash", "value":"', app.builds[app.current_build].commit_hash,'"},', '{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
'{"trait_type": "Repository", "value":"', app.builds[app.current_build].git_repository,'"},', '{"trait_type": "Repository", "value":"', app.builds[app.currentBuild].gitRepository,'"},',
'{"trait_type": "Author", "value":"', app.builds[app.current_build].author,'"},', '{"trait_type": "Version", "value":"', Strings.toString(app.currentBuild),'"}',
'{"trait_type": "Version", "value":"', Strings.toString(app.current_build),'"}',
']', ']',
'}' '}'
); );
@ -104,16 +121,41 @@ contract FleekERC721 is ERC721, FleekAccessControl {
return string(abi.encodePacked(_baseURI(), Base64.encode((dataURI)))); return string(abi.encodePacked(_baseURI(), Base64.encode((dataURI))));
} }
/**
* @dev Adds a new address with the`tokenController` privileges to a previously minted `tokenId`.
*
* May emit a {RoleGranted} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenOwner` role.
*
*/
function addTokenController(uint256 tokenId, address controller) public requireTokenOwner(tokenId) { function addTokenController(uint256 tokenId, address controller) public requireTokenOwner(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_grantRole(_tokenRole(tokenId, "CONTROLLER"), controller); _grantRole(_tokenRole(tokenId, "CONTROLLER"), controller);
} }
/**
* @dev Strips an address from their `tokenController` privileges on a previously minted `tokenId`.
*
* May emit a {RoleRevoked} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenOwner` role.
*
*/
function removeTokenController(uint256 tokenId, address controller) public requireTokenOwner(tokenId) { function removeTokenController(uint256 tokenId, address controller) public requireTokenOwner(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_revokeRole(_tokenRole(tokenId, "CONTROLLER"), controller); _revokeRole(_tokenRole(tokenId, "CONTROLLER"), controller);
} }
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) { function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId); return super.supportsInterface(interfaceId);
} }
@ -143,61 +185,140 @@ contract FleekERC721 is ERC721, FleekAccessControl {
super._beforeTokenTransfer(from, to, tokenId, batchSize); super._beforeTokenTransfer(from, to, tokenId, batchSize);
} }
/**
* @dev A baseURI internal function implementation to be called in the `tokenURI` function.
*/
function _baseURI() internal view virtual override returns (string memory) { function _baseURI() internal view virtual override returns (string memory) {
return "data:application/json;base64,"; return "data:application/json;base64,";
} }
/**
* @dev Updates the `externalURL` metadata field of a minted `tokenId`.
*
* May emit a {NewTokenExternalURL} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenExternalURL( function setTokenExternalURL(
uint256 tokenId, uint256 tokenId,
string memory _tokenExternalURL string memory _tokenExternalURL
) public virtual requireTokenController(tokenId) { ) public virtual requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_apps[tokenId].external_url = _tokenExternalURL; _apps[tokenId].externalURL = _tokenExternalURL;
emit NewTokenExternalURL(tokenId, _tokenExternalURL); emit NewTokenExternalURL(tokenId, _tokenExternalURL, msg.sender);
} }
/**
* @dev Updates the `ENS` metadata field of a minted `tokenId`.
*
* May emit a {NewTokenENS} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenENS(uint256 tokenId, string memory _tokenENS) public virtual requireTokenController(tokenId) { function setTokenENS(uint256 tokenId, string memory _tokenENS) public virtual requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_apps[tokenId].ENS = _tokenENS; _apps[tokenId].ENS = _tokenENS;
emit NewTokenENS(tokenId, _tokenENS); emit NewTokenENS(tokenId, _tokenENS, msg.sender);
} }
/**
* @dev Updates the `name` metadata field of a minted `tokenId`.
*
* May emit a {NewTokenName} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenName(uint256 tokenId, string memory _tokenName) public virtual requireTokenController(tokenId) { function setTokenName(uint256 tokenId, string memory _tokenName) public virtual requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_apps[tokenId].name = _tokenName; _apps[tokenId].name = _tokenName;
emit NewTokenName(tokenId, _tokenName); emit NewTokenName(tokenId, _tokenName, msg.sender);
} }
/**
* @dev Updates the `description` metadata field of a minted `tokenId`.
*
* May emit a {NewTokenDescription} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenDescription( function setTokenDescription(
uint256 tokenId, uint256 tokenId,
string memory _tokenDescription string memory _tokenDescription
) public virtual requireTokenController(tokenId) { ) public virtual requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_apps[tokenId].description = _tokenDescription; _apps[tokenId].description = _tokenDescription;
emit NewTokenDescription(tokenId, _tokenDescription); emit NewTokenDescription(tokenId, _tokenDescription, msg.sender);
} }
/**
* @dev Updates the `image` metadata field of a minted `tokenId`.
*
* May emit a {NewTokenImage} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenImage(uint256 tokenId, string memory _tokenImage) public virtual requireTokenController(tokenId) { function setTokenImage(uint256 tokenId, string memory _tokenImage) public virtual requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_apps[tokenId].image = _tokenImage; _apps[tokenId].image = _tokenImage;
emit NewTokenImage(tokenId, _tokenImage); emit NewTokenImage(tokenId, _tokenImage, msg.sender);
} }
/**
* @dev Adds a new build to a minted `tokenId`'s builds mapping.
*
* May emit a {NewBuild} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setTokenBuild( function setTokenBuild(
uint256 tokenId, uint256 tokenId,
string memory _commit_hash, string memory _commitHash,
string memory _git_repository, string memory _gitRepository
string memory _author
) public virtual requireTokenController(tokenId) { ) public virtual requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_apps[tokenId].builds[++_apps[tokenId].current_build] = Build(_commit_hash, _git_repository, _author); _apps[tokenId].builds[++_apps[tokenId].currentBuild] = Build(_commitHash, _gitRepository);
emit NewBuild(tokenId, _commit_hash); emit NewBuild(tokenId, _commitHash, msg.sender);
} }
/**
* @dev Burns a previously minted `tokenId`.
*
* May emit a {Transfer} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenOwner` role.
*
*/
function burn(uint256 tokenId) public virtual requireTokenOwner(tokenId) { function burn(uint256 tokenId) public virtual requireTokenOwner(tokenId) {
super._burn(tokenId); super._burn(tokenId);
if (bytes(_apps[tokenId].external_url).length != 0) { if (bytes(_apps[tokenId].externalURL).length != 0) {
delete _apps[tokenId]; delete _apps[tokenId];
} }
} }

View File

@ -14,7 +14,6 @@ describe('FleekERC721', () => {
externalUrl: 'https://fleek.co', externalUrl: 'https://fleek.co',
commitHash: 'b72e47171746b6a9e29b801af9cb655ecf4d665c', commitHash: 'b72e47171746b6a9e29b801af9cb655ecf4d665c',
gitRepository: 'https://github.com/fleekxyz/contracts', gitRepository: 'https://github.com/fleekxyz/contracts',
author: 'author',
}); });
const COLLECTION_PARAMS = Object.freeze({ const COLLECTION_PARAMS = Object.freeze({
@ -70,8 +69,7 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl, MINT_PARAMS.externalUrl,
MINT_PARAMS.ens, MINT_PARAMS.ens,
MINT_PARAMS.commitHash, MINT_PARAMS.commitHash,
MINT_PARAMS.gitRepository, MINT_PARAMS.gitRepository
MINT_PARAMS.author
); );
expect(response.value).to.be.instanceOf(ethers.BigNumber); expect(response.value).to.be.instanceOf(ethers.BigNumber);
@ -92,8 +90,7 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl, MINT_PARAMS.externalUrl,
MINT_PARAMS.ens, MINT_PARAMS.ens,
MINT_PARAMS.commitHash, MINT_PARAMS.commitHash,
MINT_PARAMS.gitRepository, MINT_PARAMS.gitRepository
MINT_PARAMS.author
) )
).to.be.revertedWith( ).to.be.revertedWith(
'FleekAccessControl: must have collection owner role' 'FleekAccessControl: must have collection owner role'
@ -117,8 +114,7 @@ describe('FleekERC721', () => {
MINT_PARAMS.externalUrl, MINT_PARAMS.externalUrl,
MINT_PARAMS.ens, MINT_PARAMS.ens,
MINT_PARAMS.commitHash, MINT_PARAMS.commitHash,
MINT_PARAMS.gitRepository, MINT_PARAMS.gitRepository
MINT_PARAMS.author
); );
tokenId = response.value.toNumber(); tokenId = response.value.toNumber();
@ -154,10 +150,6 @@ describe('FleekERC721', () => {
trait_type: 'Repository', trait_type: 'Repository',
value: MINT_PARAMS.gitRepository, value: MINT_PARAMS.gitRepository,
}, },
{
trait_type: 'Author',
value: MINT_PARAMS.author,
},
{ {
trait_type: 'Version', trait_type: 'Version',
value: '0', value: '0',

View File

@ -6,4 +6,3 @@ export const useToast = () => {
isClosable: true, isClosable: true,
}); });
}; };

View File

@ -36,4 +36,3 @@ export const fetchMintedSites = async () => {
}, 2500); }, 2500);
}); });
}; };