Khuyến nghị hôm nay | Xem qua cơ chế cốt lõi của Uniswap V4

avatar
MarsBit
10-06
Bài viết này được dịch máy
Xem bản gốc

Bài viết này giải thích chi tiết ý nghĩa của các hàm UniswapV4 và nguyên tắc triển khai của chúng.

Tác giả gốc: Lin Weichen Albert Lin

Nguồn gốc: trung bình

Kể từ khi UniswapV4 được công bố, nền tảng Swap đã trải qua một sự thay đổi lớn. Nó đã phát triển từ nền tảng Swap thành nhà cung cấp dịch vụ cơ sở hạ tầng. Đặc biệt, chức năng Hooks của V4 đã thu hút được sự quan tâm rộng rãi. Sau một thời gian nghiên cứu chuyên sâu, tôi biên soạn một số nội dung, hy vọng có thể giúp mọi người hiểu rõ hơn về sự thay đổi này cũng như việc thực hiện nó.

Trọng tâm đổi mới của UniswapV4 không phải là cải tiến công nghệ AMM mà là mở rộng hệ sinh thái. Cụ thể, sự đổi mới này bao gồm các chức năng chính sau:

  • Kế toán Flash
  • Hợp đồng đơn lẻ
  • Kiến trúc móc

Trong các phần sau, tôi sẽ giải thích chi tiết ý nghĩa của các hàm này và cách chúng hoạt động.

uniswapx

Kế toán Flash

Kế toán kép

UniswapV4 áp dụng phương pháp ghi chép tương tự như Sổ sách kế toán kép để theo dõi sự tăng giảm của số dư Token tương ứng với từng thao tác. Phương pháp ghi sổ kép này yêu cầu mỗi giao dịch phải được ghi nhận vào nhiều tài khoản cùng lúc và đảm bảo giá trị tài sản giữa các tài khoản này được cân bằng. Ví dụ: giả sử rằng người dùng trao đổi 100 TokenA vào Pool để lấy 50 TokenB, bản ghi trong sổ cái sẽ như sau:

  • NGƯỜI DÙNG: TokenA giảm 100 đơn vị (-100), trong khi TokenB tăng 50 đơn vị (+50).
  • POOL: TokenA tăng 100 đơn vị (+100), trong khi TokenB giảm 50 đơn vị (-50).

uniswapx

Các hoạt động liên quan đến Token Delta

Trong UniswapV4, phương thức tính toán này sẽ được sử dụng cho các hoạt động chính và Biến lưu trữ có tên lockState.currencyDelta[currency] được sử dụng trong mã chương trình để ghi lại sự thay đổi trong số dư Token. Nếu giá trị của thay đổi này là dương thì nó cho biết số lượng Token trong nhóm dự kiến ​​sẽ tăng lên, nếu không thì nó cho biết số lượng Token trong nhóm sẽ giảm theo dự kiến. Từ góc độ khác, nếu giá trị dương, nó biểu thị số lượng Token bị thiếu trong nhóm (số lượng Token dự kiến ​​​​sẽ nhận được), trong khi giá trị âm biểu thị số lượng Token dư thừa trong nhóm (số lượng Token dự kiến người dùng sẽ rút). Số lượng token). Phần sau đây liệt kê tác động của các hoạt động khác nhau trên Token delta (TokenDelta):

uniswapx

  • sửa đổiPosition: Cho biết hoạt động Thêm/Xóa tính thanh khoản. Để Thêm tính thanh khoản, đồng bằng Token (đại diện cho TokenA dự kiến ​​sẽ được thêm vào nhóm) được cập nhật bằng cách sử dụng phép cộng. Đối với Xóa tính thanh khoản, phép trừ được sử dụng để cập nhật đồng bằng Token (cho biết rằng TokenB dự kiến ​​rút khỏi nhóm).
  • trao đổi: Cho biết thực hiện thao tác Hoán đổi. Lấy Hoán đổi TokenA thành TokenB làm ví dụ, phép cộng được sử dụng để cập nhật TokenADelta và phép trừ được sử dụng để cập nhật TokenBDelta.
  • giải quyết: kèm theo thao tác chuyển Token vào Pool. Pool sẽ tính toán mức tăng Token trước và sau và cập nhật TokenDelta bằng phép trừ. Nếu Nhóm chỉ nhận được số lượng Token dự kiến, bản cập nhật phép trừ ở đây sẽ chỉ đặt lại TokenDelta về 0.
  • take: Kèm theo thao tác rút Token khỏi Pool. Nhóm sẽ cập nhật TokenDelta bằng cách sử dụng tính năng bổ sung, cho biết rằng Mã thông báo đã bị xóa khỏi Nhóm này.
  • mint: Hành vi cập nhật TokenDelta tương tự như "lấy", ngoại trừ việc mint không thực sự rút mã thông báo khỏi nhóm. Thay vào đó, Mã thông báo ERC1155 tương ứng được phát hành làm bằng chứng rút tiền và mã thông báo vẫn còn trong nhóm. Sau đó, người dùng có thể lấy Mã thông báo trong Nhóm bằng cách hủy Mã thông báo ERC1155. Người ta suy đoán rằng có hai mục đích: 1. Tiết kiệm chi phí gas khi chuyển Mã thông báo ERC20 (gọi hợp đồng + ghi ít hơn một lần lưu trữ) và sử dụng phương pháp ghi mã thông báo ERC1155 để cập nhật TokenDelta để sử dụng cho giao dịch trong tương lai. 2. Duy trì tính thanh khoản trong Pool và duy trì độ sâu thanh khoản để người dùng có thể có trải nghiệm Swap Token tốt hơn.
  • donate: Tuyên bố tặng Token vào Pool, nhưng thực tế bạn vẫn cần sử dụng “giải quyết” để gửi Token vào Pool. Do đó, phép cộng được sử dụng ở đây để cập nhật đồng bằng Token.

Trong số các hoạt động trên, chỉ giải quyết và nhận mới thực sự truyền Mã thông báo, còn các hoạt động khác chỉ cần cập nhật giá trị TokenDelta.

Ví dụ về đồng bằng mã thông báo

Dưới đây chúng tôi sử dụng một ví dụ đơn giản để minh họa cách cập nhật TokenDelta. Giả sử hôm nay chúng ta đổi 100 TokenA lấy 50 TokenB:

uniswapx

  1. Cả TokenADelta và TokenBDelta đều bằng 0 trước khi giao dịch bắt đầu.
  2. swap: Tính toán số lượng TokenA mà Pool cần nhận và số lượng TokenB mà người dùng sẽ nhận được. Lúc này TokenADelta = 100, TokenBDelta = -50.
  3. giải quyết: Gửi 100 TokenA vào Pool và cập nhật TokenADelta = 100–100 = 0.
  4. lấy: Chuyển 50 TokenB từ Pool sang tài khoản người dùng và cập nhật TokenBDelta = -50 + 50 = 0.
  5. Sau khi giao dịch, cả TokenADelta và TokenBDelta đều bằng 0.

Khi toàn bộ thao tác quy đổi hoàn tất, cả TokenADelta và TokenBDelta đều được đặt lại về 0. Điều này có nghĩa là hoạt động đã được cân bằng hoàn toàn, từ đó đảm bảo tính nhất quán của số dư tài khoản.

EIP-1153: Mã hoạt động lưu trữ tạm thời

Như đã đề cập trước đó, UniswapV4 sử dụng Biến lưu trữ để ghi TokenDelta, nhưng trong hợp đồng, việc đọc và ghi Biến lưu trữ khá tốn kém. Tại thời điểm này, chúng ta nên đề cập đến một EIP khác do Uniswap tung ra: EIP1153 — Transient Storage Opcodes.

UniswapV4 có kế hoạch sử dụng hai Mã OP TSTORE và TLOAD do EIP1153 cung cấp để cập nhật TokenDelta. Biến lưu trữ sử dụng Opcode lưu trữ tạm thời sẽ bị loại bỏ sau khi Giao dịch kết thúc (tương tự như Biến bộ nhớ), do đó không cần ghi vào đĩa cứng, từ đó giảm chi phí Gas .

EIP1153 đã được xác nhận sẽ có trong bản nâng cấp Cancun tiếp theo và UniswapV4 cũng chỉ ra rằng UniswapV4 sẽ được ra mắt sau bản nâng cấp Cancun.

uniswapx

Kế toán Flash—Khóa

UniswapV4 giới thiệu cơ chế khóa, có nghĩa là trước khi thực hiện các thao tác trên Pool, trước tiên PoolManager.lock() phải được gọi để lấy khóa. Trước khi quá trình thực thi lock() kết thúc, nó sẽ kiểm tra xem giá trị của TokenDelta có bằng 0 hay không, nếu không thì việc hoàn nguyên sẽ được kích hoạt. Khi PoolManager.lock() được gọi và khóa được lấy thành công, hàm lockAcquired() của msg.sender sẽ được gọi. Các hoạt động liên quan đến nhóm (chẳng hạn như trao đổi, sửa đổi Vị trí, v.v.) chỉ được thực hiện trong hàm lockAcquired().

Sơ đồ sau đây được sử dụng làm ví dụ để minh họa quá trình này. Khi người dùng cần thực hiện thao tác Hoán đổi mã thông báo, Hợp đồng thông minh có chức năng lockAcquired() phải được gọi (sau đây gọi là hợp đồng gọi lại, Hợp đồng gọi lại). Hợp đồng gọi lại trước tiên sẽ gọi PoolManager.lock(), sau đó PoolManager sẽ gọi hàm lockAcquired() của hợp đồng gọi lại. Trong hàm lockAcquired(), logic liên quan đến các hoạt động của Nhóm được xác định, chẳng hạn như các hoạt động hoán đổi, giải quyết và nhận. Cuối cùng, khi toàn bộ lock() sắp kết thúc, PoolManager sẽ kiểm tra xem TokenDelta liên quan đến thao tác này đã được reset về 0 hay chưa để đảm bảo tài sản trong Pool vẫn được cân bằng.

uniswapx

Hợp đồng đơn lẻ

Hợp đồng Singleton có nghĩa là UniswapV4 đã từ bỏ mô hình Factory-Pool trước đó. Mỗi Pool không còn là một Hợp đồng thông minh độc lập nữa mà tất cả các Pool đều có chung một hợp đồng đơn lẻ. Thiết kế này được kết hợp với cơ chế Flash Accounting và chỉ cần cập nhật các Biến lưu trữ cần thiết, giúp giảm hơn nữa độ phức tạp và chi phí của hoạt động.

Sơ đồ sau đây được sử dụng làm ví dụ: Lấy UniswapV3 làm ví dụ, việc trao đổi ETH lấy Dai yêu cầu ít nhất bốn lần chuyển Token (Hoạt động ghi lưu trữ). Điều này bao gồm nhiều bản ghi thay đổi cho USDC, USDT và Dai Token. Tuy nhiên, thông qua những cải tiến của UniswapV4 và cơ chế Flash Accounting, chỉ cần một lần chuyển token (để chuyển Dai từ Pool đến người dùng), điều này giúp giảm đáng kể số lượng hoạt động và chi phí.

uniswapx

Kiến trúc móc

Trong bản cập nhật này của UniswapV4, điểm bắt mắt nhất là Hooks Architecture. Bản cập nhật này sẽ mang đến sự linh hoạt tuyệt vời về tính khả dụng của Pool. Hooks có nghĩa là khi thực hiện một thao tác cụ thể trên Pool, Hooks Contract sẽ được gọi thêm để thực hiện các hành động bổ sung. Các hành động này có thể được chia thành các danh mục khác nhau, bao gồm khởi tạo (tạo nhóm), sửa đổiPosition (thêm/xóa tính thanh khoản), hoán đổi và quyên góp. Mỗi danh mục có các hành động trước và sau thực thi:

  • beforeInitialize / afterInitialize
  • beforeModifyPosition / afterModifyPosition
  • trướcSwap/sauSwap
  • beforeDonate / afterDonate

Thiết kế này cho phép người dùng thực thi logic tùy chỉnh linh hoạt hơn trước và sau các hoạt động cụ thể, do đó mở rộng chức năng của UniswapV4.

uniswapx

Ví dụ về hook - Hook giới hạn lệnh

Tiếp theo chúng ta sẽ dùng ví dụ về lệnh giới hạn để minh họa quá trình hoạt động thực tế của Hooks. Trước khi bắt đầu, hãy giải thích ngắn gọn nguyên tắc thực hiện lệnh giới hạn trong UniswapV4.

Cơ chế đặt hàng giới hạn UniswapV4

Nguyên tắc thực hiện lệnh giới hạn trong UniswapV4 là thêm thanh khoản (Thêm thanh khoản) vào một phạm vi giá cụ thể, sau đó thực hiện thao tác Xóa thanh khoản nếu thanh khoản trong phạm vi đó được trao đổi.

Ví dụ: giả sử chúng tôi đã thêm tính thanh khoản cho ETH trong phạm vi giá 1900–2000 và sau đó khi giá ETH tăng từ 1800 lên 2100. Tại thời điểm này, tất cả thanh khoản ETH mà chúng tôi đã thêm trước đây trong phạm vi giá 1900–2000 đã được đổi lấy USDC(giả sử nó nằm trong Nhóm ETH- USDC ). Việc loại bỏ thanh khoản tại thời điểm này sẽ có tác dụng thực hiện lệnh thị trường ETH ở mức giá hiện tại là 1900–2000.

uniswapx

Hợp đồng móc lệnh giới hạn

Ví dụ này được cung cấp bởi GitHub từ UniswapV4. Trong ví dụ này, hợp đồng Limit Order Hook cung cấp hai Hook, đó là afterInitialize và afterSwap. Trong số đó, afterInitialize được sử dụng để ghi lại phạm vi giá (đánh dấu) khi Pool được thiết lập, nhằm xác định lệnh giới hạn nào đã được khớp sau khi ai đó thực hiện hoán đổi.

Đặt hàng

Khi người dùng có nhu cầu đặt lệnh, hợp đồng Hook sẽ thực hiện thao tác bổ sung thanh khoản dựa trên khoảng giá và số lượng mà người dùng chỉ định. Trong hợp đồng Hook của lệnh giới hạn, bạn có thể thấy hàm place(). Logic chính là gọi hàm lockAcquiredPlace() sau khi lấy được lock để thực hiện thao tác thêm thanh khoản, phần này tương đương với việc đặt lệnh giới hạn.

uniswapx

sauSwap Hook

Sau khi người dùng hoàn thành Swap Token trong Pool này, Pool sẽ gọi hàm afterSwap() của hợp đồng Hook. Logic chính của afterSwap là loại bỏ tính thanh khoản khỏi các lệnh đã được thực hiện giữa phạm vi giá trước đó và phạm vi giá hiện tại. Hành vi như vậy tương đương với lệnh được điền.

uniswapx

Giới hạn dòng lệnh

Sau đây là sơ đồ của quá trình đặt lệnh giới hạn:

uniswapx

  1. Người đặt hàng sẽ gửi đơn đặt hàng đến hợp đồng Hook.
  2. Hợp đồng Hook thực hiện thêm các hoạt động thanh khoản dựa trên thông tin đơn hàng.
  3. Nói chung, người dùng thực hiện các hoạt động Swap Token trong Pool.
  4. Sau khi thao tác Swap Token hoàn tất, Pool sẽ gọi hàm afterSwap() của hợp đồng Hook.
  5. Hợp đồng Hook thực hiện hoạt động loại bỏ tính thanh khoản của các lệnh giới hạn được thực hiện dựa trên những thay đổi trong phạm vi giá của Swap Token.

Trên đây là toàn bộ quá trình sử dụng cơ chế Hook để thực hiện Limit-Order.

Móc: Các tính năng khác

Hooks cũng có một số điểm thú vị mà tác giả thấy thú vị trong quá trình nghiên cứu và tôi nghĩ chúng đáng được đề cập và chia sẻ với mọi người.

Móc địa chỉ hợp đồng Bit

Việc xác định xem có cần thực hiện các hoạt động trước/sau cụ thể hay không được xác định bởi byte ngoài cùng bên trái của địa chỉ hợp đồng Hook. 1 byte bằng 8 bit, tương ứng chính xác với 8 hành động bổ sung. Pool sẽ kiểm tra xem bit hành động có phải là 1 hay không để xác định xem có nên gọi hàm hook tương ứng của hợp đồng Hook hay không. Điều này cũng có nghĩa là địa chỉ của hợp đồng Hook cần phải được thiết kế theo một cách cụ thể và địa chỉ hợp đồng không thể được chọn ngẫu nhiên làm hợp đồng Hook. Mục đích chính của thiết kế này là giảm mức tiêu thụ Gas và chuyển chi phí sang triển khai theo hợp đồng để đạt được hoạt động hiệu quả hơn. (PS: Trong thực tế, các loại muối CREATE2 khác nhau có thể được sử dụng để tính toán mạnh mẽ địa chỉ hợp đồng đủ điều kiện)

uniswapx

Phí động

Ngoài khả năng thực hiện thêm các thao tác trước và sau mỗi hành động, Hooks còn hỗ trợ thực hiện tính phí động. Khi tạo Nhóm, bạn có thể chỉ định xem có bật phí xử lý động hay không. Nếu phí động được bật, hàm getFee() của hợp đồng Hook sẽ được gọi khi Swap Token. Hợp đồng Hook có thể quyết định mức phí xử lý sẽ được tính dựa trên trạng thái Pool hiện tại. Thiết kế này cho phép việc tính phí xử lý được điều chỉnh theo điều kiện thực tế, nâng cao tính linh hoạt của hệ thống.

Tạo hồ bơi

Mỗi Nhóm cần xác định hợp đồng Hook khi nó được tạo và sau đó không thể thay đổi hợp đồng này (nhưng các Nhóm khác nhau có thể chia sẻ cùng một hợp đồng Hook). Điều này chủ yếu là do Hook được coi là một phần của PoolKey, được PoolManager sử dụng để xác định Pool nào sẽ thực hiện các thao tác trên đó. Ngay cả khi tài sản giống nhau nhưng nếu hợp đồng Hook khác nhau thì đây sẽ được coi là một Pool khác. Thiết kế này đảm bảo rằng trạng thái và hoạt động của các Nhóm khác nhau có thể được quản lý độc lập và đảm bảo tính nhất quán của Nhóm. Nhưng đồng thời, độ phức tạp của việc định tuyến tăng lên khi số lượng Pool tăng lên (có lẽ UniswapX là một trong những cách được thiết kế để giải quyết vấn đề này).

uniswapx

TL;DR

  • Flash Accounting được sử dụng để theo dõi những thay đổi về số lượng của từng Token và đảm bảo rằng tất cả những thay đổi được đặt lại về 0 sau khi giao dịch hoàn tất. Để tiết kiệm chi phí gas , Flash Accounting sử dụng phương pháp lưu trữ đặc biệt do EIP1153 cung cấp.
  • Thiết kế của Hợp đồng Singleton giúp giảm mức tiêu thụ gas vì tránh cập nhật nhiều biến được lưu trữ.
  • Kiến trúc Hooks cung cấp các hoạt động bổ sung, được chia thành các giai đoạn "trước thực thi" và "hậu thực thi". Điều này làm cho mỗi hoạt động của Pool trở nên linh hoạt hơn nhưng cũng khiến việc định tuyến của Pool trở nên phức tạp hơn.

UniswapV4 rõ ràng chú trọng nhiều hơn đến việc mở rộng toàn bộ hệ sinh thái Uniswap và xây dựng nó thành cơ sở hạ tầng để có thể xây dựng nhiều dịch vụ hơn trên cơ sở Uniswap Pool. Điều này sẽ giúp nâng cao khả năng cạnh tranh của Uniswap và giảm nguy cơ bị thay thế bởi các dịch vụ khác, nhưng liệu nó có thể thành công như mong đợi hay không thì cần phải quan sát thêm. Một số điểm nổi bật bao gồm sự kết hợp giữa Flash Accounting và EIP1153, đồng thời chúng tôi tin rằng sẽ có nhiều dịch vụ áp dụng các tính năng này trong tương lai, cùng với nhiều kịch bản ứng dụng khác nhau đang xuất hiện. Đây là khái niệm cốt lõi của UniswapV4 và chúng tôi hy vọng điều này sẽ giúp mọi người hiểu sâu hơn về cách UniswapV4 hoạt động. Nếu bài viết có sai sót gì, các bạn có thể sửa chữa và cũng có thể thảo luận, trao đổi ý kiến.

Cuối cùng, xin cảm ơn Anton Cheng và Ping Chen đã giúp đỡ trong việc xem xét bài viết và đưa ra những nhận xét có giá trị!

Nguồn
Tuyên bố từ chối trách nhiệm: Nội dung trên chỉ là ý kiến của tác giả, không đại diện cho bất kỳ lập trường nào của Followin, không nhằm mục đích và sẽ không được hiểu hay hiểu là lời khuyên đầu tư từ Followin.
Thích
Thêm vào Yêu thích
Bình luận