ERC721Envious & ghostNFT documentation!
ghostNFT is the first application of ERC721Envious Standard aimed at adding collateral to NFTs. ghostNFT introduces an intuitive user experience enabling creators and users to add, redeem, and view collateral to individual NFTs and NFT collections. ghostNFT targets NFT collections, NFT owners, Token Holders, and Web3 Users.
The ERC-721 standard was proposed in January 2018. Starting from Cryptokitties project getting its fame in 2017 to Doodles success in 2021, NFT space attracted a lot of attention resulting in everincreasing ecosystem, spiking trading volumes and diverse sets of NFT collections.
Further innovation in the NFT space was introduced by NFTfi. NFTfi focuses on the NFT floor price to enable the market value of the NFT serve as a collateral in lending protocols. Floor price is impacted by supply-demand dynamics of the NFT market which typically experiences higher volatility relative to price action of the general crypto market. Additionally, potential price increase the floor price accounted for by lending protocols. Using floor price based on the market manipulation in individual NFT collections may artificially increase market prices and, thus, value alone is both volatile and unreliable.
The ERC721Envious standard is an extension of ERC721, similar to OpenZeppelin’s ERC721Enumerable abstract contract. ERC721Envious is designed to ensure compatibility with OpenZeppelin ERC721, making it more convenient to use. This standard permits the collateralization of individual NFTs and NFT collections. Furthermore, EnviousHouse allows for the addition of collateral to previously minted NFTs, turning them into collateralized NFTs.
Warning
ghostNFT is an experimental initiative that seeks to unite the DeFi and NFT communities to benefit both. It is crucial to have a complete understanding of the project’s objectives, examine the code thoroughly, and review the contents of the ./audits
folder.
The ERC721Envious framework aims to utilize the smart contract address as a shared ERC20 token vault, with each unique tokenId
acting as the key to the partial amount that belongs to the token holder and never leaves their wallet.
Hint
To obtain this documentation, you can access the versions flyout menu located at the bottom-left corner of the page and select the preferred download format, which includes PDF, HTML, or Epub.
Getting Started
1. Create a gNFT.
If you already have a collection, you can use the EnviousHouse wrapper to integrate the ERC721Envious standard and make it compatible with the Envious protocol.
On the other hand, if you are starting a new project, it is recommended to use the ERC721Envious extension or one of the available Presets as a starting point to simplify the process of implementing the Envious standard.
2. ERC721Envious Presets.
Preset contracts combine ERC721Envious with custom extensions and modules, presenting common configurations and business logic that can be easily deployed without the need to write Solidity code.
Hint
Preset contracts are pre-built smart contracts that come with pre-configured extensions and modules, demonstrating common configurations and business logic. They allow intermediate and advanced users to utilize them as a foundation when developing their own contracts, expanding them with custom features to suit their needs. As the GHOST team continues to work on new ideas and real-world use cases, they welcome suggestions for new presets.
Warning
The most battle-tested preset is ERC721EnviousDynamic, which has been thoroughly tested and is recommended for use. Please refer to John McAfee Legacy (JML) NFT Collection for more information on this preset. GHOST team is continuously exploring new opportunities to implement other presets for Web3 use cases.
3. Use Cases.
The ERC721Dynamic preset was first used for the John McAfee Legacy (JML) NFT Collection. However, because of its dynamic nature, it requires the use of a measurementToken
called Ghost McAfee Vision (GMV). GMV is utilized to rotate NFT images in accordance with the actual collateral and represents the initial balance for the genesis block on the GHOST Chain.
Hint
Additional information on the Initial NFT Offering (INO) can be found here.
To ensure a decentralized approach, a ghostFaucet has been developed, which represents the first real-world Initial NFT Offering (INO). It gamifies the idea of an airdrop by providing actual collateral in the form of NFTs.
4. Testing.
You can locate full test coverage in the ./coverage
folder, while test results and gas reports are stored in the ./gas_reporter
folder.
To test smart contracts locally, please execute the following commands:
truffle run coverage # prepare test coverage report
truffle test # run all tests as single unit
# OR
truffle test tests/FILENAME.test.js # run specific needed test
You can find Slither reports for each smart contract in the ./audits/slither/
folder. Similarly, Mythril reports can be found in the ./audits/mythril/
folder.
We welcome your feedback and pull requests!
Warning
The Mythril analysis was conducted in a Docker container and took around 1 hour for each smart contract.
Contents
Environment
Requirements
Install git, node, and truffle.
Hint
During the development process, truffle@5.5.18 was utilized. Using other truffle versions may be prone to instability when running the coverage
plugin.
Clone git
git clone https://github.com/somegit.git
cd ./envious/
Install dependencies
npm install
Usage
Compile smart contracts
truffle compile
Hint
During the development process, Debian GNU/Linux 10 (buster) was utilized. However, attempts to use Hardhat were unsuccessful due to the size of the generated bytecode. It is worth noting that despite using the same optimizer and optimization runs, Hardhat and Truffle produced different results.
Once the smart contracts are compiled, smart contract testing may begin.
truffle test
# OR
truffle run coverage
Please explore ./audits/slither/
for every smart contract in this project or run slither independently.
slither contracts/FILENAME.sol
Advanced users are strongly recommended to use mytril, which is considered one of the best tools for analyzing Solidity smart contracts.
Extension Usage
Inherit ERC721Envious
To begin minting an ERC721Envious NFT Collection, it is recommended to follow the OpenZeppelin ERC721 standard for actual EIP-721 implementation. Follow the steps outlined below to mint an ERC721Envious NFT Collection.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./contracts/extension/ERC721Envious.sol";
contract YourCollectionName is ERC721Envious {
constructor (string memory name, string memory symbol) ERC721(name, symbol) {}
}
Basic Customization
Many NFT collections prefer to use IPFS, which is an excellent tool for Web3 developers. Let’s assume that every new NFT is minted after the asset is designed and uploaded onto IPFS. This way, the NFT collection will have the creator role.
While creating a unique IPFS hash for every new NFT is not a standard way of implementing NFT, it is still feasible by overriding the tokenURI
function logic.
Hint
This is a simplified method to incorporate smart contract admin. Make sure to incorporate any logic that suits the project requirements.
Sending native coins to a smart contract by mistake can lead to the permanent loss of those coins. The issue can be resolved by implementing a receive
function and rerouting the mistake.
It is recommended to use ERC721Enumerable to improve the search capabilities in the collection.
ERC721Envious standard enables developers to create their own distribution logic for the _disperse
function, which is responsible for distributing funds across assets in a collection. The standard also offers customizable templates for this function. However, by default, the _disperse
function splits the contract’s balance equally among all NFTs in the collection.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./contracts/extension/ERC721Envious.sol";
import "@openzeppelin/token/ERC721/extensions/ERC721Enumerable.sol";
contract YourCollectionName is ERC721Envious, ERC721Enumerable {
address private immutable _creator;
uint256 private _tokenNumber;
mapping(uint256 => string) private _tokenURIs;
/* --snip-- */
receive() external payable {
_disperseTokenCollateral(msg.value, address(0));
}
function mint(address who, string memory hash) public override {
require(_msgSender() == address(this), "only for itself");
_tokenNumber += 1;
_safeMint(who, _tokenNumber);
}
function creatorMint(address who, string memory hash) external {
require(_msgSender() == _creator(), "only for creator");
mint(who);
_tokenURIs[_tokenNumber] = hash;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
_requireMinted(tokenId);
return _tokenURIs[tokenId];
}
}
Defining Disperse Function
In most cases the default dispersion method will follow its classic definition in which the entire balance splits equality among all NFTs in the collection. However, the _disperse
function is left undefined so that developers can define their own custom dispersion logic tailored to their specific project needs.
Hint
When the _disperse
function is executed the collateral amount is not transferred under the corresponding tokenId. To keep track of this intermediate step, it is necessary to store both the total disperse balance and the disperse balance for each tokenId.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./contracts/extension/ERC721Envious.sol";
import "@openzeppelin/token/ERC721/extensions/ERC721Enumerable.sol";
contract YourCollectionName is ERC721Envious, ERC721Enumerable {
/* --snip-- */
function _disperse(address tokenAddress, uint256 tokenId) internal virtual override {
uint256 balance = disperseBalance[tokenAddress] / totalSupply();
if (disperseTotalTaken[tokenAddress] + balance > disperseBalance[tokenAddress]) {
balance = disperseBalance[tokenAddress] - disperseTotalTaken[tokenAddress];
}
if (balance > disperseTaken[tokenId][tokenAddress]) {
uint256 amount = balance - disperseTaken[tokenId][tokenAddress];
disperseTaken[tokenId][tokenAddress] += amount;
(bool shouldAppend,) = _arrayContains(tokenAddress, collateralTokens[tokenId]);
if (shouldAppend) {
collateralTokens[tokenId].push(tokenAddress);
}
collateralBalances[tokenId][tokenAddress] += amount;
disperseTotalTaken[tokenAddress] += amount;
}
}
}
Clean Up
Since both ERC721Enumerable and ERC721Envious inherit from the ERC721 standard, there may be some intersections that can cause errors during compilation. All intersections should be overridden to compile without issues.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./contracts/extension/ERC721Envious.sol";
import "@openzeppelin/token/ERC721/extensions/ERC721Enumerable.sol";
contract YourCollectionName is ERC721Envious, ERC721Enumerable {
/* --snip-- */
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721Envious, ERC721Enumerable, ERC721)
returns (bool)
{
return ERC721Envious.supportsInterface(interfaceId) || ERC721Enumerable.supportsInterface(interfaceId);
}
function _disperse(address tokenAddress, uint256 tokenId) internal virtual override {
uint256 balance = disperseBalance[tokenAddress] / totalSupply();
if (disperseTotalTaken[tokenAddress] + balance > disperseBalance[tokenAddress]) {
balance = disperseBalance[tokenAddress] - disperseTotalTaken[tokenAddress];
}
if (balance > disperseTaken[tokenId][tokenAddress]) {
uint256 amount = balance - disperseTaken[tokenId][tokenAddress];
disperseTaken[tokenId][tokenAddress] += amount;
(bool shouldAppend,) = _arrayContains(tokenAddress, collateralTokens[tokenId]);
if (shouldAppend) {
collateralTokens[tokenId].push(tokenAddress);
}
collateralBalances[tokenId][tokenAddress] += amount;
disperseTotalTaken[tokenAddress] += amount;
}
}
}
Final Code
Code can now be deployed to any EVM-compatible blockchain network and let the code handle the rest. Developers have the freedom to explore and integrate gamification features around collateralization
and/or dispersion
as they see fit. More advanced Solidity developers will find this powerful tool inspiring to design creative and diverse solutions that push the boundaries of both NFT and DeFi ecosystems.
Please find the final version of the code below:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./contracts/extension/ERC721Envious.sol";
import "@openzeppelin/token/ERC721/extensions/ERC721Enumerable.sol";
contract YourCollectionName is ERC721Envious, ERC721Enumerable {
address private immutable _creator;
uint256 private _tokenNumber;
mapping(uint256 => string) private _tokenURIs;
constructor (string memory name, string memory symbol) ERC721(name, symbol) {
_creator = _msgSender();
}
receive() external payable {
_disperseTokenCollateral(msg.value, address(0));
}
function mint(address who, string memory hash) public override {
require(_msgSender() == address(this), "only for itself");
_tokenNumber += 1;
_safeMint(who, _tokenNumber);
}
function creatorMint(address who, string memory hash) external {
require(_msgSender() == _creator(), "only for creator");
mint(who);
_tokenURIs[_tokenNumber] = hash;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
_requireMinted(tokenId);
return _tokenURIs[tokenId];
}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721Envious, ERC721Enumerable, ERC721)
returns (bool)
{
return ERC721Envious.supportsInterface(interfaceId) || ERC721Enumerable.supportsInterface(interfaceId);
}
}
EnviousHouse Usage
Concept
This section contains a more comprehensive overview of the EnviousHouse smart contract.
The EnviousHouse contract enables any already deployed ERC721 collection to upgrade to the ERC721Envious standard and gain collateral functionality by simply calling the registerCollection
function. This allows any NFT collection to become envious and take advantage of the benefits offered by the ERC721Envious standard.
function registerCollection(address collection, address token, uint256 incoming, uint256 outcoming) external payable override
registerCollection
function will require the following parameters:
Collection address
measurementToken
addressIncoming fee (collateralization fee)
Outcoming fee (uncollateralization fee)
Simply insert an NFT collection address to access EnviousHouse functionality. More information can be found in EnviousHouse Specifications.
Warning
Every NFT Collection can only be registered once, and the set parameters cannot be reversed or updated. It is crucial to ensure that the set parameters are aligned with the goals of the project.
ERC721 Collection Integration
This section provides instructions on how to add an ERC721 NFT collection to ghostNFT. The process comprises six straightforward steps that can be completed in less than two minutes.
Definitions:
Term |
Description |
---|---|
Collection address |
address of ERC721 NFT collection |
Commission Token |
ERC20 token that will |
Collateralization Fee |
percentage fee charged from every collateral deposit |
Uncollateralization Fee |
percentage fee change from every collateral redemption |
Dispersion Amount |
minimum amount of the native coin required to register an ERC721 NFT collection |
Warning
The Commission Token
is an ERC20 token, therefore, do not input an externally owned account (EOA) address in the Commission Token field.
Hint
Holders of Commission Token
are granted exclusive access to exchange their tokens for Collateralization Fee
and Uncollateralization Fee
.
Hint
At the time of deployment, the Dispersion Amount
was established at $69.00 in the native coin based on current market prices.

Step 1. Please choose a blockchain network. ghostNFT is currently available on 16 EVM-compatible chains.
Step 2. Press Add your collection button.

Step 3.
Provide the Collection Address
.
Step 4.
Provide the Commission Token
.
Hint
It is advisable to either create a new ERC20 token specifically for use as a Commission Token
, or utilize an existing ERC20 token that already has a thriving community.
Step 5.
Set appropriate Collateralization Fee
and Uncollateralization Fee
.
Hint
The Collateralization Fee
and Uncollateralization Fee
should be established at appropriate levels to avoid discouraging users from adding collateral to the collection.
Step 6.
Set the Dispersion Amount
.
Hint
Dispersion Amount
fully goes to all tokenId holders.
That’s it! Congratulations on successfully registering your ERC721 collection with ghostNFT!
Preset Usage
Concept
The primary objective of all presets is to predefine the majority of the template’s functionality for developers, in order to strike a balance between code flexibility and time efficiency. Please read the documentation for all presets to detect already implemented functionality which can be inherited by simply copying the code.
If you have any ideas regarding code improvement or additional presets, pull requests (PRs) are welcome.
Inherit ERC721Envious
ERC721EnviousPreset
logic should be simply inherited if the business logic of the project is aligned with the logic of the standard.
Hint
For most NFT collections, the predefined functionalities and structure provided by the EnviousHouse framework and ERC721EnviousPreset will not meet the requirements, and additional customization will be necessary.
// SPDX-License-Identifier: MIT
import "./presets/ERC721EnviousPreset.sol";
pragma solidity ^0.8.0;
contract YourAwesomeName is ERC721EnviousPreset {
constructor(
string memory name,
string memory symbol,
string memory baseURI
) ERC721Envious(name, symbol, baseURI) {}
}
A more detailed description of each existing ERC721Envious Preset can be found in the Presets section of this documentation.
ERC721Envious Extension
Description
ERC721Envious smart contract is an abstract smart contract that extends the functionality of ERC721 by enabling collateral features. The address of an ERC721Envious collection stores the native coin and ERC20 tokens where the tokenId serves as the access key unlocking the corresponding portion of the balance.
Hint
Following best practices, the native coin will be associated with the 0x0000000000000000000000000000000000000000 address to avoid collision between the native coin and ERC20 tokens.
Any user can collateralize any specific tokenID with any combination of the native coin and any ERC20 tokens. ERC721Envious allows each tokenId to store a unique array of token addresses owned, which eliminates the need for token registration and array length.
However, only the owner of the tokenId can redeem or uncollateralize the native coin and ERC20 tokens attached to the tokenId. This ensures that the collateral balance remains with the tokenId owner at any given point of time, and makes it easier to transfer ownership of the tokenId without having to worry about transferring the collateral balance separately.
Hint
When a new ERC20 token is added as collateral, its token address is added to the array of token addresses associated with the tokenId. When the balance of a specific ERC20 token drops to 0, its address is removed from the array of token addresses.
Harvesting
is required to collect accumulated commissions. The total token quantity is calculated after aligning the decimals and taking out a proportional value according to the number of communityToken
submitted.
Hint
Not all ERC20 tokens support the burn function. To work around this limitation, the ERC721Envious standard includes a specific entity called BlackHole, which serves as an analog to the zero address.
Another important feature of the ERC721Envious standard is to disperse
tokens across all assets in the collection in one single transaction.
Hint
When tokens are dispersed to NFTs in a collection the collateral is stored in a temporary variable, and is not immediately reflected in the actual collateral balance behind respective tokenIds. Instead, the dispersed collateral balance for each tokenId is updated when collateral
or uncollateral
operation takes place on that specific tokenId.
Warning
The dispersion logic relies on the totalSupply
function. It is important to ensure that there are no issues with the totalSupply
function to prevent any unintended consequences in the dispersion logic.
It is possible to make the collateral
, uncollateral
, harvest
, and disperse
functions more flexible by allowing users to specify an array of actions to be performed in a single transaction. This can help reduce the gas fees associated with performing these actions individually.
IERC721Envious
IERC721Envious is an optional Envious extension for ERC-721 Non-Fungible Token Standard.
commissions
function commissions(uint256 index) external view returns (uint256)
commissions are defined by an array with two elements as input, each representing a commission percentage charged on collateral. The first element denotes the commission charged for collateralization, while the second element represents the commission for uncollateralization. It is important to note that a 3 decimal buffer should be added to each commission rate. For example, 1% would be represented as 1000.
commissions function returns the value of the respective commission fee.
_Arguments_
Name |
Type |
Description |
---|---|---|
index |
uint256 |
index of value in array |
ghostAddress
function ghostAddress() external view returns (address)
ghostAddress function returns the token address for bond payouts. Following the launch of ghostDAO, ghostAddress will be set to the tokenAddress
of the GHST token.
ghostBondingAddress
function ghostBondingAddress() external view returns (address)
ghostBondingAddress function returns the smart contract address that facilitates the purchase of bonds using the DeFi 2.0 protocol. Following the launch of ghostDAO, ghostBondingAddress will be set to the bonding smart contract address of ghostDAO.
blackHole
function blackHole() external view returns (address)
blackHole
is an address that ensures any tokens sent to it cannot be retrieved.
blackHole function returns the address of the blackHole
.
communityToken
function communityToken() external view returns (address)
communityToken is an ERC20 token set by the collection registrant. communityToken
can be exchanged to harvest accumulated commissions.
communityToken function returns the address of the communityToken
.
communityPool
function communityPool(uint256 index) external view returns (address)
Pool of available tokens for harvesting.
communityPool is an array of ERC20 addresses that can be harvested by communityToken
holders.
communityPool function returns the address of a specific ERC20 token available for harvesting by communityToken
holders.
_Arguments_
Name |
Type |
Description |
---|---|---|
index |
uint256 |
index of value in array |
communityBalance
function communityBalance(address tokenAddress) external view returns (uint256)
communityBalance is the amount of ERC20 token available for harvesting.
communityBalance function returns the total balance of a specified ERC20 token that has been accumulated from collected commissions and is currently available for harvesting.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of an ERC20 token available for harvesting |
disperseTokens
function disperseTokens(uint256 index) external view returns (address)
disperseTokens is an array of ERC20 tokens that have already been dispersed.
disperseTokens function returns the address of a specific ERC20 token that has been dispersed.
_Arguments_
Name |
Type |
Description |
---|---|---|
index |
uint256 |
index of value in array |
disperseBalance
function disperseBalance(address tokenAddress) external view returns (uint256)
disperseBalance is the total amount of ERC20 tokens that have been distributed to all tokenIds within a particular NFT collection.
disperseBalance function returns the total amount of a particular ERC20 token that has been dispersed to all tokenIds within a particular NFT collection.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of a dispersed ERC20 token |
disperseTotalTaken
function disperseTotalTaken(address tokenAddress) external view returns (uint256)
disperseTotalTaken is the quantity of ERC20 tokens that has been already claimed from the disperseBalance
.
disperseBalance function returns the number of dispersed ERC20 tokens of a specific tokenAddress
from the disperseBalance
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of a dispersed ERC20 token |
disperseTaken
function disperseTaken(uint256 tokenId, address tokenAddress) external view returns (uint256)
disperseTaken is the quantity of ERC20 tokens that has been already claimed from the disperseBalance
, specifically in reference to a particular tokenId
.
disperseTaken function returns the quantity of a specific ERC20 token that has been distributed from the disperseBalance
to a particular tokenId
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
tokenAddress |
address |
address of a dispersed ERC20 token |
bondPayouts
function bondPayouts(uint256 bondId) external view returns (uint256)
bondPayouts is an estimated quantity of the ghostAddress
token to be obtained from the bond upon completion of the vesting period.
bondPayouts function returns the approximate payout quantity of the ghostAddress token to be obtained from a particular bondId
after the vesting period is over.
_Arguments_
Name |
Type |
Description |
---|---|---|
bondId |
uint256 |
unique bond identifier |
bondIndexes
bondIndexes is a mapping that associates each tokenId
from a particular NFT collection with an array of bonds.
bondIndexes function returns the index
of a bond based on collection address
, tokenId
, and chronological index
position.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
index |
uint256 |
index in array |
collateralTokens
function collateralTokens(uint256 tokenId, uint256 index) external view returns (address)
collateralTokens represents ERC20 tokens used as a collateral for a particular NFT.
collateralTokens function returns the address of an ERC20 token used as a collateral for a particular tokenId
, determined by its chronological index
position.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
tokenAddress |
address |
address of an ERC20 token being held as collateral |
collateralBalances
collateralBalances reflects the total quantity of ERC20 tokens that are currently being held as collateral for a particular tokenId
.
collateralBalances function returns the quantity of ERC20 tokens held as collateral for a specific tokenId
, based on the provided tokenAddress
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
tokenAddress |
address |
address of an ERC20 token being held as collateral |
getAmount
function getAmount(uint256 amount, address tokenAddress) external view returns (uint256)
getAmount is a calculator for estimating the harvesting
amount.
getAmount function returns the harvesting
amount for a specific ERC20 token based on the amount of communityToken
to be exchanged.
_Arguments_
Name |
Type |
Description |
---|---|---|
amount |
uint256 |
amount of |
tokenAddress |
address |
address of a harvested ERC20 token |
harvest
function harvest(uint256[] memory amounts, address[] memory tokenAddresses) external
harvest function collects commission fees in exchange for communityToken
.
_Arguments_
Name |
Type |
Description |
---|---|---|
amounts |
uint256[] |
array of amounts to be harvested |
tokenAddresses |
address[] |
array of token addresses to be harvested |
collateralize
function collateralize(uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses) external payable
collateralize function facilitates the collateralization of a specific tokenId
using a specified amount of a designated ERC20 token.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
amounts |
uint256[] |
array of amounts to be added to the collateral |
tokenAddresses |
address[] |
array of token addresses to be added to the collateral |
uncollateralize
function uncollateralize(uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses) external
uncollateralize function facilitates the redemption of a specific tokenId
using a specified amount of a designated ERC20 token.
Hint
Only the owner of the tokenId is able to trigger the uncollateralize function.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
amounts |
uint256[] |
array of amounts to be redeemed from the collateral |
tokenAddresses |
address[] |
array of token addresses to be redeemed from the collateral |
getDiscountedCollateral
function getDiscountedCollateral(uint256 bondId, address quoteToken, uint256 tokenId, uint256 amount, uint256 maxPrice) external
getDiscountedCollateral function enables NFT collateralization with a discount determined by the available bonds. The smart contract acts as the temporary owner of the bond during the bond vesting period.
_Arguments_
Name |
Type |
Description |
---|---|---|
bondId |
uint256 |
unique bond identifier |
quoteToken |
address |
address of a token that is accepted as a payment for a bond |
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
quantity of the quoteToken paid for the bond |
maxPrice |
uint256 |
maximum price allowed to pay for the bond |
claimDiscountedCollateral
function claimDiscountedCollateral(uint256 tokenId, uint256[] memory indexes) external
claimDiscountedCollateral function allows for the redemption of the corresponding bond notes for ghostAddress collateral after the bond vesting period has elapsed.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
indexes |
uint256[] |
array of note indexes to redeem |
disperse
function disperse(uint256[] memory amounts, address[] memory tokenAddresses) external payable
disperse function logs the amounts of tokenAddresses` into ``disperseBalance
.
_Arguments_
Name |
Type |
Description |
---|---|---|
amounts |
uint256[] |
array of amounts to be dispersed |
tokenAddresses |
address[] |
array of token addresses to be dispersed |
mint
function mint(address who) external
Please refer to full documentation at IERC721-_mint.
_Arguments_
Name |
Type |
Description |
---|---|---|
who |
address |
receiver of NFT |
event Collateralized
event Collateralized is triggered every time a collateral transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be added to the collateral |
tokenAddress |
address |
address of an EC20 token to be added to the collateral |
event Uncollateralized
event Uncollateralized is triggered every time an uncollateral transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be redeemed from the collateral |
tokenAddress |
address |
address of an ERC20 token to be redeemed from the collateral |
event Dispersed
event Dispersed is triggered every time a disperse transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
amount to be dispersed |
amount |
uint256 |
address of an ERC20 token to be dispersed |
event Harvested
event Harvested is triggered every time a harvest transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
amount to be harvested |
amount |
uint256 |
address of an ERC20 token to be harvested |
scaledAmount |
uint256 |
amount of |
ERC721Envious
_arrayContains
function _arrayContains(address tokenAddress, address[] memory findFrom) private pure returns (bool shouldAppend, uint256 index)
_arrayContains function checks whether an element exists in the array. If the element is found, the function returns the index of the element. Otherwise, it sets the variable shouldAppend
to true.
_arrayContains function returns a tuple of values. The first value indicates whether the element should be added to the array (true if the element is not found in the array, false otherwise). The second value indicates the index of the element in the array if it exists.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of an ERC20 token to be added to the collateral |
findFrom |
address[] |
array of available tokenAddresses |
_arrayContains
function _arrayContains(uint256 noteId, uint256[] memory findFrom) private pure returns (uint256 index)
_arrayContains function checks whether a noteId
exists in the bond index array.
_arrayContains function returns the index of the bond based on the noteId
.
_Arguments_
Name |
Type |
Description |
---|---|---|
noteId |
uint256 |
unique bond note identifier |
_scaledAmount
function _scaledAmount(address tokenAddress) private view returns (uint256)
_scaledAmount function adjusts the decimal alignment of tokens collected in communityBalance
to match the decimal places of a communityToken
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of an ERC20 token to be harvested |
_harvest
function _harvest(uint256 amount, address tokenAddress) private
_harvest function is an internal function for function harvest.
_Arguments_
Name |
Type |
Description |
---|---|---|
amount |
uint256 |
amount to an ERC20 token to be harvested |
tokenAddress |
address |
address of an ERC20 token to be harvested |
_addTokenCollateral
function _addTokenCollateral(uint256 tokenId, uint256 amount, address tokenAddress, bool claim) private
_addTokenCollateral function is an internal function for function collateralize
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be added to the collateral |
tokenAddress |
address |
address of an ERC20 token to be added to the collateral |
claim |
bool |
true for bond collateral redemption and false for common collateralization process |
_removeTokenCollateral
function _removeTokenCollateral(uint256 tokenId, uint256 amount, address tokenAddress) private
_removeTokenCollateral function is an internal function for function uncollateralize
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be redeemed from the collateral |
tokenAddress |
address |
address of an ERC20 token to be redeemed from the collateral |
_disperseTokenCollateral
function _disperseTokenCollateral(uint256 amount, address tokenAddress) private
_disperseTokenCollateral function is an internal function for function disperse
.
_Arguments_
Name |
Type |
Description |
---|---|---|
amount |
uint256 |
amount to an ERC20 token to be dispersed |
tokenAddress |
address |
address of an ERC20 token to be dispersed |
_checkValidity
function _checkValidity(address tokenAddress) private view
_checkValidity function determines whether a given address represents a valid ERC20 token by invoking the decimals function.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of any ERC20 token |
_communityCommission
function _communityCommission(uint256 amount, uint256 percentage, address tokenAddress) private returns (uint256)
_communityCommission computes the amount remaining after deducting the commission.
_communityCommission function returns amount after commission based on the amount
before commission, commission percentage
charged, and tokenAddress
.
_Arguments_
Name |
Type |
Description |
---|---|---|
amount |
uint256 |
amount before commission is charged |
percentage |
uint256 |
commission fee rate |
tokenAddress |
address |
address of an ERC20 token |
_disperse
function _disperse(address collection, address tokenAddress, uint256 tokenId) private
_disperse function enables input of a dispersion value, which is then used to increase the collateralBalances
of a particular tokenAddress
for the corresponding tokenId
.
Hint
_disperse function is required to be implemented by the collection creator.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of an ERC20 token to be dispersed |
tokenId |
uint256 |
unique token identifier |
_changeCommunityAddresses
function _changeCommunityAddresses(address newTokenAddress, address newBlackHole) internal virtual
_changeCommunityAddresses function enables to change the address of the communityToken
and the blackHole
.
_Arguments_
Name |
Type |
Description |
---|---|---|
newTokenAddress |
address |
new address of an ERC20 |
newBlackHole |
address |
new address of a |
_changeGhostAddresses
function _changeGhostAddresses(address newGhostTokenAddress, address newGhostBondingAddress) internal virtual
_changeGhostAddresses function enables to change the address of the ghostAddress
and the ghostBondingAddress
.
_Arguments_
Name |
Type |
Description |
---|---|---|
newGhostTokenAddress |
address |
new address of a |
newGhostBondingAddress |
address |
new address of a |
EnviousHouse Contract
Description
EnviousHouse smart contract serves as a middleware between standard ERC721 and ERC721Envious NFT collections.
By integrating EnviousHouse, standard ERC721 collections can become Envious without needing to redeploy their smart contracts. EnviousHouse mirrors the ERC721Envious standard and serves as storage for tokens and native coins. On the other hand, ERC721Envious collections already have all the necessary Envious functionality, and EnviousHouse simply routes the calls.
Hint
Any user has the ability to rescue
unregistered collections by either adding collateral (collateralize
) to an individual NFT or executing a disperse
on the entire collection. Rescued
collections have their commission fees set to 0 by default.
Warning
Commissions
and communityToken
cannot be modified after the standard ERC721 collection has been registered at EnviousHouse
.
The GHOST team believes in the principles of decentralization and web3, and therefore, we do not grant or maintain any admin rights over the current contract. The first user to register a collection will have an opportunity to irreversibly set the communityToken
.
The GHOST team strongly encourages all users to act in good faith and share communityToken
and/or harvested commissions
with the collection creators and community.
Hint
The first user to register a collection will have the ability to set the rate for commissions
and communityToken
. To prevent spam registrations, the registrant is required to make an initial contribution of the minimum dispersion in the native coin to all NFT holders. The minimum required disperse
amount was set to approximately $69.00 on all networks at the time of deployment.
IEnviousHouse
totalCollections
function totalCollections() external view returns (uint256)
totalCollections represents the total number of registered collections.
totalCollections function returns the total count of registered collections.
ghostAddress
function ghostAddress(address collection) external view returns (address)
ghostAddress function returns the token address for bond payouts. Following the launch of ghostDAO, ghostAddress will be set to the tokenAddress
of the GHST token.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
ghostBondingAddress
function ghostBondingAddress(address collection) external view returns (address)
ghostBondingAddress function returns the smart contract address that facilitates the purchase of bonds using the DeFi 2.0 protocol. Following the launch of ghostDAO, ghostBondingAddress will be set to the bonding smart contract address of ghostDAO.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
blackHole
function blackHole(address collection) external view returns (address)
blackHole
is an address that ensures any tokens sent to it cannot be retrieved.
blackHole function returns the address of the blackHole
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
collections
function collections(uint256 index) external view returns (address)
collections is a getter function for registered collection addresses based on the collection index
.
collections function returns the collection address based on the collection index
input.
_Arguments_
Name |
Type |
Description |
---|---|---|
index |
uint256 |
index in array of collections |
collectionIds
function collectionIds(address collection) external view returns (uint256)
collectionIds is a getter function for collection index based on the registered collection address.
collectionIds function returns the collection index based on the collection address input.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
specificCollections
function specificCollections(address collection) external view returns (bool)
specificCollections is a getter function for collections that do not follow the ERC721 standard.
specificCollections function returns whether a particular collection follows the ERC721 standard or not.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
commissions
function commissions(address collection, uint256 index) external view returns (uint256)
commissions are defined by an array with two elements as input, each representing a commission percentage charged on collateral. The first element denotes the commission charged for collateralization, while the second element represents the commission for uncollateralization. It is important to note that a 3 decimal buffer should be added to each commission rate. For example, 1% would be represented as 1000.
commissions function returns the value of the respective commission fee.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
index |
uint256 |
index of value in array |
communityToken
function communityToken(address collection) external view returns (address)
communityToken
is an ERC20 token set by the collection registrant. communityToken can be exchanged to harvest accumulated commissions.
communityToken function returns the address of the communityToken.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
communityPool
function communityPool(address collection, uint256 index) external view returns (address)
communityPool is an array of ERC20 tokens that can be harvested by communityToken
holders.
communityPool function returns the address of a specific ERC20 token available for harvesting by communityToken
holders.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
index |
uint256 |
index of value in array |
communityBalance
function communityBalance(address collection, address tokenAddress) external view returns (uint256)
communityBalance is the amount of ERC20 token available for harvesting.
communityBalance function returns the total balance of a specified ERC20 token that has been accumulated from collected commissions and is currently available for harvesting.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of a token available for harvesting |
disperseTokens
function disperseTokens(address collection, uint256 index) external view returns (address)
disperseTokens is an array of ERC20 tokens that have already been dispersed.
disperseTokens function returns the address of a specific ERC20 token that has been dispersed.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
index |
uint256 |
index of value in array |
disperseBalance
function disperseBalance(address collection, address tokenAddress) external view returns (uint256)
disperseBalance is the total amount of ERC20 tokens that have been distributed to all tokenIds
within a particular NFT collection.
disperseBalance function returns the total amount of a particular ERC20 token that has been dispersed to all tokenIds within a particular NFT collection.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of a dispersed ERC20 token |
disperseTotalTaken
function disperseTotalTaken(address collection, address tokenAddress) external view returns (uint256)
disperseTotalTaken is the quantity of ERC20 tokens that has been already claimed from the disperseBalance
.
disperseBalance function returns the number of dispersed ERC20 tokens of a specific tokenAddress
from the disperseBalance
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of token |
disperseTaken
function disperseTaken(address collection, uint256 tokenId, address tokenAddress) external view returns (uint256)
disperseTaken is the quantity of ERC20 tokens that has been already claimed from the disperseBalance
, specifically in reference to a particular tokenId.
disperseTaken function returns the quantity of a specific ERC20 token that has been distributed from the disperseBalance
to a particular tokenId
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
tokenAddress |
address |
address of a dispersed ERC20 token |
bondPayouts
function bondPayouts(address collection, uint256 bondId) external view returns (uint256)
bondPayouts is an estimated quantity of the ghostAddress
token to be obtained from the bond upon completion of the vesting period.
bondPayouts function returns the approximate payout quantity of the ghostAddress token to be obtained from a particular bondId
after the vesting period is over.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
bondId |
uint256 |
unique bond identifier |
bondIndexes
function bondIndexes(address collection, uint256 tokenId, uint256 index) external view returns (uint256)
bondIndexes is a mapping that associates each tokenId
from a particular NFT collection with an array of bonds.
bondIndexes function returns the index
of a bond based on collection address
, tokenId
, and chronological index
position.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
index |
uint256 |
index in array |
collateralTokens
function collateralTokens(address collection, uint256 tokenId, uint256 index) external view returns (address)
collateralTokens represents ERC20 tokens used as a collateral for a particular NFT.
collateralTokens function returns the address of an ERC20 token used as a collateral for a particular tokenId
, determined by its chronological index
position.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
index |
uint256 |
index in array |
collateralBalances
function collateralBalances(address collection, uint256 tokenId, address tokenAddress) external view returns (uint256)
collateralBalances reflects the total quantity of ERC20 tokens that are currently being held as collateral for a particular tokenId
.
collateralBalances function returns the quantity of ERC20 tokens held as collateral for a specific tokenId
, based on the provided tokenAddress
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
tokenAddress |
address |
address of an ERC20 token being held as collateral |
getAmount
function getAmount(address collection, uint256 amount, address tokenAddress) external view returns (uint256)
getAmount is a calculator for estimating the harvesting
amount.
getAmount function returns the harvesting
amount for a specific ERC20 token based on the amount of communityToken
to be exchanged.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amount |
uint256 |
amount of |
tokenAddress |
address |
address of an ERC20 harvested token |
setGhostAddresses
function setGhostAddresses(address ghostToken, address ghostBonding) external
setGhostAddress function enables the feature of bonding, representing the ability to add discounted collateral.
_Arguments_
Name |
Type |
Description |
---|---|---|
ghostToken |
address |
address of a non-rebasing bonding token |
ghostBonding |
address |
address of a bonding smart contract |
setSpecificCollection
function setSpecificCollection(address collection) external
setSpecificCollection function enables the addition of any collection that is not compatible with the ERC721 standard to the list of exceptions.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
registerCollection
function registerCollection(address collection, address token, uint256 incoming, uint256 outcoming) external payable
registerCollection function grants Envious functionality to any ERC721-compatible collection and streamlines the distribution of an initial minimum disbursement to all NFT holders.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
token |
address |
address of an ERC20 |
incoming |
uint256 |
collateralization fee, incoming / 1e5 * 100% |
outcoming |
uint256 |
uncollateralization fee, incoming / 1e5 * 100% |
harvest
function harvest(address collection, uint256[] memory amounts, address[] memory tokenAddresses) external
harvest function collects commission fees in exchange for communityToken
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amounts |
uint256[] |
array of amounts to be harvested |
tokenAddresses |
address[] |
array of token addresses to be harvested |
collateralize
function collateralize(address collection, uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses) external payable
collateralize function facilitates the collateralization of a specific tokenId
using a specified amount of a designated ERC20 token.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
amounts |
uint256[] |
array of amounts to be added to the collateral |
tokenAddresses |
address[] |
array of token addresses to be added to the collateral |
uncollateralize
function uncollateralize(address collection, uint256 tokenId, uint256[] memory amounts, address[] memory tokenAddresses) external
uncollateralize function facilitates the redemption of a specific tokenId
using a specified amount of a designated ERC20 token.
Hint
Only the owner of the tokenId is able to trigger the uncollateralize function.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
amounts |
uint256[] |
array of amounts to be redeemed from the collateral |
tokenAddresses |
address[] |
array of token addresses to be redeemed from the collateral |
getDiscountedCollateral
function getDiscountedCollateral(address collection, uint256 bondId, address quoteToken, uint256 tokenId, uint256 amount, uint256 maxPrice) external
getDiscountedCollateral function enables NFT collateralization with a discount determined by the available bonds. The smart contract acts as the temporary owner of the bond during the bond vesting period.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
bondId |
uint256 |
unique bond identifier |
quoteToken |
address |
address of the token that is accepted as a payment for a bond |
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
quantity of the quoteToken paid for the bond |
maxPrice |
uint256 |
maximum price allowed to pay for the bond |
claimDiscountedCollateral
function claimDiscountedCollateral(address collection, uint256 tokenId, uint256[] memory indexes) external
claimDiscountedCollateral function allows for the redemption of the corresponding bond notes for ghostAddress collateral after the bond vesting period has elapsed.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
indexes |
uint256[] |
array of note indexes to redeem |
disperse
function disperse(address collection, uint256[] memory amounts, address[] memory tokenAddresses) external payable
disperse function logs the amounts of tokenAddresses
into disperseBalance
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amounts |
uint256[] |
array of amounts to be dispersed |
tokenAddresses |
address[] |
array of token addresses to be dispersed |
event Collateralized
event Collateralized is triggered every time a collateral transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be added to the collateral |
tokenAddress |
address |
address of an ERC20 token to be added to the collateral |
event Uncollateralized
event Uncollateralized is triggered every time an uncollateral transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be redeemed from the collateral |
tokenAddress |
address |
address of an ERC20 token to be redeemed from the collateral |
event Dispersed
event Dispersed is triggered every time a disperse transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amount |
uint256 |
amount to be dispersed |
tokenAddress |
address |
address of an ERC20 token to be dispersed |
event Harvested
event Harvested is triggered every time a harvest transaction occurs on-chain.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of an ERC20 token to be harvested |
amount |
uint256 |
amount to be harvested |
scaledAmount |
uint256 |
amount of |
EnviousHouse
_arrayContains
function _arrayContains(address tokenAddress, address[] memory findFrom) private pure returns (bool shouldAppend, uint256 index)
_arrayContains function checks whether an element exists in the array. If the element is found, the function returns the index of the element. Otherwise, it sets the variable shouldAppend
to true.
_arrayContains function returns a tuple of values. The first value indicates whether the element should be added to the array (true if the element is not found in the array, false otherwise). The second value indicates the index of the element in the array if it exists.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of an ERC20 token to be added to the collateral |
findFrom |
address[] |
array of available tokenAddresses |
_arrayContains
function _arrayContains(uint256 noteId, uint256[] memory findFrom) private pure returns (uint256 index)
_arrayContains function checks whether a noteId
exists in the bond index array.
_arrayContains function returns the index of the bond based on the noteId
.
_Arguments_
Name |
Type |
Description |
---|---|---|
noteId |
uint256 |
unique bond note identifier |
_scaledAmount
function _scaledAmount(address collection, address tokenAddress) private view returns (uint256)
_scaledAmount function adjusts the decimal alignment of tokens collected in communityBalance
to match the decimal places of a communityToken
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of an ERC20 token to be harvested |
_harvest
function _harvest(address collection, uint256 amount, address tokenAddress) private
_harvest function is an internal function for function harvest.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amount |
uint256 |
amount to an ERC20 token to be harvested |
tokenAddress |
address |
address of an ERC20 token to be harvested |
_addTokenCollateral
function _addTokenCollateral(address collection, uint256 tokenId, uint256 amount, address tokenAddress, bool claim) private
_addTokenCollateral function is an internal function for function collateralize
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be added to the collateral |
tokenAddress |
address |
address of an ERC20 token to be added to the collateral |
claim |
bool |
true for bond collateral redemption and false for common collateralization process |
_removeTokenCollateral
function _removeTokenCollateral(address collection, uint256 tokenId, uint256 amount, address tokenAddress) private
_removeTokenCollateral function is an internal function for function uncollateralize
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenId |
uint256 |
unique token identifier |
amount |
uint256 |
amount to be redeemed from the collateral |
tokenAddress |
address |
address of an ERC20 token to be redeemed from the collateral |
_disperseTokenCollateral
function _disperseTokenCollateral(address collection, uint256 amount, address tokenAddress) private
_disperseTokenCollateral function is an internal function for function disperse
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amount |
uint256 |
amount to an ERC20 token to be dispersed |
tokenAddress |
address |
address of an ERC20 token to be dispersed |
_checkValidity
function _checkValidity(address tokenAddress) private view
_checkValidity function determines whether a given address represents a valid ERC20 token by invoking the decimals function.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of any ERC20 token |
_communityCommission
function _communityCommission(address collection, uint256 amount, uint256 percentage, address tokenAddress) private returns (uint256)
_communityCommission computes the amount remaining after deducting the commission.
_communityCommission function returns amount after commission based on the amount
before commission, commission percentage
charged, and tokenAddress
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
amount |
uint256 |
amount before commission is charged |
percentage |
uint256 |
commission fee rate |
tokenAddress |
address |
address of an ERC20 token |
_disperse
function _disperse(address collection, address tokenAddress, uint256 tokenId) private
_disperse function enables input of a dispersion value, which is then used to increase the collateralBalances
of a particular tokenAddress
for the corresponding tokenId
.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
tokenAddress |
address |
address of an ERC20 token to be dispersed |
tokenId |
uint256 |
unique token identifier |
_rescueCollection
function _rescueCollection(address collection) private
_rescueCollection function sets the commissions
to 0% permanently after an individual NFT from an unregistered collection is collateralized.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
_checkEnvious
function _checkEnvious(address collection) private view
_checkEnvious function determines whether a particular address supports IERC721Envious functionality.
_Arguments_
Name |
Type |
Description |
---|---|---|
collection |
address |
NFT collection address |
Gas Report
The complete test results can be found in the ./gas reporter/EnviousHouse.txt
file. The actual tests are available in the ./tests/EnviousHouse.test.js
file.
·-----------------------------------------------------|---------------------------|--------------|----------------------------·
| Solc version: 0.8.4+commit.c7e474f2 · Optimizer enabled: true · Runs: 1337 · Block limit: 6718946 gas │
······················································|···························|··············|·····························
| Methods │
························|·····························|·············|·············|··············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
························|·····························|·············|·············|··············|··············|··············
| BaseToken · approve · 46220 · 46244 · 46232 · 127 · - │
························|·····························|·············|·············|··············|··············|··············
| BaseToken · mint · - · - · 68285 · 72 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · claimDiscountedCollateral · - · - · 180886 · 2 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · collateralize · 157311 · 328704 · 189772 · 42 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · disperse · 42280 · 131304 · 108063 · 10 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · getDiscountedCollateral · 206118 · 206130 · 206128 · 6 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · harvest · 115467 · 134801 · 122870 · 8 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · registerCollection · 80192 · 213650 · 128844 · 116 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · setGhostAddresses · 68807 · 68819 · 68818 · 11 · - │
························|·····························|·············|·············|··············|··············|··············
| EnviousHouse · uncollateralize · 153272 · 269507 · 188441 · 8 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · claimDiscountedCollateral · - · - · 171087 · 1 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · collateralize · 144540 · 149340 · 145189 · 15 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · disperse · - · - · 130087 · 2 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · getDiscountedCollateral · 183430 · 201799 · 189558 · 6 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · mint · - · - · 167530 · 59 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · setGhostAddresses · 69177 · 69189 · 69188 · 12 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · uncollateralize · - · - · 76840 · 2 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721Mock · mint · - · - · 91012 · 66 · - │
························|·····························|·············|·············|··············|··············|··············
| Deployments · · % of limit · │
······················································|·············|·············|··············|··············|··············
| BaseToken · 775391 · 775451 · 775414 · 11.5 % · - │
······················································|·············|·············|··············|··············|··············
| BlackHole · 321380 · 321452 · 321416 · 4.8 % · - │
······················································|·············|·············|··············|··············|··············
| BondingMock · 1114846 · 1114870 · 1114868 · 16.6 % · - │
······················································|·············|·············|··············|··············|··············
| EnviousHouse · 4266540 · 4266552 · 4266551 · 63.5 % · - │
······················································|·············|·············|··············|··············|··············
| ERC721EnviousPreset · - · - · 5433128 · 80.9 % · - │
······················································|·············|·············|··············|··············|··············
| ERC721Mock · 1477822 · 1477834 · 1477827 · 22 % · - │
·-----------------------------------------------------|-------------|-------------|--------------|--------------|-------------·
BlackHole Contract
Description
Since some ERC20 tokens forbid transfers to the zero address and/or lack implementation of the burn
functionality, it is necessary to have a reliable burning mechanism in the harvest
transactions. blackHole smart contract removes ERC20 communityTokens
from the circulating supply in exchange for commission fees withdrawn.
blackHole has been designed to prevent the transfer of any tokens from itself and can only perform read operations. It is intended to be used with the ERC721Envious extension in implementations related to commission harvesting
.
IBlackHole
function whoAmI
function whoAmI() external view returns (string memory)
whoAmI function returns the name of the BlackHole instance. For instance, the function could be set to return the name IC 1011, which would serve as a unique identifier for the blackHole instance.
absorbedBalance
function absorbedBalance(address token) external view returns (uint256)
absorbedBalance function returns the balance of an ERC20 token that was harvested
and subsequently forwarded to the blackHole smart contract.
_Arguments_
Name |
Type |
Description |
---|---|---|
token |
address |
address of an ERC20 token |
availableSupply
function availableSupply(address token) external view returns (uint256)
availableSupply function returns the remaining balance of an ERC20 token that has not yet been harvested
and is still considered as part of the actual circulating supply.
_Arguments_
Name |
Type |
Description |
---|---|---|
token |
address |
address of an ERC20 token |
Gas Report
The complete test results can be found in the ./gas reporter/BlackHole.txt
file. The actual tests are available in the ./tests/BlackHole.test.js
file.
·---------------------------------------|---------------------------|--------------|----------------------------·
| Solc version: 0.8.4+commit.c7e474f2 · Optimizer enabled: true · Runs: 1337 · Block limit: 6718946 gas │
········································|···························|··············|·····························
| Methods │
·····················|··················|·············|·············|··············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
·····················|··················|·············|·············|··············|··············|··············
| BaseToken · mint · - · - · 68285 · 8 · - │
·····················|··················|·············|·············|··············|··············|··············
| BaseToken · transfer · - · - · 51396 · 3 · - │
·····················|··················|·············|·············|··············|··············|··············
| Deployments · · % of limit · │
········································|·············|·············|··············|··············|··············
| BaseToken · - · - · 775367 · 11.5 % · - │
········································|·············|·············|··············|··············|··············
| BlackHole · - · - · 321380 · 4.8 % · - │
·---------------------------------------|-------------|-------------|--------------|--------------|-------------·
Basic Envious Preset
Description
This preset provides a basic implementation of ERC721Envious with the added functionality of utilizing IBondDepository
and INoteKeeper
. The ERC721Enumerable extension is used in this example, so the _disperse
function is based on the totalSupply
of this extension. Although the current smart contract will implement five extensions, its resulting size is approximately 23.59 KiB as determined by 1337 optimization runs.
Hint
During the development process, Debian and truffle were utilized.
ERC721EnviousPreset
ERC721EnviousPreset is a combination of AccessControlEnumerable, ERC721Burnable, ERC721Pausable, ERC721Enumerable, ERC721Envious.
Implemented roles:
Minter_Role allows for token minting
Pauser_Role grants permissions to pauseNFT transfers
Ghosty_Role is capable of modifying modify Envious-specific variables
Hint
By default, the smart contract deployer will be assigned the Minter_Role, Pauser_Role, and Ghosty_Role.
receive
receive() external payable
receive function routes incoming transfers of the native coin towards dispersing the value of msg.value
.
baseURI
function baseURI() external view virtual returns (string memory)
baseURI is a getter function for the baseURI.
baseURI function returns baseURI for the entire collection.
tokenURI
function tokenURI(uint256 tokenId) public view virtual override returns (string memory)
tokenURI is a getter function for a particular tokenURI.
tokenURI function returns tokenURI for a specific NFT.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
mint
function mint(address to) public virtual override
mint function generates a new token. mint function can be triggered by the account with Minter_Role only.
_Arguments_
Name |
Type |
Description |
---|---|---|
to |
address |
receiver of new NFT |
pause
function pause() external virtual
pause function halts all transfers of NFTs in the collection. pause function can be activated by the account with the Pauser_Role only.
unpause
function unpause() external virtual
unpause function resumes all NFT transfers in the collection. unpause function can be triggered by the account with the Pauser_Role only.
setGhostAddresses
function setGhostAddresses(address ghostToken, address ghostBonding) public virtual
setGhostAddresses function modifies the underlying ghost-related addresses. setGhostAddresses function can be triggered by the account with the Ghosty_Role only.
_Arguments_
Name |
Type |
Description |
---|---|---|
ghostToken |
address |
address of a non-rebasing bonding token |
ghostBonding |
address |
address of a bonding smart contract |
Gas Report
The complete test results can be found in the ./gas reporter/ERC721EnviouspPreset.txt
file. The actual tests are available in the ./tests/ERC721EnviousPreset.test.js
file.
·-----------------------------------------------------|---------------------------|--------------|----------------------------·
| Solc version: 0.8.4+commit.c7e474f2 · Optimizer enabled: true · Runs: 1337 · Block limit: 6718946 gas │
······················································|···························|··············|·····························
| Methods │
························|·····························|·············|·············|··············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
························|·····························|·············|·············|··············|··············|··············
| BadToken · approve · 46201 · 46213 · 46211 · 12 · - │
························|·····························|·············|·············|··············|··············|··············
| BadToken · mint · - · - · 70691 · 6 · - │
························|·····························|·············|·············|··············|··············|··············
| BaseToken · approve · 29180 · 46244 · 46079 · 104 · - │
························|·····························|·············|·············|··············|··············|··············
| BaseToken · burn · - · - · 26889 · 1 · - │
························|·····························|·············|·············|··············|··············|··············
| BaseToken · mint · 51185 · 68321 · 67972 · 109 · - │
························|·····························|·············|·············|··············|··············|··············
| BaseToken · transfer · - · - · 46608 · 1 · - │
························|·····························|·············|·············|··············|··············|··············
| DAI · approve · 29149 · 46213 · 45965 · 69 · - │
························|·····························|·············|·············|··············|··············|··············
| DAI · burn · - · - · 27704 · 1 · - │
························|·····························|·············|·············|··············|··············|··············
| DAI · mint · 70713 · 70749 · 70714 · 69 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · approve · 26628 · 51081 · 44728 · 216 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · burn · 48532 · 66848 · 62738 · 21 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · changeCommissions · 28680 · 68480 · 47782 · 748 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · changeCommunityAddresses · 29310 · 69134 · 49192 · 720 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · claimDiscountedCollateral · 55765 · 244786 · 209562 · 14 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · collateralize · 74616 · 682712 · 193841 · 101 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · disperse · 72718 · 403232 · 150497 · 27 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · getDiscountedCollateral · 158329 · 206611 · 187426 · 23 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · grantRole · 31608 · 101218 · 90625 · 46 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · harvest · 81301 · 312987 · 132263 · 14 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · mint · 155730 · 167530 · 162693 · 571 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · pause · - · - · 47048 · 20 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · renounceRole · 27123 · 36464 · 32906 · 21 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · revokeRole · 31643 · 48470 · 39263 · 21 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · safeTransferFrom · 33631 · 103781 · 86934 · 104 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · safeTransferFrom · 34307 · 104899 · 87796 · 104 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · setApprovalForAll · 26408 · 46320 · 45372 · 189 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · setGhostAddresses · 69177 · 69189 · 69188 · 24 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · transferFrom · 33274 · 96376 · 82939 · 56 · - │
························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousPreset · uncollateralize · 61761 · 298701 · 111653 · 42 · - │
························|·····························|·············|·············|··············|··············|··············
| RebaseToken · approve · 29135 · 46235 · 45986 · 69 · - │
························|·····························|·············|·············|··············|··············|··············
| RebaseToken · initialize · 94307 · 94319 · 94318 · 68 · - │
························|·····························|·············|·············|··············|··············|··············
| RebaseToken · transfer · - · - · 34665 · 1 · - │
························|·····························|·············|·············|··············|··············|··············
| StakingMock · fund · - · - · 61607 · 69 · - │
························|·····························|·············|·············|··············|··············|··············
| TetherToken · approve · 26344 · 46244 · 45955 · 69 · - │
························|·····························|·············|·············|··············|··············|··············
| TetherToken · burn · - · - · 26907 · 1 · - │
························|·····························|·············|·············|··············|··············|··············
| TetherToken · mint · - · - · 68219 · 69 · - │
························|·····························|·············|·············|··············|··············|··············
| Deployments · · % of limit · │
······················································|·············|·············|··············|··············|··············
| BadToken · - · - · 1140859 · 17 % · - │
······················································|·············|·············|··············|··············|··············
| BaseToken · 775391 · 775475 · 775423 · 11.5 % · - │
······················································|·············|·············|··············|··············|··············
| BlackHole · - · - · 321368 · 4.8 % · - │
······················································|·············|·············|··············|··············|··············
| BondingMock · 1114858 · 1114870 · 1114868 · 16.6 % · - │
······················································|·············|·············|··············|··············|··············
| DAI · - · - · 1148998 · 17.1 % · - │
······················································|·············|·············|··············|··············|··············
| ERC721EnviousPreset · - · - · 5478148 · 81.5 % · - │
······················································|·············|·············|··············|··············|··············
| ERC721ReceiverMock · 285979 · 286027 · 286014 · 4.3 % · - │
······················································|·············|·············|··············|··············|··············
| RebaseToken · - · - · 1711816 · 25.5 % · - │
······················································|·············|·············|··············|··············|··············
| StakingMock · 246573 · 246585 · 246585 · 3.7 % · - │
······················································|·············|·············|··············|··············|··············
| TetherToken · - · - · 758083 · 11.3 % · - │
·-----------------------------------------------------|-------------|-------------|--------------|--------------|-------------·
Dynamic Envious Preset
Description
In the specification of the ERC721 standard, the tokenId
maps to a unique URI using the tokenURI
function. This mapping is possible since the tokenURI function is bijective.
In ERC721Envious and EnviousHouse, a new parameter collateral
is added to represent the power of the NFT. The tokenURI
function is modified to include this new parameter and to update the result of the function on every collateral
, uncollateral
, and disperse
function call. These functions are overridden with additional logic to include the new collateral parameter. This allows for more flexibility and customization in how the NFTs are used and represented.
Hint
Currently, collateral is only measured for the measurementToken
, but an upgrade is possible to enable checking of all collateral and achieve a dynamic tokenURI
.
The tokenURI
function in the template implementation appears as follows:
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory currentURI = _baseURI();
return string(abi.encodePacked(currentURI, tokenId.toString()));
}
The results are likely recognizable to most readers and take the form of ipfs://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/1337
for a specific Bored Ape Yacht Club NFT (in this case, number 1337). This link points to the metadata for the given NFT and consists of two components:
Basic URI (in the example, an IPFS hash)
tokenId for an existing NFT
To make the collection dynamic, it’s only necessary to update the tokenURI
function with the following:
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory currentURI = _baseURI();
uint256 tokenPointer = getTokenPointer(tokenId);
return string(abi.encodePacked(currentURI, tokenPointer.toString()));
}
The tokenPointer
refers to the proportional quantity of the measurementToken
.
Hint
Although the GHOST team favors appending .json
to every tokenURI
, any preferred method will suffice.
To implement the getTokenPointer
function, it is necessary to define the edges
that correspond to specific groups of URIs. The keccak256
hashing function can then be applied to merge different parameters into one, resulting in the final tokenPointer. An example of the getTokenPointer
function is provided below:
function getTokenPointer(uint256 tokenId) public view virtual override returns (uint256) {
uint256 collateral = collateralBalances[tokenId][measurmentTokenAddress];
uint256 totalDisperse = disperseBalance[measurmentTokenAddress] / totalSupply();
uint256 takenDisperse = disperseTaken[tokenId][measurmentTokenAddress];
uint256 value = collateral + totalDisperse - takenDisperse;
uint256 range = 1;
uint256 offset = 0;
for (uint256 i = edges.length; i > 0; i--) {
if (value >= edges[i-1].value) {
range = edges[i-1].range;
offset = edges[i-1].offset;
break;
}
}
uint256 seed = uint256(keccak256(abi.encodePacked(tokenId, collateral, totalDisperse))) % range;
return seed + offset;
}
The initial step is to obtain the amount of full collateral in the measurementToken
for a specific tokenId
. Subsequently, the iteration through predetermined edges
takes place to determine the level at which the collateral amount falls into. Finally, the keccak256
is applied to retrieve a specific value within a predefined range.
John McAfee Legacy (JML) NFT Collection is the first implementation of the ERC721EnviousDynamic preset.
IERC721EnviousDynamic
struct Edge
struct Edge stores the required data for enabling dynamic behavior in the collection, which can be compared to levels in gaming.
_Arguments_
Name |
Type |
Description |
---|---|---|
value |
uint256 |
minimal measurementToken collateral in edge |
offset |
uint256 |
minimum tokenId in edge |
range |
uint256 |
maximum tokenId range between the edges |
getTokenPointer
function getTokenPointer(uint256 tokenId) external view returns (uint256)
getTokenPointer serves as a tokenURI getter for a specific tokenId
, with the edge being determined by the collateral.
getTokenPointer function returns a pseudo pointer to the metadata.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
ERC721EnviousDynamic
baseURI
function baseURI() external view virtual returns (string memory)
baseURI is a getter function for the baseURI, typically represented by an IPFS hash.
baseURI function returns the prefix for the URI with metadata.
setGhostAddresses
function setGhostAddresses(address ghostToken, address ghostBonding) public virtual
setGhostAddresses function modifies the underlying ghost-related addresses.
_Arguments_
Name |
Type |
Description |
---|---|---|
ghostToken |
address |
address of a non-rebasing bonding token |
ghostBonding |
address |
address of a bonding smart contract |
changeCommunityAddresses
function changeCommunityAddresses(address newTokenAddress, address newBlackHole) public virtual
changeCommunityAddresses function enables to change the address of the communityToken
and the blackHole
.
_Arguments_
Name |
Type |
Description |
---|---|---|
newTokenAddress |
address |
new address of an ERC20 |
newBlackHole |
address |
new address of a |
_changeBaseURI
function _changeBaseURI(string memory newBaseURI) internal virtual
_changeBaseURI function enables to change baseURI.
_Arguments_
Name |
Type |
Description |
---|---|---|
newBaseURI |
string |
new link prefix |
Gas Report
The complete test results can be found in the ./gas reporter/ERC721EnviousDynamicPreset.txt
file. The actual tests are available in the ./tests/ERC721EnviousDynamicPreset.test.js
file.
·------------------------------------------------------------|---------------------------|--------------|----------------------------·
| Solc version: 0.8.4+commit.c7e474f2 · Optimizer enabled: true · Runs: 1337 · Block limit: 6718946 gas │
·····························································|···························|··············|·····························
| Methods │
·······························|·····························|·············|·············|··············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
·······························|·····························|·············|·············|··············|··············|··············
| BadToken · approve · - · - · 46213 · 12 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BadToken · mint · - · - · 70691 · 6 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · approve · 46220 · 46244 · 46241 · 109 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · mint · 51185 · 68285 · 67982 · 114 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · transfer · - · - · 46608 · 1 · - │
·······························|·····························|·············|·············|··············|··············|··············
| DAI · approve · 46201 · 46213 · 46212 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| DAI · mint · - · - · 70713 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · approve · 26672 · 51125 · 44754 · 215 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · burn · 46412 · 62487 · 59571 · 15 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · changeCommunityAddresses · - · - · 66687 · 2 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · claimDiscountedCollateral · 55765 · 182596 · 156257 · 14 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · collateralize · 69447 · 466833 · 137521 · 105 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · disperse · 72718 · 403232 · 148481 · 31 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · getDiscountedCollateral · 158312 · 206589 · 187408 · 23 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · mint · 151053 · 162853 · 158041 · 562 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · safeTransferFrom · 31313 · 101463 · 84615 · 104 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · safeTransferFrom · 32033 · 102625 · 85522 · 104 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · setApprovalForAll · 26386 · 46298 · 45350 · 189 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · setGhostAddresses · 66774 · 66786 · 66784 · 26 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · transferFrom · 30954 · 94056 · 80619 · 56 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · uncollateralize · 56897 · 138116 · 90793 · 39 · - │
·······························|·····························|·············|·············|··············|··············|··············
| RebaseToken · approve · 46223 · 46235 · 46234 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| RebaseToken · initialize · 94307 · 94319 · 94317 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| StakingMock · fund · - · - · 61607 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| TetherToken · approve · 46232 · 46244 · 46243 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| TetherToken · mint · - · - · 68219 · 59 · - │
·······························|·····························|·············|·············|··············|··············|··············
| Deployments · · % of limit · │
·····························································|·············|·············|··············|··············|··············
| BadToken · - · - · 1140859 · 17 % · - │
·····························································|·············|·············|··············|··············|··············
| BaseToken · 775391 · 775475 · 775422 · 11.5 % · - │
·····························································|·············|·············|··············|··············|··············
| BondingMock · 1114846 · 1114870 · 1114867 · 16.6 % · - │
·····························································|·············|·············|··············|··············|··············
| DAI · - · - · 1148998 · 17.1 % · - │
·····························································|·············|·············|··············|··············|··············
| ERC721EnviousDynamicPreset · 4701295 · 4701307 · 4701306 · 70 % · - │
·····························································|·············|·············|··············|··············|··············
| ERC721ReceiverMock · 285979 · 286027 · 286014 · 4.3 % · - │
·····························································|·············|·············|··············|··············|··············
| RebaseToken · - · - · 1711816 · 25.5 % · - │
·····························································|·············|·············|··············|··············|··············
| StakingMock · 246573 · 246585 · 246584 · 3.7 % · - │
·····························································|·············|·············|··············|··············|··············
| TetherToken · - · - · 758083 · 11.3 % · - │
·------------------------------------------------------------|-------------|-------------|--------------|--------------|-------------·
Royalty Envious Preset
Description
The possibility for creators of an ERC721Envious Collection to receive royalty payments on every transaction between different addresses is due to the fact that the tokenId
can hold actual collateral in ERC20 tokens and native coin.
Hint
By default, all ERC20 tokens that collateralize an NFT will be included in the royalty payments. However, there is an option to customize the list and include only specific tokens if needed.
Commission fees can be collected during the collateralization and uncollateralization processes, which creates an additional revenue stream for creators that is triggered during transferFrom
. It’s worth noting that there are two types of addresses:
Externally Owned Accounts (EOA) that are controlled by private keys and are typically used by humans
Contract Accounts that represent smart contracts deployed on the EVM network
Hint
It is possible for transfers between different accounts to have varying commission fees, which can be customized by the collection developer.
More detailed information on potential use cases for the Royalty Envious Preset can be found here.
IERC721RoyaltyPreset
royalties
function royalties(uint256 id) external view returns (uint256)
royalties function represents royalties that can be assigned to both user addresses and smart contracts. When a transfer occurs between a user address and another user address or smart contract, the first element of the royalty array will be used. Conversely, when a transfer occurs between two smart contracts, the second element of the array will be used.
royalties function returns royalty percentage with a 3 decimal point buffer, meaning that a value of 1,000 represents a royalty percentage of 1%.
_Arguments_
Name |
Type |
Description |
---|---|---|
id |
uint256 |
index position of an element in an array with a length of 2 |
changeRoyalties
function changeRoyalties(uint256 user, uint256 smart) external
_changeRoyalties function enables to change royalties.
_Arguments_
Name |
Type |
Description |
---|---|---|
user |
uint256 |
royalty percentage between EOA addresses |
smart |
uint256 |
royalty percentage between smart contracts |
ERC721RoyaltyPreset
baseURI
function baseURI() external view virtual returns (string memory)
baseURI is a getter function for the baseURI, typically represented by an IPFS hash.
baseURI function returns the prefix for the URI with metadata.
setGhostAddresses
function setGhostAddresses(address ghostToken, address ghostBonding) public virtual
setGhostAddresses function modifies the underlying ghost-related addresses.
Hint
OpenZeppelin’s Ownable provides the onlyOwner
modifier by default.
_Arguments_
Name |
Type |
Description |
---|---|---|
ghostToken |
address |
address of a non-rebasing bonding token |
ghostBonding |
address |
address of a bonding smart contract |
changeCommunityAddresses
function changeCommunityAddresses(address newTokenAddress, address newBlackHole) public virtual
changeCommunityAddresses function enables to change the address of the communityToken
and the blackHole
.
_Arguments_
Name |
Type |
Description |
---|---|---|
newTokenAddress |
address |
new address of an ERC20 |
newBlackHole |
address |
new address of a |
_changeBaseURI
function _changeBaseURI(string memory newBaseURI) internal virtual
_changeBaseURI function enables to change baseURI.
_Arguments_
Name |
Type |
Description |
---|---|---|
newBaseURI |
string |
new link prefix |
changeCommissions
function changeCommissions(uint256 incoming, uint256 outcoming) public virtual
changeCommissions function enables to change the rates of commission fees.
Hint
OpenZeppelin’s Ownable provides onlyOwner
as the default availability.
_Arguments_
Name |
Type |
Description |
---|---|---|
incoming |
uint256 |
updated collateralization fee |
outcoming |
uint256 |
updated uncollateralization fee |
changeRoyalties
function changeRoyalties(uint256 user, uint256 smart) public virtual override onlyOwner
changeRoyalties function enables to change royalties.
Hint
OpenZeppelin’s Ownable provides onlyOwner
as the default availability.
_Arguments_
Name |
Type |
Description |
---|---|---|
user |
uint256 |
royalty percentage between EOA addresses |
smart |
uint256 |
royalty percentage between smart contracts |
_getRoyaltyFromCollateral
function _getRoyaltyFromCollateral(uint256 tokenId, uint256 royalty) internal virtual
_getRoyaltyFromCollateral function calculates and stores royalty payments.
Warning
The collection owner can withdraw collected royalties only in the same manner as other commissions were collected.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
royalty |
uint256 |
royalty percentage |
Gas Report
The complete test results can be found in the ./gas reporter/ERC721EnviousRoyaltyPreset.txt
file. The actual tests are available in the ./tests/ERC721EnviousRoyaltyPreset.test.js
file.
·------------------------------------------------------------|---------------------------|--------------|----------------------------·
| Solc version: 0.8.4+commit.c7e474f2 · Optimizer enabled: true · Runs: 1337 · Block limit: 6718946 gas │
·····························································|···························|··············|·····························
| Methods │
·······························|·····························|·············|·············|··············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
·······························|·····························|·············|·············|··············|··············|··············
| BadToken · approve · - · - · 46213 · 12 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BadToken · mint · - · - · 70691 · 6 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · approve · 29180 · 46244 · 46115 · 133 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · burn · - · - · 26889 · 1 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · mint · 51185 · 68321 · 67929 · 144 · - │
·······························|·····························|·············|·············|··············|··············|··············
| BaseToken · transfer · - · - · 46608 · 1 · - │
·······························|·····························|·············|·············|··············|··············|··············
| DAI · approve · 29149 · 46213 · 45966 · 69 · - │
·······························|·····························|·············|·············|··············|··············|··············
| DAI · burn · - · - · 27704 · 1 · - │
·······························|·····························|·············|·············|··············|··············|··············
| DAI · mint · 70713 · 70749 · 70714 · 69 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · approve · 26628 · 51081 · 44710 · 215 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · burn · 52199 · 68274 · 65358 · 15 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · changeCommissions · 27230 · 68285 · 68074 · 389 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · changeCommunityAddresses · 34651 · 68851 · 68659 · 360 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · changeRoyalties · - · - · 28271 · 6 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · claimDiscountedCollateral · 55765 · 244786 · 209562 · 28 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · collateralize · 74616 · 682724 · 194172 · 106 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · disperse · 72718 · 403232 · 150496 · 27 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · getDiscountedCollateral · 158329 · 206611 · 187426 · 46 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · harvest · 81301 · 312999 · 132266 · 14 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · mint · 160493 · 172293 · 167614 · 578 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · renounceOwnership · - · - · 23269 · 2 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · safeTransferFrom · 36109 · 106120 · 90073 · 104 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · safeTransferFrom · 36783 · 107239 · 90936 · 104 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · setApprovalForAll · 26386 · 46298 · 45350 · 189 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · setGhostAddresses · 68948 · 68972 · 68970 · 50 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · transferFrom · 35755 · 139697 · 92096 · 64 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · transferOwnership · - · - · 28654 · 2 · - │
·······························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · uncollateralize · 61717 · 298705 · 111035 · 43 · - │
·······························|·····························|·············|·············|··············|··············|··············
| RebaseToken · approve · 29135 · 46235 · 45987 · 69 · - │
·······························|·····························|·············|·············|··············|··············|··············
| RebaseToken · initialize · 94307 · 94319 · 94318 · 68 · - │
·······························|·····························|·············|·············|··············|··············|··············
| RebaseToken · transfer · - · - · 34665 · 1 · - │
·······························|·····························|·············|·············|··············|··············|··············
| StakingMock · fund · - · - · 61607 · 69 · - │
·······························|·····························|·············|·············|··············|··············|··············
| TetherToken · approve · 26344 · 46244 · 45955 · 69 · - │
·······························|·····························|·············|·············|··············|··············|··············
| TetherToken · burn · - · - · 26907 · 1 · - │
·······························|·····························|·············|·············|··············|··············|··············
| TetherToken · mint · - · - · 68219 · 69 · - │
·······························|·····························|·············|·············|··············|··············|··············
| Deployments · · % of limit · │
·····························································|·············|·············|··············|··············|··············
| BadToken · - · - · 1140859 · 17 % · - │
·····························································|·············|·············|··············|··············|··············
| BaseToken · 775391 · 775475 · 775424 · 11.5 % · - │
·····························································|·············|·············|··············|··············|··············
| BlackHole · - · - · 321368 · 4.8 % · - │
·····························································|·············|·············|··············|··············|··············
| BondingMock · 1114846 · 1114870 · 1114868 · 16.6 % · - │
·····························································|·············|·············|··············|··············|··············
| DAI · - · - · 1148998 · 17.1 % · - │
·····························································|·············|·············|··············|··············|··············
| ERC721EnviousRoyaltyPreset · - · - · 4539709 · 67.6 % · - │
·····························································|·············|·············|··············|··············|··············
| ERC721ReceiverMock · 285979 · 286027 · 286014 · 4.3 % · - │
·····························································|·············|·············|··············|··············|··············
| RebaseToken · - · - · 1711816 · 25.5 % · - │
·····························································|·············|·············|··············|··············|··············
| StakingMock · 246573 · 246585 · 246584 · 3.7 % · - │
·····························································|·············|·············|··············|··············|··············
| TetherToken · - · - · 758083 · 11.3 % · - │
·------------------------------------------------------------|-------------|-------------|--------------|--------------|-------------·
VRF Envious Preset
Description
The Chainlink VRF (Verifiable Random Function) is a secure and trustworthy method of generating random numbers that enables smart contracts to access unpredictable values while maintaining the integrity and usability of the system. Upon receiving a request, the Chainlink VRF produces one or multiple random values, along with cryptographic evidence of how these values were generated. The evidence is then recorded on the blockchain and validated before being available for consumption by applications. This approach guarantees that the outcomes cannot be altered or controlled by any single party, including oracle operators, miners, users, or smart contract developers. For further details, please refer to the ChainLink documentation <https://docs.chain.link/vrf/v2/introduction/>`_.
The Envious standard offers a variety of functions, but in certain circumstances, they may not suffice. Consider a gaming NFT platform that requires a reward system that disperses
a particular amount of specific tokenIds
chosen at random. In such situations, the VRF Envious Preset is an exceptional solution.
IERC721EnviousVrfPreset
vrfCoordinatorAddress
function vrfCoordinatorAddress() external view returns (address)
vrfCoordinatorAddress function is the coordinator address, which is unique and immutable for each network. Read more here.
sSubscriptionId
function sSubscriptionId() external view returns (uint64)
sSubscriptionId function returns the ChainLink VRF v2 subscription ID.
sKeyHash
function sKeyHash() external view returns (bytes32)
sKeyHash function returns the gas lane that determines the upper limit for gas prices that can be increased. To view the available gas lanes for each network, please refer to the following link.
callbackGasLimit
function callbackGasLimit() external view returns (uint32)
callbackGasLimit function depends on the number of requested values to be forwarded to the fulfillRandomWords()
function. Since storing each word requires about 20,000 gas, a safe default value for this example contract is 40,000 gas. However, it is recommended to test and adjust this limit based on the selected network, the request’s size, and the processing of the callback request in the fulfillRandomWords()
function.
numWords
function numWords() external view returns (uint32)
numWords function returns the word count. It should be noted that numWords cannot exceed the value defined in VRFCoordinatorV2.MAX_NUM_WORDS
.
requestConfirmations
function requestConfirmations() external view returns (uint16)
requestConfirmations function returns the required number of block confirmations, with a default value of 3 confirmations.
prepareRandomness
function prepareRandomness() external returns (uint256)
prepareRandomness function returns on-chain randomness from Chainlink VRF v2.
extraDisperseAmount
function extraDisperseAmount(address tokenAddress) external view returns (uint256)
extraDisperseAmount is an extra quantity of a particular tokenAddress
to be randomly distributed.
extraDisperseAmount function returns the additional quantity of a specific tokenAddress
to be randomly dispersed.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of a dispersed ERC20 token |
extraDisperseTaken
function extraDisperseTaken(address tokenAddress) external view returns (uint256)
extraDisperseTaken is a quantity of an ERC20 token that has been already claimed from the extraDisperseAmount
.
extraDisperseTaken function returns the amount of a specific tokenAddress
that has been distributed from the extraDisperseAmount
.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of a dispersed ERC20 token |
extraDisperseTokenId
function extraDisperseTokenId(address tokenAddress) external view returns (uint256)
extraDisperseTokenId function selects all tokenIds
that are divisible by a specified number, without leaving a remainder, for random distribution.
extraDisperseTokenId function returns divisor used to determine which tokenIds
are eligible for random distribution.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of a dispersed ERC20 token |
randomAmountsDisperse
function randomAmountsDisperse(address tokenAddress, uint256 tokenId) external view returns(uint256)
randomAmountsDisperse generates an additional random amount of tokens to be distributed.
randomAmountsDisperse returns an additional random quantity of tokens for distribution.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenAddress |
address |
address of a dispersed ERC20 token |
tokenId |
uint256 |
unique token identifier |
collateralRandomTokens
function collateralRandomTokens(uint256[] memory amounts, address[] memory tokenAddresses) external payable;
collateralRandomTokens function collateralizes randomly selected tokenIds
with predetermined amount of tokenAddresses
.
_Arguments_
Name |
Type |
Description |
---|---|---|
amounts |
uint256[] |
array of amounts to be added to the collateral |
tokenAddresses |
address[] |
array of token addresses to be added to the collateral |
collateralRandomAmounts
function collateralRandomAmounts(uint256[] memory tokenIds, uint256 amount, address tokenAddress) external payable
collateralRandomAmounts function collateralizes specific tokenIds
with randomly generated amounts
.
Warning
If ETH is used, the amount of collateral required should match the value of the msg.value
parameter.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenIds |
uint256[] |
unique token identifiers |
amounts |
uint256[] |
array of amounts to be added to the collateral |
tokenAddresses |
address[] |
array of token addresses to be added to the collateral |
function initializeVRF
function initializeVRF(uint64 newSSubscriptionId, bytes32 newSKeyHash, uint32 newNumWords, uint32 newCallbackGasLimit, uint16 newRequestConfirmations) external
initializeVRF function is used to initialize all the necessary information related to ChainlinkVRF.
_Arguments_
Name |
Type |
Description |
---|---|---|
newSSubscriptionId |
uint64 |
Chainlink subscription id |
newSKeyHash |
bytes32 |
gas lane used to specify the maximum gas price to increase to |
newNumWords |
uint32 |
number of random values to retrieve |
newCallbackGasLimit |
uint32 |
required gas limit for the fulfillRandomWords() function |
newRequestConfirmations |
uint16 |
number of confirmations required |
event VrfChanged
event VrfChanged(uint64 newSSubscriptionId, bytes32 newSKeyHash, uint32 newNumWords, uint32 newCallbackGasLimit, uint16 newRequestConfirmations);
event vrfChanged is triggered after the parameters related to Chainlink VRF v2 have been changed.
_Arguments_
Name |
Type |
Description |
---|---|---|
newSSubscriptionId |
uint64 |
Chainlink subscription id |
newSKeyHash |
bytes32 |
gas lane used to specify the maximum gas price to increase to |
newNumWords |
uint32 |
number of random values to retrieve |
newCallbackGasLimit |
uint32 |
required gas limit for the fulfillRandomWords() function |
newRequestConfirmations |
uint16 |
number of confirmations required |
ERC721EnviousVrfPreset
baseURI
function baseURI() external view virtual returns (string memory)
baseURI is a getter function for the baseURI.
baseURI function returns baseURI for the entire collection.
tokenURI
function tokenURI(uint256 tokenId) public view virtual override returns (string memory)
tokenURI is a getter function for a particular tokenURI.
tokenURI function returns tokenURI for a specific NFT.
_Arguments_
Name |
Type |
Description |
---|---|---|
tokenId |
uint256 |
unique token identifier |
totalSupply
function totalSupply() public view virtual returns (uint256)
totalSupply is a getter function for the total count of NFTs in the collection.
totalSupply function returns the overall count of NFTs within the collection.
setGhostAddresses
function setGhostAddresses(address ghostToken, address ghostBonding) public virtual
setGhostAddress function enables the feature of bonding, representing the ability to add discounted collateral.
_Arguments_
Name |
Type |
Description |
---|---|---|
ghostToken |
address |
address of a non-rebasing bonding token |
ghostBonding |
address |
address of a bonding smart contract |
changeCommunityAddresses
function changeCommunityAddresses(address newTokenAddress, address newBlackHole) public virtual
changeCommunityAddresses function enables to change the address of the communityToken
and the blackHole
.
_Arguments_
Name |
Type |
Description |
---|---|---|
newTokenAddress |
address |
new address of an ERC20 communityToken |
newBlackHole |
address |
new address of a blackHole |
_nullifyRandomness
function _nullifyRandomness(address who) internal virtual
_nullifyRandomness function invalidates mappings after their use.
_Arguments_
Name |
Type |
Description |
---|---|---|
who |
address |
address that requires nullification |
Gas Report
The complete test results can be found in the ./gas reporter/ERC721VRFRoyaltyPreset.txt
file. The actual tests are available in the ./tests/ERC721VRFRoyaltyPreset.test.js
file.
·--------------------------------------------------------|---------------------------|--------------|----------------------------·
| Solc version: 0.8.4+commit.c7e474f2 · Optimizer enabled: true · Runs: 1337 · Block limit: 6718946 gas │
·························································|···························|··············|·····························
| Methods │
···························|·····························|·············|·············|··············|··············|··············
| Contract · Method · Min · Max · Avg · # calls · eur (avg) │
···························|·····························|·············|·············|··············|··············|··············
| BadToken · approve · 46201 · 46213 · 46211 · 25 · - │
···························|·····························|·············|·············|··············|··············|··············
| BadToken · mint · - · - · 70691 · 15 · - │
···························|·····························|·············|·············|··············|··············|··············
| BaseToken · approve · 29180 · 46244 · 46094 · 115 · - │
···························|·····························|·············|·············|··············|··············|··············
| BaseToken · burn · - · - · 26889 · 1 · - │
···························|·····························|·············|·············|··············|··············|··············
| BaseToken · mint · 51185 · 68321 · 68000 · 120 · - │
···························|·····························|·············|·············|··············|··············|··············
| BaseToken · transfer · - · - · 46608 · 1 · - │
···························|·····························|·············|·············|··············|··············|··············
| DAI · approve · 29149 · 46213 · 45964 · 69 · - │
···························|·····························|·············|·············|··············|··············|··············
| DAI · burn · - · - · 27704 · 1 · - │
···························|·····························|·············|·············|··············|··············|··············
| DAI · mint · 70713 · 70749 · 70714 · 69 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · approve · 26650 · 51103 · 44732 · 215 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · burn · - · - · 31690 · 6 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · changeCommissions · - · - · 46175 · 343 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · changeCommunityAddresses · 32553 · 66753 · 66541 · 326 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · claimDiscountedCollateral · 55787 · 187261 · 160258 · 14 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · collateralize · 74112 · 490178 · 143443 · 101 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · collateralRandomAmounts · - · - · 79304 · 3 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · collateralRandomTokens · 69452 · 102238 · 94950 · 9 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · disperse · 72740 · 403254 · 150519 · 27 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · getDiscountedCollateral · 158294 · 206567 · 187390 · 23 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · harvest · 81301 · 312999 · 132266 · 14 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · initializeVRF · 36246 · 56182 · 54796 · 29 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · mint · 59205 · 76305 · 69393 · 522 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · prepareRandomness · - · - · 98895 · 12 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · renounceOwnership · - · - · 23335 · 2 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · safeTransferFrom · 31028 · 69852 · 59029 · 104 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · safeTransferFrom · 31704 · 70970 · 59892 · 104 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · setApprovalForAll · 26364 · 46276 · 45328 · 189 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · setGhostAddresses · 66642 · 66654 · 66653 · 24 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · transferFrom · 30714 · 62490 · 54579 · 50 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · transferOwnership · - · - · 28676 · 2 · - │
···························|·····························|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · uncollateralize · 89204 · 506027 · 153918 · 45 · - │
···························|·····························|·············|·············|··············|··············|··············
| RebaseToken · approve · 29135 · 46235 · 45986 · 69 · - │
···························|·····························|·············|·············|··············|··············|··············
| RebaseToken · initialize · 94307 · 94319 · 94319 · 68 · - │
···························|·····························|·············|·············|··············|··············|··············
| RebaseToken · transfer · - · - · 34665 · 1 · - │
···························|·····························|·············|·············|··············|··············|··············
| StakingMock · fund · - · - · 61607 · 69 · - │
···························|·····························|·············|·············|··············|··············|··············
| TetherToken · approve · 26344 · 46244 · 45954 · 69 · - │
···························|·····························|·············|·············|··············|··············|··············
| TetherToken · burn · - · - · 26907 · 1 · - │
···························|·····························|·············|·············|··············|··············|··············
| TetherToken · mint · - · - · 68219 · 69 · - │
···························|·····························|·············|·············|··············|··············|··············
| VRFCoordinatorV2Mock · addConsumer · 70732 · 70744 · 70740 · 13 · - │
···························|·····························|·············|·············|··············|··············|··············
| VRFCoordinatorV2Mock · createSubscription · - · - · 67774 · 13 · - │
···························|·····························|·············|·············|··············|··············|··············
| VRFCoordinatorV2Mock · fulfillRandomWords · 82435 · 82447 · 82443 · 13 · - │
···························|·····························|·············|·············|··············|··············|··············
| VRFCoordinatorV2Mock · fundSubscription · - · - · 29385 · 12 · - │
···························|·····························|·············|·············|··············|··············|··············
| Deployments · · % of limit · │
·························································|·············|·············|··············|··············|··············
| BadToken · - · - · 1140859 · 17 % · - │
·························································|·············|·············|··············|··············|··············
| BaseToken · 775391 · 775475 · 775422 · 11.5 % · - │
·························································|·············|·············|··············|··············|··············
| BlackHole · - · - · 321368 · 4.8 % · - │
·························································|·············|·············|··············|··············|··············
| BondingMock · 1114858 · 1114870 · 1114868 · 16.6 % · - │
·························································|·············|·············|··············|··············|··············
| DAI · - · - · 1148998 · 17.1 % · - │
·························································|·············|·············|··············|··············|··············
| ERC721EnviousVRFPreset · 4949552 · 4949564 · 4949563 · 73.7 % · - │
·························································|·············|·············|··············|··············|··············
| ERC721ReceiverMock · 285979 · 286027 · 286014 · 4.3 % · - │
·························································|·············|·············|··············|··············|··············
| RebaseToken · - · - · 1711816 · 25.5 % · - │
·························································|·············|·············|··············|··············|··············
| StakingMock · 246573 · 246585 · 246585 · 3.7 % · - │
·························································|·············|·············|··············|··············|··············
| TetherToken · - · - · 758083 · 11.3 % · - │
·························································|·············|·············|··············|··············|··············
| VRFCoordinatorV2Mock · - · - · 1448986 · 21.6 % · - │
·--------------------------------------------------------|-------------|-------------|--------------|--------------|-------------·
Multi-Chain
The following list of actual deployments and implementations that has been conducted by the GHOST team.
All products outlined below have been deployed on the following 16 networks, including 14 MainNets and 2 TestNets:
GHOST team is planning to deploy the products on more EVM-compatible chains based on demand. GHOST team is also planning to deploy all products on non-EVM-compatible blockchain networks depending on grants, co-marketing opportunities, and collaboration available.
GHOST team went an extra mile to deploy all smart contracts on multiple chains under the same smart contract address to make it more convenient for developers and users.
ghostHouse
ghostHouse is the first implementation of the EnviousHouse standard. With ghostHouse, existing ERC721 collections or custom NFT collections on any EVM network can utilize the collateral feature.
Check out ghostNFT DApp to try ghostHouse on 16 EVM-compatible networks.
Discover the advantages of collateralizing your collections by visiting the provided link.
Blockchain |
ghostHouse Smart Contract Address |
---|---|
Ethereum |
|
Astar |
|
Aurora |
|
Avalanche |
|
Binance |
|
Celo |
|
Classic |
|
Fantom |
|
Fuse |
|
Gnosis |
|
Harmony |
|
Metis |
|
Moonbeam |
|
Polygon |
|
Goerli |
|
zkEVM |
JML NFT Collection
John McAfee Legacy (JML) NFT Collection is the first ER721EnviousDynamic collection consisting of 71,202 unique NFTs.
JML gNFTs get dynamically upgraded towards a higher level of rarity as the collateral in GMV token increases. GMV is a utility token that serves as a measurementToken for the JML Collection.
Check out JML Wiki to learn more about JML NFT Collection.
Blockchain |
JML Collection Address |
---|---|
Ethereum |
|
Astar |
|
Aurora |
|
Avalanche |
|
Binance |
|
Celo |
|
Classic |
|
Fantom |
|
Fuse |
|
Gnosis |
|
Harmony |
|
Metis |
|
Moonbeam |
|
Polygon |
|
Goerli |
|
zkEVM |
GMV Token
GMV is an ERC20 utility token that serves as a measurementToken
for the John McAfee Legacy (JML) NFT Collection.
Quantity of GMV token used as collateral increases rarity for JML gNFT. To learn about JML edges in relevance to GMV token quantity, learn here.
Blockchain |
GMV Token Address |
---|---|
Ethereum |
|
Astar |
|
Aurora |
|
Avalanche |
|
Binance |
|
Celo |
|
Classic |
|
Fantom |
|
Fuse |
|
Gnosis |
|
Harmony |
|
Metis |
|
Moonbeam |
|
Polygon |
|
Goerli |
|
zkEVM |
ghostAirdrop
ghostAirdrop DApp is the first implementation of the Initial NFT Offering (INO) where token allocation is stored in JML gNFT collateral and every user has to claim their GMV token collateral.
After claiming free gNFT every user starts having access to a personal affiliate url comprised of user’s public key.
The GMV rewards increase in proportion to the number of referrals, following a sigmoid function.
To claim a free gNFT or learn more about ghostAirdop follow this link.
Blockchain |
ghostFaucet Smart Contract Addresses |
---|---|
Ethereum |
|
Astar |
|
Aurora |
|
Avalanche |
|
Binance |
|
Celo |
|
Classic |
|
Fantom |
|
Fuse |
|
Gnosis |
|
Harmony |
|
Metis |
|
Moonbeam |
|
Polygon |
|
Goerli |
|
zkEVM |
NFT 2.0 == Promises of NFT 1.0
NFT 2.0 is a new concept with a number of features and use cases. The list of features and use cases is ever expanding as NFT 2.0 gets more adoption.
A number of promises of NFT 1.0 are just not feasible given NFT 1.0 limitations. However, NFT 2.0 extends these limitations.
On-chain verifiable price floor
NFT 1.0 attempts to bring ‘big data’ and statistical methods to estimate the price floor. There are many problems with such an approach. First of all, the data is easily manipulated to inflate the prices of NFTs through inside wash sale, which gives a very inaccurate picture on the real liquidity deposited into a given NFT collection. Secondly, many NFT marketplaces are powered by off-chain NFT storage and operations resulting in even more obscure datapoints. Finally, there is simply not enough data to make any statistically significant forecasts let alone fair ‘big data’ predictions.
NFT 2.0 easily solves the problem of on-chain verifiable price floors since every gNFT has an on-chain collateral attached to it.
Sustainable NFT royalties
Since its origination, the concept of NFT staking was always desirable. Many NFT and Play2Earn projects were offering the yield on their NFTs. However, the yield was often in the form of a native token with unlimited supply where inflated supply was not backed appropriately creating all types of busts in bank-run scenario.
Appropriate collateral enables a gNFT to generate sustainable and sometimes consistently sustainable royalties. As it was already mentioned throughout this lightpaper, collateralizing a gNFT with DeFi 2.0 tokens or LP tokens could result in sustainable appreciation of gNFT value.
Further integration with DeFi 2.0 protocols such as ghostDAO enables discounted collateral and additional appreciation of the value of gNFT.
New Monetization Streams
NFT 2.0 enables additional monetization of NFT collections through the following fees:
Collateralization Fee
Uncollateralization Fee
NFT Transfer Fee
Additional NFT collection gamification can be implemented by utilizing VRFPreset and DynamicPreset described earlier
NFT 2.0 Powers DAOs
As DAOs are getting more traction in Web 3.0, NFT 2.0 offers novel ways to realize governance mechanisms. NFTs representing DAO decision makers was receiving more and more popularization in 2020-2021. gNFTs can significantly improve governance mechanisms by aligning incentives more appropriately.
For example, the voting power can be correlated to the amount of collateral behind a voting gNFT. Council members with more belief in the protocol will have to provide a larger collateral to achieve a higher voting power. Similarly, all gNFT collection holders can have an equivalent amount of native token distributed behind every gNFT; those holders to redeem gNFT collateral partial or in-full will lose a proportional amount of voting power.
Another way to utilize gNFT for voting is by rewarding Council members who dispersed larger amounts of collateral to other members of the gNFT collection with a higher voting power. All gNFT collateral activities are on-chain verifiable making it easy for DAOs to construct various mechanisms and incentive structures.
NFT 2.0 Powers DeFi
Utility NFTs that the world was expecting for a very long time are somewhat difficult with NFT 1.0 and super achievable with NFT 2.0.
On-chain portfolio management applications can be designed with gNFTs. gNFT can be collateralized by any combinations of underlying tokens.
For example, let’s assume that a given gNFT was collateralized by:
10 ETH
1,000 DAI
5,000 eGHST
30 LP
The owner of the gNFT has the claim for all 4 tokens: ETH, DAI, eGHST, LP. Transfer of this gNFT to another user would give that user the claim for the 4 tokens. Thus, the gNFT serves as a receipt for the underlying tokens in the collateralized digital asset basket.
Initial NFT Offering (INO)
NFT 2.0 empowers a new crowdfunding standard of the Initial NFT Offering (INO). The following example will illustrate how INOs work.
Let’s assume there is a new gNFT collection based on ERC721Envious | DynamicPreset. Let’s assume there are 5 levels of gNFTs based on the amount of collateral attached where Level 1 has the lowest amount of collateral and Level 5 is achieved by depositing the largest amount of collateral. The visual associated with gNFT changes dynamically and becomes rarer with larger amounts of tokens and/or capital contributed.
Users place respective NFT visuals on their avatars to reflect their status. Users with Level 1 gNFT have common NFT visuals. They would need to acquire the native token and collateralize Level 1 gNFT to get to Level 5 gNFT with more status-rich NFT visuals.
Cross-Chain Interoperability
ghostNFT has natural integration with the GHOST protocol, which is responsible for decentralized cross-chain interoperability. GHOST protocol powers cross-chain interoperability of both NFTs and gNFTs. To reiterate, both NFTs and NFTs with attached collateral can move between EVM-compatible blockchains powered by the GHOST protocol. Please read the GHOST Lightpaper for a more in-depth explanation.