Skip to content

Commit

Permalink
添加 Factory 实现 (WTFAcademy#110)
Browse files Browse the repository at this point in the history
* feat: 添加基本的 Factory 实现

* feat: 完善Factory合约

* feat: 完善 Factory 合约,添加相关创建池子信息存储

* feat: 调整 Factory 合约细节

* factory: 重构 Factory 中 PoolInfo 结构体

---------

Co-authored-by: 影和 <[email protected]>
  • Loading branch information
MarioJames and 影和 authored Sep 3, 2024
1 parent ad08aca commit 357fad3
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 36 deletions.
101 changes: 74 additions & 27 deletions demo-contract/contracts/wtfswap/Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
25 changes: 17 additions & 8 deletions demo-contract/contracts/wtfswap/interfaces/IFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion demo-contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
},
"dependencies": {
"@openzeppelin/contracts": "^5.0.2"
}
},
"repository": "[email protected]:WTFAcademy/WTF-Dapp.git"
}

0 comments on commit 357fad3

Please sign in to comment.