A decentralized Automated Market Maker (AMM) built on Solana using the Anchor framework. This AMM allows users to create liquidity pools, provide liquidity, and swap tokens with constant product pricing.
- Initialize Pool: Create new AMM pools with custom parameters
- Add Liquidity: Deposit tokens to earn trading fees
- Remove Liquidity: Withdraw tokens from pools
- Token Swaps: Exchange tokens using constant product formula
- Fee Management: Configurable trading fees for pool creators
Before you begin, ensure you have the following installed:
- Node.js (v18+ recommended)
- Rust (latest stable version)
- Solana CLI (v1.18+)
- Anchor CLI (v0.31.1)
-
Clone the repository
git clone <your-repo-url> cd amm
-
Install dependencies
cd tests npm install
-
Configure Solana CLI
# Set to localnet for development solana config set --url localhost # Generate a new keypair (if needed) solana-keygen new
Build the Anchor program:
anchor build
-
Start local validator
solana-test-validator
-
Run tests
anchor test # or cd tests && npm run test:local
# Test on devnet
npm run test:devnet
# Test on mainnet (use with caution)
npm run test:mainnet
anchor deploy
# or
npm run deploy:local
npm run deploy:devnet
npm run deploy:mainnet
Creates a new AMM pool with specified parameters.
await program.methods
.initialize(seed, fee, authority)
.accounts({
// ... accounts
})
.rpc();
Parameters:
seed
: Unique identifier for the poolfee
: Trading fee (in basis points, e.g., 30 = 0.3%)authority
: Optional pool authority
Provides liquidity to the pool in exchange for LP tokens.
await program.methods
.deposite(amount, maxX, maxY)
.accounts({
// ... accounts
})
.rpc();
Parameters:
amount
: Amount of LP tokens to mintmaxX
: Maximum amount of token X to depositmaxY
: Maximum amount of token Y to deposit
Burns LP tokens to withdraw underlying assets.
await program.methods
.withdraw(amount, minX, minY)
.accounts({
// ... accounts
})
.rpc();
Parameters:
amount
: Amount of LP tokens to burnminX
: Minimum amount of token X to receiveminY
: Minimum amount of token Y to receive
Exchanges one token for another using the constant product formula.
await program.methods
.swap(isX, amountIn, minAmountOut)
.accounts({
// ... accounts
})
.rpc();
Parameters:
isX
:true
to swap X for Y,false
to swap Y for XamountIn
: Amount of input tokensminAmountOut
: Minimum amount of output tokens (slippage protection)
amm/
├── Anchor.toml # Anchor configuration
├── Cargo.toml # Rust workspace configuration
├── programs/amm/ # Main program directory
│ ├── src/
│ │ ├── lib.rs # Program entry point
│ │ ├── instructions/ # Instruction handlers
│ │ │ ├── initialize.rs # Pool initialization
│ │ │ ├── deposite.rs # Liquidity deposit
│ │ │ ├── withdraw.rs # Liquidity withdrawal
│ │ │ └── swap.rs # Token swapping
│ │ ├── states/ # Program state definitions
│ │ │ └── config.rs # Pool configuration
│ │ ├── errors.rs # Custom error definitions
│ │ └── constant.rs # Program constants
└── tests/ # TypeScript tests
├── ammTest.ts # Main test suite
├── package.json # Test dependencies
└── tsconfig.json # TypeScript configuration
- Anchor Version: 0.31.1
- Default Cluster: Localnet
- Update
Anchor.toml
with your desired cluster - Configure wallet path in
Anchor.toml
- Ensure sufficient SOL balance for deployments
The test suite demonstrates a complete AMM workflow:
- Setup: Create token mints and accounts
- Initialize: Create AMM pool with 0.3% fee
- Deposit: Add initial liquidity
- Swap: Execute token swaps
- Withdraw: Remove liquidity
- This is a development version - audit before mainnet use
- Contains a typo:
deposite
should bedeposit
(consistent in codebase) - Always test thoroughly on devnet before mainnet deployment
- Ensure proper slippage protection in production
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
anchor test
- Submit a pull request
This project is licensed under the ISC License.
⚡ Quick Start:
anchor build && anchor test