Securityadvancedarticle25 min read

DeFi Composability Mẫu: Một hướng dẫn kỹ thuật toàn diện | VCC

Các mô hình DeFi và composability là bản vẽ kiến trúc cho phép các nhà phát triển kết hợp các giao thức giống như các khối LEGO® – mỗi khối độc lập, nhưng có thể kết hợp vô hạn. Tính chất này, độc đáo với hệ thống blockchain, biến mỗi hợp đồng triển khai thành một cấu trúc xây dựng tiềm năng cho sự

Vietcardano teamTeam

Đội ngũ biên tập VietCardanoCommunity — các chuyên gia blockchain và Cardano, cung cấp nội dung giáo dục và nghiên cứu chuyên sâu cho cộng đồng.

Published 14 tháng 9, 2026

Các mô hình DeFi và composability là bản vẽ kiến trúc cho phép các nhà phát triển kết hợp các giao thức giống như các khối LEGO® – mỗi khối độc lập, nhưng có thể kết hợp vô hạn. Tính chất này, độc đáo với hệ thống blockchain, biến mỗi hợp đồng triển khai thành một cấu trúc xây dựng tiềm năng cho sự đổi mới tiếp theo. Đối với các nhà phát triển Việt Nam xây dựng trên các cầu nối KyberSwap, VNDC hoặc cross-chain, hiểu biết về các mô hình này không chỉ là một vấn đề học thuật – đó là sự khác biệt giữa một giao thức composable và một khối vỡ.

Diagram - DeFi Composability Taxonomy: Four dimensions (Input, Output, State, Control) with example

Diagram - DeFi Composability Taxonomy: Four dimensions (Input, Output, State, Control) with example

Các cơ sở Composability

Trước khi sáng tác, bạn cần các phần có chuẩn. DeFi dựa trên ba tiêu chuẩn token và một số giao diện chính thức:

ERC-20 — Mã thông báo có thể thay thế (USDC, VNDC, WETH). Giao diện IERC20 (transfer, approve, transferFrom) là ngôn ngữ chung để chuyển giá trị.

ERC-721 — Token không thể thay thế (Uniswap vị trí V3, tài sản đảm bảo NFTfi). IERC721 bổ sung các thuộc tính ownerOf, safeTransferFrom và các mở rộng dữ liệu.

ERC-1155 — Các token đa dạng (các vật phẩm chơi game, các vị trí bán phần). Các lô chuyển đổi qua safeBatchTransferFrom, rất quan trọng cho việc xây dựng hiệu quả theo gas.

Các giao diện của Canonical DeFi:

  • IUniswapV3Pool — swap, mint, burn, flash, swapCallback
  • IPool (Aave V3) — supply, borrow, flashLoan, liquidationCall
  • IFlashLoanReceiver — callback tiêu chuẩn onFlashLoan
  • ICCIPReceiver — ccipReceive cho các tin nhắn cross-chain
Comparison Table - Token Standards & Key Interfaces: columns for Standard, Key Methods, Composabilit

Comparison Table - Token Standards & Key Interfaces: columns for Standard, Key Methods, Composabilit

Các mẫu cấu trúc cơ bản

Tạo cấu trúc theo thứ tự: Đầu ra cung cấp đầu vào

Mẫu đơn giản nhất: Xuất của Protokol A trở thành đầu vào của Protokol B, trong một transaction.

`solidity // Flash loan → Swap → Repay (arbitrage) function atomicArbitrage(address tokenA, address tokenB, uint256 amount) external { // 1. Borrow from Aave IPool(aavePool).flashLoan(address(this), tokenA, amount, "", 0); }

function onFlashLoan(address token, uint256 amount, uint256 fee, bytes calldata) external override { // 2. Swap on Uniswap V3 uint256 amountOut = ISwapRouter(uniswapRouter).exactInputSingle( IV3SwapRouter.ExactInputSingleParams({tokenIn: token, tokenOut: tokenB, fee: 3000, recipient: address(this), amountIn: amount, amountOutMinimum: 0, sqrtPriceLimitX96: 0}) ); // 3. Repay flash loan + keep profit IERC20(token).approve(aavePool, amount + fee); // Profit remains in this contract } `

Invariant chính: Nếu bất kỳ bước nào bị hủy, toàn bộ transaction sẽ bị hủy – không có thay đổi trạng thái một phần nào đó.

Flowchart - Sequential Composition: Flash Loan → DEX Swap → Repay → Profit, with state transitions l

Flowchart - Sequential Composition: Flash Loan → DEX Swap → Repay → Profit, with state transitions l

Tạo thành phần song song: các tác vụ độc lập được nhóm lại

Nhiều hoạt động độc lập được thực hiện trong một transaction thông qua Multicall hoặc các chức năng tập trung.

`solidity // Batch: Approve USDC → Approve WETH → Add liquidity to two pools bytes[] memory calls = new bytes[](4); calls[0] = abi.encodeWithSelector(IERC20.approve.selector, uniswapRouter, type(uint256).max); calls[1] = abi.encodeWithSelector(IERC20.approve.selector, uniswapRouter, type(uint256).max); calls[2] = abi.encodeWithSelector(IV3PoolActions.mint.selector, params1); calls[3] = abi.encodeWithSelector(IV3PoolActions.mint.selector, params2); IMulticall3(multicall).aggregate3(calls); `

Gas tiết kiệm: ~21,000 gas cho mỗi cuộc gọi được tránh so với các giao dịch riêng lẻ.

Graph - Parallel Composition DAG: User → Multicall → [Approve A, Approve B, Mint Pool 1, Mint Pool 2

Graph - Parallel Composition DAG: User → Multicall → [Approve A, Approve B, Mint Pool 1, Mint Pool 2

→ Done]

Tạo thành phần điều kiện: thực hiện thông qua các cổng logic

Các đường dẫn thực thi được chia theo các điều kiện trên chuỗi – giá, số dư, trạng thái governance.

`solidity // Conditional: Only swap if price > threshold function conditionalSwap(uint256 minPrice) external { (uint160 sqrtPriceX96,,,,,,) = IUniswapV3Pool(pool).slot0(); uint256 currentPrice = (uint256(sqrtPriceX96) ** 2) >> 192;

if (currentPrice >= minPrice) { ISwapRouter(router).exactInputSingle(params); } // Else: revert or no-op } `

Mẫu nâng cao: Diamond proxy facet được chọn dựa trên msg.sender hoặc block.timestamp.

Flowchart - Conditional Composition: Price Check → Decision Diamond (Yes/No) → Swap / Revert

Flowchart - Conditional Composition: Price Check → Decision Diamond (Yes/No) → Swap / Revert

Các mẫu kiến trúc tiên tiến

Diamond Proxy / Facet Mẫu (EIP-2535)

Tính nâng cấp mô-đun cho các giao thức được cấu thành. Mỗi "facet" thực thi một phần chức năng; hình kim cương thực hiện ủy quyền thông qua fallback.

`solidity // Diamond.sol — minimal fallback function fallback() external payable { address facet = diamondStorage.facetAddress[msg.sig]; require(facet != address(0), "Facet not found"); assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) let size := returndatasize() returndatacopy(0, 0, size) switch result case 0 { revert(0, size) } default { return(0, size) } } } `

Lợi thế của Composability: Thêm UniswapFacet, AaveFacet và BridgeFacet một cách độc lập. Cập nhật một trong các tính năng này mà không ảnh hưởng đến các tính năng khác.

Diagram - Diamond Architecture: Diamond Contract → Facet Registry → [UniswapFacet, AaveFacet, Bridge

Diagram - Diamond Architecture: Diamond Contract → Facet Registry → [UniswapFacet, AaveFacet, Bridge

with delegatecall arrows]

Tiến hành dựa trên ý định (ERC-4337)

Người dùng ký các ý định UserOperation; các nhà gói thực hiện; các nhà trả tiền tài trợ cho gas. Composability chuyển từ "các hợp đồng nào cần gọi" sang "kết quả tôi muốn".

`solidity // UserOperation for: "Swap 1000 USDC → WETH on best DEX, pay gas in USDC" UserOperation { sender: smartAccount, nonce: 0, initCode: "", // account already deployed callData: abi.encodeWithSelector(ISmartAccount.execute.selector, targets, calldatas), callGasLimit: 500_000, verificationGasLimit: 100_000, preVerificationGas: 50_000, maxFeePerGas: 20 gwei, maxPriorityFeePerGas: 2 gwei, paymasterAndData: paymaster.encodeUSDCGasPayment(), signature: userSignature } `

Composability shift: Các giải thuật cạnh tranh để thực hiện các ý định – MEV trở thành một tính năng, không phải lỗi.

Flowchart - Intent Resolution: User → UserOperation → Bundler → Solver Network → EntryPoint → Smart

Flowchart - Intent Resolution: User → UserOperation → Bundler → Solver Network → EntryPoint → Smart

Cross-Chain Composability

Việc kết hợp giữa các chuỗi yêu cầu việc truyền thông tin với đảm bảo giao hàng.

CCIP Mẫu (Chainlink): `solidity // Source chain: Send tokens + message ccipRouter.ccipSend( destinationChainSelector, EVM2AnyMessage({ receiver: abi.encode(destinationContract), data: abi.encodeWithSelector(ICrossChainReceiver.receive.selector, params), tokenAmounts: [{token: usdc, amount: 10000}] }) );

// Destination chain: Receive + execute function ccipReceive(Client.EVM2AnyMessage memory message) external override { (bool success,) = address(this).call(message.data); require(success, "Execution failed"); } `

LayerZero Mẫu V2: `solidity // OApp sends via DVN _lzSend(dstEid, abi.encode(params), paymasterParams, adapterParams);

// OApp receives + verifies via DVN function lzReceive(uint16, bytes calldata, uint64, bytes calldata message) external override { (bool success,) = address(this).call(message); require(success); } `

Diagram - Cross-Chain Message Flow: Source Chain → CCIP/LayerZero → DVN/Committee → Destination Chai

Diagram - Cross-Chain Message Flow: Source Chain → CCIP/LayerZero → DVN/Committee → Destination Chai

Các mẫu bảo mật cho Composability an toàn

Reentrancy Bảo vệ

Checks-Effects-Interactions (CEI): Cập nhật trạng thái trước các cuộc gọi bên ngoài.

`solidity // ❌ Vulnerable: External call before state update function withdraw() external { uint256 amount = balances[msg.sender]; (bool success,) = msg.sender.call{value: amount}(""); balances[msg.sender] = 0; // Too late! }

// ✅ CEI: State update first function withdraw() external { uint256 amount = balances[msg.sender]; balances[msg.sender] = 0; (bool success,) = msg.sender.call{value: amount}(""); } `

ReentrancyGuard (OpenZeppelin): Mẫu Mutex cho các trường hợp không thuộc CEI.

`solidity import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract ComposedProtocol is ReentrancyGuard { function complexOperation() external nonReentrant { // Safe to make multiple external calls } } `

Lưu trữ tạm thời (EIP-1153): Chất lượng khóa reentrancy rẻ hơn (khoảng 100 gas so với 5.000+).

`solidity function transientLock() external { if (tload(0) == 1) revert ReentrantCall(); tstore(0, 1); // ... external calls ... tstore(0, 0); } `

Oracle Kháng lực khi vận động

Các giao thức được cấu thành thường cần giá cả. Đừng bao giờ tin vào một giá tại một điểm duy nhất.

`solidity // TWAP from Uniswap V3 (manipulation-resistant) function getTWAP(address pool, uint32 secondsAgo) external view returns (int256) { (int56 tickCumulative,,) = IUniswapV3Pool(pool).observe([secondsAgo]); // Convert tick to price }

// Chainlink + TWAP medianizer function getSafePrice() external view returns (uint256) { uint256 chainlinkPrice = AggregatorV3Interface(feed).latestAnswer(); uint256 twapPrice = getTWAP(pool, 300); // 5-min TWAP return (chainlinkPrice + twapPrice) / 2; // Median } `

MEV Bảo vệ trong các giao dịch kết hợp

Private Mempool (Flashbots Protect): Gửi các gói trực tiếp cho các nhà phát triển.

Commit-Reveal: Tính toán hash → tiết lộ trong block tiếp theo.

Thương mại lô (CoW Swap): Các giải pháp cạnh tranh để thực hiện lô; số dư được trả lại cho người dùng.

Comparison Table - MEV Protection Methods: columns for Method, Gas Overhead, Trust Assumptions, Comp

Comparison Table - MEV Protection Methods: columns for Method, Gas Overhead, Trust Assumptions, Comp

Tính nâng cấp an toàn

  • Timelocks: Tạm dừng 48 giờ đối với các hành động của quản trị viên (OpenZeppelin TimelockController)
  • Multisig Governance: Safe (Gnosis Safe) cho nâng cấp giao thức

Gas Tối ưu hóa cho các giao dịch kết hợp

MẫuGas Chi phí (đề xuất)Tiết kiệm vs Naive
Multicall3 lô (4 lần gọi)~180,000~84,000 (4 × 21k base)
Cung cấp lưu trữ tạm thời (EIP-1153)~100/slot~5,000 vs SSTORE
Tiến hành triển khai xác định CREATE2~32,000Tránh truy xuất từ nhà máy
Sự nén dữ liệu cuộc gọi (ERC-2771)~16/byte~ Giảm 68%
Hàm view multicall~2,000Tránh các vòng lặp RPC

Pro tip: Use Foundry forge snapshot --diff to track gas regressions in composed flows.

Before/After Gas Comparison Bar Chart: Naive vs Optimized for 5 common composed flows

Before/After Gas Comparison Bar Chart: Naive vs Optimized for 5 common composed flows

Khoa học thử nghiệm và mô phỏng

Foundry Fork Thử nghiệm

`solidity // test/Composability.t.sol import "forge-std/Test.sol"; import "../src/ComposedProtocol.sol";

contract ComposabilityTest is Test { address mainnetRpc = vm.envString("MAINNET_RPC");

function setUp() public { vm.createFork(mainnetRpc); // Impersonate whale for token setup }

function test_SequentialArbitrage() public { vm.prank(whale); composedProtocol.atomicArbitrage(USDC, WETH, 100_000e6); // Assert profit > 0 }

function test_CrossChainMessage() public { vm.createFork(arbitrumRpc); // Test CCIP message delivery } } `

Tenderly Mô phỏng

`bash

tenderly simulate --network mainnet \ --from 0xYourAddress \ --to 0xComposedProtocol \ --input "0x..." \ --block-number 19500000 `

Các nghiên cứu trường hợp thực tế

Uniswap V3 + Aave V3: Tăng vốn Yield Farming

Strategic: Vay USDC trên Aave → Tạo ra USDC/WETH lượng tiền ảo tập trung trên Uniswap V3 → Kiếm được phí + phần thưởng trồng trọt.

`solidity function leveragedFarm() external { // 1. Flash loan WETH from Aave // 2. Swap half to USDC on Uniswap // 3. Mint concentrated position (tickLower, tickUpper) // 4. Stake position in incentive gauge // 5. Repay flash loan } `

Rủi ro: Impermanent loss được tăng cường bởi đòn bẩy. Giảm thiểu rủi ro: Dải giá hẹp + tái cân bằng hoạt động.

Cross-Chain thông qua LayerZero

Tiến trình: Ethereum USDC → LayerZero → Arbitrum USDC.e → Thay đổi trên Camelot → Về lại.

Chú ý quan trọng: xác thực DVN tăng thời gian chậm trễ ~3-5 phút. Sử dụng cho phương thức quyết định thống kê, không phải HFT.

Tiếng Việt: DeFi = KyberSwap + VNDC

KyberSwap's nguồn vốn tập trung + VNDC (VND-đồng giá với stablecoin) cho phép:

`solidity // VNDC/USDC stable pair — near-zero IL function vnStableFarm() external { // 1. Deposit VNDC + USDC to KyberSwap elastic pool // 2. Earn swap fees + KYBER emissions // 3. Auto-compound via KyberSwap's reinvestment } `

Bối cảnh địa phương: Người dùng Việt Nam ưa thích sử dụng VNDC để chuyển đổi giữa hệ thống tiền tệ và các dịch vụ thông qua các tích hợp MoMo/ZaloPay.

Các mô hình chống lại và những rủi ro phổ biến

Mẫu chốngNặng nhẹTriệu chứngĐịnh vị
Truyền cảm giác quá nhiềuQuan trọngTx quay lại "ra ngoài gas" hoặc vượt quá giới hạn blockGiới hạn ≤5 cuộc gọi bên ngoài; sử dụng multicall
Thất bại theo cấp cạnCaoMột giây ngừng của giao thức làm tê liệt toàn bộ dòng dữ liệuCác thiết bị cắt điện; các đường dẫn dự phòng
Sự lệch lạc về giả định tin cậyMức trungOracle/bridge được nâng cấp mà không thông báo trướcCác giao diện được cố định phiên bản; giám sát
Sự va chạm của các trạng tháiMức trungDiamond facets clobber storage slotsEIP-2535 DiamondStorage pattern
MEV sandwichHighComposed swap front-runPrivate mempool; commit-reveal
Anti-Pattern Cards: 5 cards with severity badges (Critical/High/Medium), description, and mitigation

Anti-Pattern Cards: 5 cards with severity badges (Critical/High/Medium), description, and mitigation

Future of DeFi Composability

  1. Kiến trúc tập trung vào mục đích — Anoma, SUAVE: Người dùng biểu thị mục đích, các giải pháp xác định cách thức thực hiện.

Hỏi đáp

Sự khác biệt giữa composability và khả năng tương tác là gì? Composability = kết hợp các giao thức trong môi trường thực thi chung (các chuỗi, nguyên tử). Khả năng tương tác = giao tiếp trong các môi trường khác nhau (cross-chain, đồng bộ).

flash loans làm thế nào để kích hoạt composability? Họ cung cấp vốn tức thì, không có tài sản đảm bảo trong suốt một transaction – cho phép arbitrage, thanh lý và tái tài trợ mà không có hạn chế về vốn của người dùng.

Các giới hạn cho các giao dịch được cấu trúc là gì? Ethereum mainnet: 30M gas/block. Giới hạn thực tế cho mỗi giao dịch: ~15-20M. Đề xuất tối thiểu là 5 cuộc gọi bên ngoài phức tạp.

Có thể composability hoạt động trên các L2 không? Có — thông qua lập trình chung (OP Stack, Arbitrum Orbit), giao tiếp xuyên L2 (Hop, Across) hoặc giải quyết trên L1. composability xuyên L2 nguyên tử yêu cầu lập trình chung.

Làm thế nào để kiểm tra một giao thức được cấu thành? Kiểm tra từng facet/kết hợp một cách riêng biệt, sau đó kiểm tra logic cấu thành (hệ thống gọi, phụ thuộc trạng thái, các trường hợp thất bại). Sử dụng Slither + Echidna để kiểm tra thuộc tính.


Thông báo: Bài viết này chỉ dành cho mục đích giáo dục. DeFi composability có rủi ro tài chính lớn. Hãy luôn kiểm tra hợp đồng, thử nghiệm trên các mạng thử nghiệm và tham khảo các nhà kiểm toán có đủ năng lực trước khi triển khai.

Tags:

defi composability patternswhat is defi composability patternsdefi composability patterns guide