The Dapps Challenge is undergoing updates. Some functionality may not work for the time-being. Thank you for your patience as we work to make it available again soon!
A liquidity pool is a collection of tokens or digital assets deposited by users and held in a smart contract or dapp that can be used to provide essential liquidity to decentralized exchanges (DEXs) and other decentralized finance (DeFi) protocols. Since liquidity plays a crucial role in enabling DeFi systems, liquidity pools, where assets can be held, lent, borrowed, swapped, or traded (depending on dapp functionality), are fundamental to these systems.
The functionality of this liquidity pool dapp will allow users to mint tokens, deposit liquidity, swap between asset types, and withdraw funds from the liquidity pool. This dapp challenge will walk you through the step-by-step process of creating and launching a liquidity pool dapp on Stellar using Soroban smart contracts. You will learn how to deploy smart contracts to a sandbox environment and interact with them through a web frontend. In this context, the term "ship" refers to finalizing the development process of your dapp, ensuring that it functions as expected and is accessible for user interaction and testing through a hosted frontend. Despite the end-to-end functionality of this challenge, this dapp is not promoted nor intended for deployment in a production-level setting on Futurenet, but rather is designed for educational purposes.
Checkpoint 0: π¦ Install πβ
Start by installing the required dependencies. You'll also want to be sure you have the most updated version of Rust installed.
Required:
soroban-cli alias
(installed in the next step)Node
v18: Download NodeFreighter Wallet
: Freighter Wallet
First, clone the Soroban example dapp repo and navigate to the liquidity-pool
directory:
git clone https://github.com/stellar/soroban-dapps-challenge
cd soroban-dapps-challenge
git checkout liquidity-pool
Then, install soroban-cli alias by running the following command:
cargo install_soroban
Soroban CLI is the command line interface to Soroban. It allows you to build, deploy, and interact with smart contracts, configure identities, generate key pairs, manage networks, and more. The soroban-cli alias that is used in this challenge is a pinned version of the soroban-cli that is used in the Soroban Dapps Challenge. Using the soroban-cli alias ensures that the challenge is reproducible and that all participants are using the same version of Soroban.
Checkpoint 1: π¬ Deploy Smart Contractsβ
Deploying a smart contract in a production setting involves submitting the contract code to the blockchain's main network (Mainnet), where it becomes part of the chain's immutable ledger. When you deploy the smart contracts in this challenge, you'll instead deploy to Futurenet, a test network with more cutting-edge features that have not yet been implemented in the Mainnet. Deploying smart contracts to a sandbox environment simulates the production-level deployment process without actually affecting Mainnet.
Now that you have the Liquidity Pool branch checked out, load the contracts and initialize them in the sandbox environment by running the following commands in your terminal:
./initialize.sh futurenet
If the command runs successfully, your terminal will return a series of messages notifying you about the successful initialization of the contracts and the post-installation sequence.
Contract deployed successfully with ID: CBXHU5BWWTOCZRYX3DMSSKCFG7B3K2YG2I5F75ALPQ6GCY6ZES2XKLTI
Deploy the liquidity pool contract
Contract deployed successfully with ID: CBKY7UN5VGD4LIQFOBOTSUSQWK67BZZTA23NIEVWSWRR5SAT26JQN2BN
Initialize the abundance token contract
Initialize the liquidity pool contract
Done
> [email protected] build-contracts
...
The contract ID is a unique identifier for a smart contract deployed on a blockchain. This contract ID is used to interact with and reference the smart contract, allowing users to invoke functions from the smart contract, send transactions, or otherwise interact with the smart contract's functionalities and data stored on the blockchain.
Please, save your deployed contract ID. You will need it to complete the challenge.
Checkpoint 2: π€ Connect the Frontend to the Backendβ
Now that you have deployed the smart contract, it's time to check out the frontend of your dapp. The frontend is the browser interface where users will connect their digital wallets to make deposits into and withdrawals from the liquidity pool. The frontend is also where users will be able to see their balances and swap tokens.
Because interacting with dapps requires both backend and frontend development, the Soroban Dapps Challenge includes the functionality to easily deploy a frontend interface of the dapps. Building out the frontend from scratch would typically involve creating a user interface (UI) and user experience (UX) design, as well as writing the code for the frontend. In this challenge, you will use the frontend that is already built for you.
To set up the development server, navigate to the frontend
folder of the soroban-dapps-challenge repository and run the following command:
make setup && make start_dev
Note: This may require admin privileges on some systems.
Now open your browser and visit http://localhost:5173. You should be able to see the frontend of your dapp.
Note: Follow the instructions below and ensure that you have funded your wallet address that you intend to use from browser.
Now that you have the frontend running, it's time to connect it with the backend, your smart contract, that defines the rules and logic of the liquidity pool, including the token swap and liquidity pool functions.
You will need to add some Futurenet network lumens to your wallet to interact with the dapp. Visit Stellar Lab, and follow the instructions to create and or fund an account on Futurenet. Remember, these are test lumens for use on Futurenet and cannot be used on Mainnet.
Checkpoint 3: π Dive into the Liquidity Poolβ
Embark on a tidal journey! In this step you will mint, deposit, swap, and withdraw tokens from the liquidity pool. Minting tokens, depositing liquidity, swapping between asset types, and withdrawing funds from the liquidity pool constitute the basic lifecycle of interacting with a DeFi protocol.
In the context of liquidity pools, depositing and withdrawing assets involve connecting a digital wallet and submitting deposit/withdraw transactions. In this liquidity pool dapp challenge specifically, you will also need to mint the test tokens that you will then use to make deposits to the liquidity pool. (This minting of test tokens is different from liquidity pools where depositors may receive minted tokens in exchange for their deposited funds.) Perhaps one of the most important actions a user can take through liquidity pool dapps is swapping tokens. In fact, the ability to swap from one asset to another through a liqudity pool is a powerful feature of DeFi protocols: instead of exchanging assets through traditional financial institutions and intermediaries, users can have direct access to decentralized asset exchange via liquidity pool dapps, without needing a bank account or other traditional financial instruments.
- π¦ Mint Tokens
- π° Add Liquidity
- π Make a Swap
- β€΄οΈ Remove Liquidity
- Mint
- Approve
- Check
Mint USDC and BTCβ
In order to use this liquidity pool dapp, you will need to mint test tokens which can then be used to make deposits and swaps via the frontend of the dapp. To mint USDC and BTC test tokens, open the dapp frontend and click the "MINT" button for USDC and BTC.
Approve Transactionβ
You should see a popup from Freighter asking you to sign the transactions. Click on "Approve" and wait for the transaction to be confirmed.
Check Updated Balanceβ
You should see an updated balance in the account balance component.
- Deposit
- Approve
- Check
Deposit into the Liquidity Poolβ
Depositing assets into the liquidity pool involves users submitting deposit transactions via the frontend to deposit tokens from their wallet into the liquidity pool. In this dapp you will make a deposit of two asset types in order to swap between those asset types. In other DeFi protocols, users may also deposit liquidity into a liquidity pool in order to earn yields on their deposits. The intial deposit of liquidity into a liquidity pool is what sets the initial price of the tokens in the pool. For example, if a user deposits 37000 USDC and 1 BTC, the price of each BTC token will be 37000 USDC.
Open the frontend, enter the desired token amounts, and click the "Deposit" button. You should see a popup from Freighter asking you to sign the transaction.
Approve Transactionβ
Click on "Approve" and wait for the transaction to be confirmed. Once the transaction is confirmed, you should see your balances updated.
Check Updated Balanceβ
You should see an updated balance in the amounts you have deposited in the account and reserve balance components, respectively. Following the example, you should see 50 USDC, 50 BTC, and 50 POOL.
- Swap
- Approve
- Check
Swap Tokensβ
Now that you have funded the liquidity pool, you can make a swap to easily exchange one token for another. Swaps in a liquidity pool usually depend on the relationship between two or more different tokens that can be exchanged with each other. Typical liquidity pools rely on a mathematical formula that determines the price of the tokens within the pool. With every deposit and withdraw transaction to or from the pool, the formula adjusts the token price of each token based on this formula. When a swap occurs, the liquidity pool uses the formula and the balances of each token with the pool to determine the swap value of each token relative to the others within the pool.
This liquidity pool dapp challenge uses a specific formula in its smart contracts to enable swapping between tokens while ensuring that the liquidity pool remains balanced and that liquidity providers are compensated for their contributions to the pool (.3% of swap amount are sent to liquidity providers). Since this liquidity pool dapp currently only holds the two tokens you deposited in the previous step, the formula will reflect those token balances: the price of each token will be be relative to the amount of the other token in the pool. For example, if you deposited 50 USDC and 50 BTC, the price of each token will be 1:1. If you deposited 100 USDC and 50 BTC, the price of each token will be 2:1.
Also important to note is how slippage works in this dapp. Slippage refers to the maximum variation percentage accepted for the desired deposit amounts. The higher the percentage, the greater the chance of a successful transaction, but you may not get such a good price. Here, users can set the max slippage to their desired amount.
To complete a swap between USDC and BTC test tokens, open the swap tab of the frontend, input the desired token swap amounts, and click the "Swap" button. You should see a popup from Freighter asking you to sign the transaction.
Approve Transactionβ
Click on "Approve" and wait for the transaction to be confirmed.
Check Updated Balanceβ
Once the transaction is confirmed, you should see updated balances on the frontend.
- Withdraw
- Approve
- Check
Withdraw Tokens from the Liquidity Poolβ
Now that you have swapped tokens through the liquidity pool, you can make a withdrawal of your funds.
The "Pool Share" slider in this dapp refers to the slider for the percentage of liquidity you want to withdraw from the pool. For example, if you have 100 USDC and 100 BTC in the pool, and you want to withdraw 50% of your liquidity, you would select 50% on the slider. The withdrawal amounts are relative to the estimated price of the tokens in the pool base on the conversion ratio set in the Deposit that created the liquidity pool. For example if a user deposits 50 USDC and 1 BTC, the price of USDC will be 50:1 BTC. If the user then withdraws 50% of their liquidity, they will receive 25 USDC and 0.5 BTC. The price of BTC in the pool will then be recalculated based on the token supply in the pool, potentially causing slippage and resulting in a price different from the original 50:1 ratio.
Open the withdraw tab, select how much liquidity you want to remove with the sliding bar, and click the "Withdraw" button. You should see a popup from Freighter asking you to sign the transaction.
Approve Transactionβ
Click on "Approve" and wait for the transaction to be confirmed.
Check Updated Balanceβ
Once the transaction is confirmed, you should see updated balances on the frontend.
Note: These are test tokens for use on Futurenet or Mainnet.
Checkpoint 4: π’ Ship It! πβ
Now that your dapp is fully functional, its time to deploy it to a production environment. In this step, you will learn how to deploy your dapp to Vercel, a cloud platform for static sites that offers a quick and effective way to deploy the frontend of your dapp. This section requires that you have a Vercel account and install the Vercel CLI.
First, you will remove the target directory, as it is not used by Vercel to deploy your site. To do this, navigate to the liquidity-pool
directory and run the following:
rm -rf target
Note: You can build this directory again by running
soroban contract build
in thecontracts/abundance
directory.
Next, you must move your .soroban
directory to the frontend directory.
From a terminal in the liquidity-pool
directory, run the following command:
mv .soroban frontend/.soroban
Then, you need to update the package.json
file in the frontend
directory to point to the new contract binding locations.
-"liquidity-pool-contract": "file:../.soroban/contracts/liquidity-pool",
-"share-token-contract": "file:../.soroban/contracts/share-token",
-"token-a-contract": "file:../.soroban/contracts/token-a",
-"token-b-contract": "file:../.soroban/contracts/token-b",
+"liquidity-pool-contract": "file:.soroban/contracts/liquidity-pool",
+"share-token-contract": "file:.soroban/contracts/share-token",
+"token-a-contract": "file:.soroban/contracts/token-a",
+"token-b-contract": "file:.soroban/contracts/token-b",
Next, you will use the Vercel CLI to complete your deployment.
First, install the Vercel CLI:
npm i --global vercel
Then, remove any existing .vercel
directory in your project to ensure that you are starting with a clean slate:
rm -rf .vercel
Then, run the following command to deploy your example dapp:
vercel --prod
Vercel will prompt you to link your local project to a new Vercel project. Follow the answers to the prompts below to ensure that your local project is correctly linked to a new Vercel project:
? Set up β~/Documents/GitHub/test/soroban-dapps-challengeβ? [Y/n] y
? Which scope should contain your project? <VERCEL_UNAME>
? Link to existing project? [y/N] n
? Whatβs your projectβs name? <PROJECT_NAME>
? In which directory is your code located? ./
Then, continue through the prompts until you see the following message regarding setting overrides:
? Want to override the settings? [y/N] y
? Which settings would you like to override? (Press <space> to select, <a> to toggle all, <i> to invert selection)
β―β― Build Command
β― Development Command
β― Output Directory
Select each entry (type "a") and set the following values:
build command
cd frontend && make build
development command
cd frontend && make start_dev
output directory
frontend/dist
Once the deployment is complete, you should see a completion message similar to the following:
π Linked to julian-dev28/liquidity-pool (created .vercel)
π Inspect: https://vercel.com/julian-dev28/liquidity-pool/FfsAJdgUR9LKH5EmGiuMCMYUMTi2 [2s]
β
Production: https://liquidity-pool.vercel.app [54s]
Please, save your production url, you will need it to complete the challenge.
You can now visit the preview link to see your deployed dapp! π
Remember, you must add Futurenet network lumens to your Freighter wallet to interact with the deployed example dapp. Visit Stellar Lab, and follow the instructions to create your Freighter account on Futurenet.
Checkpoint 5: β Complete the Challenge!β
Now it's time to submit your work!
Submit your Production
URL from the previous step into the challenge form to pass the challenge!
Checkpoint 6: πͺ Flex!β
π΄ Fork the Soroban Dapps Challenge repo and make your own changes to the Liquidity Pool branch.
Customize the code and submit a pull request for the Liquidity Pool Dapp Challenge. You can experiment with new fee strategies, improve the user interface, or integrate additional token pair options.
Take this opportunity to showcase your skills and make your mark on the Liquidity Pool Dapp. Good luck!
π User Workflows Checklistβ
During this exercise, you should be able to:
- Clone the example repo (Liquidity Pool Dapp)
- Deploy your contract to a sandbox environment.
- Deploy the example web UI somewhere (e.g., Netlify, Vercel, Surge, etc.)
Then, via the web UI, you should be able to:
- Connect your wallet
- See your current balance(s)
- Mint assets
- Deposit assets
- Swap assets
- Withdraw assets
- See your transaction(s) appear on the page as the transactions are confirmed
π‘οΈπ‘οΈ Take On More Challengesβ
View your progress and take on more challenges by visiting your User Dashboard!