pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract LiquidityPool { IERC20 public token0; IERC20 public token1; uint256 public reserve0; uint256 public reserve1; constructor(address _token0, address _token1) { token0 = IERC20(_token0); token1 = IERC20(_token1); // Initial liquidity (needs to be added separately) // This example omits the initial liquidity addition for brevity. } function addLiquidity(uint256 _amount0, uint256 _amount1) external { require(_amount0 > 0 && _amount1 > 0, "Amounts must be greater than zero"); // Transfer tokens to the contract token0.transferFrom(msg.sender, address(this), _amount0); token1.transferFrom(msg.sender, address(this), _amount1); // Update reserves reserve0 += _amount0; reserve1 += _amount1; } function swap(address _tokenIn, uint256 _amountIn, address _tokenOut, uint256 _amountOutMin) external { require(_amountIn > 0 && _amountOutMin > 0, "Amounts must be greater than zero"); IERC20 tokenIn = IERC20(_tokenIn); IERC20 tokenOut = IERC20(_tokenOut); //Transfer tokens to the contract tokenIn.transferFrom(msg.sender, address(this), _amountIn); uint256 amountOut; if (_tokenIn == address(token0) ) { // Calculate amountOut using constant product formula (x * y = k) amountOut = (_amountIn * reserve1) / (reserve0 + _amountIn); require(amountOut >= _amountOutMin, "Insufficient output amount"); reserve0 += _amountIn; reserve1 -= amountOut; } else if (_tokenIn == address(token1)) { amountOut = (_amountIn * reserve0) / (reserve1 + _amountIn); require(amountOut >= _amountOutMin, "Insufficient output amount"); reserve1 += _amountIn; reserve0 -= amountOut; } else { revert("Invalid token"); } // Transfer output tokens tokenOut.transfer(msg.sender, amountOut); } function getReserves() external view returns (uint256, uint256) { return (reserve0, reserve1); } }
0.4.18