Skip to content

NEP: Token Sales Standard#39

Closed
snowypowers wants to merge 6 commits intoneo-project:masterfrom
snowypowers:feat/tokensales
Closed

NEP: Token Sales Standard#39
snowypowers wants to merge 6 commits intoneo-project:masterfrom
snowypowers:feat/tokensales

Conversation

@snowypowers
Copy link
Copy Markdown
Member

This NEP proposes a standard for implementing certain features for a token sale. With this NEP, wallets will be able to present the user with relevant information during the token purchase process, allowing for a smoother experience.

Copy link
Copy Markdown

@nickfujita nickfujita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together!

I went through and updated a ICO contract to conform to this proposal, but got hung up on implementing kycLimit.


* Remarks: ''kycStatus'' Checks the whitelist status for the provided address. Returns True if registered.

====kycLimit====
Copy link
Copy Markdown

@nickfujita nickfujita Apr 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While kycLimit can be a useful method in some specific sales cases, it might not be appropriate as a standard method.

  • Depending on the token sale, there are different limits; with some sales having multiple limited rounds.
  • Doesn't fit if there are sales that have no limits, and returning the largest possible integer seems a bit hacky.
  • Doesn't address sales where there are minimum contribution requirements.

Side note: if this method were to be kept, a different name may be more appropriate. kycLimit may seems to suggest there is a limit pertaining to the kyc process or number of kyc addresses. This is really more a part of the sales methods.

It may just be better to remove this method, and have contract owners provide users with information about round limits as a part of saleDetails. saleDetails can also be updated to take an optional address parameter to allow contracts to provide user specific details about their contributions to date.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with your assessment, @nickfujita! I'm not sure this is compelling enough to be a universal NEP standard. If a utility like this is kept in the NEP, I would recommend making it optional, at a minimum.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will remove this in favor of making saleDetails be the main source of information since it will be difficult in ensuring this information stays relevant for all token sales.


====mintToken====

* Syntax: <code> public static event Action<byte[], int> token_mint</code>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a unified standard for minting all NEP-5 tokens that doesn't require a token sale. Any NEP-5 token that doesn't have a token sale should be able to conform to a token minting standard. Since every NEP-5 token will require minting, I think the event for minting tokens ultimately belongs on the NEP-5 standard. It would be used any time tokens are minted, regardless of whether they were bought in a token sale, airdropped, or minted for other purposes (e.g. when team tokens are minted by the owner).

If token_mint is part of this NEP, then how would a NEP-5 token conform to the standard when nothing else in the NEP is applicable?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think this is a valid point. @lllwvlvwlll @anfn101 What do you think?


* Syntax: <code>public static int saleRemaining()</code>

* Remarks: "saleRemaining" returns the amount of tokens left for sale. This is the remaining amount of token left available for exchange. Sales without a limit should return the largest possible integer.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think saleRemaining should either be optional or perhaps better, not included in the NEP. Token sales can be complex and many have different phases of the sale, so what this represents will be ambiguous in many cases. I think it's better to keep the interface as simple as possible and only include methods and events that add value almost universally to all token sales.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove this in favor of using saleDetails be the main function to convey any meta information for the contract.


====mintTokens====

* Syntax: <code>public static string mintTokens(byte[] address)</code>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the string return type for? It would be cool if it was possible to return a string message when a mint fails, but I'm not sure that's feasible given how raw transactions are submitted, and also in the context of TriggerType.Verification. It's worth considering if there is a way to return a human-readable message, and if not, changing this to just return bool.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not well versed in this area so I need to ask if the return value appears anywhere else other than through RPC invoke? I think that return values are a little wasted currently... I do like if we can return something more relevant than just a bool.


====saleDetails ''(optional)''====

* Syntax: <code>public static string saleDetails()</code>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be cool to add an optional byte[] address argument that could be used to generate a personalized status message for a given address. This message could indicate any per-address sale details (e.g. if different users get different token ratios or have different limits). This would give ICO implementors a bit more flexibility and power in delivering a more useful and accurate message in the wallet interface. Worth consideration, anyway.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, by doing this, we can remove the limit / sale remaining by letting the contract owner compile their own custom string that may target the specific address if needed.

@erikzhang
Copy link
Copy Markdown
Member

erikzhang commented Apr 17, 2018

We don't need any kyc methods in the standard if NeoID has been implemented I think.

@snowypowers
Copy link
Copy Markdown
Member Author

@erikzhang Even with NeoID, there will still need to be a standard in order for wallets to display the IsAddressWhitelisted status. The kycRegister / kycDeregister methods are optional and can be deprecated once NeoID reaches production.

I do think that in the short term we should focus this on KYC and have a review once NeoID looks to go live.

@erikzhang
Copy link
Copy Markdown
Member

Can we remove mintTokens because NEP-7 will be implemented.

@snowypowers
Copy link
Copy Markdown
Member Author

I have removed mintToken from this NEP. Now, the methods left are purely focused on the crowdsale side of things.

@erikzhang
Copy link
Copy Markdown
Member

erikzhang commented Apr 20, 2018

Perhaps the standard can standardize not only the methods, but also the triggers for token sale.

The contracts should use Verification trigger for withdrawal, VerificationR for refusing transfer after ICO, ApplicationR for minting tokens.

@snowypowers
Copy link
Copy Markdown
Member Author

At this stage, it is difficult for us to standardize on something that cannot be implemented and tested. Pushing it early would also cause confusion between contracts before / after NEP7.

My suggestion would be to have an amendment (version 1.1) to include the relevant triggers after NEP-7 goes to production.

On a side note, I do think that the token creation functionality should be part of NEP-5 instead of this as suggested by Brian.

@erikzhang
Copy link
Copy Markdown
Member

erikzhang commented Apr 23, 2018

Actually NEP-7 is ready to be merged into neo master branch.
neo-project/neo#172

@snowypowers
Copy link
Copy Markdown
Member Author

@erikzhang Yes I think I can work triggers into the standard. Off the top of my head, here's a rough draft:

In order for a transaction to be a valid transaction for minting tokens, it will have to attach a TransactionAttribute of Description with the text mintTokens. VerificationR trigger will check the attribute and reject transactions without a purpose.

The attribute check is to make sure that the contract is still able to receive funds for other purposes beyond ICO.

Upon accepting the transfer, ApplicationR is invoked in the contract. It should check for the existance of TransactionAttribute of Description with the text mintTokens to ensure this transaction is used for ICO. The contract should then perform the necessary actions to mint tokens and raise the event tokens_created on success.

Similarly, we have to check for the purpose here because the contract may have uses for asset transfers beyond ICO. The event raised here can be fleshed out in this NEP but it should be transferred to NEP5.

I do believe that Verification trigger functionality is out of the scope of this NEP.

If this is OK, I would like to propose a separate PR to amend NEP5 to include relevant token events such as token_created and token_destroyed

@erikzhang
Copy link
Copy Markdown
Member

I think it seems more like a KYC standard. But not all token sales need KYC.

@snowypowers
Copy link
Copy Markdown
Member Author

snowypowers commented May 17, 2018

This isn't a specification purely for KYC but it does have a lot of elements for KYC simply due to the fact that KYC has more to it.

With the merger of NEP-10, it looks like we should keep specifications to a singular purpose. This specification looks to split:

  1. Sales Standard - Interface for common wallets to retrieve information for sales in order to streamline the sales process. The methods saleStatus and saleDetails are included in this spec. Requires NEP-5.

  2. KYC Standard - Interface for wallets to integrate the KYC process with common wallets. The methods kycStatus, kycRegister and kycDeregister are included in this spec. Requires NEP-5 and the Sales Standard.

@erikzhang
Copy link
Copy Markdown
Member

Agreed.

@snowypowers snowypowers changed the title NEP: Crowdsale Standard NEP: Token Sales Standard May 17, 2018
@snowypowers
Copy link
Copy Markdown
Member Author

Updated:

  • Title to Token Sales Standard
  • Removed Thomas as author (he made the KYC standard but the Sales standard under me)
  • Tweak motivation to suit the standard more
  • Removed KYC methods
  • Removed Required tag (there should not be any optional methods anymore)
  • Removed all events

@erikzhang
Copy link
Copy Markdown
Member

There's a problem. In the method saleDetails, it returns a string that briefly describes the sale. And this string usually contains some numbers.

The problem is that there is currently no good way to convert numbers to strings in NeoVM. Some APIs need to be added.

@nickfujita nickfujita mentioned this pull request Jun 6, 2018
@erikzhang
Copy link
Copy Markdown
Member

erikzhang commented May 17, 2019

@snowypowers Maybe saleDetails should return a url?

@erikzhang erikzhang closed this Jan 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants