diff --git a/demo-contract/contracts/wtfswap/Factory.sol b/demo-contract/contracts/wtfswap/Factory.sol index 7520491..f1a7e70 100644 --- a/demo-contract/contracts/wtfswap/Factory.sol +++ b/demo-contract/contracts/wtfswap/Factory.sol @@ -2,47 +2,94 @@ pragma solidity ^0.8.24; import "./interfaces/IFactory.sol"; +import "./Pool.sol"; contract Factory is IFactory { mapping(address => mapping(address => address[])) public pools; - // parameters 是用于 Pool 创建时回调获取参数用 - // 不是用构造函数是为了避免构造函数变化,那样会导致 Pool 合约地址不能按照参数计算出来 - // 具体参考 https://docs.openzeppelin.com/cli/2.8/deploying-with-create2 - // new_address = hash(0xFF, sender, salt, bytecode) - function parameters() - external - view - override - returns ( - address factory, - address token0, - address token1, - int24 tickLower, - int24 tickUpper, - uint24 fee - ) - {} + Parameters public override parameters; + + function sortToken( + address tokenA, + address tokenB + ) private pure returns (address, address) { + return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); + } function getPool( - address token0, - address token1, + address tokenA, + address tokenB, uint32 index ) external view override returns (address) { - return pools[token0][token1][index]; + require(tokenA != tokenB, "IDENTICAL_ADDRESSES"); + require(tokenA != address(0) && tokenB != address(0), "ZERO_ADDRESS"); + + // Declare token0 and token1 + address token0; + address token1; + + (token0, token1) = sortToken(tokenA, tokenB); + + return pools[tokenA][tokenB][index]; } function createPool( - address token0, - address token1, + address tokenA, + address tokenB, int24 tickLower, int24 tickUpper, uint24 fee ) external override returns (address pool) { - // 先调用 getPools 获取当前 token0 token1 的所有 pool - // 然后判断是否已经存在 tickLower tickUpper fee 相同的 pool - // 如果存在就直接返回 - // 如果不存在就创建一个新的 pool - // 然后记录到 pools 中 + // validate token's individuality + require(tokenA != tokenB, "IDENTICAL_ADDRESSES"); + + // Declare token0 and token1 + address token0; + address token1; + + // sort token, avoid the mistake of the order + (token0, token1) = sortToken(tokenA, tokenB); + + // get current all pools + address[] memory existingPools = pools[token0][token1]; + + // check if the pool already exists + for (uint256 i = 0; i < existingPools.length; i++) { + IPool currentPool = IPool(existingPools[i]); + + if ( + currentPool.tickLower() == tickLower && + currentPool.tickUpper() == tickUpper && + currentPool.fee() == fee + ) { + return existingPools[i]; + } + } + + // save pool info + parameters = Parameters( + address(this), + tokenA, + tokenB, + tickLower, + tickUpper, + fee + ); + + // generate create2 salt + bytes32 salt = keccak256( + abi.encodePacked(token0, token1, tickLower, tickUpper, fee) + ); + + // create pool + address poolAddress = address(new Pool{salt: salt}()); + + // save created pool + pools[token0][token1].push(poolAddress); + + // delete pool info + delete parameters; + + return address(pool); } } diff --git a/demo-contract/contracts/wtfswap/interfaces/IFactory.sol b/demo-contract/contracts/wtfswap/interfaces/IFactory.sol index 230568e..c10f8b4 100644 --- a/demo-contract/contracts/wtfswap/interfaces/IFactory.sol +++ b/demo-contract/contracts/wtfswap/interfaces/IFactory.sol @@ -2,21 +2,30 @@ pragma solidity ^0.8.24; interface IFactory { + struct Parameters { + address factory; + address tokenA; + address tokenB; + int24 tickLower; + int24 tickUpper; + uint24 fee; + } + function parameters() external view returns ( address factory, - address token0, - address token1, + address tokenA, + address tokenB, int24 tickLower, int24 tickUpper, uint24 fee ); event PoolCreated( - address token0, - address token1, + address tokenA, + address tokenB, uint32 index, int24 tickLower, int24 tickUpper, @@ -25,14 +34,14 @@ interface IFactory { ); function getPool( - address token0, - address token1, + address tokenA, + address tokenB, uint32 index ) external view returns (address pool); function createPool( - address token0, - address token1, + address tokenA, + address tokenB, int24 tickLower, int24 tickUpper, uint24 fee diff --git a/demo-contract/package.json b/demo-contract/package.json index 46b86cc..b5c969c 100644 --- a/demo-contract/package.json +++ b/demo-contract/package.json @@ -6,5 +6,6 @@ }, "dependencies": { "@openzeppelin/contracts": "^5.0.2" - } + }, + "repository": "git@github.com:WTFAcademy/WTF-Dapp.git" }