paint-brush
Introducing the Nash Stablecoin Projectby@lisk
168 reads

Introducing the Nash Stablecoin Project

by LiskJuly 11th, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Stablecoins are designed to maintain price stability by using an algorithmic mechanism, without the requirement for central control on supply and demand. In addition to ordinary users who can buy Nash as a stable-value crypto-asset, arbitrageurs can earn money from the price fluctuations whilst helping maintain the peg. There is a decentralized reserve whereby investors can lock their crypto-assets and make a profit, (for example, using LSK) In the future, we will use this reserve to make the system sustainable under critical conditions.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coins Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Introducing the Nash Stablecoin Project
Lisk HackerNoon profile picture

Nash is a stablecoin which is designed to maintain its price stability by using an algorithmic mechanism, without the requirement for central control on supply and demand, as is the case with most famous stablecoins such as Tether, USDC, etc.

In addition to ordinary users who can buy Nash as a stable-value crypto-asset, arbitrageurs can earn money from the price fluctuations whilst helping maintain the peg. In addition, there is a decentralized reserve whereby investors can lock their crypto-assets and make a profit, (for example, using LSK). In the future, we will use this reserve to make the system sustainable under critical conditions.

Finally, I am currently working on this project as part of my internship at Rastak Media Sepehr.

About Stablecoins

The somewhat volatile price swings of Bitcoin and other cryptocurrencies are one of the biggest entry barriers to deploying them in the mainstream financial markets. As without price stability, it is difficult for credit and debt markets to justifiably utilize a cryptocurrency.

On the other hand, stablecoins have been gaining a lot of traction, as they offer the security and relative price stability that other cryptos are unable to match. Today’s stablecoin solutions seek to combine the benefits of blockchain technology with the stability associated with certain fiat currencies or specific commodities.

It should be noted that there are many stablecoins existing in the blockchain market, however they can be classified into four general types based on the kind of collateral they use:

  1. Fiat-collateralized: The most popular type of stablecoins are directly backed by a single or a basket of fiat currencies. A central issuer holds an amount of money in a reserve and issues a proportionate amount of tokens. The issuer has the right to use the reserve, in order to increase the supply when the price is too high, and subsequently to reduce it when the price becomes too low. The main issue regarding these types of stablecoins is central control of the reserve, which can result in problems such as low transparency or single points of failure.
  2. Commodity-collateralized: This type uses commodities (e.g., gold, oil), as collateral. Although these are different collaterals, it actually employs the same mechanism as the fiat-collateralized stablecoin and hence, also shares the same problems.
  3. Crypto-collateralized: With crypto-collateralized stablecoins the users are required to lock their cryptocurrency into a contract, which then issues the token. When it is required to retrieve their collateral, they pay the stablecoins back into the same contract. The main problem here is that it is necessary to lock up an unsustainable amount of crypto-assets for this system to function.
  4. Non-collateralized: With non-collateralized stablecoins, these are not backed by any collateral. Instead, their peg is achieved entirely by algorithms that manage the supply of the tokens issued, and by contracting or expanding the supply automatically in different conditions, the price will remain stable. This is the most recent type of stablecoin that has attracted a great deal of attention in the last year from both academia and the crypto industry. However, unfortunately there are a few stablecoins currently existing in the market that are based on algorithmic mechanisms, and most of them have not been implemented yet.

Through this project my aim is to implement one of the main ideas on algorithmic stablecoins and seigniorage shares, using the Lisk SDK so that it can be tested and simulated. I started by creating a simple PoC version with minimum functionalities, and will now extend, and build the required features to bring this to fruition.

How does Nash work?

In this project we have 3 types of tokens: Nash, Bond and Share. These tokens are each described below, including clarification of the price-stability mechanism deployed.

Nash​: The core token of the system which is pegged directly to the US Dollar.

Bond: Users of the PoC version of this application can feed the system by a desired price and test the application. If this price is lower than $1, new bonds will be created and initialized, then they will be added to the bond market, hence all users will be able to buy them with a 20% reduction, only if exchanged for Nash. This is how the supply can be reduced at low prices. In addition, when the price of Nash rises over $1 some bonds will be converted to Nash automatically in a FIFO order to expand the total Nash supply, and subsequently return the price to $1. Each bond is equivalent to 100 Nash and also each bond is an

account
with a custom asset object consisting of properties such as ownerId, price, status (sold, unsold, expired).

Share: With this token, the users are like the shareholders of our system. This token is required to keep the system stable in critical conditions by having a decentralized reserve of Lisk. For example, if you wish to buy a ‘share’, the only way is to transfer some LSK with a value of 10LSK/share to the reserve. For real-world use cases we need to implement a DAO, therefore users of this DAO will be shareholders. In critical conditions whereby the algorithmic expansion or contraction is not sufficient, shareholders can vote on possible reactions to handle the situation using the reserve.

When the system wants to expand the supply of Nash at high prices, at most 80% of new tokens can be supported by bonds. The remaining tokens will be distributed to the shareholders. In this manner it is possible to encourage people to buy shares and invest in the Reserve.

Please note that in the PoC version we ignore implementing the DAO.

Custom Transactions

The list of implemented custom transactions can be seen below:

1. Nash Transfer: This is similar to the balance transfer as a default transaction in the SDK, but instead of the balance, nash property of accounts is changed.

//update recipient's account
const new_recipient_nash = (!recipient.asset.nash)? this.asset.amount
                            : new BigNum(recipient.asset.nash).add(this.asset.amount).toString();

const updated_recipient = { ...recipient, asset: { ...recipient.asset, nash: new_recipient_nash} };

store.account.set(updated_recipient.address, updated_recipient);

//update sender's account
const new_sender_nash = new BigNum(sender.asset.nash).sub(this.asset.amount).toString();

const updated_sender = { ...sender, asset: { ...sender.asset, nash: new_sender_nash} }; 

store.account.set(updated_sender.address, updated_sender);

2. Bond Transfer: Users can transfer the ownership of bonds between each other. The only requirement is to change the ownerId property of the corresponding bond account.

//update bond's account
const updated_bond = {...bond, asset: {...bond.asset, ownerId: this.asset.newOwnerId}};

store.account.set(updated_bond.address, updated_bond);

3. Buy Share: With this transaction the users can send 10 LSK/share to the reserve account, and they will receive an equivalent share corresponding to the value of 10LSK. Furthermore, it is necessary to maintain a list of shareholders, together with the amount of shares they own. This information is kept in the manager account as the holders field.

//update sender's account
const new_sender_balance = new BigNum(sender.balance).sub(lisk_amount).toString();

const new_sender_share = (!sender.asset.share)? this.asset.amount 
                : new BigNum(sender.asset.share).add(this.asset.amount).toString();

const updated_sender = { ...sender, balance: new_sender_balance, asset: { ...sender.asset, share: new_sender_share}};

store.account.set(sender.address, updated_sender);


//update manager's account
const new_manager_balance = new BigNum(Manager.balance).add(lisk_amount).toString();

var new_holders = (!Manager.asset.holders) ? {} : Manager.asset.holders;

new_holders[sender.address] = new_sender_share;

const new_share_supply = (!Manager.asset.shareSupply) ? this.asset.amount 
                  : new BigNum(Manager.asset.shareSupply).add(this.asset.amount).toString();

const updated_manager = {...Manager, balance : new_manager_balance,
                       asset:{...Manager.asset,  holders: new_holders, shareSupply: new_share_supply}};

store.account.set(updated_manager.address, updated_manager);

4. Sell Share: This is based on the same logic as covered in the previous transaction, only this time the users sell their share to the reserve and receive their LSK back.

//update sender's account
const new_sender_balance = new BigNum(sender.balance).add(lisk_amount).toString();

const new_sender_share = (!sender.asset.share)? this.asset.amount: 
new BigNum(sender.asset.share).sub(this.asset.amount).toString();

const updated_sender = { ...sender, balance: new_sender_balance,
asset: { ...sender.asset, share: new_sender_share} };

store.account.set(updated_sender.address, updated_sender);

//update Manager's account

const new_recipient_balance = new BigNum(recipient.balance).sub(lisk_amount).toString();

var new_holders = recipient.asset.holders;
new_holders[sender.address] = new_sender_share;
if(new_sender_share === '0'){
delete new_holders[sender.address];
}

const new_share_supply = new BigNum(recipient.asset.shareSupply).sub(this.asset.amount).toString();

const updated_recipient = {...recipient, balance : new_recipient_balance,
                           asset:{...recipient.asset, holders: new_holders, shareSupply: new_share_supply}};

store.account.set(updated_recipient.address, updated_recipient);

5. Bond2Nash: This particular transaction is used in the expanding mechanism whereby a number of Bonds need to be converted to Nash. To implement this, the ownerId field of the corresponding bond account is cleared, the status is changed to “expired”, and 100 Nash is added to the owner's Nash balance.

Finally the address of the bond is deleted from the bonds list that is located in the manager’s account. In addition, the manager’s nashSupply field should also be updated.

//update bond's account
const updated_bond = { ...bond, asset: { ...bond.asset, ownerId: '', status: 'expired'} };

store.account.set(updated_bond.address, updated_bond);

//update owner's account
const new_owner_nash = (!owner.asset.nash)? '100' :  new BigNum(owner.asset.nash).add('100').toString();

const updated_owner = { ...owner, asset: { ...owner.asset, nash : new_owner_nash } };

store.account.set(updated_owner.address, updated_owner);

//update Manager's account
const new_supply = (!Manager.asset.nashSupply) ? '100' : new BigNum(Manager.asset.nashSupply).add('100').toString();

const new_bondsList = Manager.asset.bondsList.filter( item => item !== bond.address );

const updated_Manager = {...Manager,asset : {...Manager.asset, bondsList : new_bondsList, nashSupply: new_supply}};

store.account.set(updated_Manager.address, updated_Manager);

6. Initialization: This transaction is deployed in two cases, firstly whereby it is necessary to initialize new bonds that are created in a contract mechanism. At this time their price is set to a value of 20% less than (current price of nash*100), status field is set to “unsold”, and the owner is set to manager’s account, and then they will be available on the bond market. Secondly, the other use case of this transaction is initializing the manager's account when starting the application.

 if( this.asset.type === 'manager'){

            const Manager = store.account.get(manager.address); 
            const updated_Manager = {...Manager, 
                                     asset: {...Manager.asset, type:'manager', nash: '10000', nashSupply: '10000'}} ;
   
            store.account.set(updated_Manager.address,updated_Manager);

        }

        else if ( this.asset.type === 'bond'){

            if(!this.asset.price){
                errors.push(new TransactionError(
                    'invalid transaction asset',
                    this.id,
                    '.asset',
                    this.asset,
                    'price must be provided'));
            }
            else{

                const bond = store.account.get(this.senderId);
                const updated_bond = {...bond, asset: { price: this.asset.price, 
                                                       status: 'not sold', type: 'bond', ownerId: manager.address}} ;
              
                store.account.set(updated_bond.address,updated_bond);
            }
        }

7. Buy Bond: Here the users can buy “unsold” bonds from the market. Through this transaction, owner and status properties of bond account, buyer nash balance and manager’s nash supply should be updated. In addition, the address of the bond is placed in the sold bonds list.

//update sender's account
const new_sender_nash = new BigNum(sender.asset.nash).sub(bond.asset.price).toString() ;

const updated_sender = {...sender, asset: {...sender.asset, nash: new_sender_nash} }; 

store.account.set(updated_sender.address, updated_sender);

//update bond's account
const updated_bond = {...bond, asset: {...bond.asset, ownerId:sender.address, status: 'sold'}};

store.account.set(updated_bond.address, updated_bond);

//update Manager's account
const new_supply =  new BigNum(Manager.asset.nashSupply).sub(bond.asset.price).toString();

var new_bondsList = (!Manager.asset.bondsList) ? [] : Manager.asset.bondsList;

new_bondsList.push(bond.address);

const updated_Manager = {...Manager,asset : {...Manager.asset, bondsList : new_bondsList , nashSupply: new_supply}};

store.account.set(updated_Manager.address, updated_Manager);

8. New Nash: During the supply expansion, some of the new Nashs should be distributed amongst the shareholders. This is managed through the NewNash transactions that updates the Nash balance of shareholders, and also the manager’s nashSupply property.

//update recipient's account
const new_recipient_nash = (!recipient.asset.nash)? this.asset.amount 
                        : new BigNum(recipient.asset.nash).add(this.asset.amount).toString();

const updated_recipient = { ...recipient, asset: { ...recipient.asset, nash: new_recipient_nash} };

store.account.set(updated_recipient.address, updated_recipient);

//update Manager's account
const new_supply = (!Manager.asset.nashSupply) ? this.asset.amount
                        : new BigNum(Manager.asset.nashSupply).add(this.asset.amount).toString();

const updated_Manager = {...Manager,asset : {...Manager.asset, nashSupply: new_supply}};

store.account.set(updated_Manager.address, updated_Manager);

Front-end

As I am a beginner working with JavaScript, and especially in front-end development it will take some time for me to build an appropriate UI. I started with a very simple front-end to test the basic functionalities, and I will continue to work on and improve it further to higher versions as soon as possible. To further complement my work, l have included some of the relevant screenshots below:

Conclusion

It was a great experience to build this PoC, and I will continue working on improving the application further, both in the custom transactions and client interface; and finally to extend the features and functionalities in the fullness of time. I hope this blog gave you some insight regarding how we can build our DeFi ideas with Lisk.

If you have any questions or feedback, feel free to reach out on Discord (user `Kasra99ab#0990`).
 

Resources 

If you feel inspired and want to build your own proof of concept blockchain application, check out the Lisk Builders program. More information about the program and the application procedure can be found on the Lisk webpage for the Lisk Builders program.

Disclaimer: This blog post was written by our community member, Kasra (LinkedIn profile) as part of his participation in the Lisk Builders program.