Waves Smart Asset Applications: Whitelists, Blacklists and Interval Trading

In the two previous articles we discussed using smart accounts and smart assets for running auctions and creating customer loyalty programs , as well as facilitating transparency for financial instruments.

Today, we will look at some specific use cases for smart assets, including asset freezing and restricting transactions for certain addresses.

Smart assets allow Waves users to apply scripts to tokens in much the same way as they can apply scripts to smart accounts. Whenever a transaction for a smart asset is created, it is validated by the script before being confirmed by the blockchain.

Smart assets differ from smart accounts in the following ways:

  1. In a smart asset’s code, proofs cannot be checked (as discussed in the first article)
  2. In a smart account’s code, an ExchangeTransaction can only be checked if your account is a matcher account. Otherwise, only an order can be checked. In a smart asset’s code, you cannot check an order, but you can check an ExchangeTransaction and, if necessary, extract an order from it.
  3. Unlike a smart account, a smart asset doesn’t have a state, but we still have access to account states from the script.

Smart assets help to substantially simplify the process of writing contracts, making implementation of many use cases more concise and elegant.

Asset Freezing

To freeze assets until a certain block height, targetHeight, is reached, simply define this value in the following smart asset’s script:

let targetHeight = 1500000
height >= targetHeight
height is a language function that returns the current height

Using a certain matcher

To define a certain matcher, you can assign the matcher address as the sender value in the following smart asset’s script:

match tx 
case t : ExchangeTransaction =>
t.sender == addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3")
case _ => true

Recipient whitelist

To allow transfer of tokens only to specific accounts — to create a “whitelist” — you can use a smart asset with the following script, which checks for the presence of an address on the list:

match tx  t.recipient == trustedRecipient3
case _ => false

For purposes of security and provable completion of language, the list doesn’t complete implementation of the iterator. Therefore, it is defined as a set of specific elements.

Recipient blacklist

Similarly, to prohibit transfer of tokens to specific accounts, you can create a blacklist. Exactly the same smart asset script will be used, but it will check an address for absence from the blacklist:

match tx 
case t : TransferTransaction =>
let bannedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4")
let bannedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K")
let bannedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx")
t.recipient != bannedRecipient1 && t.recipient != bannedRecipient2 && t.recipient != bannedRecipient3
case _ => false

Transferring by issuer permission

Using a smart asset, you can also add the option of transferring the smart asset only with its issuer’s permission (commitment/debt label). The issuer expresses their consent by placing the transaction’s ID in their account’s state:

match tx 
case t : TransferTransaction =>
let issuer = extract(addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4"))
#checking that the issuer's state contains the current transaction's ID
isDefined(getInteger(issuer, toBase58String(t.id)))
case _ => false

Asset tradable only against a certain currency

A smart asset can allow trading solely against specific coins. For instance, to ensure the smart asset trades only with bitcoin, the following code can be used:

let BTCId = base58'8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS'
match tx 
case t : ExchangeTransaction =>
t.sellOrder.assetPair.priceAsset == BTCId 

Trading with prices from an oracle

In a smart asset’s script, you can set permission for trading only at a price fixed in the trusted oracle’s state:

let oracle = Address(base58'3PLNmokt22NrSiNvCLvwMUP84LCMJqbXwAD')
let assetId = toBase58String(base58'oWgJN6YGZFtZrV8BWQ1PGktZikgg7jzGmtm16Ktyvjd')
match tx  MassTransferTransaction => false
case e: ExchangeTransaction =>
#checking that trading is at the price fixed in the oracle's state for this asset
let correctPrice = e.price == extract(getInteger(oracle, assetId))
#checking that the trading is in exchange for WAVES
let correctPriceAsset = !isDefined(e.sellOrder.assetPair.priceAsset)
correctPrice && correctPriceAsset
case _ => true

Here, we face a special situation while checking the ID of the asset against which our smart asset trades. If the asset’s ID is not defined, it is WAVES by default. In the script, we check that trading is to be against WAVES.

Fixed price raise

You can set a fixed price for a smart asset, which can be raised in steps by a specific proportion. This is an example of a script for a smart asset traded with a fixed price that is raised by 5% every 1,000 blocks:

let startPrice = 10
let startHeight = 1000
let interval = 1000
#by what percentage the price is increased in one step
let raise = 5
match tx  MassTransferTransaction => false
case e: ExchangeTransaction =>
e.price == startPrice + ((height - startHeight) / interval) * (100 + raise) / 100
&& !isDefined(e.sellOrder.assetPair.priceAsset)
case _ => true

Interval trading

A script can also be applied to allow trading of a smart asset that is limited to a predetermined time frame. This is an example of such a script:

let startHeight = 10000
let interval = 44000
let limit = 1500
match tx  MassTransferTransaction 

In the script, we check that no more than “limit” of intervals has elapsed since the start of trading (startHeight). The interval length equals the number of blocks defined in the interval field.

Join Waves Community
Read Waves News channel
Follow Waves Twitter
Subscribe to Waves Subreddit


Waves Smart Asset Applications: Whitelists, Blacklists and Interval Trading was originally published in Waves Platform on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Reply

Your email address will not be published. Required fields are marked *