디사이퍼에서 진행한 솔리디티 문해력 특강을 개인적으로 기록으로 남기기 위해 정리한 글입니다.
해당 특강은 아래 링크에서 확인 가능합니다. 강의를 진행해주신 안수찬님께 감사드립니다.
안수찬님 블로그 : https://solidity.ansuchan.com/
디사이퍼 솔리디티 문해력 특강 유튜브 : https://www.youtube.com/playlist?list=PLOY0jYV3zWiElk6lAXhuyRJ8dMDqelU_r
UNISWAP
탈중앙거래소 종류
1. Order book (EtherDelta)
→ 등록 할때 가스비가 들고 그외에 비효율성이 많음
2. AMM - LP, Swap
- Uniswap(CPMM: x*y=K) : $ETH <> $A , $ETH<>$B
- Bancor($BNT)
→ 스마트 토큰 개념 도입 v1 $BNT<>$A, $BNT<>$B → v2
- mStable (CSMM : constant sum market maker x+y=k )
- Curve (StableSwap =CSMM+CPMM)
- Balancer(CPMM; xy=k) → CM(Mean)MM xy*z=k
AMM 작동방식
기울기 = 가격
넣는 양과 받는 양의 차이를 슬리피지라고 하며 유동성이 많이 공급될수록 슬리피지가 작아지는 것을 확인 할수있다. 즉, TVL이 많을수록 슬리피지가 적게 거래 할수있다는 것을 의미하게된다.
Swap 하는 사람입장에서는 K값이 변하지 않지만 유동성 공급은 K값이 변한다.
AMM의 네가지 기능 구현
Swap
-etherToToken
-tokenToEther
LP
-addLiquidity
-removeLiquidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract TokenA is ERC20 {
constructor() ERC20("TokenA", "A") {
_mint(msg.sender, 50 * 10)
}
contract Exchange is ERC20 {
address public tokenAddress;
constructor(address _tokenAddress) ERC20("Uniswap LP", "UNI-LP") {
tokenAddress = _tokenAddress;
}
function addLiquidity() public payable {
uint etherAmount = msg.value;
uint tokenAmount = etherAmount;
TokenA tokenContract = TokenA(tokenAddress);
tokenContract.transferFrom(msg.sender, address(this), tokenAmount);
_mint(msg.sender, etherAmount);
}
function removeLiquidity(uint lpTokenAmount) public {
_burn(msg.sender, lpTokenAmount);
uint etherAmount = lpTokenAmount;
uint tokenAmount = lpTokenAmount;
payable(msg.sender).transfer(etherAmount);
TokenA tokenContract = TokenA(tokenAddress);
tokenContract.transfer(msg.sender, tokenAmount);
}
function etherToTokenSwap() public payable {
uint etherAmount = msg.value;
uint tokenAmount = etherAmount;
TokenA tokenContract = TokenA(tokenAddress);
tokenContract.transfer(msg.sender, tokenAmount);
}
function tokenToEtherSwap(uint tokenAmount) public {
TokenA tokenContract = TokenA(tokenAddress);
tokenContract.transferFrom(msg.sender, address(this), tokenAmount);
uint etherAmount = tokenAmount;
payable(msg.sender).transfer(etherAmount);
}
}
💡 tokenToEtherSwap 함수에서 중요한점은 컨트랙트는 이 컨트랙트 사용자 토큰에 접근할 권리가 없기에 approve가 되어있는 만큼 transferFrom이라는 함수를 통해 옮길수있다는 것이다.
UNISWAP
v1: Eth <> Token pair … factory <> exchange
v2 : ERC20 <> ERC20 Pair
v3 : 집중화된 유동성
v4 : hooks, singleton
Factory
pragma solidity 0.8.20;
contract Exchange {
uint public number;
constructor(uint _number) {
number = _number;
}
}
contract Factory {
mapping(uint => address) public numberToExchange;
mapping(address => uint) public exchangeToNumber;
function createExchange(uint number) public returns (address) {
Exchange created = new Exchange(number);
numberToExchange[number] = address(created);
exchangeToNumber[address(created)] = number;
return address(created);
}
}
개발 디자인 패턴 설명 사이트
The Catalog of Design Patterns
The Catalog of Design Patterns
refactoring.guru
'⛓️ Web3' 카테고리의 다른 글
Acount Abstraction (1) | 2023.12.19 |
---|---|
다자간 연산 MPC (Multi-party computation) (0) | 2023.11.16 |
솔리디티 문해력 특강_4강 (0) | 2023.09.17 |
마스터링 이더리움_Ch.4 암호학 (0) | 2023.09.15 |
마스터링 이더리움_Ch.3 이더리움 클라이언트 (0) | 2023.09.12 |