
Ghi chú của nhà phát triển: Sự ra đời của Aggregator Hook
Tuyển chọn TechFlowTuyển chọn TechFlow

Ghi chú của nhà phát triển: Sự ra đời của Aggregator Hook
Bài viết này sẽ thảo luận về nguồn gốc, cơ chế hoạt động của Aggregator Hook, cũng như tác động sâu rộng mà nó mang lại cho Uniswap và hệ sinh thái DEX nói chung.
Tác giả: Attens & Bruce
Chỉnh sửa: Lisa, DODO Research
Việc này (Aggregator Hook) là điều tốt lành đối với các DEX khác — chỉ cần thêm một đoạn mã là có thể kết nối thêm vào một "trình tổng hợp siêu cấp", hà cớ gì mà không làm; đương nhiên đây cũng là điều tuyệt vời đối với Uniswap, bởi nó có thể trơn tru và miễn phí hấp thụ thanh khoản từ các DEX khác để sử dụng cho riêng mình.
— Attens, Trưởng nhóm phát triển DODO
Sau khi ra mắt Uniswap V4, một làn sóng sôi động nhanh chóng lan tỏa trong cộng đồng nhà phát triển: cấu trúc Hook đã mang lại khả năng mở rộng phong phú cho các hợp đồng pool truyền thống vốn dĩ khuôn mẫu và bất biến. Giao diện Hook của Uniswap V4 gần như bao quát toàn bộ vòng đời tương tác giữa pool và vốn, tạo nên mảnh đất màu mỡ cho những ý tưởng sáng tạo của các nhà phát triển. Từ TWAMM Hook tương đối đơn giản, giới thiệu cơ chế bảo vệ thông qua oracles trọng số theo thời gian, đến LimitOrder Hook thể hiện tiềm năng mạnh mẽ hơn của Hook, hay thậm chí là các Hook giao dịch liên chuỗi được sinh ra tại các cuộc thi hackathon, đủ loại Hook đang mọc lên như nấm sau mưa.
Là những người làm trong lĩnh vực DeFi, chúng tôi tự nhiên cũng không ngồi yên nhìn. Tại sự kiện ETH Global tháng 11 vừa qua, chúng tôi đã đề xuất một thiết kế Hook mới và may mắn giành giải thưởng “Best of Use Hook”. Vì tính ứng dụng cao, có thể đóng vai trò như một thành phần mã nguồn tích hợp vào nhiều loại hợp đồng pool khác nhau, chúng tôi đặt tên cho nó là: Aggregator Hook.
Aggregator Hook nhằm đóng vai trò như một “cầu nối”, giúp thanh khoản trên thị trường trực tiếp kết nối tới các pool Uniswap V4; đồng thời áp dụng nguyên tắc “kịp thời” để quản lý linh hoạt nguồn vốn lưu động, bơm thanh khoản trước giao dịch và rút ra sau giao dịch, giảm thiểu tối đa ảnh hưởng việc di chuyển thanh khoản lên pool gốc. Việc tích hợp này cho phép các LP quản lý vốn một cách tiện lợi chưa từng có, tận dụng kiến trúc vững chắc của Uniswap, đồng thời khai thác thanh khoản từ hệ sinh thái DEX rộng lớn hơn.
Bài viết này sẽ thảo luận về nguồn gốc, cơ chế hoạt động và tác động sâu rộng mà Aggregator Hook mang lại cho Uniswap và toàn bộ hệ sinh thái DEX.
I. Sự ra đời của Aggregator Hook
Ý tưởng ban đầu bắt nguồn từ một nhu cầu rất đơn giản của chúng tôi: Chúng tôi có một pool DODO V3 hiệu quả báo giá rất cao, liệu có thể tận dụng cơ chế Hook để di chuyển toàn bộ hệ thống này sang Uni V4?
Khi nghiên cứu LimitOrderHook, chúng tôi nhận được cảm hứng: Hook có thể giữ một phần vốn. Đây là một phát hiện nhỏ bé nhưng đã mở ra cánh cửa thần kỳ. Kết hợp "“Hook là một hợp đồng độc lập”" và "“Hook có thể giữ vốn”", liệu chúng ta có thể suy luận rằng: bản thân Hook hoàn toàn có thể trở thành một pool? Và giờ đây, nếu có một hợp đồng nào đó — dù là pool của DEX khác hoặc có logic riêng (ví dụ: một pool gây quỹ cộng đồng, hay một hệ thống giao dịch ký quỹ), nhưng đồng thời thỏa mãn yêu cầu của Uni V4 đối với hợp đồng Hook và có các hàm tương ứng với Hook Uni V4 — thì nó cũng có thể đồng thời là một Hook.
Từ đó, chúng tôi hình thành ý tưởng ban đầu: Aggregator Hook là một Hook lấy pool làm trung tâm, vừa là một pool DODO V3, vừa có thể đóng vai trò là một Hook Uni V4. Chúng tôi muốn di chuyển hệ thống báo giá sang các hàm tương ứng trong Hook, sử dụng JIT để người dùng khi giao dịch trên Uni V4 nhận được mức giá giống như trên DODO V3. Phương án ban đầu rất tự nhiên: chúng tôi có giới hạn giá trên, giới hạn giá dưới và số lượng token cần bán, chuyển khoảng giá thành tick, điền thanh khoản theo khối lượng, người dùng thực hiện giao dịch, giao dịch thành công, hoàn hảo —— khoan đã! Chúng tôi gặp phải chênh lệch giá cực lớn.
Chúng tôi thử nghiệm nhiều tổ hợp khác nhau về tickSpacing và Fee, cũng như các tổ hợp tick tương ứng với các ngưỡng giá, nhưng kết quả tốt nhất vẫn chênh lệch 0,2% so với mức báo giá gốc trên DODO V3 — đủ để ảnh hưởng đến trải nghiệm giao dịch của người dùng. Rõ ràng, điều này là do sự khác biệt thuật toán giữa DODO V3 và Uni V4. Để giải quyết chênh lệch này, chúng tôi đứng trước hai lựa chọn:
-
Cửa chính: Tính toán kỹ lưỡng sự khác biệt thuật toán giữa Uni V4 và DODO V3, tìm ra công thức ánh xạ lại thanh khoản
-
Cửa hậu: Sử dụng fromAmount để lấy giá từ DODO V3, rồi dùng giá này trực tiếp xác định tham số điền thanh khoản nhằm loại bỏ chênh lệch giá
Sau một thời gian ngắn thử nghiệm, chúng tôi không do dự chọn luôn con đường cửa hậu! Dù tin rằng phương án thứ nhất nếu tìm được lời giải phân tích sẽ cho ra một bài tiểu luận tinh tế, tiếc rằng chúng tôi không phải nhà toán học. Nhược điểm của phương án thứ hai hiển nhiên: chắc chắn sẽ tiêu tốn thêm gas vì phải thêm một lần truy vấn giá; nhưng ưu điểm cũng rất rõ ràng: Hàm lấy giá bằng fromAmount không phải là duy nhất của DODO V3, mọi pool DEX đều có hàm truy vấn giá tương tự như getAmountsOut, get_dy, querySellTokens... Dù tên gọi thế nào, luôn có cách lấy kết quả báo giá từ hợp đồng. Do đó, thành phần Hook này không chỉ dùng được trong pool DODO V3 mà còn có thể tích hợp vào bất kỳ pool DEX nào, thậm chí không nhất thiết phải là một pool, mà có thể là một thành phần báo giá solver. Bất kỳ hợp đồng nào có thanh khoản và có thể báo giá cho thanh khoản đó, chỉ cần thêm đoạn mã Hook này, đều có thể đồng thời trở thành một Hook mà không ảnh hưởng đến logic độc lập ban đầu, và nó có thể thông qua Hook - Pool đồng thời tạo thành một pool Uni V4 hợp lệ. Khi ấy, lý tưởng nhất, tuyến đường dẫn (routing) của Uni V4 không chỉ định tuyến tới các pool Uni V4 truyền thống, mà còn có thể định tuyến tới các "trick pool" do chúng tôi tạo ra.
Chúng tôi cảm thấy phấn khích — đây là điều tốt lành đối với các DEX khác, chỉ cần thêm một đoạn mã là có thể kết nối thêm vào một “trình tổng hợp siêu cấp”, hà cớ gì mà không làm. Với Uniswap đương nhiên cũng là điều tuyệt vời: nó có thể trơn tru và miễn phí hấp thụ thanh khoản từ các DEX khác để sử dụng cho riêng mình.
Dĩ nhiên, viễn cảnh hoành tráng này phụ thuộc vào việc cuối cùng Uni V4 sẽ sử dụng thuật toán định tuyến nào và xử lý thứ tự ưu tiên của các pool ra sao. Đó là một chủ đề khác, có lẽ chúng tôi sẽ viết một bài riêng về thuật toán định tuyến của Uni V4. Nhưng do tính đặc biệt của Hook, có thể khẳng định rằng bất kể thuật toán định tuyến nào cũng phải tính đến ảnh hưởng của Hook, bởi các thao tác trong Hook trực tiếp liên quan đến mức giá cuối cùng mà người dùng nhận được.
Hy vọng bạn đọc vẫn nhớ tiền đề cơ bản nhất của giả thuyết hoành tráng này: chúng tôi nhận được một mức báo giá, sau đó tìm ra một cách điền thanh khoản có thể "chiếu" mức giá đó lên Uni V4, để người dùng khi giao dịch qua Uni V4 nhận được mức giá giống như khi giao dịch trực tiếp qua Hook-Pool.
Cuối cùng, chúng tôi đã làm được. Đó là lý do chúng tôi chính thức gọi nó là “Aggregator Hook”.
II. Quy trình vận hành của Aggregator Hook
Khi nói đến hiện thực cụ thể của Aggregator Hook, bạn sẽ nhận ra rằng phép màu thực ra chỉ là một đồng xu nhỏ bé nằm khuất trong tay áo người biểu diễn:
-
Người dùng khởi tạo lệnh swap
-
Kích hoạt beforeSwapHook, trong Hook thực hiện ba thao tác:
-
Gỡ bỏ toàn bộ thanh khoản còn lại trong pool (Im lặng! Đây là điểm then chốt.)
-
Sử dụng fromAmount của người dùng để lấy mức giá giao dịch gốc từ Hook-Pool
-
Tính toán tham số modifyPosition dựa trên mức giá giao dịch, rồi điền thanh khoản
-
Kết thúc lệnh swap
-
Router bên ngoài xử lý transferIn và transferOut cho người dùng
Như hình dưới đây:

Khi lệnh giao dịch của người dùng sắp tới, Hook BeforeSwap được kích hoạt, các nhà cung cấp thanh khoản (LPs) bơm thanh khoản vào pool Uniswap V4. Phần thanh khoản tăng thêm thích ứng với lệnh giao dịch sắp tới, thúc đẩy việc thực hiện thành công. Tuy nhiên, thay vì rút thanh khoản này sau khi giao dịch kết thúc, hãy để nó ở lại trong pool. Điều này tạo thành một phần của chu kỳ sống đầy đủ cho giao dịch đầu tiên.
Điểm đột phá nằm ở việc xử lý các giao dịch tiếp theo. Trước khi giao dịch tiếp theo bắt đầu, Hook BeforeSwap lại được kích hoạt. Nhiệm vụ hàng đầu của nó là gỡ bỏ bất kỳ thanh khoản dư thừa nào còn sót lại từ giao dịch trước.
Sau khi gỡ bỏ thanh khoản còn dư, các LP lặp lại bước ban đầu: phân tích nhu cầu giao dịch mới và thêm chính xác một lượng thanh khoản vào hai khoảng giá. Việc bổ sung chi tiết này đảm bảo rằng thanh khoản không chỉ được sử dụng tối ưu mà còn được định vị với hiệu suất cao nhất, từ đó giảm trượt giá và cải thiện việc thực hiện giao dịch tổng thể trong hệ sinh thái Uniswap.
III. Phân tích cơ chế và mã nguồn
Phần hay nhất nên được giữ lại cuối cùng.
Khi nào nên gỡ bỏ thanh khoản
Trước tiên, chúng tôi cần giải thích lý do tại sao cần phải gỡ bỏ thanh khoản, dựa trên hai điểm sau:
-
Trong Hook này, Hook-Pool mới là chủ thể, thanh khoản nên được tập trung tối đa trong Hook-Pool.
-
Việc tính toán ánh xạ lại giá sẽ đơn giản hơn khi pool không còn thanh khoản dư thừa.
Trong JIT, cách làm phổ biến là: bơm thanh khoản trước khi người dùng swap, và rút ra sau khi swap. Ban đầu chúng tôi cũng nghĩ như vậy, thêm thanh khoản trong beforeSwapHook, gỡ bỏ trong afterSwapHook, logic rất mạch lạc —— tuy nhiên Hook luôn đầy bất ngờ. Hãy xem cấu trúc testRouter mới nhất hiện tại của Uni V4:



Bạn thấy đấy, rào cản chính cản trở kế hoạch vĩ đại của chúng tôi là: Người dùng chỉ thực hiện trao đổi token thật sự với poolManager sau khi manager.swap hoàn tất. Điều này có nghĩa là: afterSwapHook không thực sự xảy ra 'sau khi swap', do đó chúng tôi không thể xử lý việc gỡ bỏ thanh khoản trong afterSwapHook. Hàm removeLiquidity mất đi vị trí lý tưởng, khiến chúng tôi rối loạn, buộc phải để vị diễn viên bị bỏ rơi này đứng khô khốc phía sau lời gọi hàm swap trong phần kiểm thử, đơn độc và lố bịch như một gã hề. Khi đang túng quẫn, chúng tôi định lợi dụng hookData trong hàm swap, cân nhắc khả năng chỉnh sửa testRouter; đúng lúc đó, một trong những người tạo ra quả táo vàng, @ken từ Uni và dev @saucepoint của họ đã đưa ra lời khuyên cực kỳ quan trọng: Có thể gỡ bỏ thanh khoản ngay đầu giao dịch tiếp theo.
Giải pháp này chắc chắn là tối ưu nhất với chúng tôi. Thứ nhất, nó thay đổi mã nguồn cực kỳ ít, lúc đó chúng tôi chỉ còn 7 tiếng nữa là đến buổi thuyết trình hackathon; thứ hai, nó không còn phụ thuộc vào testRouter thất thường để tự động gỡ bỏ thanh khoản, bạn chỉ cần kiên nhẫn đợi một chút, đến khi người dùng tiếp theo vào, khoản thanh khoản từ giao dịch trước sẽ được hoàn trả nguyên vẹn.
Dĩ nhiên, chủ sở hữu của Hook-Pool có thể rút thanh khoản khỏi Uni V4 bất cứ lúc nào, không nhất thiết phải đợi người dùng giao dịch tiếp theo, hàm remove dưới đây là public:


Đồng thời, để bảo vệ vốn, chúng tôi sử dụng beforeModifyPosition Hook để xác minh msg.sender thực hiện thay đổi thanh khoản

Cách điền thanh khoản
Công thức tính toán của Uni V4 và Uni V3 là nhất quán, mặc dù pool của Uni V4 đã trở thành một thư viện (lib). Chúng tôi chỉ xét việc điền thanh khoản một chiều trong một khoảng tick cực nhỏ, ví dụ như điền thanh khoản giữa tick -46874 và tick -46873, nhằm giảm thiểu tối đa chi phí vượt tick. Bằng cách đọc mã nguồn và các bài phân tích liên quan, có thể sử dụng thuật toán Uni để có được công thức sau.

Mã nguồn tương ứng:

Nhưng đây chưa phải là kết thúc. Quan sát phân bố thanh khoản của Uni V3/V4, ta thấy:

Sau khi điền thanh khoản, thực tế chỉ có 50% khoảng giá trong đoạn đó đáp ứng được nhu cầu giao dịch một chiều của chúng tôi. Nếu chúng ta sell token0 để lấy token1, khoảng tick điền thanh khoản được chọn là [tickLower, tickUpper], tương ứng với khoảng giá [priceLower, priceUpper]. Trong quá trình giao dịch, hành vi giá mong đợi là giảm từ mức giá hiện tại xuống mức giá mục tiêu, nhưng giá mục tiêu này không được thấp hơn (priceLower + priceUpper) / 2. Nếu thấp hơn (priceLower + priceUpper) / 2, sẽ biểu hiện là price_next vượt quá giới hạn dưới, cần hiệu chỉnh giới hạn tick dưới. Đầu giao dịch kia cũng cần hiệu chỉnh. Ví dụ:

Phần hiệu chỉnh này tương ứng với mã nguồn:

Cân bằng giá
Cho đến nay, những điều chúng tôi hứa hẹn hầu như đã thực hiện được. Aggregator Hook là tốt, nhưng không hoàn hảo. Hạn chế cốt lõi nhất chính là hướng giao dịch. Hạn chế này được mô tả trong các trường hợp sau:
-
Hiện tại, giá của pool V4 nằm ở mức giá tương ứng với tick 0, ký hiệu là currentPrice
-
Khi targetPrice > currentPrice, pool V4 chỉ có thể thực hiện swap 1 to 0
-
Khi targetPrice < currentPrice, pool V4 chỉ có thể thực hiện swap 0 to 1
Hạn chế này thực ra cũng rất hợp với trực giác. Ta có thể coi targetPrice là giá thị trường, currentPrice là giá được tạo ra bởi giao dịch trong pool Dex cũ. Khi giá pool Dex thấp hơn giá thị trường, pool yêu cầu người dùng chỉ được mua token0 để nâng giá, đạt được cân bằng giá; khi giá pool Dex cao hơn giá thị trường, pool yêu cầu người dùng chỉ được mua token1 để hạ giá, đạt được cân bằng giá.
Điều kiện hạn chế này được biểu diễn bằng mã như sau:

IV. Thảo luận sâu và triển vọng
Chúng tôi cho rằng ý nghĩa lớn nhất của Aggregator Hook nằm ở việc đổi mới góc nhìn khi thiết kế Hook.
Trước đây, khi nghĩ về thiết kế Hook, chúng tôi luôn theo góc nhìn lấy Pool Uni V4 làm trung tâm, suy nghĩ việc sử dụng Hook có thể mang lại chức năng mới gì cho “giao dịch”; Aggregator Hook đã đưa ra một góc nhìn hoàn toàn mới. Do tính độc lập của Hook, hợp đồng này không nhất thiết phải “All in Hook”, Hook có thể chỉ là một phần chức năng của nó —— tạo cầu nối với pool Uni V4, nhưng bản thân nó có thể là một hợp đồng thực hiện mọi thao tác, “giao dịch” và Uni V4 chỉ là một phần chức năng của hợp đồng đó.
Ví dụ đơn giản, một số dự án nhỏ thường tuyên bố sau khi gây quỹ token sẽ dành một tỷ lệ nhất định token và vốn để thêm vào UniSwap. Trong thời đại Uni V3, các thao tác giữa hợp đồng gây quỹ và hợp đồng Uni V3 là bất đồng bộ, người dùng chỉ có thể tin tưởng dự án để chuyển vốn. Nhưng với Uni V4 Hook: Tại sao chúng ta không tận dụng tính độc lập của Hook để tích hợp trực tiếp thao tác thêm thanh khoản vào cùng một hợp đồng? Thậm chí thực hiện ngay khi người dùng nạp tiền (dĩ nhiên điều này sẽ tốn rất nhiều gas, nhưng nếu có người dùng cần sự minh bạch này thì sao)? Điều này thật điên rồ, nhưng nó báo hiệu vô số khả năng của Hook.
Hạn chế lớn nhất của Aggregator Hook thực ra là chi phí gas cho giao dịch. Chi phí gas thông thường của Uni V3 khoảng 120k, nhưng do chúng tôi thực hiện nhiều thao tác thêm/gỡ thanh khoản, chi phí gas cho một giao dịch đơn lẻ tính bằng forge snapshot dao động từ 420k đến 550k, cao hơn nhiều so với hành vi swap bình thường, điều này quyết định rằng phương pháp tích hợp pool này chỉ có thể sử dụng trên các L2 không nhạy cảm với storage gas, hoặc trên các chuỗi có giá gas rất thấp. Thủ thuật phải trả giá cho thủ thuật, điều này rất hợp lý.
Tất nhiên, vẫn còn những điểm có thể cải thiện, tập trung vào phần thêm/gỡ thanh khoản. Có hai hướng khả thi, một đơn giản và một phức tạp. Trước tiên là món khai vị đơn giản:
-
Trong mục Cân bằng giá, chúng tôi đã thảo luận vấn đề hướng giao dịch. Nếu chúng tôi giữ phương án gỡ bỏ thanh khoản, quy tắc giữa targetPrice và currentPrice không thể thay đổi, nhưng khoảng cách giữa tick0 và limitTick thì không nhất thiết phải khác nhau. Chỉ là khi limitTick = tick0, việc điền thanh khoản sẽ trở thành nạp hai chiều, công thức tính toán lượng thanh khoản cần thay đổi. Thay đổi này có thể nới lỏng yêu cầu hướng giao dịch một chút. Nới lỏng một tick.
Phức tạp hơn:
-
Khi đã xét đến việc nạp thanh khoản hai chiều, tại sao không triệt để thực hiện, thay vì bắt buộc gỡ bỏ thanh khoản? Mà chỉ gỡ bỏ thanh khoản khi quản trị viên Hook-Pool cho là cần thiết. Giảm thêm chi phí gas khi user swap, giúp Aggregator Hook trở nên ”dùng được“ hơn. Tất nhiên, điều này rất có thể dẫn đến thuật toán nạp thanh khoản phức tạp hơn nhiều so với phương án khai vị ở trên.
Mã nguồn hiện tại của pool Aggregator Hook như sau:
https://github.com/Attens1423/Aggregator-Hook
Để trực quan thấy kết quả giao dịch, chúng tôi đã thêm phần in kết quả gọi afterSwap Hook, nhưng điều này không bắt buộc. Bên trong có nhiều giá trị trung gian in ra, có thể dùng forge test để xem màn trình diễn của Aggregator Hook.
DODO V3 có lẽ sẽ là pool đầu tiên dám ăn quả hồng tiên. Kế hoạch tiếp theo của chúng tôi là tích hợp Aggregator Hook vào các pool DODO V3, ở đây vẫn còn một số công việc cập nhật reserve và trạng thái pool cần thiết, sau khi hoàn thành tất cả kiểm thử, chúng tôi sẽ mã nguồn mở, hiện thực hóa ý tưởng Hook-Pool ban đầu.
Chào mừng tham gia cộng đồng chính thức TechFlow
Nhóm Telegram:https://t.me/TechFlowDaily
Tài khoản Twitter chính thức:https://x.com/TechFlowPost
Tài khoản Twitter tiếng Anh:https://x.com/BlockFlow_News














