Amm x*y=k
Smart Contract Code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// Gold Token (GOLD)
contract GoldToken is ERC20 {
constructor() ERC20("GoldToken", "GOLD") {
_mint(msg.sender, 100000 * 10 ** decimals()); // Mint 100,000 GOLD
}
}
// Diamond Token (DIAMOND)
contract DiamondToken is ERC20 {
constructor() ERC20("DiamondToken", "DIAMOND") {
_mint(msg.sender, 50000 * 10 ** decimals()); // Mint 50,000 DIAMOND
}
}
// Automated Market Maker (AMM) Contract
contract AMM {
IERC20 public gold;
IERC20 public diamond;
uint256 public reserveGold;
uint256 public reserveDiamond;
constructor(address _gold, address _diamond) {
gold = IERC20(_gold);
diamond = IERC20(_diamond);
}
function addLiquidity(uint256 goldAmount, uint256 diamondAmount) external {
gold.transferFrom(msg.sender, address(this), goldAmount);
diamond.transferFrom(msg.sender, address(this), diamondAmount);
reserveGold += goldAmount;
reserveDiamond += diamondAmount;
}
function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut) public pure returns (uint256) {
require(amountIn > 0 && reserveIn > 0 && reserveOut > 0, "Invalid reserves");
uint256 amountInWithFee = amountIn * 997; // 0.3% fee
uint256 numerator = amountInWithFee * reserveOut;
uint256 denominator = (reserveIn * 1000) + amountInWithFee;
return numerator / denominator;
}
function swapGoldForDiamond(uint256 goldAmount) external {
uint256 diamondAmount = getAmountOut(goldAmount, reserveGold, reserveDiamond);
require(diamondAmount > 0, "Insufficient output amount");
gold.transferFrom(msg.sender, address(this), goldAmount);
diamond.transfer(msg.sender, diamondAmount);
reserveGold += goldAmount;
reserveDiamond -= diamondAmount;
}
function swapDiamondForGold(uint256 diamondAmount) external {
uint256 goldAmount = getAmountOut(diamondAmount, reserveDiamond, reserveGold);
require(goldAmount > 0, "Insufficient output amount");
diamond.transferFrom(msg.sender, address(this), diamondAmount);
gold.transfer(msg.sender, goldAmount);
reserveDiamond += diamondAmount;
reserveGold -= goldAmount;
}
}
Constant Product Formula Analysis (x * y = k)
The constant product formula is a key concept used in automated market makers (AMMs) like Uniswap. It makes sure that the product of the amounts (reserves) of two assets in a liquidity pool stays the same during any swap. This helps keep the market balanced and liquid.
This example shows how swapping one asset (Gold) for another (Diamond) changes their amounts, while keeping the product constant.
Given:
- Initial Gold reserve is 1000
- Initial Diamond reserve is 2000
=====================================> Constant product formulae
x*y=k;
For instance , Gold=1000
Diamond =2000
k=Gold* Diamond
= 2000000
1. Swap for 100 Gold to the Diamond = > goldNew=1000+100
=1100
2. diamondNew =>
diamondNew= k / goldNew
=2000000/11000
=1818.1818
3. Diamonds to the user => Diamond - diamondNew
=2000-1818.1818
=181.8182
4. Updated Diamonds Are =2000 - 181.8282
=1818.1818
================================================================>
fee=0.3%
==========> amountinFee = amountin * 997
________________
1000
numerator= (amountInWithFee × reserveOut)
denominator= reserveIn × 1000 + amountInWithFee
amountOut= numerator/ denominator
Step 1: Calculate the constant product k
Multiply the initial Gold and Diamond amounts:
k = 1000 * 2000 = 2,000,000
This number k does not change before and after a swap.
Step 2: Swap 100 Gold for Diamonds
- After the swap, the Gold reserve increases by 100:
new Gold reserve = 1000 + 100 = 1100
- To keep the product constant, calculate the new Diamond reserve by dividing k by the new Gold reserve:
new Diamond reserve = 2,000,000 / 1100 ≈ 1818.18
Step 3: Calculate how many Diamonds the user receives
The user gets the difference between the old Diamond reserve and the new Diamond reserve:
Diamonds to user = 2000 - 1818.18 = 181.82
Step 4: Update the Diamond reserve in the pool
The Diamond reserve is now decreased to:
updated Diamond reserve = 1818.18
Summary:
- The product of the two asset reserves stays the same during the swap.
- Adding 100 Gold to the pool reduces the Diamond reserve to maintain balance.
- The user receives about 181.82 Diamonds for their 100 Gold.
- This formula helps keep liquidity and sets fair prices in decentralized exchanges.