Open zmrocze opened 5 months ago
My notes, including user and protocol requirements:
Some high-level notes and assumptions about the protocol design based on the spec overview. These are not clearly specified and may not match the actual implementation.
s - concrete protocol instance.
1 Token MP s ↔ 1 UpdateableAddresses Validator s ↔ 1 NFT s ↔ 1 NFT MP s ↔ 0+ Token s
Token MP s -knows→ UpdateableAddresses Validator s -knows→ NFT MP s
Follows:
That actually follows from U3, so even if adversary have half of the keys, it can't change protocol state using only them, while signers can use compromised keys as well, having majority this way.
All the protocol requirements MUST imply preconditions.
Follows from: U0
Follows from: U1, U2, U3
Because of common vilnerabilities:
Follows from U0
Because of common vilnerabilities:
Follows from U3
Because of common vilnerabilities:
Follows from U3, U0
Corresponding UpdateableAddresses validator MUST ensure that.
Because of common vilnerabilities:
Follows from U3, U0
Because of common vilnerabilities:
Follows from U1, U4
Because of common vilnerabilities:
Because of common vilnerabilities:
Follows from U0
Follows from U0
Because of common vilnerabilities:
It should not be possible, because:
So it should not be possible to burn tokens and put a lot of trash tokens into a state thread UTxO in the same Tx.
Covered by P2, but just in case.
Because of common vilnerabilities:
To mint tokens safely and allow holders of these tokens to burn them freely.
min_threshold
signatures from the minters_set
.minters_set
must be updatable. Any addition/removal of owners to/from this set must have min_threshold
signatures from the minters_set
.minters_set
must have at least 2 members.min_threshold
must be updatable. Any change to this number must have min_threshold
signatures from the minters_set
.min_threshold
must always be within the range of [2; |minters_set|]What if the same public key hash is used more than once in the datum? Depending on the implementation, this could be a problem.
Minting the state thread token
Who can initiate?
Why?
Under which conditions?
The state thread token policy must be parameterized by a TxOutRef.
The UTxO referred by the TxOutRef must be an input to the transaction.
Exactly one token must be minted.
The output containing the token must have a valid datum.
The datum must contain at least 2 pubkey hashes (smallest value for the min threshold)
The datum must have the pubkey hashes of all the desired signatories.
(Optional) These should be checked to be distinct.
(Optional) There should be an upper limit to the number of signatories. Otherwise, the datum could grow unbounded and result in an unspendable utxo.
The minimum threshold in the datum must be at least 2.
The minimum threshold should be at most the total number of pubkey hashes.
The output containing the token must be sent to a script address.
(Optional): The output containing the token should not be able to have an unbounded number of native assets (ideally only the state thread token). This avoids having a UTxO that's too large to be spendable.
(Optional): The state thread token must not be able to be burned. This check can be forwarded to the validator instead by requiring transactions to always have an output containing the token sent back to the script's address.
Consequences?
The UTxO referenced will be spent and therefore no new tokens with this policy will be able to be minted.
The protocol's state thread UTxO (token + datum) will sit at the desired address.
NOTE: Reading the specification, it looks like they're minting the token and sending it to the script in two different transactions (and thus no checks about the output address or datums would be included). This needs to be checked in the code, as this is mildly dangerous (can result in an unspendable output due to a malformed datum and the need to mint a new token - though, as this would happen before the protocol is launched, it's probably not big deal).
Minting the protocol tokens
Who can initiate?
Under which conditions?
The name of the token being minted should be "correct".
The transaction must be signed by at least the minimum threshold of signatories from the state thread datum.
The state thread output must be an input to the transaction.
An output containing the state thread token and an unchanged state thread datum must be sent back to the validator's address (i.e. the same address as the input state thread utxo's).
Consequences?
Whatever number of the desired tokens will be minted and sent to the payer's address (if this is not checked, see the note about the state thread utxo above).
The state thread will be consumed (and replaced). This means that no other actions other than burning the tokens can take place simultaneously.
Burning the distribution tokens
Who can initiate?
Under which conditions?
Consequences?
Adding or removing a signatory to the state thread datum
Who can initiate?
Under which conditions?
The transaction must be signed by at least the minimum threshold of signatories from the state thread datum.
The state thread output must be an input to the transaction.
An output containing the state thread token and an unchanged state thread datum must be sent back to the validator's address (i.e. the same address as the input state thread utxo's).
The number of signatories in the output datum must be at least as large as the minimum threshold.
The desired set of pubkey hashes must be listed in the output datum.
Consequences?
Removing a signatory from the state thread datum
Who can initiate?
Under which conditions?
The transaction must be signed by at least the minimum threshold of signatories from the state thread datum.
The state thread output must be an input to the transaction.
An output containing the state thread token and an unchanged state thread datum must be sent back to the validator's address (i.e. the same address as the input state thread utxo's).
Consequences?
Changing the minimum number of signatories
Who can initiate?
Under which conditions?
The transaction must be signed by at least the minimum threshold of signatories from the state thread datum.
The state thread output must be an input to the transaction.
An output containing the state thread token and a valid thread datum must be sent back to the validator's address (i.e. the same address as the input state thread utxo's).
The output datum must have the desired threshold.
The new threshold must be at most the number of pubkey hashes present in the datum.
The new threshold must be at least 2.
Consequences?
The state thread will be consumed (and replaced). This means that no other actions other than burning the tokens can take place simultaneously.
NOTE: in principle, there's nothing stopping this transaction to happen simultaneously with the other datum updates. In that case, all the properties of both transactions must be true.
SingularityNet UpgradeableOwners Protocol Audit
Validators
Vulnerabilities