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 |