Skip to content

Commit a92dc98

Browse files
committed
LP token update
1 parent 0a5642e commit a92dc98

File tree

4 files changed

+76
-11
lines changed

4 files changed

+76
-11
lines changed

src/Factory.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ contract Factory {
2828
}
2929

3030
getPair[token0][token1] = pair;
31-
getPair[token1][token0] = pair; // optional: not needed
31+
getPair[token1][token0] = pair; // Easy to find in router
3232
allPair.push(pair);
3333
emit PairCreated(token0, token1, pair, allPair.length);
3434
}

src/LPToken.sol

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
2+
pragma solidity 0.8;
3+
4+
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
5+
6+
contract LPToken is ERC20 {
7+
address public pair;
8+
9+
constructor(string memory name, string memory symbol, address _pair) ERC20(name, symbol) {
10+
pair = _pair;
11+
}
12+
13+
modifier onlyPair() {
14+
require(msg.sender == pair, "Only pair contract can access it");
15+
_;
16+
}
17+
18+
function mint(address to, uint256 amount) external onlyPair {
19+
_mint(to, amount);
20+
}
21+
22+
function burn(address from, uint256 amount) external onlyPair {
23+
_burn(from, amount);
24+
}
25+
}

src/Pair.sol

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
pragma solidity 0.8;
33

44
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5+
import {LPToken} from "./LPToken.sol";
56

67
contract Pair {
8+
LPToken public lptoken;
79
address public token0;
810
address public token1;
911

@@ -13,18 +15,46 @@ contract Pair {
1315
constructor(address _token0, address _token1) {
1416
token0 = _token0;
1517
token1 = _token1;
18+
19+
lptoken = new LPToken("LPTOKEN", "LPTK", address(this));
1620
}
1721

1822
function getReserve() public view returns (uint256, uint256) {
1923
return (reserve0, reserve1);
2024
}
2125

22-
function addLiquidity(uint256 amount0, uint256 amount1) external {
26+
function addLiquidity(uint256 amount0, uint256 amount1, address to) external {
2327
IERC20(address(token0)).transferFrom(msg.sender, address(this), amount0);
2428
IERC20(address(token1)).transferFrom(msg.sender, address(this), amount1);
2529

2630
reserve0 += amount0;
2731
reserve1 += amount1;
32+
33+
uint256 liquidity;
34+
if (lptoken.totalSupply() == 0) {
35+
liquidity = sqrt(amount0 * amount1);
36+
} else {
37+
liquidity = min((amount0 * lptoken.totalSupply()) / reserve0, (amount1 * lptoken.totalSupply()) / reserve1);
38+
}
39+
//potential error if we use msg.sender it will be router so we have taken to
40+
lptoken.mint(to, liquidity);
41+
}
42+
43+
function min(uint256 x, uint256 y) internal pure returns (uint256) {
44+
return x < y ? x : y;
45+
}
46+
47+
function sqrt(uint256 y) internal pure returns (uint256 z) {
48+
if (y > 3) {
49+
z = y;
50+
uint256 x = y / 2 + 1;
51+
while (x < z) {
52+
z = x;
53+
x = (y / x + x) / 2;
54+
}
55+
} else if (y != 0) {
56+
z = 1;
57+
}
2858
}
2959

3060
function swap(address tokenIn, uint256 amountIn, address to) external {

src/Router.sol

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ pragma solidity 0.8;
33

44
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
55
import {Pair} from "./Pair.sol";
6+
import {Factory} from "./Factory.sol";
67

78
contract Router {
8-
address public immutable i_pair;
9+
Factory public factory;
910

10-
constructor(address _pair) {
11-
i_pair = _pair;
11+
constructor(address _factory) {
12+
factory = Factory(factory);
1213
}
1314

1415
function sortToken(address tokenA, address tokenB) public pure returns (address, address) {
@@ -20,18 +21,27 @@ contract Router {
2021
}
2122

2223
function addLiquidity(address tokenA, address tokenB, uint256 amountA, uint256 amountB) external {
24+
address pair = factory.getPair(tokenA, tokenB);
25+
26+
if (pair == address(0)) {
27+
factory.createPair(tokenA, tokenB);
28+
pair = factory.getPair(tokenA, tokenB);
29+
}
2330
IERC20(tokenA).transferFrom(msg.sender, address(this), amountA);
2431
IERC20(tokenB).transferFrom(msg.sender, address(this), amountB);
2532

26-
IERC20(tokenA).approve(i_pair, amountA);
27-
IERC20(tokenB).approve(i_pair, amountB);
33+
IERC20(tokenA).approve(pair, amountA);
34+
IERC20(tokenB).approve(pair, amountB);
2835

29-
Pair(i_pair).addLiquidity(amountA, amountB);
36+
Pair(pair).addLiquidity(amountA, amountB, msg.sender);
3037
}
3138

32-
function swapExactToken(address tokenIn, uint256 amountIn) external {
39+
function swapExactToken(address tokenIn, address tokenOut, uint256 amountIn) external {
40+
address pair = factory.getPair(tokenIn, tokenOut);
41+
require(pair != address(0), "Pair doesnt exist");
42+
3343
IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);
34-
IERC20(tokenIn).approve(i_pair, amountIn);
35-
Pair(i_pair).swap(tokenIn, amountIn, msg.sender);
44+
IERC20(tokenIn).approve(pair, amountIn);
45+
Pair(pair).swap(tokenIn, amountIn, msg.sender);
3646
}
3747
}

0 commit comments

Comments
 (0)