Introduction to automated market makers
In the year 2023, Automated Market Makers (AMMs) have become extremely prevalent in the decentralized finance (DeFi) landscape. It is important to note that AMMs are a relatively recent concept in the realm of DeFi.
The idea of an AMM in the context of web3 was conceived by Vitalik Buterin in 2017, as described in his post titled ‘On Path Independence.’ The first implementation of an AMM-based decentralized exchange (DEX) called Bancor brought this concept to life. Subsequently, the launch of Uniswap in 2018 led to wider adoption of AMMs. Since then, several other AMM-based DEXs such as Balancer, GMX, and Curve Finance have emerged.
Ever since their introduction, AMMs have played a crucial role in DeFi by allowing anyone to trade assets without the need for manual order matching. They have also been instrumental in the development of new DeFi protocols, including lending, borrowing, and prediction markets.
AMMs have greatly propelled the progress of the DeFi industry by offering a globally scalable system. Unlike alternative over-the-counter (OTC) solutions, which can indeed be precise and effective, AMMs have facilitated the necessary adoption to drive the advancement of the space.
Liquidity on traditional financial markets is delivered by companies called “market makers”. The primary role of a market maker is to buy and sell financial instruments on a continuous basis to deliver key element of financial instruments - liquidity.
Liquidity is everything
Traditional market makers has many advantages like helping stabilize prices by absorbing temporary imbalances in supply and demand and contribute to market depth. One of the main drawback is centralized nature of market makers and operational cost as every traditional company. Automated market maker is just a source code deployed on a smart contract platform. In the tutorial I will explain how automated market maker works and how to implement it in ink! smart contract language.
Types of decentralized exchanges
There are several types of decentralized exchanges (DEXs) that exist, each with its own unique characteristics and mechanisms. Here are some of the main types of DEXs:
Automated Market Maker (AMM) DEXs: Like Uniswap, SushiSwap utilize liquidity pools and mathematical formulas to determine token prices. Traders can swap tokens directly from these pools, and liquidity providers earn fees by supplying tokens to the pools.
Order Book DEXs: Replicate the traditional order book model used in centralized exchanges. Users can place and fulfill buy and sell orders, and the DEX matches orders based on price and quantity.
Overview of the implementation and ink! smart contract
1#![cfg_attr(not(feature = "std"), no_std)]23const PRECISION: u128 = 1_000_000;45#[ink::contract]6pub mod automated_market_maker {7 use ink_prelude::collections::BTreeMap;8910 /// Section 0: Definition of a storage111213 #[ink(impl)]14 impl AutomatedMarketMaker {151617 /// Section 1: Constructor181920 /// Section 2: Providing new liquidity to the pool212223 /// Section 3: Estimation of swap token1 for given token2242526 /// Section 4: Swap, amount of token1 that the user should swap to get _amount_token2 in return272829 /// Section 5: Returns amount of token1 required when providing liquidity with _amount_token2 quantity of token2303132 /// Section 6: Returns amount of token2 required when providing liquidity with _amount_token1 quantity of token1333435 /// Section 7: Returns estimation of token1 and token2 that will be released on burning given _share363738 /// Section 8: Removes liquidity from a pool and releases corresponding token_1 and token_2 to the withdrawer394041 /// Section 9: Utils, ensure that quantity is non-zero and user has enough balance424344 /// Section 10: Utils, sends free token(s) to the invoker454647 /// Section 11: Liquidity constant of a pool484950 /// Section 12: Restriction of withdrawing and swapping feature till liquidity is added to a pool515253 /// Section 13: Returns the balance of a user545556 /// Section 14: Returns the amount of tokens locked in the pool, total shares issued and trading fee parameter5758 }5960 /// Section 15: Utils, errors definitions61 }62}
Implementation
1#[derive(Default)]2#[ink(storage)]3pub struct AutomatedMarketMaker {4 total_shares: Balance, // Stores the total amount of share issued for the pool5 total_token1: Balance, // Stores the amount of Token1 locked in the pool6 total_token2: Balance, // Stores the amount of Token2 locked in the pool7 shares: Mapping<AccountId, Balance>, // Stores the share holding of each provider8 token1_balance: Mapping<AccountId, Balance>, // Stores the token1 balance of each user9 token2_balance: Mapping<AccountId, Balance>, // Stores the token2 balance of each user10 fees: Balance, // Percent of trading fees charged on trade11}
Do you have an experience with implementing of decentralized exchanges? Ping me, please.
TBD
Testing
HINT: In many examples you can find ink-experimental-engine = ["ink_env/ink-experimental-engine"]
. In case you will find experiment engine it means that the source code is not up to date. ink-experimental-engine is legacy.
Deployment: WebAssembly and Astar Network
Astar & Shiden runtimes are based on Substrate, and both networks incorporate pallet-contracts, a sandboxed environment used to deploy and execute WebAssembly smart contracts. Any language that compiles to Wasm may be deployed and run on this Wasm Virtual Machine, however, the code should be compatible with the pallet-contracts API.
For WASM smart contracts you can use any compatible programming language, not only Rust.
Improvements proposals
- Economy analysis and cost usage of the smart contract
- More tests
- Proxy pattern
- Topics to research: different price models and bonding curves, price effects in AMM.
- Audit