이 컨트랙트는 유니스왑에서 Pair가 교환하는 기능을 만듭니다.
함수 | 설명 |
allPairsLength
|
모든 Pair의 길이를 반환하는 함수 |
createPair
|
교환하는 Pair의 수를 반환함 |
setFeeTo
|
feeTo 주소를 설정하는 함수 |
setFeeToSetter
|
feeToSetter 주소를 설정하는 함수 |
pragma solidity =0.5.16;
import './interfaces/IUniswapV2Factory.sol';
import './UniswapV2Pair.sol';
//이 컨트랙트는 페어 교환을 생성합니다.
contract UniswapV2Factory is IUniswapV2Factory {
// 이러한 상태 변수는 프로토콜 수수료를 구현하는 데 필요합니다(백서, 5페이지 참조).
// feeTo 주소는 프로토콜 수수료에 대한 유동성 토큰을 축적하며, feeToSetter는 feeTo를 다른 주소로 변경할 수 있는 주소입니다.
address public feeTo; //유동성 토큰 축적
address public feeToSetter; //feeTo를 다른 주소로 변경할 수 있는 주소
// 두 개의 공개 상태 변수가 더 정의되어 있습니다: getPair와 allPairs.
mapping(address => mapping(address => address)) public getPair; //getPair는 토큰 주소 Pair을 해당 Pair의 컨트랙트 주소에 매핑하는 것
address[] public allPairs; // allPairs는 이 컨트랙트에 의해 생성된 모든 Pair의 주소를 포함하는 배열입니다.
//이벤트는 새 Pair이 생성될 때 발생하도록 정의됩니다. 이벤트에는 Pair이 구성하는 두 토큰의 주소, 새 Pair 컨트랙트의 주소, 새 Pair이 추가된 후 allPairs 배열의 길이가 포함됩니다.
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
//생성자는 인자로 전달된 주소로 feeToSetter 주소를 설정하도록 정의됩니다.
constructor(address _feeToSetter) public {
feeToSetter = _feeToSetter;
}
//모든 Pair 배열의 길이를 반환하는 공용 함수 allPairsLength()가 정의되어 있습니다.
function allPairsLength() external view returns (uint) {
return allPairs.length;
}
function createPair(address tokenA, address tokenB) external returns (address pair) {
// CreatePair는 Factory 컨트랙트의 주요함수로 두 개의 ERC-20 토큰간의 Pair 교환을 생성한다.
// 누구나 이 함수를 호출할 수 있으며 Pair끼리 새롭게 교환할 때 유니스왑의 허가를 필요로하지 않는다.
// 토큰 A와 B는 달라야한다.
require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
// 삼항연산자에 따라 토큰0과 토큰1의 크기를 비교해서 다음값으로 할당한다.
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
// 토큰0이 제로 어드레스가 아닌지 체크한다.
require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS');
// getPair 함수를 호출해서 token0과 token1이 이미 있는 Pair가 아닌지 체크한다. 이미 존재하면 이 구문을 통과할 수 없다.
require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient
// 새 컨트랙트를 생성하려면 컨트랙트를 생성하는 코드가 필요합니다(생성자 함수와 실제 컨트랙트의 EVM 바이트코드를 메모리에 쓰는 코드 모두).
// 일반적으로 솔리디티에서는 addr = new <컨트랙트 이름>(<생성자 매개변수>)를 사용하면 컴파일러가 모든 것을 처리하지만,
// 결정론적 컨트랙트 주소를 가지려면 CREATE2 op코드를 사용해야 합니다.
// 이 코드를 작성할 당시에는 솔리디티에서 해당 op코드를 아직 지원하지 않았기 때문에 수동으로 코드를 가져와야 했습니다. 이제 솔리디티에서 CREATE2를 지원하므로 더 이상 문제가 되지 않습니다.
bytes memory bytecode = type(UniswapV2Pair).creationCode;
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
//솔리디티에서 아직 지원되지 않는 op코드는 인라인 어셈블리(새 탭에서 열기)를 사용하여 호출할 수 있습니다.
assembly {
pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
//초기화 함수를 호출하여 새 거래소에 어떤 두 개의 토큰을 교환할지 알려줍니다.
IUniswapV2Pair(pair).initialize(token0, token1);
//새 페어 정보를 상태 변수에 저장하고 이벤트를 발생시켜 새로운 페어 교환을 네트워크에 알립니다..
getPair[token0][token1] = pair;
getPair[token1][token0] = pair;
//allPair 배열에 삽입
allPairs.push(pair);
//이벤트를 발생
emit PairCreated(token0, token1, pair, allPairs.length);
}
//다음 두 가지 기능을 통해 수수료 설정자는 수수료 수취인을 제어하고 수수료 설정자를 새 주소로 변경할 수 있습니다.
//프로토콜 수수료로 유동성 토큰을 적립하는 함수
function setFeeTo(address _feeTo) external {
require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN');
feeTo = _feeTo;
}
//수수료를 변경할 수 있는 주소 함수
function setFeeToSetter(address _feeToSetter) external {
require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN');
feeToSetter = _feeToSetter;
}
}
출처:
https://ethereum.org/en/developers/tutorials/uniswap-v2-annotated-code/#uniswapv2factory
유니스왑 V2 컨트랙트 리뷰에서 알아보는 디파이 개발자를 위한 5가지 팁과 요령 (0) | 2023.03.27 |
---|---|
UniswapV2-core - UniswapV2ERC20.sol 코드 분석 (0) | 2023.03.26 |
UniswapV2-core - UniswapV2Pair.sol 코드 분석 (0) | 2023.03.26 |
UniswapV2-periphery - UniswapV2Library.sol 코드 분석 (0) | 2023.03.17 |
UniswapV2 periphery - Uniswapv2Router.sol 코드 분석 (0) | 2023.03.17 |