read.cash Log in
@p0oker

Yield Farming in Bitcoin Cash - A practical guide

Yield farming or liquidity mining is the newest trend in crypto, particularly introduced by Ethereum community and with the invention of Compound governance token and is considered the latest trend in DeFi. The basic idea is for participants in a protocol to mine tokens using their liquidity or generally investing on a specific platform. This concept is new and is not used in many other cryptocurrency communities. I believe many people think performing that kind of functions is not feasible on Bitcoin Cash because the smart contracts on BCH are not as advanced as Ethereum. Even though that notion is true, the very act of minting a SLP token in a decentralized manner is already proven by projects like Mistcoin. https://mistcoin.org/ In this article I like to go in depth into the possibility of Yield Farming in Bitcoin Cash, the implementation and provide you a real sample transaction and Cash Script code that successfully minted a SLP token using an investment (called premium) without any centralized interference. The Smart Contract Bitcoin Cash smart contracts are inherently different from platforms like Ethereum. In Ethereum smart contracts are large, they can easily issue tokens and have full access to the state of the protocol. Bitcoin Cash smart contracts are stack based and very limited. However, they are more advanced than Bitcoin in the sense that developers can access the full data of the transaction and **limit the inputs and outputs to specific parameters**. These type of contracts are called **Covenants**. A detailed explanation of the differences between BCH and ETH smart contracts can be found in Rosco Kali's blog post. https://kalis.me/smart-contracts-eth-btc-bch/ SLP Minting Baton Another element that requires for this type of transactions to work are SLP Minting Batons. Generally anytime someone creates a new SLP token, they can specify a Bitcoin Cash address to store the minting baton. Meaning that everyone who holds control of that address can issue new SLP tokens in the future. Keeping this Baton in a normal BCH address is very dangerous and a centralized way to keep the supply of a SLP token. The owner of the SLP token have the authority to destroy that Baton to stop the issuance of the new tokens, however in order to do that they have to issue a large amount of tokens and keep them centrally for future use. SLP tokens like Spice or Sour are some of those examples. Good news that there is a better way to do this as well. A SLP minting Baton can be sent to a smart contract which controls the issuance of the token and takes away any central control over the token. However, the smart contract should be able to provide conditions to prevent minting of the token by actors who did not provide sufficient value for that. Transaction Details Considering the elements discussed, we need to perform these actions to create the Yield Farming contract for users of a token: Create a SLP token with zero issuance Store the minting baton centrally temporarily to get the genesis TX id (token ID) Create a smart contract with 2 parameters, **premiumPkh** and **tokenId** Perform a mint transaction with zero issuance to move the Baton to the P2SH contract forever. Now every party can spend this contract with an atomic transaction only and only if these conditions are met: A minimum amount of BCH should be sent to **premiumPkh** ( a normal BCH address or another contract) Minting baton should be sent back to the **same contract** Enough BCH should be provided by the farmer to cover the transaction fees and the locked satoshis for the freshly minted tokens If the transaction by the farmer (end user) is created according to the rules above, the user will end up creating new SLP tokens which will be sent to her address. Failure to do so, will fully reject the transaction and no BCH is lost in the process. Here is an overview of how this transaction looks like:

You can view the above transaction here. https://explorer.bitcoin.com/bch/tx/708fd137a2abd5b5c20e81bc71ec5fd345c225353c5ef2e24215e2de7626598f Smart Contract Implementation Thanks to the efforts done by Rosco Kalis and the sponsors of the Cash Script (General Protocols and Bitcoin.com), this language is evolving to become the standard for BCH smart contracts. The new version of the Cash Script makes the process of working with Covenants pretty straightforward. https://generalprotocols.com/ Here is the code to implement the smart contract described in this example. As you can see, there is no central key in the contract to control the issuance and it makes the contract reusable by everyone for an unlimited amount of time. This contract is more like a proof of concept and lacks the edge cases like emission control, change addresses or proportional reward according to the premium. So with this contract, a person simply can send a minimum of 1000 satoshi to the premium address to mint 250 new tokens for herself. contract Yield(bytes20 premiumPkh, bytes tokenIdHex) { function farm(pubkey farmerPk, sig s, int premium) { require(checkSig(s, farmerPk)); // minimum amount of premium to be paid in order to farm the yield int minPremium = 1000; int satsToBeMinted = 546; int satsLockedInForBaton = 546; int dust = 546; require(premium >= minPremium); bytes opReturnOut = new OutputNullData([ 0x534c5000, // Lokad ID for SLP 0x01, bytes('MINT'), tokenIdHex, 0x03, // minting baton vout (very important to avoid burning the baton) 0x00000000000061A8 // 250 SLPs (considering 2 decimals) ]); // minted token sent back to the farmer bytes34 out1 = new OutputP2PKH(bytes8(satsToBeMinted), hash160(farmerPk)); // investment to the premium in order to farm bytes34 out2 = new OutputP2PKH(bytes8(premium), premiumPkh); // minting baton should be sent back to the contract bytes32 out3 = new OutputP2SH(bytes8(satsLockedInForBaton), hash160(tx.bytecode)); require(hash256(opReturnOut + out1 + out2 + out3) == tx.hashOutputs); } } Farming the Contract Farming the contract should happen with inputs from the end-user + the Minting Baton input which is inside the smart contract. This address is reusable by anyone and can be used forever to mint tokens as long as the premium amount is paid (could be investment in another contract or just a one time payment). Here is an example of how it should look like (in Node JS): // Making the transaction to pay the premium and mint SLP to alice address using the minting baton // stored in the smart contract let tx = await contract.functions .farm(alicePk, new SignatureTemplate(aliceKeyPair), premiumAmount) .from(aliceUtxos) .from(mintingBaton) .withOpReturn([ "0x534c5000", // Lokad ID "0x01", // Token type "MINT", // Action `0x${tokenId}`, // Token ID "0x03", // Minting baton vout "0x00000000000061A8", // mint 250 new tokens (considering 2 decimals) ]) .to(aliceBchAddr, 546) // freshly minted tokens .to(premiumBchAddr, premiumAmount) // minimum 1000 sats premium is required .to(contract.address, 546) // minting baton is sent back to contract .withoutChange() .send(); The codes demonstrated here are very new and not thoroughly tested or optimized. However the full implementation of this functionality, including the genesis of the token, moving the baton to smart contract and functional mint transaction is maintained in a repository in my Github. Fully open source under the MPL-2.0 license. https://github.com/p0o/yield-farming-bch-smart-contract Use Cases There are numerous use cases for this type of contract including but not limited to: Reward tokens for other contracts (e.g DeFi, AnyHedge, etc) Governance Token distribution Decentralized token sales without custody Loyalty tokens to a merchant's customers Fundraiser without assurance contract (e.g GoFundMe ) Decentralized Exchange (requires an oracle for rates) Conclusion Thanks for following through the article. SLP and Bitcoin Cash smart contracts are amazing technologies and most of the advanced use cases from these technologies are still not utilized. Feel free to get the code, run it and explore the unlimited use cases that you can imagine to build on Bitcoin Cash. The challenge of using these type of contracts in the wild is the type of transaction that should be constructed differently. There is no native wallet support for these transactions yet, however, if you are familiar with my other project Signup, one of the main plans in the roadmap of that wallet is bringing Bitcoin Cash smart contracts to the web and mainstream apps. Here is the article about Signup's release in case you missed it. https://signup.cash https://read.cash/@SIGNUP/signups-new-bch-web-wallet-is-released-4fcd8576 If you are interested to build a Yield Farming/Reward contract but don't have the required knowledge feel free to reach out to me at my Twitter. I would be happy to help you out. https://twitter.com/p0oker

$14.49

13 comments

Log in to join in Reading is open to everyone. Replying needs an account.