# ERC-1000 EIP

The ERC-1000 epitomises the culmination of Polarise Protocol’s proprietary Non-Fungible Token fractionalization technology and P-Token mechanism.

ERC-1000 Overview

### Summary <a href="#h.b6ct5x6ypjpw" id="h.b6ct5x6ypjpw"></a>

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 open-sourcing the contract, 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:

* Minting a specific quantity of ERC-20 tokens through the process of burning ERC-721 NFTs, or conversely, minting 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 in consignments, as well as redemption options for ERC-721 NFTs utilised as collateral in lending.


# 1. Description of Functions

As depicted by the following diagram:

<figure><img src="https://2664404726-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FujxOb37ccfusm9M8y1zq%2Fuploads%2FodNKIX9E2VoU3A15OzRV%2FIMG_4278.PNG?alt=media&amp;token=542f79c2-89f7-466f-8890-5457ae178a42" alt=""><figcaption></figcaption></figure>

"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.

### 1.1 Mint ERC-20 Tokens <a href="#h.9sh9rykfglbq" id="h.9sh9rykfglbq"></a>

Through ERC-1000, Owners can mint ERC-20 tokens by:

* Directly minting a batch of ERC-20 tokens via mintErc20.
* Minting a specific quantity of ERC-20 tokens by burning ERC-721 NFTs via burnErc721 and mintErc20.

### 1.2 Mint ERC-721 NFTs <a href="#h.ksfy45uo3m5j" id="h.ksfy45uo3m5j"></a>

Through ERC-1000, Owners can mint ERC-721 NFTs by:

* Directly minting ERC-721 NFTs via mintErc721.
* Minting ERC-721 NFTs by burning designated quantities of ERC-20 tokens via burnErc20 and mintErc721.

### 1.3 Swap ERC-721 NFTs for ERC-20 Tokens <a href="#h.gw8dz9ajor3c" id="h.gw8dz9ajor3c"></a>

Through ERC-1000, Sellers can swap ERC-721 NFTs for specific quantities of ERC-20 tokens by:

* 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 (“loanquantum”) 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 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 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 (“loanquantum”) to the Sellers based on the same formula as above.
  * Sellers can redeem the collateralised ERC-721 NFTs using the same method as in the consignment and at any point during the loan period. &#x20;

### 1.4 Swap ERC-20 Tokens for ERC-721 NFTs <a href="#h.lw9s0070f4kf" id="h.lw9s0070f4kf"></a>

Through ERC-1000, Buyers can swap specific quantities of ERC-20 tokens for ERC-721 NFTs by:

* Acquiring ERC-721 NFTs at the consignment price.
* Purchasing random ERC-721 NFTs via randomTrade, wherein Buyers designate the desired quantity of ERC-721 NFTs to be purchased and the ERC-1000 smart contract autonomously selects the ERC-721 NFTs based on the quantity requirement. Acquiring random ERC-721 NFTs necessitates the payment of a transaction fee, set at a predetermined rate.
* Purchasing selected ERC-721 NFTs via specificTrade, allowing Buyers to specify the desired NFT IDs for purchasing. Such specific transactions involve the payment of a transaction fee at a predetermined rate.


# 2. External Interfaces

| 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                                                                                                                                                                                                                                                                                |


# 3. Usage Scenarios

Via ERC-1000, the following primary usage scenarios are envisioned:

### 3.1 Flash Trade <a href="#h.k0o9mdczz2xv" id="h.k0o9mdczz2xv"></a>

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.

### 3.2 Consignment <a href="#h.upzf94rowszr" id="h.upzf94rowszr"></a>

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.

### 3.3 Leverage <a href="#h.lyyl7nxmqbpg" id="h.lyyl7nxmqbpg"></a>

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.


# 4. Compatibility

Currently, the functionalities implemented and the interfaces defined by ERC-1000 are compatible with ERC-20 and ERC-721 standards, specifically as follows:

### 4.1 ERC-20 Compatibility <a href="#h.dt3kjot7k1gn" id="h.dt3kjot7k1gn"></a>

<table data-header-hidden><thead><tr><th width="184"></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>No.</td><td>Item</td><td>Description</td><td>Status</td></tr><tr><td>1.</td><td>name()</td><td>Is declared as a public view function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns a string, for example “Tether USD”</td><td>✓</td></tr><tr><td>2.</td><td>symbol()</td><td>Is declared as a public view function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns the symbol by which the token contract should be known, for example “USDT”.<br>It is usually 3 or 4 characters in length</td><td>✓</td></tr><tr><td>3. </td><td>Decimals()</td><td>Is declared as a public view function</td><td>✓</td></tr><tr><td><br></td><td></td><td>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</td><td>✓</td></tr><tr><td>4.</td><td>totalSupply()</td><td>Is declared as a public view function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns the number of total supplied tokens, including the total minted tokens (minus the total burned tokens) ever since the deployment</td><td>✓</td></tr><tr><td>5.</td><td>balanceOf()</td><td>Is declared as a public view function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Anyone can query any addresses’ balance as all data on the blockchain is public</td><td>✓</td></tr><tr><td>6.</td><td>allowance()</td><td>Is declared as a public view function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns the amount which the spender is still allowed to withdraw from the owner</td><td>✓</td></tr><tr><td>7.</td><td>transfer()</td><td>Is declared as a public function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns a boolean value which accurately reflects the token transfer status</td><td>✓</td></tr><tr><td><br></td><td></td><td>Reverts if the caller does not have enough tokens to spend</td><td>✓</td></tr><tr><td><br></td><td></td><td>Allows zero amount transfers</td><td>✓</td></tr><tr><td><br></td><td></td><td>Emits Transfer() event when tokens are transferred successfully (include 0 amount transfers)</td><td>✓</td></tr><tr><td><br></td><td></td><td>Reverts while transferring to zero address</td><td>✓</td></tr><tr><td><p>8.</p><p><br></p></td><td>transferFrom()</td><td>Is declared as a public function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns a boolean value which accurately reflects the token transfer status</td><td>✓</td></tr><tr><td><br></td><td></td><td>Reverts if the spender does not have enough token allowances to spend</td><td>✓</td></tr><tr><td><br></td><td></td><td>Updates the spender’s token allowances when tokens are transferred successfully</td><td>✓</td></tr><tr><td><br></td><td></td><td>Reverts if the from address does not have enough tokens to spend</td><td>✓</td></tr><tr><td><br></td><td></td><td>Allows zero amount transfers</td><td>✓</td></tr><tr><td><br></td><td></td><td>Emits Transfer() event when tokens are transferred successfully (including zero amount transfers)</td><td>✓</td></tr><tr><td><br></td><td></td><td>Is declared as a public function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Reverts while transferring from zero address</td><td>✓</td></tr><tr><td>9..</td><td>approve()</td><td>Is declared as a public function</td><td>✓</td></tr><tr><td><br></td><td></td><td>Returns a boolean value which accurately reflects the token approval status</td><td>✓</td></tr><tr><td><br></td><td></td><td>Emits Approval() event when tokens are approved successfully</td><td>✓</td></tr><tr><td><br></td><td></td><td>Reverts while approving to zero address</td><td>✓</td></tr><tr><td>10.</td><td>Transfer()event</td><td>Is emitted when tokens are transferred, including zero value transfers</td><td>✓</td></tr><tr><td><br></td><td></td><td>Is emitted with the from address set to 𝑎𝑑𝑑𝑟𝑒𝑠𝑠(0𝑥0) when new tokens are generated</td><td>✓</td></tr><tr><td>11.</td><td>Approval()event</td><td>Is emitted on any successful call to approve()</td><td>✓</td></tr></tbody></table>

### 5.2 ERC-721 Compatibility <a href="#h.du7694htznuu" id="h.du7694htznuu"></a>

| No.         | Item                  | Description                                                                                                    | Status |
| ----------- | --------------------- | -------------------------------------------------------------------------------------------------------------- | ------ |
| 1.          | balanceOf()           | Is declared as a public view function                                                                          | ✓      |
| <p><br></p> | <p><br></p>           | Anyone can query any addresses’ balance as all data on the blockchain is public                                | ✓      |
| 2.          | ownerOf()             | Is declared as a public view function                                                                          | ✓      |
| <p><br></p> | <p><br></p>           | Returns the address of the owner of the NFT                                                                    | ✓      |
| 3.          | getApproved()         | Is declared as a public view function                                                                          | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while ‘\_tokenId’ does not exist                                                                       | ✓      |
| <p><br></p> | <p><br></p>           | Returns the approved address for this NFT                                                                      | ✓      |
| 4.          | isApprovedForAll()    | Is declared as a public view function                                                                          | ✓      |
| <p><br></p> | <p><br></p>           | Returns a boolean value which check ‘\_operator’ is an approved operator                                       | ✓      |
| 5.          | safeTransferFrom()    | Is declared as a public function                                                                               | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while ‘to’ refers to a smart contract and not implement IERC721Receiver-onERC721Received               | ✓      |
| <p><br></p> | <p><br></p>           | Reverts unless ‘msg.sender’ is the current owner, an authorized operator, or the approved address for this NFT | ✓      |
| <p><br></p> | <p><br></p>           | <p>Reverts while ‘\_tokenId’ is not a valid NFT</p><p><br></p>                                                 | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while ‘\_from’ is not the current owner                                                                | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while transferring to zero address                                                                     | ✓      |
| <p><br></p> | <p><br></p>           | Emits Transfer() event when tokens are transferred successfully                                                | ✓      |
| 6.          | transferFrom()        | Is declared as a public function                                                                               | ✓      |
| <p><br></p> | <p><br></p>           | Reverts unless ‘msg.sender’ is the current owner, an authorized operator, or the approved address for this NFT | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while ‘\_tokenId’ is not a valid NFT                                                                   | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while ‘\_from’ is not the current owner                                                                | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while transferring to zero address                                                                     | ✓      |
| <p><br></p> | <p><br></p>           | Emits Transfer() event when tokens are transferred successfully                                                | ✓      |
| 7.          | approve()             | Is declared as a public function                                                                               | ✓      |
| <p><br></p> | <p><br></p>           | Reverts unless ‘msg.sender’ is the current owner, an authorized operator, or the approved address for this NFT | ✓      |
| <p><br></p> | <p><br></p>           | Emits Approval() event when tokens are approved successfully                                                   | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while approving to zero address                                                                        | ✓      |
| 8.          | setApprovalForAll()   | Is declared as a public function                                                                               | ✓      |
| <p><br></p> | <p><br></p>           | Reverts while not approving to caller                                                                          | ✓      |
| <p><br></p> | <p><br></p>           | 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()                                                       | ✓      |


# 5. Security

PeckShield has thoroughly scrutinised and audited the code of the ERC-1000 contract and deemed it safe for usage.


# 6. Extensibility and Others

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. Additionally, ERC-1000-specific functionalities can be further extended through inheritance. 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                                                                                                                                                                |


