feat: erc interface and split out access points to single module (#151)

* wip: compilant version of interface

* refactor: split out access point to single module

* test: fix mint call on hardhat tests

* fix: remove auto approval from NewMint event
This commit is contained in:
Felipe Mendes 2023-03-13 11:07:40 -03:00 committed by GitHub
parent fbee0945fd
commit df6fbea5c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 906 additions and 791 deletions

View File

@ -0,0 +1,212 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import {FleekStrings} from "./util/FleekStrings.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
error AccessPointNotExistent();
error AccessPointAlreadyExists();
error AccessPointScoreCannotBeLower();
error MustBeAccessPointOwner();
error InvalidTokenIdForAccessPoint();
error AccessPointCreationStatusAlreadySet();
abstract contract FleekAccessPoints is Initializable {
using FleekStrings for FleekAccessPoints.AccessPoint;
event NewAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
event RemoveAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
event ChangeAccessPointScore(string apName, uint256 indexed tokenId, uint256 score, address indexed triggeredBy);
event ChangeAccessPointNameVerify(
string apName,
uint256 tokenId,
bool indexed verified,
address indexed triggeredBy
);
event ChangeAccessPointContentVerify(
string apName,
uint256 tokenId,
bool indexed verified,
address indexed triggeredBy
);
event ChangeAccessPointCreationStatus(
string apName,
uint256 tokenId,
AccessPointCreationStatus status,
address indexed triggeredBy
);
/**
* Creation status enums for access points
*/
enum AccessPointCreationStatus {
DRAFT,
APPROVED,
REJECTED,
REMOVED
}
/**
* The stored data for each AccessPoint.
*/
struct AccessPoint {
uint256 tokenId;
uint256 score;
bool contentVerified;
bool nameVerified;
address owner;
AccessPointCreationStatus status;
}
mapping(string => AccessPoint) private _accessPoints;
mapping(uint256 => bool) private _autoApproval;
/**
* @dev Checks if the AccessPoint exists.
*/
modifier requireAP(string memory apName) {
if (_accessPoints[apName].owner == address(0)) revert AccessPointNotExistent();
_;
}
/**
* @dev A view function to gether information about an AccessPoint.
* It returns a JSON string representing the AccessPoint information.
*/
function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {
AccessPoint storage _ap = _accessPoints[apName];
return _ap.toString();
}
/**
* @dev A view function to check if a AccessPoint is verified.
*/
function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {
return _accessPoints[apName].nameVerified;
}
/**
* @dev Increases the score of a AccessPoint registry.
*/
function increaseAccessPointScore(string memory apName) public requireAP(apName) {
_accessPoints[apName].score++;
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
}
/**
* @dev Decreases the score of a AccessPoint registry if is greater than 0.
*/
function decreaseAccessPointScore(string memory apName) public requireAP(apName) {
if (_accessPoints[apName].score == 0) revert AccessPointScoreCannotBeLower();
_accessPoints[apName].score--;
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
}
/**
* @dev Add a new AccessPoint register for an app token.
* The AP name should be a DNS or ENS url and it should be unique.
*/
function _addAccessPoint(uint256 tokenId, string memory apName) internal {
if (_accessPoints[apName].owner != address(0)) revert AccessPointAlreadyExists();
emit NewAccessPoint(apName, tokenId, msg.sender);
if (_autoApproval[tokenId]) {
// Auto Approval is on.
_accessPoints[apName] = AccessPoint(
tokenId,
0,
false,
false,
msg.sender,
AccessPointCreationStatus.APPROVED
);
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
} else {
// Auto Approval is off. Should wait for approval.
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender, AccessPointCreationStatus.DRAFT);
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.DRAFT, msg.sender);
}
}
/**
* @dev Remove an AccessPoint registry for an app token.
* It will also remove the AP from the app token APs list.
*/
function _removeAccessPoint(string memory apName) internal requireAP(apName) {
if (msg.sender != _accessPoints[apName].owner) revert MustBeAccessPointOwner();
_accessPoints[apName].status = AccessPointCreationStatus.REMOVED;
uint256 tokenId = _accessPoints[apName].tokenId;
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REMOVED, msg.sender);
emit RemoveAccessPoint(apName, tokenId, msg.sender);
}
/**
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
*/
function _setAccessPointAutoApproval(uint256 tokenId, bool _apAutoApproval) internal {
_autoApproval[tokenId] = _apAutoApproval;
}
/**
* @dev Set approval settings for an access point.
* It will add the access point to the token's AP list, if `approved` is true.
*/
function _setApprovalForAccessPoint(uint256 tokenId, string memory apName, bool approved) internal {
AccessPoint storage accessPoint = _accessPoints[apName];
if (accessPoint.tokenId != tokenId) revert InvalidTokenIdForAccessPoint();
if (accessPoint.status != AccessPointCreationStatus.DRAFT) revert AccessPointCreationStatusAlreadySet();
if (approved) {
// Approval
accessPoint.status = AccessPointCreationStatus.APPROVED;
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
} else {
// Not Approved
accessPoint.status = AccessPointCreationStatus.REJECTED;
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REJECTED, msg.sender);
}
}
/**
* @dev Set the content verification of a AccessPoint registry.
*/
function _setAccessPointContentVerify(string memory apName, bool verified) internal requireAP(apName) {
_accessPoints[apName].contentVerified = verified;
emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
}
/**
* @dev Set the name verification of a AccessPoint registry.
*/
function _setAccessPointNameVerify(string memory apName, bool verified) internal requireAP(apName) {
_accessPoints[apName].nameVerified = verified;
emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
}
/**
* @dev Get the AccessPoint token id.
*/
function _getAccessPointTokenId(string memory apName) internal view requireAP(apName) returns (uint256) {
return _accessPoints[apName].tokenId;
}
/**
* @dev Get the Auto Approval setting for token id.
*/
function _getAccessPointAutoApproval(uint256 tokenId) internal view returns (bool) {
return _autoApproval[tokenId];
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}

View File

@ -7,22 +7,25 @@ import "@openzeppelin/contracts/utils/Base64.sol";
import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/Strings.sol";
import "./FleekAccessControl.sol"; import "./FleekAccessControl.sol";
import "./FleekBilling.sol"; import "./FleekBilling.sol";
import "./util/FleekStrings.sol";
import "./FleekPausable.sol"; import "./FleekPausable.sol";
import "./FleekAccessPoints.sol";
import "./util/FleekStrings.sol";
import "./IERCX.sol";
error AccessPointNotExistent();
error AccessPointAlreadyExists();
error AccessPointScoreCannotBeLower();
error MustBeAccessPointOwner();
error MustBeTokenOwner(uint256 tokenId); error MustBeTokenOwner(uint256 tokenId);
error ThereIsNoTokenMinted(); error ThereIsNoTokenMinted();
error InvalidTokenIdForAccessPoint();
error AccessPointCreationStatusAlreadySet();
contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, FleekPausable, FleekBilling { contract FleekERC721 is
IERCX,
Initializable,
ERC721Upgradeable,
FleekAccessControl,
FleekPausable,
FleekBilling,
FleekAccessPoints
{
using Strings for uint256; using Strings for uint256;
using FleekStrings for FleekERC721.App; using FleekStrings for FleekERC721.Token;
using FleekStrings for FleekERC721.AccessPoint;
using FleekStrings for string; using FleekStrings for string;
using FleekStrings for uint24; using FleekStrings for uint24;
@ -36,89 +39,12 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
string gitRepository, string gitRepository,
string logo, string logo,
uint24 color, uint24 color,
bool accessPointAutoApproval,
address indexed minter, address indexed minter,
address indexed owner address indexed owner
); );
event MetadataUpdate(uint256 indexed _tokenId, string key, string value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, uint24 value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, string[2] value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, bool value, address indexed triggeredBy);
event NewAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
event RemoveAccessPoint(string apName, uint256 indexed tokenId, address indexed owner);
event ChangeAccessPointScore(string apName, uint256 indexed tokenId, uint256 score, address indexed triggeredBy);
event ChangeAccessPointNameVerify(
string apName,
uint256 tokenId,
bool indexed verified,
address indexed triggeredBy
);
event ChangeAccessPointContentVerify(
string apName,
uint256 tokenId,
bool indexed verified,
address indexed triggeredBy
);
event ChangeAccessPointCreationStatus(
string apName,
uint256 tokenId,
AccessPointCreationStatus status,
address indexed triggeredBy
);
/**
* The properties are stored as string to keep consistency with
* other token contracts, we might consider changing for bytes32
* in the future due to gas optimization.
*/
struct App {
string name; // Name of the site
string description; // Description about the site
string externalURL; // Site URL
string ENS; // ENS ID
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
string logo;
uint24 color; // Color of the nft
bool accessPointAutoApproval; // AP Auto Approval
}
/**
* The metadata that is stored for each build.
*/
struct Build {
string commitHash;
string gitRepository;
}
/**
* Creation status enums for access points
*/
enum AccessPointCreationStatus {
DRAFT,
APPROVED,
REJECTED,
REMOVED
}
/**
* The stored data for each AccessPoint.
*/
struct AccessPoint {
uint256 tokenId;
uint256 score;
bool contentVerified;
bool nameVerified;
address owner;
AccessPointCreationStatus status;
}
uint256 private _appIds; uint256 private _appIds;
mapping(uint256 => App) private _apps; mapping(uint256 => Token) private _apps;
mapping(string => AccessPoint) private _accessPoints;
/** /**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
@ -134,14 +60,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
__FleekPausable_init(); __FleekPausable_init();
} }
/**
* @dev Checks if the AccessPoint exists.
*/
modifier requireAP(string memory apName) {
if (_accessPoints[apName].owner == address(0)) revert AccessPointNotExistent();
_;
}
/** /**
* @dev Mints a token and returns a tokenId. * @dev Mints a token and returns a tokenId.
* *
@ -163,22 +81,20 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
string memory commitHash, string memory commitHash,
string memory gitRepository, string memory gitRepository,
string memory logo, string memory logo,
uint24 color, uint24 color
bool accessPointAutoApproval
) public payable requirePayment(Billing.Mint) returns (uint256) { ) public payable requirePayment(Billing.Mint) returns (uint256) {
uint256 tokenId = _appIds; uint256 tokenId = _appIds;
_mint(to, tokenId); _mint(to, tokenId);
_appIds += 1; _appIds += 1;
App storage app = _apps[tokenId]; Token storage app = _apps[tokenId];
app.name = name; app.name = name;
app.description = description; app.description = description;
app.externalURL = externalURL; app.externalURL = externalURL;
app.ENS = ENS; app.ENS = ENS;
app.logo = logo; app.logo = logo;
app.color = color; app.color = color;
app.accessPointAutoApproval = accessPointAutoApproval;
// 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. // 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.currentBuild = 0;
@ -193,7 +109,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
gitRepository, gitRepository,
logo, logo,
color, color,
accessPointAutoApproval,
msg.sender, msg.sender,
to to
); );
@ -210,12 +125,13 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
* - the tokenId must be minted and valid. * - 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(ERC721Upgradeable, IERCX) returns (string memory) {
_requireMinted(tokenId); _requireMinted(tokenId);
address owner = ownerOf(tokenId); address owner = ownerOf(tokenId);
App storage app = _apps[tokenId]; bool accessPointAutoApproval = _getAccessPointAutoApproval(tokenId);
Token storage app = _apps[tokenId];
return string(abi.encodePacked(_baseURI(), app.toString(owner).toBase64())); return string(abi.encodePacked(_baseURI(), app.toString(owner, accessPointAutoApproval).toBase64()));
} }
/** /**
@ -237,7 +153,7 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
returns (string memory, string memory, string memory, string memory, uint256, string memory, uint24) returns (string memory, string memory, string memory, string memory, uint256, string memory, uint24)
{ {
_requireMinted(tokenId); _requireMinted(tokenId);
App storage app = _apps[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.externalURL, app.ENS, app.currentBuild, app.logo, app.color);
} }
@ -287,26 +203,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
return "data:application/json;base64,"; return "data:application/json;base64,";
} }
/**
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
*
* May emit a {MetadataUpdate} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setAccessPointAutoApproval(
uint256 tokenId,
bool _apAutoApproval
) public virtual requireTokenOwner(tokenId) {
_requireMinted(tokenId);
_apps[tokenId].accessPointAutoApproval = _apAutoApproval;
emit MetadataUpdate(tokenId, "accessPointAutoApproval", _apAutoApproval, msg.sender);
}
/** /**
* @dev Updates the `externalURL` metadata field of a minted `tokenId`. * @dev Updates the `externalURL` metadata field of a minted `tokenId`.
* *
@ -443,197 +339,6 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
setTokenColor(tokenId, _tokenColor); setTokenColor(tokenId, _tokenColor);
} }
/**
* @dev Add a new AccessPoint register for an app token.
* The AP name should be a DNS or ENS url and it should be unique.
* Anyone can add an AP but it should requires a payment.
*
* May emit a {NewAccessPoint} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - billing for add acess point may be applied.
* - the contract must be not paused.
*
*/
function addAccessPoint(
uint256 tokenId,
string memory apName
) public payable whenNotPaused requirePayment(Billing.AddAccessPoint) {
// require(msg.value == 0.1 ether, "You need to pay at least 0.1 ETH"); // TODO: define a minimum price
_requireMinted(tokenId);
if (_accessPoints[apName].owner != address(0)) revert AccessPointAlreadyExists();
emit NewAccessPoint(apName, tokenId, msg.sender);
if (_apps[tokenId].accessPointAutoApproval) {
// Auto Approval is on.
_accessPoints[apName] = AccessPoint(
tokenId,
0,
false,
false,
msg.sender,
AccessPointCreationStatus.APPROVED
);
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
} else {
// Auto Approval is off. Should wait for approval.
_accessPoints[apName] = AccessPoint(tokenId, 0, false, false, msg.sender, AccessPointCreationStatus.DRAFT);
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.DRAFT, msg.sender);
}
}
/**
* @dev Set approval settings for an access point.
* It will add the access point to the token's AP list, if `approved` is true.
*
* May emit a {ChangeAccessPointApprovalStatus} event.
*
* Requirements:
*
* - the tokenId must exist and be the same as the tokenId that is set for the AP.
* - the AP must exist.
* - must be called by a token controller.
*/
function setApprovalForAccessPoint(
uint256 tokenId,
string memory apName,
bool approved
) public requireTokenOwner(tokenId) {
AccessPoint storage accessPoint = _accessPoints[apName];
if (accessPoint.tokenId != tokenId) revert InvalidTokenIdForAccessPoint();
if (accessPoint.status != AccessPointCreationStatus.DRAFT) revert AccessPointCreationStatusAlreadySet();
if (approved) {
// Approval
accessPoint.status = AccessPointCreationStatus.APPROVED;
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.APPROVED, msg.sender);
} else {
// Not Approved
accessPoint.status = AccessPointCreationStatus.REJECTED;
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REJECTED, msg.sender);
}
}
/**
* @dev Remove an AccessPoint registry for an app token.
* It will also remove the AP from the app token APs list.
*
* May emit a {RemoveAccessPoint} event.
*
* Requirements:
*
* - the AP must exist.
* - must be called by the AP owner.
* - the contract must be not paused.
*
*/
function removeAccessPoint(string memory apName) public whenNotPaused requireAP(apName) {
if (msg.sender != _accessPoints[apName].owner) revert MustBeAccessPointOwner();
_accessPoints[apName].status = AccessPointCreationStatus.REMOVED;
uint256 tokenId = _accessPoints[apName].tokenId;
emit ChangeAccessPointCreationStatus(apName, tokenId, AccessPointCreationStatus.REMOVED, msg.sender);
emit RemoveAccessPoint(apName, tokenId, msg.sender);
}
/**
* @dev A view function to gether information about an AccessPoint.
* It returns a JSON string representing the AccessPoint information.
*
* Requirements:
*
* - the AP must exist.
*
*/
function getAccessPointJSON(string memory apName) public view requireAP(apName) returns (string memory) {
AccessPoint storage _ap = _accessPoints[apName];
return _ap.toString();
}
/**
* @dev A view function to check if a AccessPoint is verified.
*
* Requirements:
*
* - the AP must exist.
*
*/
function isAccessPointNameVerified(string memory apName) public view requireAP(apName) returns (bool) {
return _accessPoints[apName].nameVerified;
}
/**
* @dev Increases the score of a AccessPoint registry.
*
* May emit a {ChangeAccessPointScore} event.
*
* Requirements:
*
* - the AP must exist.
*
*/
function increaseAccessPointScore(string memory apName) public requireAP(apName) {
_accessPoints[apName].score++;
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
}
/**
* @dev Decreases the score of a AccessPoint registry if is greater than 0.
*
* May emit a {ChangeAccessPointScore} event.
*
* Requirements:
*
* - the AP must exist.
*
*/
function decreaseAccessPointScore(string memory apName) public requireAP(apName) {
if (_accessPoints[apName].score == 0) revert AccessPointScoreCannotBeLower();
_accessPoints[apName].score--;
emit ChangeAccessPointScore(apName, _accessPoints[apName].tokenId, _accessPoints[apName].score, msg.sender);
}
/**
* @dev Set the content verification of a AccessPoint registry.
*
* May emit a {ChangeAccessPointContentVerify} event.
*
* Requirements:
*
* - the AP must exist.
* - the sender must have collection verifier role.
*
*/
function setAccessPointContentVerify(
string memory apName,
bool verified
) public requireAP(apName) requireCollectionRole(CollectionRoles.Verifier) {
_accessPoints[apName].contentVerified = verified;
emit ChangeAccessPointContentVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
}
/**
* @dev Set the name verification of a AccessPoint registry.
*
* May emit a {ChangeAccessPointNameVerify} event.
*
* Requirements:
*
* - the AP must exist.
* - the sender must have collection verifier role.
*
*/
function setAccessPointNameVerify(
string memory apName,
bool verified
) public requireAP(apName) requireCollectionRole(CollectionRoles.Verifier) {
_accessPoints[apName].nameVerified = verified;
emit ChangeAccessPointNameVerify(apName, _accessPoints[apName].tokenId, verified, msg.sender);
}
/** /**
* @dev Adds a new build to a minted `tokenId`'s builds mapping. * @dev Adds a new build to a minted `tokenId`'s builds mapping.
* *
@ -675,6 +380,142 @@ contract FleekERC721 is Initializable, ERC721Upgradeable, FleekAccessControl, Fl
} }
} }
/*//////////////////////////////////////////////////////////////
ACCESS POINTS
//////////////////////////////////////////////////////////////*/
/**
* @dev Mints with access auto approval setting
*/
function mint(
address to,
string memory name,
string memory description,
string memory externalURL,
string memory ENS,
string memory commitHash,
string memory gitRepository,
string memory logo,
uint24 color,
bool accessPointAutoApproval
) public payable returns (uint256) {
uint256 tokenId = mint(to, name, description, externalURL, ENS, commitHash, gitRepository, logo, color);
_setAccessPointAutoApproval(tokenId, accessPointAutoApproval);
return tokenId;
}
/**
* @dev Add a new AccessPoint register for an app token.
* The AP name should be a DNS or ENS url and it should be unique.
* Anyone can add an AP but it should requires a payment.
*
* May emit a {NewAccessPoint} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - billing for add acess point may be applied.
* - the contract must be not paused.
*
*/
function addAccessPoint(
uint256 tokenId,
string memory apName
) public payable whenNotPaused requirePayment(Billing.AddAccessPoint) {
_requireMinted(tokenId);
_addAccessPoint(tokenId, apName);
}
/**
* @dev Remove an AccessPoint registry for an app token.
* It will also remove the AP from the app token APs list.
*
* May emit a {RemoveAccessPoint} event.
*
* Requirements:
*
* - the AP must exist.
* - must be called by the AP owner.
* - the contract must be not paused.
*
*/
function removeAccessPoint(string memory apName) public whenNotPaused {
_removeAccessPoint(apName);
}
/**
* @dev Updates the `accessPointAutoApproval` settings on minted `tokenId`.
*
* May emit a {MetadataUpdate} event.
*
* Requirements:
*
* - the tokenId must be minted and valid.
* - the sender must have the `tokenController` role.
*
*/
function setAccessPointAutoApproval(uint256 tokenId, bool _apAutoApproval) public requireTokenOwner(tokenId) {
_requireMinted(tokenId);
_setAccessPointAutoApproval(tokenId, _apAutoApproval);
emit MetadataUpdate(tokenId, "accessPointAutoApproval", _apAutoApproval, msg.sender);
}
/**
* @dev Set approval settings for an access point.
* It will add the access point to the token's AP list, if `approved` is true.
*
* May emit a {ChangeAccessPointApprovalStatus} event.
*
* Requirements:
*
* - the tokenId must exist and be the same as the tokenId that is set for the AP.
* - the AP must exist.
* - must be called by a token controller.
*/
function setApprovalForAccessPoint(
uint256 tokenId,
string memory apName,
bool approved
) public requireTokenOwner(tokenId) {
_setApprovalForAccessPoint(tokenId, apName, approved);
}
/**
* @dev Set the content verification of a AccessPoint registry.
*
* May emit a {ChangeAccessPointContentVerify} event.
*
* Requirements:
*
* - the AP must exist.
* - the sender must have the token controller role.
*
*/
function setAccessPointContentVerify(
string memory apName,
bool verified
) public requireCollectionRole(CollectionRoles.Verifier) {
_setAccessPointContentVerify(apName, verified);
}
/**
* @dev Set the name verification of a AccessPoint registry.
*
* May emit a {ChangeAccessPointNameVerify} event.
*
* Requirements:
*
* - the AP must exist.
* - the sender must have the token controller role.
*
*/
function setAccessPointNameVerify(
string memory apName,
bool verified
) public requireCollectionRole(CollectionRoles.Verifier) {
_setAccessPointNameVerify(apName, verified);
}
/*////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////
ACCESS CONTROL ACCESS CONTROL
//////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////*/

View File

@ -0,0 +1,109 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
/**
* @title ERCX Interface
* @author
* @notice
*
* ERCX is a standard for NFTs that represent websites. It is a standard that
* allows for the storage of metadata about a website, and allows for the
* storage of multiple builds of a website. This allows for the NFT to be
* used as a way to store the history of a website.
*/
interface IERCX {
/**
* Event emitted when a token's metadata is updated.
* @param _tokenId the updated token id.
* @param key which metadata key was updated
* @param value the new value of the metadata
* @param triggeredBy the address that triggered the update
*/
event MetadataUpdate(uint256 indexed _tokenId, string key, string value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, uint24 value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, string[2] value, address indexed triggeredBy);
event MetadataUpdate(uint256 indexed _tokenId, string key, bool value, address indexed triggeredBy);
/**
* The metadata that is stored for each build.
*/
struct Build {
string commitHash;
string gitRepository;
}
/**
* The properties are stored as string to keep consistency with
* other token contracts, we might consider changing for bytes32
* in the future due to gas optimization.
*/
struct Token {
string name; // Name of the site
string description; // Description about the site
string externalURL; // Site URL
string ENS; // ENS for the site
string logo; // Branding logo
uint24 color; // Branding color
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
}
/**
* @dev Mints a token and returns a tokenId.
*/
function mint(
address to,
string memory name,
string memory description,
string memory externalURL,
string memory ENS,
string memory commitHash,
string memory gitRepository,
string memory logo,
uint24 color
) external payable returns (uint256);
/**
* @dev Sets a minted token's external URL.
*/
function setTokenExternalURL(uint256 tokenId, string memory _tokenExternalURL) external;
/**
* @dev Sets a minted token's ENS.
*/
function setTokenENS(uint256 tokenId, string memory _tokenENS) external;
/**
* @dev Sets a minted token's name.
*/
function setTokenName(uint256 tokenId, string memory _tokenName) external;
/**
* @dev Sets a minted token's description.
*/
function setTokenDescription(uint256 tokenId, string memory _tokenDescription) external;
/**
* @dev Sets a minted token's logo.
*/
function setTokenLogo(uint256 tokenId, string memory _tokenLogo) external;
/**
* @dev Sets a minted token's color.
*/
function setTokenColor(uint256 tokenId, uint24 _tokenColor) external;
/**
* @dev Sets a minted token's build.
*/
function setTokenBuild(uint256 tokenId, string memory commitHash, string memory gitRepository) external;
/**
* @dev Returns the token metadata for a given tokenId.
* It must return a valid JSON object in string format encoded in Base64.
*/
function tokenURI(uint256 tokenId) external returns (string memory);
}

View File

@ -2,7 +2,6 @@
pragma solidity ^0.8.7; pragma solidity ^0.8.7;
import "../FleekERC721.sol";
import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Base64.sol"; import "@openzeppelin/contracts/utils/Base64.sol";

View File

@ -2,10 +2,11 @@
pragma solidity ^0.8.7; pragma solidity ^0.8.7;
import "../FleekERC721.sol";
import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Base64.sol"; import "@openzeppelin/contracts/utils/Base64.sol";
import "./FleekSVG.sol"; import "./FleekSVG.sol";
import "../IERCX.sol";
import "../FleekAccessPoints.sol";
library FleekStrings { library FleekStrings {
using Strings for uint256; using Strings for uint256;
@ -29,10 +30,14 @@ library FleekStrings {
} }
/** /**
* @dev Converts FleekERC721.App to a JSON string. * @dev Converts IERCX.Token to a JSON string.
* It requires to receive owner address as a parameter. * It requires to receive owner address as a parameter.
*/ */
function toString(FleekERC721.App storage app, address owner) internal view returns (string memory) { function toString(
IERCX.Token storage app,
address owner,
bool accessPointAutoApproval
) internal view returns (string memory) {
// prettier-ignore // prettier-ignore
return string(abi.encodePacked( return string(abi.encodePacked(
'{', '{',
@ -41,7 +46,7 @@ library FleekStrings {
'"owner":"', uint160(owner).toHexString(20), '",', '"owner":"', uint160(owner).toHexString(20), '",',
'"external_url":"', app.externalURL, '",', '"external_url":"', app.externalURL, '",',
'"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",', '"image":"', FleekSVG.generateBase64(app.name, app.ENS, app.logo, app.color.toColorString()), '",',
'"access_point_auto_approval":',app.accessPointAutoApproval.toString(),',', '"access_point_auto_approval":', accessPointAutoApproval.toString(),',',
'"attributes": [', '"attributes": [',
'{"trait_type": "ENS", "value":"', app.ENS,'"},', '{"trait_type": "ENS", "value":"', app.ENS,'"},',
'{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},', '{"trait_type": "Commit Hash", "value":"', app.builds[app.currentBuild].commitHash,'"},',
@ -54,9 +59,9 @@ library FleekStrings {
} }
/** /**
* @dev Converts FleekERC721.AccessPoint to a JSON string. * @dev Converts FleekAccessPoints.AccessPoint to a JSON string.
*/ */
function toString(FleekERC721.AccessPoint storage ap) internal view returns (string memory) { function toString(FleekAccessPoints.AccessPoint storage ap) internal view returns (string memory) {
// prettier-ignore // prettier-ignore
return string(abi.encodePacked( return string(abi.encodePacked(
"{", "{",

View File

@ -91,7 +91,9 @@ const mintTo = '0x7ED735b7095C05d78dF169F991f2b7f1A1F1A049';
console.log('SVG length: ', params[params.length - 1].length); console.log('SVG length: ', params[params.length - 1].length);
params.push(await getSVGColor(svgPath)); params.push(await getSVGColor(svgPath));
const transaction = await contract.mint(...params); const transaction = await contract[
'mint(address,string,string,string,string,string,string,string,uint24)'
](...params);
console.log('Response: ', transaction); console.log('Response: ', transaction);
})(); })();

View File

@ -1,7 +1,12 @@
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { ethers } from 'hardhat'; import { ethers } from 'hardhat';
import { expect } from 'chai'; import { expect } from 'chai';
import { Fixtures, TestConstants, Errors } from './helpers'; import {
Fixtures,
TestConstants,
Errors,
OverloadedFunctions,
} from './helpers';
const { Billing, MintParams } = TestConstants; const { Billing, MintParams } = TestConstants;
@ -12,7 +17,7 @@ describe('FleekERC721.Billing', () => {
const mint = (value?: any) => { const mint = (value?: any) => {
const { contract, owner } = fixture; const { contract, owner } = fixture;
return contract.mint( return contract[OverloadedFunctions.Mint.Default](
owner.address, owner.address,
MintParams.name, MintParams.name,
MintParams.description, MintParams.description,
@ -22,7 +27,6 @@ describe('FleekERC721.Billing', () => {
MintParams.gitRepository, MintParams.gitRepository,
MintParams.logo, MintParams.logo,
MintParams.color, MintParams.color,
MintParams.accessPointAutoApprovalSettings,
{ value } { value }
); );
}; };

View File

@ -1,6 +1,11 @@
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { expect } from 'chai'; import { expect } from 'chai';
import { TestConstants, Fixtures, Errors } from './helpers'; import {
TestConstants,
Fixtures,
Errors,
OverloadedFunctions,
} from './helpers';
const { CollectionRoles } = TestConstants; const { CollectionRoles } = TestConstants;
@ -179,7 +184,7 @@ describe('FleekERC721.CollectionRoles', () => {
it('should not be able to verify access point if not verifier', async () => { it('should not be able to verify access point if not verifier', async () => {
const { contract, otherAccount } = fixture; const { contract, otherAccount } = fixture;
await contract.mint( await contract[OverloadedFunctions.Mint.Default](
otherAccount.address, otherAccount.address,
TestConstants.MintParams.name, TestConstants.MintParams.name,
TestConstants.MintParams.description, TestConstants.MintParams.description,
@ -188,8 +193,7 @@ describe('FleekERC721.CollectionRoles', () => {
TestConstants.MintParams.commitHash, TestConstants.MintParams.commitHash,
TestConstants.MintParams.gitRepository, TestConstants.MintParams.gitRepository,
TestConstants.MintParams.logo, TestConstants.MintParams.logo,
TestConstants.MintParams.color, TestConstants.MintParams.color
TestConstants.MintParams.accessPointAutoApprovalSettings
); );
await contract.addAccessPoint(0, 'random.com'); await contract.addAccessPoint(0, 'random.com');

View File

@ -1,15 +1,17 @@
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { expect } from 'chai'; import { expect } from 'chai';
import { TestConstants, Fixtures, Errors } from './helpers'; import {
import { ethers } from 'hardhat'; TestConstants,
Fixtures,
const { MintParams, Roles } = TestConstants; Errors,
OverloadedFunctions,
} from './helpers';
describe('FleekERC721.GetLastTokenId', () => { describe('FleekERC721.GetLastTokenId', () => {
let fixture: Awaited<ReturnType<typeof Fixtures.default>>; let fixture: Awaited<ReturnType<typeof Fixtures.default>>;
const mint = async () => { const mint = async () => {
const response = await fixture.contract.mint( const response = await fixture.contract[OverloadedFunctions.Mint.Default](
fixture.owner.address, fixture.owner.address,
TestConstants.MintParams.name, TestConstants.MintParams.name,
TestConstants.MintParams.description, TestConstants.MintParams.description,
@ -18,8 +20,7 @@ describe('FleekERC721.GetLastTokenId', () => {
TestConstants.MintParams.commitHash, TestConstants.MintParams.commitHash,
TestConstants.MintParams.gitRepository, TestConstants.MintParams.gitRepository,
TestConstants.MintParams.logo, TestConstants.MintParams.logo,
TestConstants.MintParams.color, TestConstants.MintParams.color
false
); );
return response; return response;

View File

@ -1,5 +1,6 @@
import { ethers, upgrades } from 'hardhat'; import { ethers, upgrades } from 'hardhat';
import { TestConstants } from './constants'; import { TestConstants } from './constants';
import { OverloadedFunctions } from './overloaded-functions';
export abstract class Fixtures { export abstract class Fixtures {
static async paused() {} static async paused() {}
@ -35,7 +36,9 @@ export abstract class Fixtures {
static async withMint() { static async withMint() {
const fromDefault = await Fixtures.default(); const fromDefault = await Fixtures.default();
const response = await fromDefault.contract.mint( const response = await fromDefault.contract[
OverloadedFunctions.Mint.Default
](
fromDefault.owner.address, fromDefault.owner.address,
TestConstants.MintParams.name, TestConstants.MintParams.name,
TestConstants.MintParams.description, TestConstants.MintParams.description,
@ -44,8 +47,7 @@ export abstract class Fixtures {
TestConstants.MintParams.commitHash, TestConstants.MintParams.commitHash,
TestConstants.MintParams.gitRepository, TestConstants.MintParams.gitRepository,
TestConstants.MintParams.logo, TestConstants.MintParams.logo,
TestConstants.MintParams.color, TestConstants.MintParams.color
TestConstants.MintParams.accessPointAutoApprovalSettings
); );
const tokenId = response.value.toNumber(); const tokenId = response.value.toNumber();

View File

@ -3,3 +3,4 @@ export * from './fixture';
export * from './utils'; export * from './utils';
export * from './errors'; export * from './errors';
export * from './events'; export * from './events';
export * from './overloaded-functions';

View File

@ -0,0 +1,8 @@
export const OverloadedFunctions = Object.freeze({
Mint: {
Default:
'mint(address,string,string,string,string,string,string,string,uint24)',
WithAPAutoApproval:
'mint(address,string,string,string,string,string,string,string,uint24,bool)',
},
});

View File

@ -1,15 +1,15 @@
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { expect } from 'chai'; import { expect } from 'chai';
import { TestConstants, Fixtures, Errors } from './helpers'; import { TestConstants, Fixtures, OverloadedFunctions } from './helpers';
import { ethers } from 'hardhat'; import { ethers } from 'hardhat';
const { MintParams, CollectionRoles } = TestConstants; const { MintParams } = TestConstants;
describe('FleekERC721.Minting', () => { describe('FleekERC721.Minting', () => {
it('should be able to mint a new token', async () => { it('should be able to mint a new token', async () => {
const { owner, contract } = await loadFixture(Fixtures.default); const { owner, contract } = await loadFixture(Fixtures.default);
const response = await contract.mint( const response = await contract[OverloadedFunctions.Mint.Default](
owner.address, owner.address,
MintParams.name, MintParams.name,
MintParams.description, MintParams.description,
@ -18,8 +18,7 @@ describe('FleekERC721.Minting', () => {
MintParams.commitHash, MintParams.commitHash,
MintParams.gitRepository, MintParams.gitRepository,
MintParams.logo, MintParams.logo,
MintParams.color, MintParams.color
MintParams.accessPointAutoApprovalSettings
); );
expect(response.value).to.be.instanceOf(ethers.BigNumber); expect(response.value).to.be.instanceOf(ethers.BigNumber);
@ -31,7 +30,7 @@ describe('FleekERC721.Minting', () => {
Fixtures.default Fixtures.default
); );
const response = await contract.mint( const response = await contract[OverloadedFunctions.Mint.Default](
owner.address, owner.address,
MintParams.name, MintParams.name,
MintParams.description, MintParams.description,
@ -40,8 +39,7 @@ describe('FleekERC721.Minting', () => {
MintParams.commitHash, MintParams.commitHash,
MintParams.gitRepository, MintParams.gitRepository,
MintParams.logo, MintParams.logo,
MintParams.color, MintParams.color
MintParams.accessPointAutoApprovalSettings
); );
const tokenId = response.value.toNumber(); const tokenId = response.value.toNumber();

View File

@ -1,6 +1,11 @@
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'; import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { expect } from 'chai'; import { expect } from 'chai';
import { TestConstants, Fixtures, Errors } from './helpers'; import {
TestConstants,
Fixtures,
Errors,
OverloadedFunctions,
} from './helpers';
const { MintParams, CollectionRoles, TokenRoles } = TestConstants; const { MintParams, CollectionRoles, TokenRoles } = TestConstants;
@ -10,7 +15,7 @@ describe('FleekERC721.Pausable', () => {
const mint = () => { const mint = () => {
const { owner, contract } = fixture; const { owner, contract } = fixture;
return contract.mint( return contract[OverloadedFunctions.Mint.Default](
owner.address, owner.address,
MintParams.name, MintParams.name,
MintParams.description, MintParams.description,
@ -19,8 +24,7 @@ describe('FleekERC721.Pausable', () => {
MintParams.commitHash, MintParams.commitHash,
MintParams.gitRepository, MintParams.gitRepository,
MintParams.logo, MintParams.logo,
MintParams.color, MintParams.color
false
); );
}; };

View File

@ -25,7 +25,7 @@ import {
NewAccessPoint as NewAccessPointEvent, NewAccessPoint as NewAccessPointEvent,
ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent, ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent,
ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent, ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent,
TokenRolesCleared as TokenRolesClearedEvent TokenRolesCleared as TokenRolesClearedEvent,
} from '../generated/FleekNFA/FleekNFA'; } from '../generated/FleekNFA/FleekNFA';
// Entity Imports [based on the schema] // Entity Imports [based on the schema]

View File

@ -1,4 +1,4 @@
{ {
"version": "0.5.4", "version": "0.5.4",
"timestamp": 1678390993500 "timestamp": 1678390993500
} }

View File

@ -7,7 +7,13 @@ import {
afterAll, afterAll,
} from 'matchstick-as/assembly/index'; } from 'matchstick-as/assembly/index';
import { BigInt, Bytes } from '@graphprotocol/graph-ts'; import { BigInt, Bytes } from '@graphprotocol/graph-ts';
import { createNewCollectionRoleChanged, handleCollectionRoleChangedList, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils'; import {
createNewCollectionRoleChanged,
handleCollectionRoleChangedList,
makeEventId,
USER_ONE,
USER_TWO,
} from '../helpers/utils';
import { CollectionRoleChanged } from '../../../generated/FleekNFA/FleekNFA'; import { CollectionRoleChanged } from '../../../generated/FleekNFA/FleekNFA';
describe('Collection Role Changed tests', () => { describe('Collection Role Changed tests', () => {
@ -16,14 +22,13 @@ describe('Collection Role Changed tests', () => {
let collectionRoleChangedList: CollectionRoleChanged[] = []; let collectionRoleChangedList: CollectionRoleChanged[] = [];
collectionRoleChangedList.push( collectionRoleChangedList.push(
createNewCollectionRoleChanged(0, 0, USER_ONE, true, USER_TWO) // User Two grants collection owner access to User One createNewCollectionRoleChanged(0, 0, USER_ONE, true, USER_TWO) // User Two grants collection owner access to User One
); );
collectionRoleChangedList.push( collectionRoleChangedList.push(
createNewCollectionRoleChanged(2, 0, USER_ONE, false, USER_TWO) // User Two revokes the owner access of User One to the collection createNewCollectionRoleChanged(2, 0, USER_ONE, false, USER_TWO) // User Two revokes the owner access of User One to the collection
); );
handleCollectionRoleChangedList(collectionRoleChangedList); handleCollectionRoleChangedList(collectionRoleChangedList);
}); });
@ -33,18 +38,8 @@ describe('Collection Role Changed tests', () => {
describe('Assertions', () => { describe('Assertions', () => {
test('Check the `role` field of each CollectionRoleChanged event entity', () => { test('Check the `role` field of each CollectionRoleChanged event entity', () => {
assert.fieldEquals( assert.fieldEquals('CollectionRoleChanged', makeEventId(0), 'role', '0');
'CollectionRoleChanged', assert.fieldEquals('CollectionRoleChanged', makeEventId(2), 'role', '0');
makeEventId(0),
'role',
'0'
);
assert.fieldEquals(
'CollectionRoleChanged',
makeEventId(2),
'role',
'0'
);
}); });
test('Check the `toAddress` field of each CollectionRoleChanged event entity', () => { test('Check the `toAddress` field of each CollectionRoleChanged event entity', () => {
@ -78,18 +73,8 @@ describe('Collection Role Changed tests', () => {
}); });
test('Check the `status` field of each CollectionRoleChanged event entity', () => { test('Check the `status` field of each CollectionRoleChanged event entity', () => {
assert.fieldEquals( assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'status', 'true');
'TokenRoleChanged', assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'status', 'false');
makeEventId(0),
'status',
'true'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(2),
'status',
'false'
);
}); });
}); });
}); });

View File

@ -7,7 +7,13 @@ import {
afterAll, afterAll,
} from 'matchstick-as/assembly/index'; } from 'matchstick-as/assembly/index';
import { BigInt, Bytes } from '@graphprotocol/graph-ts'; import { BigInt, Bytes } from '@graphprotocol/graph-ts';
import { createNewTokenRoleChanged, handleTokenRoleChangedList, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils'; import {
createNewTokenRoleChanged,
handleTokenRoleChangedList,
makeEventId,
USER_ONE,
USER_TWO,
} from '../helpers/utils';
import { TokenRoleChanged } from '../../../generated/FleekNFA/FleekNFA'; import { TokenRoleChanged } from '../../../generated/FleekNFA/FleekNFA';
describe('Token Role Changed tests', () => { describe('Token Role Changed tests', () => {
@ -16,18 +22,38 @@ describe('Token Role Changed tests', () => {
let tokenRoleChangedList: TokenRoleChanged[] = []; let tokenRoleChangedList: TokenRoleChanged[] = [];
tokenRoleChangedList.push( tokenRoleChangedList.push(
createNewTokenRoleChanged(0, BigInt.fromI32(0), 0, USER_ONE, true, USER_TWO) // User Two gives User One controller access to TokenId 0 createNewTokenRoleChanged(
0,
BigInt.fromI32(0),
0,
USER_ONE,
true,
USER_TWO
) // User Two gives User One controller access to TokenId 0
); );
tokenRoleChangedList.push( tokenRoleChangedList.push(
createNewTokenRoleChanged(1, BigInt.fromI32(1), 0, USER_TWO, true, USER_ONE) // User One gives User Two controller access to TokenId 1 createNewTokenRoleChanged(
1,
BigInt.fromI32(1),
0,
USER_TWO,
true,
USER_ONE
) // User One gives User Two controller access to TokenId 1
); );
tokenRoleChangedList.push( tokenRoleChangedList.push(
createNewTokenRoleChanged(2, BigInt.fromI32(0), 0, USER_ONE, false, USER_TWO) // User Two revokes the controller access of User One to tokenId 0 createNewTokenRoleChanged(
2,
BigInt.fromI32(0),
0,
USER_ONE,
false,
USER_TWO
) // User Two revokes the controller access of User One to tokenId 0
); );
handleTokenRoleChangedList(tokenRoleChangedList); handleTokenRoleChangedList(tokenRoleChangedList);
}); });
@ -37,44 +63,14 @@ describe('Token Role Changed tests', () => {
describe('Assertions', () => { describe('Assertions', () => {
test('Check the `tokenId` field of each TokenRoleChanged event entity', () => { test('Check the `tokenId` field of each TokenRoleChanged event entity', () => {
assert.fieldEquals( assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'tokenId', '0');
'TokenRoleChanged', assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'tokenId', '1');
makeEventId(0), assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'tokenId', '0');
'tokenId',
'0'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(1),
'tokenId',
'1'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(2),
'tokenId',
'0'
);
}); });
test('Check the `role` field of each TokenRoleChanged event entity', () => { test('Check the `role` field of each TokenRoleChanged event entity', () => {
assert.fieldEquals( assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'role', '0');
'TokenRoleChanged', assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'role', '0');
makeEventId(0), assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'role', '0');
'role',
'0'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(1),
'role',
'0'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(2),
'role',
'0'
);
}); });
test('Check the `toAddress` field of each TokenRoleChanged event entity', () => { test('Check the `toAddress` field of each TokenRoleChanged event entity', () => {
@ -120,24 +116,9 @@ describe('Token Role Changed tests', () => {
}); });
test('Check the `status` field of each TokenRoleChanged event entity', () => { test('Check the `status` field of each TokenRoleChanged event entity', () => {
assert.fieldEquals( assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'status', 'true');
'TokenRoleChanged', assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'status', 'true');
makeEventId(0), assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'status', 'false');
'status',
'true'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(1),
'status',
'true'
);
assert.fieldEquals(
'TokenRoleChanged',
makeEventId(2),
'status',
'false'
);
}); });
}); });
}); });

View File

@ -1,98 +1,115 @@
import { import {
assert, assert,
describe, describe,
test, test,
clearStore, clearStore,
beforeAll, beforeAll,
afterAll, afterAll,
} from 'matchstick-as/assembly/index'; } from 'matchstick-as/assembly/index';
import { BigInt, Bytes } from '@graphprotocol/graph-ts'; import { BigInt, Bytes } from '@graphprotocol/graph-ts';
import { createNewAccessPointEvent, createNewChangeAccessPointCreationStatus, handleChangeAccessPointCreationStatusList, handleNewAccessPoints, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils'; import {
import { ChangeAccessPointCreationStatus, NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA'; createNewAccessPointEvent,
createNewChangeAccessPointCreationStatus,
handleChangeAccessPointCreationStatusList,
handleNewAccessPoints,
makeEventId,
USER_ONE,
USER_TWO,
} from '../helpers/utils';
import {
ChangeAccessPointCreationStatus,
NewAccessPoint,
} from '../../../generated/FleekNFA/FleekNFA';
describe('Change Access Point Creation Status tests', () => { describe('Change Access Point Creation Status tests', () => {
beforeAll(() => { beforeAll(() => {
// New Access Points
let newAccessPoints: NewAccessPoint[] = [];
// User One has two access points: one for tokenId 0 and one for tokenId 1
newAccessPoints.push(
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
);
newAccessPoints.push(
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
);
// User Two has one access point for tokenId 0
newAccessPoints.push(
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
);
handleNewAccessPoints(newAccessPoints);
});
afterAll(() => {
clearStore();
});
describe('Assertions', () => {
test('Check the `creationStatus` field of each access point entity', () => {
assert.fieldEquals('AccessPoint', 'firstAP', 'creationStatus', 'DRAFT');
assert.fieldEquals('AccessPoint', 'secondAP', 'creationStatus', 'DRAFT');
assert.fieldEquals('AccessPoint', 'thirdAP', 'creationStatus', 'DRAFT');
});
test('Check the `creationStatus` field of each access point entity after changing it', () => {
// New Access Points // New Access Points
let newAccessPoints: NewAccessPoint[] = []; let changeAccessPointCreationStatusList: ChangeAccessPointCreationStatus[] =
[];
// User One has two access points: one for tokenId 0 and one for tokenId 1 // User One has two access points: one for tokenId 0 and one for tokenId 1
newAccessPoints.push( changeAccessPointCreationStatusList.push(
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE) createNewChangeAccessPointCreationStatus(
0,
'firstAP',
BigInt.fromI32(0),
1,
USER_ONE
)
); );
newAccessPoints.push( changeAccessPointCreationStatusList.push(
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE) createNewChangeAccessPointCreationStatus(
0,
'secondAP',
BigInt.fromI32(1),
1,
USER_ONE
)
); );
// User Two has one access point for tokenId 0 // User Two has one access point for tokenId 0
newAccessPoints.push( changeAccessPointCreationStatusList.push(
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO) createNewChangeAccessPointCreationStatus(
0,
'thirdAP',
BigInt.fromI32(0),
1,
USER_TWO
)
); );
handleNewAccessPoints(newAccessPoints);
});
afterAll(() => {
clearStore();
});
describe('Assertions', () => {
test('Check the `creationStatus` field of each access point entity', () => {
assert.fieldEquals(
'AccessPoint',
'firstAP',
'creationStatus',
'DRAFT'
);
assert.fieldEquals(
'AccessPoint',
'secondAP',
'creationStatus',
'DRAFT'
);
assert.fieldEquals(
'AccessPoint',
'thirdAP',
'creationStatus',
'DRAFT'
);
});
test('Check the `creationStatus` field of each access point entity after changing it', () => { handleChangeAccessPointCreationStatusList(
// New Access Points changeAccessPointCreationStatusList
let changeAccessPointCreationStatusList: ChangeAccessPointCreationStatus[] = []; );
// User One has two access points: one for tokenId 0 and one for tokenId 1
changeAccessPointCreationStatusList.push(
createNewChangeAccessPointCreationStatus(0, 'firstAP', BigInt.fromI32(0), 1, USER_ONE)
);
changeAccessPointCreationStatusList.push(
createNewChangeAccessPointCreationStatus(0, 'secondAP', BigInt.fromI32(1), 1, USER_ONE)
);
// User Two has one access point for tokenId 0 assert.fieldEquals(
changeAccessPointCreationStatusList.push( 'AccessPoint',
createNewChangeAccessPointCreationStatus(0, 'thirdAP', BigInt.fromI32(0), 1, USER_TWO) 'firstAP',
); 'creationStatus',
'APPROVED'
handleChangeAccessPointCreationStatusList(changeAccessPointCreationStatusList); );
assert.fieldEquals(
assert.fieldEquals( 'AccessPoint',
'AccessPoint', 'secondAP',
'firstAP', 'creationStatus',
'creationStatus', 'APPROVED'
'APPROVED' );
); assert.fieldEquals(
assert.fieldEquals( 'AccessPoint',
'AccessPoint', 'thirdAP',
'secondAP', 'creationStatus',
'creationStatus', 'APPROVED'
'APPROVED' );
);
assert.fieldEquals(
'AccessPoint',
'thirdAP',
'creationStatus',
'APPROVED'
);
});
}); });
}); });
});

View File

@ -1,96 +1,94 @@
import { import {
assert, assert,
describe, describe,
test, test,
clearStore, clearStore,
beforeAll, beforeAll,
afterAll, afterAll,
} from 'matchstick-as/assembly/index'; } from 'matchstick-as/assembly/index';
import { BigInt } from '@graphprotocol/graph-ts'; import { BigInt } from '@graphprotocol/graph-ts';
import { createNewAccessPointEvent, createNewChangeAccessPointNameVerify, handleChangeAccessPointNameVerifies, handleNewAccessPoints, USER_ONE, USER_TWO } from '../helpers/utils'; import {
import { ChangeAccessPointNameVerify, NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA'; createNewAccessPointEvent,
createNewChangeAccessPointNameVerify,
handleChangeAccessPointNameVerifies,
handleNewAccessPoints,
USER_ONE,
USER_TWO,
} from '../helpers/utils';
import {
ChangeAccessPointNameVerify,
NewAccessPoint,
} from '../../../generated/FleekNFA/FleekNFA';
describe('Change Access Point Name Verify tests', () => { describe('Change Access Point Name Verify tests', () => {
beforeAll(() => { beforeAll(() => {
// New Access Points // New Access Points
let newAccessPoints: NewAccessPoint[] = []; let newAccessPoints: NewAccessPoint[] = [];
// User One has two access points: one for tokenId 0 and one for tokenId 1 // User One has two access points: one for tokenId 0 and one for tokenId 1
newAccessPoints.push( newAccessPoints.push(
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE) createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
);
newAccessPoints.push(
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
);
// User Two has one access point for tokenId 0
newAccessPoints.push(
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
);
handleNewAccessPoints(newAccessPoints);
});
afterAll(() => {
clearStore();
});
describe('Assertions', () => {
test('Check the `nameVerified` field of each access point entity', () => {
assert.fieldEquals('AccessPoint', 'firstAP', 'nameVerified', 'false');
assert.fieldEquals('AccessPoint', 'secondAP', 'nameVerified', 'false');
assert.fieldEquals('AccessPoint', 'thirdAP', 'nameVerified', 'false');
});
test('Check the `nameVerified` field of each access point entity after changing it', () => {
// New Access Point Name Verified fields
let changeAccessPointNameVerifies: ChangeAccessPointNameVerify[] = [];
changeAccessPointNameVerifies.push(
createNewChangeAccessPointNameVerify(
0,
'firstAP',
BigInt.fromI32(0),
true,
USER_ONE
)
); );
newAccessPoints.push( changeAccessPointNameVerifies.push(
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE) createNewChangeAccessPointNameVerify(
0,
'secondAP',
BigInt.fromI32(1),
true,
USER_ONE
)
); );
// User Two has one access point for tokenId 0 changeAccessPointNameVerifies.push(
newAccessPoints.push( createNewChangeAccessPointNameVerify(
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO) 0,
'thirdAP',
BigInt.fromI32(0),
true,
USER_TWO
)
); );
handleNewAccessPoints(newAccessPoints);
});
afterAll(() => {
clearStore();
});
describe('Assertions', () => {
test('Check the `nameVerified` field of each access point entity', () => {
assert.fieldEquals(
'AccessPoint',
'firstAP',
'nameVerified',
'false'
);
assert.fieldEquals(
'AccessPoint',
'secondAP',
'nameVerified',
'false'
);
assert.fieldEquals(
'AccessPoint',
'thirdAP',
'nameVerified',
'false'
);
});
test('Check the `nameVerified` field of each access point entity after changing it', () => { handleChangeAccessPointNameVerifies(changeAccessPointNameVerifies);
// New Access Point Name Verified fields
let changeAccessPointNameVerifies: ChangeAccessPointNameVerify[] = [];
changeAccessPointNameVerifies.push(
createNewChangeAccessPointNameVerify(0, 'firstAP', BigInt.fromI32(0), true, USER_ONE)
);
changeAccessPointNameVerifies.push(
createNewChangeAccessPointNameVerify(0, 'secondAP', BigInt.fromI32(1), true, USER_ONE)
);
changeAccessPointNameVerifies.push( assert.fieldEquals('AccessPoint', 'firstAP', 'nameVerified', 'true');
createNewChangeAccessPointNameVerify(0, 'thirdAP', BigInt.fromI32(0), true, USER_TWO) assert.fieldEquals('AccessPoint', 'secondAP', 'nameVerified', 'true');
); assert.fieldEquals('AccessPoint', 'thirdAP', 'nameVerified', 'true');
handleChangeAccessPointNameVerifies(changeAccessPointNameVerifies);
assert.fieldEquals(
'AccessPoint',
'firstAP',
'nameVerified',
'true'
);
assert.fieldEquals(
'AccessPoint',
'secondAP',
'nameVerified',
'true'
);
assert.fieldEquals(
'AccessPoint',
'thirdAP',
'nameVerified',
'true'
);
});
}); });
}); });
});

View File

@ -1,109 +1,100 @@
import { import {
assert, assert,
describe, describe,
test, test,
clearStore, clearStore,
beforeAll, beforeAll,
afterAll, afterAll,
} from 'matchstick-as/assembly/index'; } from 'matchstick-as/assembly/index';
import { BigInt, Bytes } from '@graphprotocol/graph-ts'; import { BigInt, Bytes } from '@graphprotocol/graph-ts';
import { createNewAccessPointEvent, handleNewAccessPoints, makeEventId, USER_ONE, USER_TWO } from '../helpers/utils'; import {
createNewAccessPointEvent,
handleNewAccessPoints,
makeEventId,
USER_ONE,
USER_TWO,
} from '../helpers/utils';
import { NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA'; import { NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA';
describe('New Access Point tests', () => { describe('New Access Point tests', () => {
beforeAll(() => { beforeAll(() => {
// New Access Points // New Access Points
let newAccessPoints: NewAccessPoint[] = []; let newAccessPoints: NewAccessPoint[] = [];
// User One has two access points: one for tokenId 0 and one for tokenId 1 // User One has two access points: one for tokenId 0 and one for tokenId 1
newAccessPoints.push( newAccessPoints.push(
createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE) createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE)
); );
newAccessPoints.push( newAccessPoints.push(
createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE) createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE)
); );
// User Two has one access point for tokenId 0 // User Two has one access point for tokenId 0
newAccessPoints.push( newAccessPoints.push(
createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO) createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO)
); );
handleNewAccessPoints(newAccessPoints); handleNewAccessPoints(newAccessPoints);
});
afterAll(() => {
clearStore();
});
describe('Assertions', () => {
test('Check the number of `NewAccessPoint` events to be valid', () => {
assert.entityCount('NewAccessPoint', 3);
}); });
afterAll(() => { test('Check the `apName` field of each event', () => {
clearStore(); assert.fieldEquals(
'NewAccessPoint',
makeEventId(0),
'apName',
'firstAP'.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(1),
'apName',
'secondAP'.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(2),
'apName',
'thirdAP'.toString()
);
}); });
describe('Assertions', () => {
test('Check the number of `NewAccessPoint` events to be valid', () => {
assert.entityCount('NewAccessPoint', 3);
});
test('Check the `apName` field of each event', () => { test('Check the `tokenId` field of each event', () => {
assert.fieldEquals( assert.fieldEquals('NewAccessPoint', makeEventId(0), 'tokenId', '0');
'NewAccessPoint', assert.fieldEquals('NewAccessPoint', makeEventId(1), 'tokenId', '1');
makeEventId(0), assert.fieldEquals('NewAccessPoint', makeEventId(2), 'tokenId', '0');
'apName',
'firstAP'.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(1),
'apName',
'secondAP'.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(2),
'apName',
'thirdAP'.toString()
);
});
test('Check the `tokenId` field of each event', () => {
assert.fieldEquals(
'NewAccessPoint',
makeEventId(0),
'tokenId',
'0'
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(1),
'tokenId',
'1'
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(2),
'tokenId',
'0'
);
});
test('Check the `owner` field of each event', () => {
assert.fieldEquals(
'NewAccessPoint',
makeEventId(0),
'owner',
USER_ONE.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(1),
'owner',
USER_ONE.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(2),
'owner',
USER_TWO.toString()
);
});
test('check the existence of a nonexistent event in the database', () => {
assert.notInStore('NewAccessPoint', makeEventId(3));
});
}); });
});
test('Check the `owner` field of each event', () => {
assert.fieldEquals(
'NewAccessPoint',
makeEventId(0),
'owner',
USER_ONE.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(1),
'owner',
USER_ONE.toString()
);
assert.fieldEquals(
'NewAccessPoint',
makeEventId(2),
'owner',
USER_TWO.toString()
);
});
test('check the existence of a nonexistent event in the database', () => {
assert.notInStore('NewAccessPoint', makeEventId(3));
});
});
});

View File

@ -10,7 +10,7 @@ import {
ChangeAccessPointNameVerify, ChangeAccessPointNameVerify,
TokenRoleChanged, TokenRoleChanged,
CollectionRoleChanged, CollectionRoleChanged,
TokenRolesCleared TokenRolesCleared,
} from '../../../generated/FleekNFA/FleekNFA'; } from '../../../generated/FleekNFA/FleekNFA';
import { import {
handleApproval, handleApproval,
@ -198,10 +198,7 @@ export function createNewAccessPointEvent(
); );
newAccessPoint.parameters.push( newAccessPoint.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('owner', ethereum.Value.fromAddress(owner))
'owner',
ethereum.Value.fromAddress(owner)
)
); );
newAccessPoint.transaction.hash = Bytes.fromI32(event_count); newAccessPoint.transaction.hash = Bytes.fromI32(event_count);
@ -217,7 +214,8 @@ export function createNewChangeAccessPointCreationStatus(
status: i32, status: i32,
triggeredBy: Address triggeredBy: Address
): ChangeAccessPointCreationStatus { ): ChangeAccessPointCreationStatus {
let changeAccessPointCreationStatus = changetype<ChangeAccessPointCreationStatus>(newMockEvent()); let changeAccessPointCreationStatus =
changetype<ChangeAccessPointCreationStatus>(newMockEvent());
changeAccessPointCreationStatus.parameters = new Array(); changeAccessPointCreationStatus.parameters = new Array();
@ -236,10 +234,7 @@ export function createNewChangeAccessPointCreationStatus(
); );
changeAccessPointCreationStatus.parameters.push( changeAccessPointCreationStatus.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('creationStatus', ethereum.Value.fromI32(status))
'creationStatus',
ethereum.Value.fromI32(status)
)
); );
changeAccessPointCreationStatus.parameters.push( changeAccessPointCreationStatus.parameters.push(
@ -262,7 +257,9 @@ export function createNewChangeAccessPointNameVerify(
verified: boolean, verified: boolean,
triggeredBy: Address triggeredBy: Address
): ChangeAccessPointNameVerify { ): ChangeAccessPointNameVerify {
let changeAccessPointNameVerify = changetype<ChangeAccessPointNameVerify>(newMockEvent()); let changeAccessPointNameVerify = changetype<ChangeAccessPointNameVerify>(
newMockEvent()
);
changeAccessPointNameVerify.parameters = new Array(); changeAccessPointNameVerify.parameters = new Array();
@ -281,10 +278,7 @@ export function createNewChangeAccessPointNameVerify(
); );
changeAccessPointNameVerify.parameters.push( changeAccessPointNameVerify.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('verified', ethereum.Value.fromBoolean(verified))
'verified',
ethereum.Value.fromBoolean(verified)
)
); );
changeAccessPointNameVerify.parameters.push( changeAccessPointNameVerify.parameters.push(
@ -320,31 +314,19 @@ export function createNewTokenRoleChanged(
); );
tokenRoleChanged.parameters.push( tokenRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('role', ethereum.Value.fromI32(role))
'role',
ethereum.Value.fromI32(role)
)
); );
tokenRoleChanged.parameters.push( tokenRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('toAddress', ethereum.Value.fromAddress(toAddress))
'toAddress',
ethereum.Value.fromAddress(toAddress)
)
); );
tokenRoleChanged.parameters.push( tokenRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('status', ethereum.Value.fromBoolean(status))
'status',
ethereum.Value.fromBoolean(status)
)
); );
tokenRoleChanged.parameters.push( tokenRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress))
'byAddress',
ethereum.Value.fromAddress(byAddress)
)
); );
tokenRoleChanged.transaction.hash = Bytes.fromI32(event_count); tokenRoleChanged.transaction.hash = Bytes.fromI32(event_count);
@ -365,31 +347,19 @@ export function createNewCollectionRoleChanged(
collectionRoleChanged.parameters = new Array(); collectionRoleChanged.parameters = new Array();
collectionRoleChanged.parameters.push( collectionRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('role', ethereum.Value.fromI32(role))
'role',
ethereum.Value.fromI32(role)
)
); );
collectionRoleChanged.parameters.push( collectionRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('toAddress', ethereum.Value.fromAddress(toAddress))
'toAddress',
ethereum.Value.fromAddress(toAddress)
)
); );
collectionRoleChanged.parameters.push( collectionRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('status', ethereum.Value.fromBoolean(status))
'status',
ethereum.Value.fromBoolean(status)
)
); );
collectionRoleChanged.parameters.push( collectionRoleChanged.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress))
'byAddress',
ethereum.Value.fromAddress(byAddress)
)
); );
collectionRoleChanged.transaction.hash = Bytes.fromI32(event_count); collectionRoleChanged.transaction.hash = Bytes.fromI32(event_count);
@ -400,8 +370,8 @@ export function createNewCollectionRoleChanged(
export function createNewTokenRolesCleared( export function createNewTokenRolesCleared(
event_count: i32, event_count: i32,
tokenId: BigInt, tokenId: BigInt,
byAddress: Address byAddress: Address
): TokenRolesCleared { ): TokenRolesCleared {
let tokenRolesCleared = changetype<TokenRolesCleared>(newMockEvent()); let tokenRolesCleared = changetype<TokenRolesCleared>(newMockEvent());
@ -415,10 +385,7 @@ export function createNewTokenRolesCleared(
); );
tokenRolesCleared.parameters.push( tokenRolesCleared.parameters.push(
new ethereum.EventParam( new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress))
'byAddress',
ethereum.Value.fromAddress(byAddress)
)
); );
tokenRolesCleared.transaction.hash = Bytes.fromI32(event_count); tokenRolesCleared.transaction.hash = Bytes.fromI32(event_count);
@ -470,13 +437,17 @@ export function handleNewAccessPoints(events: NewAccessPoint[]): void {
}); });
} }
export function handleChangeAccessPointCreationStatusList(events: ChangeAccessPointCreationStatus[]): void { export function handleChangeAccessPointCreationStatusList(
events: ChangeAccessPointCreationStatus[]
): void {
events.forEach((event) => { events.forEach((event) => {
handleChangeAccessPointCreationStatus(event); handleChangeAccessPointCreationStatus(event);
}); });
} }
export function handleChangeAccessPointNameVerifies(events: ChangeAccessPointNameVerify[]): void { export function handleChangeAccessPointNameVerifies(
events: ChangeAccessPointNameVerify[]
): void {
events.forEach((event) => { events.forEach((event) => {
handleChangeAccessPointNameVerify(event); handleChangeAccessPointNameVerify(event);
}); });
@ -488,7 +459,9 @@ export function handleTokenRoleChangedList(events: TokenRoleChanged[]): void {
}); });
} }
export function handleCollectionRoleChangedList(events: CollectionRoleChanged[]): void { export function handleCollectionRoleChangedList(
events: CollectionRoleChanged[]
): void {
events.forEach((event) => { events.forEach((event) => {
handleCollectionRoleChanged(event); handleCollectionRoleChanged(event);
}); });

View File

@ -46,23 +46,13 @@ describe('Owner tests', () => {
createTransferEvent(3, CONTRACT, USER_ONE, BigInt.fromI32(3)) createTransferEvent(3, CONTRACT, USER_ONE, BigInt.fromI32(3))
); );
transfers.push( transfers.push(
createTransferEvent( createTransferEvent(4, USER_TWO, USER_ONE, BigInt.fromI32(1))
4,
USER_TWO,
USER_ONE,
BigInt.fromI32(1)
)
); );
transfers.push( transfers.push(
createTransferEvent(5, CONTRACT, USER_TWO, BigInt.fromI32(4)) createTransferEvent(5, CONTRACT, USER_TWO, BigInt.fromI32(4))
); );
transfers.push( transfers.push(
createTransferEvent( createTransferEvent(6, USER_ONE, USER_TWO, BigInt.fromI32(0))
6,
USER_ONE,
USER_TWO,
BigInt.fromI32(0)
)
); );
handleTransfers(transfers); handleTransfers(transfers);
//logStore(); //logStore();

View File

@ -36,23 +36,13 @@ describe('Transfer tests', () => {
createTransferEvent(3, CONTRACT, USER_ONE, BigInt.fromI32(3)) createTransferEvent(3, CONTRACT, USER_ONE, BigInt.fromI32(3))
); );
transfers.push( transfers.push(
createTransferEvent( createTransferEvent(4, USER_TWO, USER_ONE, BigInt.fromI32(1))
4,
USER_TWO,
USER_ONE,
BigInt.fromI32(1)
)
); );
transfers.push( transfers.push(
createTransferEvent(5, CONTRACT, USER_TWO, BigInt.fromI32(4)) createTransferEvent(5, CONTRACT, USER_TWO, BigInt.fromI32(4))
); );
transfers.push( transfers.push(
createTransferEvent( createTransferEvent(6, USER_ONE, USER_TWO, BigInt.fromI32(0))
6,
USER_ONE,
USER_TWO,
BigInt.fromI32(0)
)
); );
handleTransfers(transfers); handleTransfers(transfers);
// logStore(); // logStore();