raydium-amm
## Program Deployments
| Environment | [PROGRAM](/program) |
| ------------------- | ---------------------------------------------- |
| Mainnet | `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` |
| Devnet | `DRaya7Kj3aMWQSy19kSjvmuwq9docCHofyP9kanQGaav` |
## Overview
- **The Raydium AMM is an on-chain smart contract based on the “constant product” in a permissionless and decentralized manner built on the Solana blockchain.And it also shares its liquidity according to the Fibonacci sequence in the form of limit orders on [OpenBook](https://github.com/openbook-dex/program), the primary central limit order book (CLOB) of Solana**
- **The audit process is [here](https://github.com/raydium-io/raydium-docs/tree/master/audit)**
- **The dev document is [here](https://github.com/raydium-io/raydium-docs/tree/master/dev-resources)**
## Environment Setup
1. Install [Rust](https://www.rust-lang.org/tools/install).
2. Install [Solana](https://docs.solana.com/cli/install-solana-cli-tools) and then run `solana-keygen new` to create a keypair at the default location.
## Build
Clone the repository and enter the source code directory.
```bash
git clone https://github.com/raydium-io/raydium-amm
cd raydium-amm/program
```
### Mainnet Build
```bash
cargo build-sbf
```
### Devnet Build
```bash
cargo build-sbf --features devnet
```
### Localnet Build
You must update these pubkeys in the "config_feature" as yours over the localnet feature before build;
```bash
cargo build-sbf --features localnet
```
After building, the smart contract files are all located in the target directory.
## Deploy
```bash
solana deploy
```
Attention, check your configuration and confirm the environment you want to deploy.
## QuickStart
1. You must have an openbook market not associated to any amm pool if you want to initialize a new amm pool.
And you can refer to [ListMarket](https://github.com/openbook-dex/program/blob/master/dex/crank/src/lib.rs#L349) to create a new market.
2. Add dependencies in your Cargo.toml
```rust
[dependencies]
[features]
# default is mainnet
devnet = [
"amm-cli/devnet",
"common/devnet",
]
[dependencies]
amm-cli = { git = "https://github.com/raydium-io/raydium-library" }
common = { git = "https://github.com/raydium-io/raydium-library" }
spl-token = { version = "4.0.0", features = ["no-entrypoint"] }
spl-associated-token-account = { version = "2.2.0", features = [
"no-entrypoint",
] }
spl-token-2022 = { version = "0.9.0", features = ["no-entrypoint"] }
solana-client = "<1.17.0"
solana-sdk = "<1.17.0"
anyhow = "1.0.53"
clap = { version = "4.1.8", features = ["derive"] }
```
3. Import dependent libraries
```rust
#![allow(dead_code)]
use anyhow::{Ok, Result};
use clap::Parser;
use solana_client::rpc_client::RpcClient;
use solana_sdk::{commitment_config::CommitmentConfig, signer::Signer};
use std::sync::Arc;
use {
amm_cli::{self, AmmCommands},
common::{common_types, common_utils, rpc},
};
```
4. Custom configuration parameters in your code.
```rust
// default config
let mut config = common_types::CommonConfig::default();
// Replace the default configuration parameters you need
config.set_cluster("http", "ws");
config.set_wallet("your wallet path");
config.set_amm_program("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
config.set_openbook_program("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX");
config.set_slippage(50);
```
5. Constructing a signed storage object.
```rust
let payer = common_utils::read_keypair_file(&config.wallet())?;
let fee_payer = payer.pubkey();
let mut signing_keypairs: Vec> = Vec::new();
let payer: Arc = Arc::new(payer);
if !signing_keypairs.contains(&payer) {
signing_keypairs.push(payer);
}
```
6. initialize a new amm pool with an associate openbook market
```rust
// build initialize pool instruction
let subcmd = AmmCommands::CreatePool {
market: Pubkey::from_str("The amm associated with openbook market").unwrap(),
coin_mint: Pubkey::from_str("The openbook market's coin_mint").unwrap(),
pc_mint: Pubkey::from_str("The openbook market's pc_mint").unwrap(),
user_token_coin: Pubkey::from_str("User's token coin").unwrap(),
user_token_pc: Pubkey::from_str("User's token pc").unwrap(),
init_coin_amount: 100000u64,
init_pc_amount: 100000u64,
open_time: 0,
};
let instruction = amm_cli::process_amm_commands(subcmd, &config).unwrap();
```
3. deposit assets to an amm pool
```rust
// build deposit instruction
let subcmd = AmmCommands::Deposit {
pool_id: Pubkey::from_str("The specified pool of the assets deposite to").unwrap(),
deposit_token_coin: Some(Pubkey::from_str("The specified token coin of the user deposit").unwrap()),
deposit_token_pc: Some(Pubkey::from_str("The specified token pc of the user deposit").unwrap()),
recipient_token_lp: Some(Pubkey::from_str("The specified lp token of the user will receive").unwrap()),
amount_specified: 100000u64,
another_min_limit: false,
base_coin: false,
};
let instruction = amm_cli::process_amm_commands(subcmd, &config).unwrap();
```
### Note
If the parameter of the deposit_token_coin, deposit_token_pc or recipient_token_lp is None, it will be ATA token by default.
4. withdraw assets from amm pool
```rust
// build withdraw instruction
let subcmd = AmmCommands::Withdraw {
pool_id: Pubkey::from_str("The specified pool of the assets withdraw from").unwrap(),
withdraw_token_lp: Some(Pubkey::from_str("The specified lp token of the user withdraw").unwrap()),
recipient_token_coin: Some(Pubkey::from_str("The specified token coin of the user will receive").unwrap()),
recipient_token_pc: Some(Pubkey::from_str("The specified token pc of the user will receive").unwrap()),
input_lp_amount: 100000u64,
slippage_limit: false,
};
let instruction = amm_cli::process_amm_commands(subcmd, &config).unwrap();
```
### Note
If the parameter of the withdraw_token_lp, recipient_token_coin or recipient_token_pc is None, it will be ATA token by default.
5. swap
```rust
// build swap instruction
let subcmd = AmmCommands::Swap {
pool_id: Pubkey::from_str(" The specified pool of trading").unwrap(),
user_input_token: Pubkey::from_str("The token of user want to swap from").unwrap(),
user_output_token: Some(Pubkey::from_str("The token of user want to swap to").unwrap()),
amount_specified: 100000u64,
base_out: false,
};
let instruction = amm_cli::process_amm_commands(subcmd, &config).unwrap();
```
### Note
If the parameter of the user_output_token is None, it will be ATA token by default.
For more information, you can see the repo [raydium-library](https://github.com/raydium-io/raydium-library)