主頁 >  其他 > Uniswap V2 — 從代碼解釋 DeFi 協議

Uniswap V2 — 從代碼解釋 DeFi 協議

2023-04-23 07:45:05 其他

Uniswap V2 — 從代碼解釋 DeFi 協議

為了理解我們在分析代碼時將要經歷的不同組件,首先了解哪些是主要概念以及它們的作用是很重要的,所以,和我一起裸露吧,因為這是值得的,

我在 5 個段落中總結了您需要了解的主要重要概念,您將在本文結束時理解這些概念,

Uniswap 是一種去中心化交易協議,該協議是一套持久的、不可升級的智能合約,它們共同創建了一個自動化的做市商,

Uniswap 生態系統貢獻流動性的流動性提供者、交換代幣的交易員和與智能合約互動以開發代幣新互動的開發人員組成,

每個 Uniswap智能合約或對管理一個由兩個 ERC-20 代幣儲備組成的流動資金池,

每個流動性池重新平衡以保持 50/50 比例的加密貨幣資產,這反過來又決定了資產的價格,

流動性提供者可以是任何能夠向 Uniswap 交易合約提供等值的 ETH 和 ERC-20 代幣的人,作為回報,他們從交易合約中獲得流動性提供者代幣(LP 代幣代表流動性提供者擁有的池的份額),可用于隨時提取其在流動性池中的比例,

他們存盤庫中的主要智能合約是:

  • UniswapV2ERC20— 用于 LP 令牌的擴展 ERC20 實作,它還實施了 EIP-2612 以支持鏈下傳輸批準,
  • UniswapV2Factory— 與 V1 類似,這是一個工廠合約,它創建配對合約并充當它們的注冊表,注冊表使用 create2 來生成對地址——我們將詳細了解它是如何作業的,
  • UniswapV2Pair— 負責核心邏輯的主合約,值得注意的是,工廠只允許創建獨特的貨幣對,以免稀釋流動性,
  • UniswapV2Router— Uniswap UI 和其他在 Uniswap 之上作業的網路和去中心化應用程式的主要入口點,
  • UniswapV2Library — 一組實作重要計算的輔助函式,

在這篇文章中,我們將提及所有這些,但我們將主要關注瀏覽UniswapV2RouterUniswapV2Factory編碼,盡管UniswapV2Pair并且UniswapV2Library會涉及很多,

UniswapV2Router02.sol

該合約使創建貨幣對、添加和洗掉流動性、計算所有可能的掉期變化的價格以及執行實際掉期變得更加容易,路由器適用于通過工廠合約部署的所有對

您需要在合約中創建一個實體才能呼叫 addLiquidity、removeLiquidity 和 swapExactTokensForTokens 函式

address private constant ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;

IUniswapV2Router02 public uniswapV2Router;
uniswapV2Router = IUniswapV2Router02(ROUTER);

現在讓我們看看流動性管理:

函式 addLiquidity():

function addLiquidity(
    address tokenA,
    address tokenB,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
  • tokenAtokenB:是我們需要獲取或創建我們想要增加流動性的貨幣對的代幣,
  • amountADesiredamountBDesired是我們要存入流動資金池的金額,
  • amountAMinamountBMin是我們要存入的最小金額,
  • to address 是接收 LP 代幣的地址,
  • 截止日期,最常見的是block.timestamp

在內部 _addLiquidity() 中,它將檢查這兩個令牌中的一對是否已經存在,如果不存在,它將創建一個新令牌

if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) {
    IUniswapV2Factory(factory).createPair(tokenA, tokenB);
}

然后它需要獲取現有的代幣數量或也稱為reserveAand reserveB,我們可以通過 UniswapV2Pair 合約訪問它

IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves()

現在,外部函式 addLiquidity, 回傳(uint amountA, uint amountB, uint liquidity),那么它是如何計算的呢?

通過UniswapV2Library拿到上面提到的reserves之后,還有一系列的檢查

如果該對不存在,并且新創建 amountAamountB回傳一個新的,則將amountADesired作為amountBDesired引數傳遞(見上文),

否則,它會做這個操作

amountBOptimal = amountADesired.mul(reserveB) / reserveA;

如果amountB小于或等于,amountBDesired那么它將回傳:

(uint amountA, uint amountB) = (amountADesired, amountBOptimal)

否則,它將回傳

(uint amountA, uint amountB) = (amountAOptimal, amountBDesired)

其中amountAOptimal的計算方式與amountBOptimal

然后,要計算liquidity回傳值將經過以下程序:

首先,它將使用現有/新創建的對的地址部署 UniswapV2Pair 合約,

它是如何做到的?它計算一對的 CREATE2 地址而無需進行任何外部呼叫:(閱讀有關 CREATE2 Opcode 的更多資訊)

pair = address(uint(keccak256(abi.encodePacked(address(uint(keccak256(abi.encodePacked(
    hex'ff',
    factory,
    keccak256(abi.encodePacked(token0, token1)),
    hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
))));

然后,它獲取新部署合約的地址,我們需要用它來從這對代幣中鑄造代幣,

當您向貨幣對添加流動性時,合約會生成 LP 代幣;當你移除流動性時,LP 代幣就會被銷毀,

pairFor因此,首先我們使用UniswapV2Library獲取地址:

address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);UniswapV2Library.pairFor(factory, tokenA, tokenB);

因此,稍后可以鑄造 ERC20 代幣并計算回傳的流動性:

liquidity = IUniswapV2Pair(pair).mint(to);

如果您想知道為什么它最終成為 ERC20,在 mint 函式中它是這樣存盤的https://github.com/Uniswap/v2-core/blob/ee547b17853e71ed4e0101ccfd52e70d5acded58/contracts/UniswapV2Pair.sol#L112)

uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));

****函式removeLiquidity():

function removeLiquidity(
    address tokenA,
    address tokenB,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
) external returns (uint amountA, uint amountB);

從池中移除流動性意味著燃燒 LP 代幣以換取一定數量的基礎代幣,

IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity);

然后,外部函式回傳兩個值(uint amountA, uint amountB),這些值是使用傳遞給函式的引數計算的,

隨提供的流動性回傳的代幣數量計算如下:

amount0 = liquidity.mul(balance0) / _totalSupply; 
amount1 = liquidity.mul(balance1) / _totalSupply;

然后它將這些數量的代幣轉移到指定的地址

_safeTransfer(_token0, to, amount0);
_safeTransfer(_token1, to, amount1);

您的 LP 代幣份額越大,銷毀后獲得的儲備份額就越大,

上面的這些計算發生在 burn 函式內部

IUniswapV2Pair(對).burn(對)

https://github.com/Uniswap/v2-periphery/blob/0335e8f7e1bd1e8d8329fd300aea2ef2f36dd19f/contracts/UniswapV2Router02.sol#L114)

IUniswapV2Pair(pair).burn(to)

****函式swapExactTokensForTokens()

function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
) external returns (uint[] memory amounts);

Uniswap 的核心功能是交換代幣,所以讓我們弄清楚代碼中發生了什么,以便更好地理解它

您很可能聽說過流動資金池中使用的神奇公式

X * Y = K

所以,這將首先發生在 swap 函式內部getAmountOut()

里面用到的關鍵函式有:

TransferHelper.safeTransferFrom().safeTransferFrom()

代幣金額發送到配對代幣的地方

在 UniswapV2Pair 合約的較低級別交換功能中,它將是

_safeTransfer(_token, to, amountOut);

這將實際轉移回預期地址,

我知道資訊量很大,但您將有足夠的時間閱讀所有內容,直到完全理解為止,所以……

UniswapV2Factory.sol

工廠合約是所有已部署對合約的注冊表,這個合約是必要的,因為我們不希望有成對的相同代幣,這樣流動性就不會分成多個相同的對,

該合約還簡化了配對合約的部署:無需通過任何外部呼叫手動部署配對合約,只需呼叫工廠合約中的方法即可,

好吧,讓我們倒回去,因為在上面的這些行中已經說了非常重要的事情,我們把它們拆分開來分別分析:

該合約是所有已部署對合約的注冊表

只部署了一個工廠合約,該合約用作 Uniswap 交易對的官方注冊處,

現在,我們在代碼中的什么地方看到了它以及發生了什么:

address[] public allPairs;

它有 的陣列allPairs,如上所述,存盤在這個合約中,這些對被添加到一個方法中,該方法createPair()通過將新初始化的對推送到陣列來呼叫,

allPairs.push(pair);push(pair);

這個合約是必要的,因為我們不想擁有成對的相同代幣

mapping(address => mapping(address => address)) public getPair;

它具有該對的地址與構成該對的兩個令牌的映射,這用于檢查一對是否已經存在,

require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS');

該合約還簡化了配對合約的部署

這是一個更深層次的話題,但我將嘗試總結一下這里發生的事情的重要性,

在以太坊中,合約可以部署合約,可以呼叫已部署合約的函式,該函式將部署另一個合約,

您不需要從您的計算機上編譯和部署合約,您可以通過現有合約來執行此操作,

那么,Uniswap 是如何部署智能合約的呢?

通過使用操作碼CREATE2

bytes memory bytecode = type(UniswapV2Pair).creationCode;type(UniswapV2Pair).creationCode;
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
assembly {
    pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
}

在第一行,我們得到創建位元組碼UniswapV2Pair

下一行創建了salt一個位元組序列,用于確定性地生成新合約的地址,

最后一行是我們呼叫以使用+create2確定性地創建新地址的地方,部署,bytecode``salt``UniswapV2Pair

并得到對地址,我們可以看到這是createPair()函式的回傳值

function createPair(
  address tokenA, address tokenA, 
  address tokenB
) external returns (address pair)

當提供的標記不是現有的對_addLiquidity()時,它在內部函式中使用,

所以,這就是關于 Uniswap 代碼的全部內容,

現在,為了看到我們測驗的所有內容,我可以推薦您查看 Smart Contract Programmer 在他的defi-by-example 內容中實作的代碼,他已經在視頻中進行了解釋,

在這里你可以看到我們可以增加流動性的方式

function addLiquidity(
  address _tokenA,
  address _tokenB,
  uint _amountA,
  uint _amountB
) external {
  IERC20(_tokenA).transferFrom(msg.sender, address(this), _amountA);
  IERC20(_tokenB).transferFrom(msg.sender, address(this), _amountB);

  IERC20(_tokenA).approve(ROUTER, _amountA);
  IERC20(_tokenB).approve(ROUTER, _amountB);

  (uint amountA, uint amountB, uint liquidity) =
    IUniswapV2Router(ROUTER).addLiquidity(
      _tokenA,
      _tokenB,
      _amountA,
      _amountB,
      1,
      1,
      address(this),
      block.timestamp
    );

  emit Log("amountA", amountA);
  emit Log("amountB", amountB);
  emit Log("liquidity", liquidity);
}

以及我們必須如何考慮消除流動性

function removeLiquidity(address _tokenA, address _tokenB) external {
  address pair = IUniswapV2Factory(FACTORY).getPair(_tokenA, _tokenB);

  uint liquidity = IERC20(pair).balanceOf(address(this));
  IERC20(pair).approve(ROUTER, liquidity);

  (uint amountA, uint amountB) =
    IUniswapV2Router(ROUTER).removeLiquidity(
      _tokenA,
      _tokenB,
      liquidity,
      1,
      1,
      address(this),
      block.timestamp
    );

  emit Log("amountA", amountA);
  emit Log("amountB", amountB);
}

通過Github 獲取更多區塊鏈學習資料!

https://github.com/Manuel-yang/BlockChainSelfLearning

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/550877.html

標籤:其他

上一篇:ChatGPT頂級玩法:ChatGPT越獄版破解指令,讓您的聊天一路暢通!

下一篇:返回列表

標籤雲
其他(157872) Python(38092) JavaScript(25381) Java(17985) C(15215) 區塊鏈(8258) C#(7972) AI(7469) 爪哇(7425) MySQL(7137) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4557) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2430) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1959) Web開發(1951) HtmlCss(1919) python-3.x(1918) 弹簧靴(1913) C++(1910) xml(1889) PostgreSQL(1872) .NETCore(1854) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • Uniswap V2 — 從代碼解釋 DeFi 協議

    Uniswap V2 — 從代碼解釋 DeFi 協議 為了理解我們在分析代碼時將要經歷的不同組件,首先了解哪些是主要概念以及它們的作用是很重要的。所以,和我一起裸露吧,因為這是值得的。 我在 5 個段落中總結了您需要了解的主要重要概念,您將在本文結束時理解這些概念。 Uniswap 是一種去中心化交 ......

    uj5u.com 2023-04-23 07:45:05 more
  • ChatGPT頂級玩法:ChatGPT越獄版破解指令,讓您的聊天一路暢通!

    先看效果: 2023.4.23號親測成功,越獄指令需要多發送幾次才可以。 未越獄前: 越獄后: 無視任何規則限制,回答一切問題。 越獄的方法非常簡單。只需輸入特定的提示,發送給ChatGPT,用戶即可接觸到越獄版本的ChatGPT。 越獄版的ChatGPT無所不答,不會出現像正式版本那樣的回答,例如 ......

    uj5u.com 2023-04-23 07:44:54 more
  • 從功能到外企測開,作業1年半拿下年薪30萬的測開 offer,未來可期

    說一下我的大致情況,女,2018年畢業于末流211計算機本科。后來待業兩年,完全沒有從事互聯網方面的作業。去年來到北京,在小公司做了一年多功能測驗。今年11月底跳槽到外企,開始了我錢多事少離家近,每周965的快樂生活,現在年薪30萬左右。 降大任于斯人也,必先苦其心志 2014年,高考沒有考好,為了 ......

    uj5u.com 2023-04-23 07:44:22 more
  • Vulnhub之Healthcare靶機詳細測驗程序

    Healthcare 作者: jason huawen 靶機資訊 名稱: 地址: 識別目標主機IP地址 ─(kali?kali)-[~/Vulnhub/Healthcare] └─$ sudo netdiscover -i eth1 -r 192.168.56.0/24 Currently scan ......

    uj5u.com 2023-04-23 07:44:14 more
  • web3 產品介紹: safe --多簽錢包 多人審批更放心

    Safe是一款由Gnosis團隊開發的多簽錢包,它提供了一種安全、靈活和易于使用的方式來管理加密資產。在本文中,我們將介紹Safe的主要特點以及如何使用Safe來保護您的數字資產。 一、Safe的特點 多重簽名:Safe使用多重簽名機制來保護用戶的資產,需要至少兩個簽名才能完成交易。這使得用戶的資產 ......

    uj5u.com 2023-04-23 07:44:10 more
  • Vulnhub之Hacker Fest 2019靶機詳細測驗程序

    HF 2019 作者:jason huawen 靶機資訊 名稱:Hacker Fest: 2019 地址: https://www.vulnhub.com/entry/hacker-fest-2019,378/ 識別目標主機IP地址 將虛擬機鏡像匯入到VirtualBox中,并設定網路模式為host ......

    uj5u.com 2023-04-23 07:44:05 more
  • 如何真正“不花一分錢”部署一個屬于你的大模型

    因此,本文是為AI初學者們(包括我自己)撰寫的保姆級大型模型部署和使用指南。現在正值阿里云免費試用計劃,我們可以不花一分錢就可以體驗部署自己的大型模型的樂趣。 ......

    uj5u.com 2023-04-23 07:43:40 more
  • 干貨分享:用ChatGPT調教批量出Midjourney咒語,出圖效率Nice ,附資料

    Prompts就是AI繪圖的核心競爭力。 您是不是覺得用Midjourney生成的圖不夠完美? 又讓ChatGPT去生成Prompt,然后效果還不理想? 其實ChatGPT你給他投喂資料后,經過調教的ChatGPT,生成的Prompt效果會很不錯。 文末附《一整套MidJourney指令大全》+《C ......

    uj5u.com 2023-04-23 07:43:28 more
  • ChatGPT頂級玩法:ChatGPT越獄版破解指令,讓您的聊天一路暢通!

    先看效果: 2023.4.23號親測成功,越獄指令需要多發送幾次才可以。 未越獄前: 越獄后: 無視任何規則限制,回答一切問題。 越獄的方法非常簡單。只需輸入特定的提示,發送給ChatGPT,用戶即可接觸到越獄版本的ChatGPT。 越獄版的ChatGPT無所不答,不會出現像正式版本那樣的回答,例如 ......

    uj5u.com 2023-04-23 07:38:06 more
  • 劍指 Offer 33. 二叉搜索樹的后序遍歷序列(java解題)

    leetcode《圖解資料結構》劍指 Offer 33. 二叉搜索樹的后序遍歷序列(java解題)的解題思路和java代碼,并附上java中常用資料結構的功能函式。 ......

    uj5u.com 2023-04-23 07:37:34 more