ERC-1000 EIP
Last updated
Last updated
ERC-1000 Overview
The ERC-1000 epitomises the culmination of Polarise Protocol’s proprietary Non-Fungible Token fractionalization technology and P-Token mechanism. Through the implementation of standards at the contract level and the fostering open-source practices in contract development, we offer comprehensive and enhanced solutions for the integration of Non-Fungible Tokens (NFTs) and Fungible Tokens (FT). Our primary goal is to imbue assets with the dual functionality of NFTs and FTs, thereby enabling seamless conversion between NFT and FT formats. This capability facilitates asset adaptability to diverse utility requirements across various contexts.
The ERC-1000 is built upon the foundations laid by the ERC-721 and ERC-20 standards, enhancing their functionalities. In addition to incorporating the capabilities of ERC-721 and ERC-20, the ERC-1000 offers the following advanced features:
Generating a specific quantity of ERC-20 tokens through the process of locking ERC-721 NFTs, or conversely, creating ERC-721 NFTs by burning ERC-20 tokens.
Acquiring a specific quantity of ERC-20 tokens by depositing NFTs into the designated contract address of the ERC-1000 protocol.
Enabling the seamless conversion of a designated quantity of ERC-20 tokens into both randomised and specific ERC-721 NFTs.
Securing a predetermined quantity of ERC-20 tokens by utilising ERC-721 NFTs as collateral within the consignment or leverage functionalities.
Providing repurchase options for ERC-721 NFTs used as collateral in consignments, as well as redemption options for ERC-721 NFTs utilised as collateral in lending.
As depicted by the following diagram:
"Owner" denotes the proprietor of the ERC-1000 contract.
"Seller" denotes individuals who swap ERC-721 NFTs for ERC-20 tokens.
"Buyer" denotes individuals who swap ERC-20 tokens for ERC-721 NFTs.
Through ERC-1000, Owners can mint ERC-20 tokens:
Directly minting ERC-20 tokens via mintErc20.
Minting a specific quantity of ERC-20 tokens by burning ERC-721 NFTs via burnErc721 and mintErc20.
Through ERC-1000, Owners can mint ERC-721 NFTs:
Directly minting ERC-721 NFTs via mintErc721.
Minting ERC-721 NFTs by burning designated quantities of ERC-20 tokens via burnErc20 and mintErc721.
Through ERC-1000, Sellers can swap ERC-721 NFTs for specific quantities of ERC-20 tokens:
Depositing ERC-721 NFTs into the contract address through the transferFrom or safeTransferFrom functions, and receiving a predetermined number of ERC-20 tokens (By default, one NFT yields 1,000 tokens).
Consigning ERC-721 NFTs to obtain designated quantities of ERC-20 tokens.
This process requires NFT sellers to lock the ERC-721 NFTs in the smart contracts via the contracts’ borrow function. In return, the ERC-1000 contract will transfer a predetermined number of ERC-20 tokens (“loan quantum”) to the NFT sellers based on the following formula: loanquantum = fragmentsVal * (fragmentsVal * blocks * ratePerBlock);
fragmentsVal represents the exchange rate between the ERC-721 NFT and ERC-20 tokens, with the default being 1,000; blocks is the number of blocks corresponding to the consignment period; and ratePerBlock is the collateral rate charged per block
These locked NFTs can only be purchased through the purchase function of the ERC-1000 contract. If a buyer purchases the consigned NFT within the valid consignment period, the final additional number of ERC-20 tokens (“income”) the NFT sellers get would be sale price of the NFT minus the sum of loanquantum, interest (“interest”), and transaction fee (“purchaseFee”) obtained at the time of consignment, i.e. interest = fragmentsVal * delta * ratePerBlock purchaseFee = (price - fragmentsVal) * purchaseFeeRate income = price - loanquantum - interest - purchaseFee
"delta" represents the variance in block height from the initiation of the NFT sale to the moment when the NFT is sold. "purchaseFeeRate" denotes the transaction fee rate for purchasing the NFT.
The consigned NFT can be redeemed ("Redeem") at any given time, incurring a specific interest charge (“interest”), calculated using the methodology as described above. However, redemption by non-consignors is restricted to occurring after the consignment period elapses, with the block height difference utilised for interest calculation always corresponding to the duration of the consignment period. Conversely, consignors retain the flexibility to redeem the consigned NFT at any point during the consignment period, with the block height difference for interest computation being the difference between the block height at commencement of consignment and at redemption.
In the event of redemption by non-consignors, the fee incurred is denoted as "fragmentsVal," while for redemption by consignors, the fee paid is the sum of the prepayment and accrued interest over the consignment period.
Using the ERC-721 NFTs as collateral to borrow specific quantities of ERC-20 tokens
Similar to consigning NFTs, this process also requires borrowers to lock the ERC-721 NFTs in the smart contracts via the contracts’ borrow function. In return, the ERC-1000 contract will transfer a predetermined number of ERC-20 tokens (“loan quantum”) to the borrowers based on the same formula as above
Borrowers can redeem the collateralised ERC-721 NFTs using the same method as the consignment function and at any point during the loan period.
Through ERC-1000, Buyers can swap specific quantities of ERC-20 tokens for ERC-721 NFTs:
Acquire ERC-721 NFTs at the consignment price.
Purchase random ERC-721 NFTs via randomTrade, wherein users designate the desired quantity of ERC-721 NFTs to be purchased. The ERC-1000 smart contract autonomously selects the ERC-721 NFTs to fulfil the specified quantity. Acquiring random ERC-721 NFTs necessitates the payment of a transaction fee, set at a predetermined rate.
Purchase selected ERC-721 NFTs via specificTrade, allowing users to specify the desired NFT IDs for purchasing the selected ERC-721 NFTs. Such specific transactions involve the payment of a transaction fee at a predetermined rate.
No.
Interface Name
Description
1
totalSupply()
Returns the total number of ERC-721 NFTs
2
balanceOf(address)
Returns the number of ERC-20 tokens owned by an account
3
ownerOf(uint256)
Returns the owner of the ERC-721 NFT
4
transfer(address, uint256)
Sends ERC-20 tokens to a specific address
5
allowance(address, address)
Returns the authorised limit
6
approve(address, uint256)
Approves a quantity of ERC-20 tokens for a specified address by checking the uint256 input parameter; if the quantity exceeds the total number of NFTs, it approves the specified quantity of ERC-20 tokens; otherwise, it approves the ERC-721 NFT for the specified address.
7
transferFrom(address, address, uint256)
Sends the approved quantity of ERC-20 tokens or ERC-721 NFTs to a specified address, based on the uint256 input parameter; if the quantity exceeds the total number of ERC-721 NFTs, it indicates sending the approved quantity of ERC-20 tokens; otherwise, it indicates sending the approved ERC-721 NFT
8
safeTransferFrom(address, address, uint256)
Sends the approved quantity of ERC-20 tokens or ERC-721 NFTs to a specified address safely, based on the uint256 input parameter; if the quantity exceeds the total ERC-721 NFTs, it indicates sending the approved quantity of ERC-20 tokens; otherwise, it indicates sending the approved ERC-721 NFT
9
setApprovalForAll(address, bool)
Approves a specified address to take ownership of all ERC-721 NFTs
10
getApproved(uint256)
Returns the address approved for a specific ERC-721 NFT
11
isApprovedForAll(address, address)
Determines whether a specified address has been approved to take ownership of all ERC-721 NFTs
12
randomTrade(uint256)
Randomly trades a certain quantity of ERC-721 NFTs
13
specificTrade(uint256[ ])
Trades specific ERC-721 NFTs
14
borrow(uint256[ ], uint256, uint256)
Using ERC-721 NFTs as collateral for a loan and sets loan terms to receive ERC-20 tokens, with added support for quoted orders
15
redeemOrPurchase(uint256[ ])
Redeems collaterised ERC-721 NFTs; if the ERC-721 NFT is used as collateral for consignment, it is purchased through the listing
16
outstandingLoanBalance(uint256)
Returns the borrowed amount
Via ERC-1000, the following primary usage scenarios are envisioned:
This feature enables seamless conversion between Non-Fungible Tokens (NFTs) and Fungible Tokens (FTs). When converting from NFT to FT, the NFT is locked, and the FT is minted. Conversely, when converting from FT to NFT, the FT is burned, and the unlocked NFT is transferred to the user's address. Flash Trade facilitates rapid exchange of NFTs for corresponding P tokens and vice versa, reducing liquidity risks. Flash Trade comprises Flash Sell, Flash Buy - Random and Flash Buy - Specific.
Using Flash Sell, Users can efficiently convert their NFTs into 1,000 P tokens. Additionally, through Flash Buy - Random, users may opt to exchange 1,000 P tokens for an NFT randomly selected from the Random Trade Pool. Alternatively, via Flash Buy - Specific, users can swap for a specific NFT from the Specific Trade Pool. Service fees are applicable for both Flash Buy - Random and - Specific. These functionalities are executed within the ERC-1000 contract through randomTrade and specificTrade.
This feature allows NFT assets to be consigned. Users will receive upfront payments in P tokens when consigning NFTs via the ERC-1000 smart contract with fees deducted based on the consignment terms and interest rate. Subsequently, users can redeem their NFTs by repaying the upfront payments previously received or continue listing the NFTs for sale to benefit from potential future price appreciation. This process offers users flexibility and security in monetizing their NFT assets while retaining ownership. Implementation within the ERC-1000 contract is achieved through borrow and redeemOrPurchase.
This feature enables NFTs to be utilised for collateralized borrowing. Leverage allows users to obtain loans of up to 1,000 P tokens instantaneously by using their NFTs as collateral. Protocol fees will be deducted based on the loan terms and interest rate. Users can subsequently redeem their NFTs by repaying the P token loan along with accrued interest. Importantly, NFT price fluctuations do not trigger mid-term liquidation. Implementation of Leverage within the ERC-1000 contract is facilitated through borrow and redeemOrPurchase.
Currently, the functionalities implemented and the interfaces defined by ERC-1000 are compliant with ERC-20 and ERC-721 standards, specifically as follows:
No.
Item
Description
Status
1.
name()
Is declared as a public view function
✓
Returns a string, for example “Tether USD”
✓
2.
symbol()
Is declared as a public view function
✓
Returns the symbol by which the token contract should be known, for example “USDT”. It is usually 3 or 4 characters in length
✓
3.
Decimals()
Is declared as a public view function
✓
Returns decimals, which refers to how divisible a token can be, from 0 (not at all divisible) to 18 (divisible) and even higher if required
✓
4.
totalSupply()
Is declared as a public view function
✓
Returns the number of total supplied tokens, including the total minted tokens (minus the total burned tokens) ever since the deployment
✓
5.
balanceOf()
Is declared as a public view function
✓
Anyone can query any addresses’ balance as all data on the blockchain is public
✓
6.
allowance()
Is declared as a public view function
✓
Returns the amount which the spender is still allowed to withdraw from the owner
✓
7.
transfer()
Is declared as a public function
✓
Returns a boolean value which accurately reflects the token transfer status
✓
Reverts if the caller does not have enough tokens to spend
✓
Allows zero amount transfers
✓
Emits Transfer() event when tokens are transferred successfully (include 0 amount transfers)
✓
Reverts while transferring to zero address
✓
8.
transferFrom()
Is declared as a public function
✓
Returns a boolean value which accurately reflects the token transfer status
✓
Reverts if the spender does not have enough token allowances to spend
✓
Updates the spender’s token allowances when tokens are transferred successfully
✓
Reverts if the from address does not have enough tokens to spend
✓
Allows zero amount transfers
✓
Emits Transfer() event when tokens are transferred successfully (including zero amount transfers)
✓
Is declared as a public function
✓
Reverts while transferring from zero address
✓
9..
approve()
Is declared as a public function
✓
Returns a boolean value which accurately reflects the token approval status
✓
Emits Approval() event when tokens are approved successfully
✓
Reverts while approving to zero address
✓
10.
Transfer()event
Is emitted when tokens are transferred, including zero value transfers
✓
Is emitted with the from address set to 𝑎𝑑𝑑𝑟𝑒𝑠𝑠(0𝑥0) when new tokens are generated
✓
11.
Approval()event
Is emitted on any successful call to approve()
✓
No.
Item
Description
Status
1.
balanceOf()
Is declared as a public view function
✓
Anyone can query any addresses’ balance as all data on the blockchain is public
✓
2.
ownerOf()
Is declared as a public view function
✓
Returns the address of the owner of the NFT
✓
3.
getApproved()
Is declared as a public view function
✓
Reverts while ‘_tokenId’ does not exist
✓
Returns the approved address for this NFT
✓
4.
isApprovedForAll()
Is declared as a public view function
✓
Returns a boolean value which check ‘_operator’ is an approved operator
✓
5.
safeTransferFrom()
Is declared as a public function
✓
Reverts while ‘to’ refers to a smart contract and not implement IERC721Receiver-onERC721Received
✓
Reverts unless ‘msg.sender’ is the current owner, an authorized operator, or the approved address for this NFT
✓
Reverts while ‘_tokenId’ is not a valid NFT
✓
Reverts while ‘_from’ is not the current owner
✓
Reverts while transferring to zero address
✓
Emits Transfer() event when tokens are transferred successfully
✓
6.
transferFrom()
Is declared as a public function
✓
Reverts unless ‘msg.sender’ is the current owner, an authorized operator, or the approved address for this NFT
✓
Reverts while ‘_tokenId’ is not a valid NFT
✓
Reverts while ‘_from’ is not the current owner
✓
Reverts while transferring to zero address
✓
Emits Transfer() event when tokens are transferred successfully
✓
7.
approve()
Is declared as a public function
✓
Reverts unless ‘msg.sender’ is the current owner, an authorized operator, or the approved address for this NFT
✓
Emits Approval() event when tokens are approved successfully
✓
Reverts while approving to zero address
✓
8.
setApprovalForAll()
Is declared as a public function
✓
Reverts while not approving to caller
✓
Emits ApprovalForAll() event when tokens are approved successfully
✓
9.
Transfer()event
Is emitted when tokens are transferred`
✓
10.
Approval()event
Is emitted on any successful call to approve()
✓
11.
ApprovalForAll()event
Is emitted on any successful call to setApprovalForAll()
✓
Peckshield has thoroughly scrutinised and audited the code of the ERC-1000 contract and deemed it safe for usage.
The proposed ERC-1000 is fully compatible with both ERC-20 and ERC-721. All extensions based on ERC-20 and ERC-721 can be applied to ERC-1000. The unique functionalities of ERC-1000 can also be extended through the inheritances of ERC-20 and ERC-721 extensions. Furthermore, to facilitate the processing of on-chain data based on ERC-1000, on-chain events can be scanned or monitored and selected data can be saved off-chain as follows:
No.
Event Name
Description
1
event Trade(address indexed account, TradeType indexed tradeType, uint256[] tokenId)
Triggered when a random or specific ERC-721 NFT purchase is made
2
event Borrow(address indexed borrower, uint256[] tokenId, uint256 endBlock, uint256 price, uint256 amount)
Triggered when a user obtains a loan of ERC-20 tokens using an ERC-721 NFT as a collateral; price greater than 0 indicates consignment of ERC-721 NFT; amount represents the ERC-20 tokens received by the user after deducting fees based on the consignment terms and interest rate
3
event Redeem(address indexed payer, uint256[] tokenIds, uint256[] amounts)
Triggered when the consigned ERC-721 NFT is redeemed; amount represents the ERC-20 tokens to be paid for redeeming the NFT
4
event Purchase(address indexed payer, uint256[] tokenIds, uint256[] amounts)
Triggered when the consigned ERC-721 NFT is purchased; amount represents the ERC-20 tokens paid for purchasing the NFT