From 9ef72de06c27cc2d22c3c92d6f101363c04385e6 Mon Sep 17 00:00:00 2001 From: James Cramer Date: Fri, 5 Jun 2020 15:29:36 -0400 Subject: [PATCH 1/2] staking and reward standardization --- apps/slp-rewards/README.md | 18 ++++++++++++++++++ apps/slp-staking/README.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 apps/slp-rewards/README.md create mode 100644 apps/slp-staking/README.md diff --git a/apps/slp-rewards/README.md b/apps/slp-rewards/README.md new file mode 100644 index 0000000..414e12a --- /dev/null +++ b/apps/slp-rewards/README.md @@ -0,0 +1,18 @@ +# SLP Rewards Standardization - DRAFT +A auditable token reward system for your customers + +Last updated: June 5, 2020 + +## Purpose + +Customer rewards are a common requirement for token issuers, and this is often the primary reason for issuing an SLP token. Issuers and customers need a proper audit trail for documenting the history of sending rewards to their customers. A strong audit trail boosts customer confidence and also satisfies bookkeeping requirements that either the token issuer or customer may have. + +## Specification + +Token rewards for a given token should be tracked using specified NFT1 Group ID provided by the token issuer. Each token reward txid sent to token holders should be documented within the Document Hash field of an NFT Genesis transaction. This will allow rewards that were in the form of either BCH or any SLP token to be tracked in the same way. + +Token issuers can simply signal that an NFT1 Group token is for the purpose of reward auditing by creating a new NFT1 Group token with a Genesis having: + +* ticker: "REWARDS" +* documentHash: "token id of token holders" + diff --git a/apps/slp-staking/README.md b/apps/slp-staking/README.md new file mode 100644 index 0000000..2289dcf --- /dev/null +++ b/apps/slp-staking/README.md @@ -0,0 +1,38 @@ +# SLP Staking Standardization - DRAFT +Add a staking system to your SLP token + +Last updated: June 5, 2020 + +## Purpose + +Token staking is a common component and requirement for decentralized governance, reward mechanics, and coin transfer restrictions. This specification provides the current methodology of staking that will be supported by the SLP ecosystem. Of course other staking methods are possible, however, they will not likely be widely supported across the ecosystem if they are not listed in this peer-reviewed specification. + +## Specification + +Currently the method for handling customer token staking is to have customer tokens based on a pay-to-script-hash (P2SH) address that is generated from a customer supplied public key. Validation of the staking contract addresses can be performed by examining the scriptSig of . + +### Standard Staking Address + +The following redeem script should be used to handle non-multisig instances where a token issuer requires each coin to be time locked for a certain period of time with no additional transfer restrictions: + +` OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG` + +### Multisig Staking Address + +The following redeem script should be used for situations when the token issuer needs to further restrict coin transfer beyond a time lock: + +` OP_CHECKLOCKTIMEVERIFY OP_DROP N ... N OP_CHECKMULTISIG` + +For the purpose of simple p2sh address verification described below, only M-of-N multisig where M=N are recommended. + +### P2SH Verification Procedure + +A p2sh address must be verified as being created from the hash160 of the staking contract before the issuer will treat it as staked coins. + +1) Query for all p2sh address type holders of a token + +2) For each transaction associated with a p2sh holder, enumerate the token input scriptSigs. + +3) For each input scriptSig, attempt compute a p2sh address using the above staking contract templates using the public keys found within the script sigs. Taking care to distinguish between p2pkh and p2ms. + +4) If any of the computed p2sh addresses match the output holding p2sh, then you can be sure the current p2sh holding tokens is indeed a staking address. From a8b481b8144f938416097935cfd320ec7433a3eb Mon Sep 17 00:00:00 2001 From: James Cramer Date: Mon, 8 Jun 2020 09:50:15 -0400 Subject: [PATCH 2/2] incorporate feedback --- apps/slp-rewards/README.md | 28 ++++++++++++++++++++-------- apps/slp-staking/README.md | 32 +++++++++++++++++++------------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/apps/slp-rewards/README.md b/apps/slp-rewards/README.md index 414e12a..d1c53d7 100644 --- a/apps/slp-rewards/README.md +++ b/apps/slp-rewards/README.md @@ -1,18 +1,30 @@ -# SLP Rewards Standardization - DRAFT -A auditable token reward system for your customers +# SLP Rewards Standard - DRAFT +*A auditable token reward system for token issuers and holders* -Last updated: June 5, 2020 +Last updated: June 8, 2020 ## Purpose -Customer rewards are a common requirement for token issuers, and this is often the primary reason for issuing an SLP token. Issuers and customers need a proper audit trail for documenting the history of sending rewards to their customers. A strong audit trail boosts customer confidence and also satisfies bookkeeping requirements that either the token issuer or customer may have. +Rewards are a common requirement for token issuers, and this is often the primary reason for issuing an SLP token. Issuers and token holders need a proper audit trail for documenting the history of sending rewards to token holders. A strong audit trail boosts token holder confidence and also satisfies bookkeeping requirements that either the token issuer or holder may have. ## Specification -Token rewards for a given token should be tracked using specified NFT1 Group ID provided by the token issuer. Each token reward txid sent to token holders should be documented within the Document Hash field of an NFT Genesis transaction. This will allow rewards that were in the form of either BCH or any SLP token to be tracked in the same way. +Token rewards for a given token should be tracked using specified NFT1 Group ID provided by the token issuer. Each token reward TXID sent to token holders should be documented within the Document Hash field of an NFT Genesis transaction. This will allow rewards in the form of BCH or any arbitrary SLP token to be tracked in the same way. -Token issuers can simply signal that an NFT1 Group token is for the purpose of reward auditing by creating a new NFT1 Group token with a Genesis having: +### Rewards Trail -* ticker: "REWARDS" -* documentHash: "token id of token holders" +Token issuers can simply signal that an NFT1 Group token is for the purpose of providing an auditable "rewards trail" by creating a new NFT1 Group token with a Genesis having: +* ticker: `__REWARDS_TRAIL` (the double underscore indicates this token is being used at an application level, not for typical interactions with users) +* documentHash: `` +* documentUrl: location of any additional information related to this + +For each rewards related transaction sent to token holders a new NFT token should be created with the following format: + +* ticker: `__REWARD` +* documentHash: `` +* documentUrl: location of any additional information related to the reward, to be used at the discretion of the token issuer. + +### Considerations + +* Token issuers may want to issue rewards for different purposes to the same token holders. There is nothing wrong with using the same Rewards Trail for different purposes, however, having unique NFT1 Groups dedicated for each rewards purpose may offer an improved user experience. \ No newline at end of file diff --git a/apps/slp-staking/README.md b/apps/slp-staking/README.md index 2289dcf..bef4c8d 100644 --- a/apps/slp-staking/README.md +++ b/apps/slp-staking/README.md @@ -1,7 +1,7 @@ -# SLP Staking Standardization - DRAFT -Add a staking system to your SLP token +# SLP Staking Standard - DRAFT +*Standardized staking for your SLP token* -Last updated: June 5, 2020 +Last updated: June 8, 2020 ## Purpose @@ -9,30 +9,36 @@ Token staking is a common component and requirement for decentralized governance ## Specification -Currently the method for handling customer token staking is to have customer tokens based on a pay-to-script-hash (P2SH) address that is generated from a customer supplied public key. Validation of the staking contract addresses can be performed by examining the scriptSig of . +The recommended method for token staking is to utilize a stateful covenant contract. Validation of the staking contract addresses can be easily performed by examining the input scriptSigs of transactions containing p2sh outputs. ### Standard Staking Address -The following redeem script should be used to handle non-multisig instances where a token issuer requires each coin to be time locked for a certain period of time with no additional transfer restrictions: +The following redeem script should be used to handle token staking: -` OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG` +`` -### Multisig Staking Address +The above stateful covenant locking script has two sequencial stages: (1) prepare and (2) staking. The following process describes the purpose of each state: -The following redeem script should be used for situations when the token issuer needs to further restrict coin transfer beyond a time lock: +- (1) prepare: When coins are initially sent to this covenant contract they will be in the "prepare" state. There are a couple of purposes for this initial stage. + - The first purpose of having this stage reduces the risk of losing tokens due to user error since the staking-contract is documented and the user's public key is known. + - The second purpose of this stage is that it provides on-chain documentation of what script the coins are being staked with after the coins have been moved to the staking stage. + - Under normal circumstances, a token holder would simply spend the tokens from the "prepare" stage address with the desired staking locktime value encoded as pushdata within the scriptSig. The receiving address would be an address derived from the locktime and enforced by the covenant. + - Alternatively, while a coin resides at the prepare stage address, the user has the option to abort the staking position and return each token UTXO to its originating address. -` OP_CHECKLOCKTIMEVERIFY OP_DROP N ... N OP_CHECKMULTISIG` +- (2) staking: Once coins are sent to this address from the previous stage they will be locked for the timelock duration provided by the token holder in the scriptSig. Anyone will be able to verify the coins are staked since the covenant script template was published in the upstream transaction along with the user specified staking timelock. -For the purpose of simple p2sh address verification described below, only M-of-N multisig where M=N are recommended. +### Issuer Multisig Staking Address + +In the future token issuers may want to have multisig capabilities for signing on the issuer side, at this time no recommendations have been developed for this use case. Due to the interactive process of multisig, additional security concerns related to the birthday attack problem may arise and should be mitigated carefully. ### P2SH Verification Procedure -A p2sh address must be verified as being created from the hash160 of the staking contract before the issuer will treat it as staked coins. +A p2sh address must be verified as being an address created from the hash160 of a time-locked staking contract before the issuer will treat it as staked coins. 1) Query for all p2sh address type holders of a token 2) For each transaction associated with a p2sh holder, enumerate the token input scriptSigs. -3) For each input scriptSig, attempt compute a p2sh address using the above staking contract templates using the public keys found within the script sigs. Taking care to distinguish between p2pkh and p2ms. +3) For each input scriptSig, attempt to compute a p2sh address using the above staking contract templates using the public keys found within the script sigs. -4) If any of the computed p2sh addresses match the output holding p2sh, then you can be sure the current p2sh holding tokens is indeed a staking address. +4) If any of the computed p2sh addresses match the output holding p2sh, then you have verified the current p2sh holding tokens is indeed a staking address. \ No newline at end of file