Trade cryptocurrencies directly on-chain with automated market making. Full custody. Zero intermediaries. 24/7 permissionless access on Binance Smart Chain.
A Decentralized Exchange (DEX) is a blockchain-based platform that allows users to trade cryptocurrencies directly with each other — no centralized intermediary required.
Unlike traditional exchanges like Binance or Coinbase, a DEX operates through smart contracts and automated protocols, giving users full control over their funds and eliminating counterparty risk.
"DEXs represent the core of DeFi — trustless, transparent, and permissionless alternatives to centralized exchanges."
DEXs are the backbone of DeFi — offering a trustless, transparent, and permissionless alternative to centralized exchanges. The DefiAX DEX empowers individuals to trade securely in a growing global ecosystem with full asset custody and zero counterparty risk.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/*
---------------------------------------------------------
Simple AMM DEX Prototype
- Constant product formula: x * y = k
- Liquidity providers earn fees
- Non-custodial trading
---------------------------------------------------------
*/
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function balanceOf(address user) external view returns (uint256);
}
contract SimpleDEX {
IERC20 public tokenA;
IERC20 public tokenB;
uint256 public reserveA;
uint256 public reserveB;
uint256 public totalLiquidity;
mapping(address => uint256) public liquidityOf;
uint256 public constant FEE_BPS = 30;
// 0.30%
uint256 public constant BPS = 10_000;
event LiquidityAdded(address indexed provider, uint256 amountA, uint256 amountB, uint256 minted);
event LiquidityRemoved(address indexed provider, uint256 amountA, uint256 amountB, uint256 burned);
event Swap(address indexed trader, address tokenIn, uint256 amountIn, address tokenOut, uint256 amountOut);
constructor(IERC20 _tokenA, IERC20 _tokenB) {
tokenA = _tokenA;
tokenB = _tokenB;
}
/* ── LIQUIDITY ── */
function addLiquidity(uint256 amountA, uint256 amountB) external {
require(amountA > 0 && amountB > 0, "Zero amounts");
tokenA.transferFrom(msg.sender, address(this), amountA);
tokenB.transferFrom(msg.sender, address(this), amountB);
uint256 liquidity = totalLiquidity == 0
? _sqrt(amountA * amountB)
: _min((amountA * totalLiquidity) / reserveA, (amountB * totalLiquidity) / reserveB);
require(liquidity > 0, "Insufficient liquidity minted");
liquidityOf[msg.sender] += liquidity;
totalLiquidity += liquidity;
reserveA += amountA;
reserveB += amountB;
emit LiquidityAdded(msg.sender, amountA, amountB, liquidity);
}
function removeLiquidity(uint256 liquidity) external {
require(liquidity > 0 && liquidityOf[msg.sender] >= liquidity, "Invalid");
uint256 amountA = (liquidity * reserveA) / totalLiquidity;
uint256 amountB = (liquidity * reserveB) / totalLiquidity;
liquidityOf[msg.sender] -= liquidity;
totalLiquidity -= liquidity;
reserveA -= amountA; reserveB -= amountB;
tokenA.transfer(msg.sender, amountA);
tokenB.transfer(msg.sender, amountB);
emit LiquidityRemoved(msg.sender, amountA, amountB, liquidity);
}
/* ── SWAP ── */
function swapAForB(uint256 amountIn) external {
require(amountIn > 0, "Zero input");
tokenA.transferFrom(msg.sender, address(this), amountIn);
uint256 fee = (amountIn * (BPS - FEE_BPS)) / BPS;
uint256 amountOut = (reserveB * fee) / (reserveA + fee);
require(amountOut > 0, "Zero output");
tokenB.transfer(msg.sender, amountOut);
reserveA += amountIn; reserveB -= amountOut;
emit Swap(msg.sender, address(tokenA), amountIn, address(tokenB), amountOut);
}
function swapBForA(uint256 amountIn) external {
require(amountIn > 0, "Zero input");
tokenB.transferFrom(msg.sender, address(this), amountIn);
uint256 fee = (amountIn * (BPS - FEE_BPS)) / BPS;
uint256 amountOut = (reserveA * fee) / (reserveB + fee);
require(amountOut > 0, "Zero output");
tokenA.transfer(msg.sender, amountOut);
reserveB += amountIn; reserveA -= amountOut;
emit Swap(msg.sender, address(tokenB), amountIn, address(tokenA), amountOut);
}
/* ── VIEW HELPERS ── */
function getPriceAinB() external view returns (uint256) { return (reserveB * 1e18) / reserveA; }
function getPriceBinA() external view returns (uint256) { return (reserveA * 1e18) / reserveB; }
function getReserves() external view returns (uint256, uint256) { return (reserveA, reserveB); }
/* ── MATH ── */
function _min(uint256 x, uint256 y) internal pure returns (uint256) { return x < y ? x : y; }
function _sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y; uint256 x = y / 2 + 1;
while (x < z) { z = x; x = (y / x + x) / 2; }
} else if (y != 0) { z = 1; }
}
}