forked from AmazingAng/WTF-Solidity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Create2.sol
53 lines (47 loc) · 2.15 KB
/
Create2.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Pair{
address public factory; // 工厂合约地址
address public token0; // 代币1
address public token1; // 代币2
constructor() payable {
factory = msg.sender;
}
// called once by the factory at time of deployment
function initialize(address _token0, address _token1) external {
require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
token0 = _token0;
token1 = _token1;
}
}
contract PairFactory2{
mapping(address => mapping(address => address)) public getPair; // 通过两个代币地址查Pair地址
address[] public allPairs; // 保存所有Pair地址
function createPair2(address tokenA, address tokenB) external returns (address pairAddr) {
// 计算用tokenA和tokenB地址计算salt
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); //将tokenA和tokenB按大小排序
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
// 用create2部署新合约
Pair pair = new Pair{salt: salt}();
// 调用新合约的initialize方法
pair.initialize(tokenA, tokenB);
// 更新地址map
pairAddr = address(pair);
allPairs.push(pairAddr);
getPair[tokenA][tokenB] = pairAddr;
getPair[tokenB][tokenA] = pairAddr;
}
// 提前计算pair合约地址
function calculateAddr(address tokenA, address tokenB) public view returns(address predictedAddress){
// 计算用tokenA和tokenB地址计算salt
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); //将tokenA和tokenB按大小排序
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
// 计算合约地址方法 hash()
predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
bytes1(0xff),
address(this),
salt,
keccak256(type(Pair).creationCode)
)))));
}
}