💻Tích hợp với Alpaca Finance

Tích hợp với Alpaca Finance

Alpaca Finance cho phép các ứng dụng DeFi và người dùng cuối tích hợp với giao thức cốt lõi của nó. Ví dụ đơn giản, một nhà phát triển có thể xây dựng một giao thức lãi kép tự động gửi tiền của người dùng vào kho tiền gửi của Alpaca Finance và cộng dồn lợi nhuận cho người dùng để sử dụng gas hiệu quả và tiện lợi. Mục đích của tài liệu này là hỗ trợ các nhà phát triển tích hợp với giao thức của chúng tôi để đảm bảo an ninh tổng thể cho hệ sinh thái.

Tích hợp Hợp đồng Thông minh

Phần này mô tả cách tích hợp với Alpaca Finance trực tiếp từ một hợp đồng thông minh.

Cho vay - Lending

Alpaca Finance cho phép người dùng kiếm thu nhập bằng lãi từ tài sản tiền điện tử bằng cách gửi chúng vào kho tiền gửi của chúng tôi. Những tài sản này sau đó được cung cấp để mang lại lợi nhuận cho những người tham gia khai thác để tận dụng vị thế của họ. Bất kỳ hợp đồng thông minh nào tương thích với EVM và được triển khai trên Binance Smart Chain đều có thể tích hợp với giao thức cho vay của Alpaca Finance.

Để gửi token cơ sở vào kho tiền của Alpaca Finance, trước tiên phải có được danh sách các kho có sẵn và token cơ sở tương ứng của chúng.

  • Vui lòng xem tại đây để biết danh sách chi tiết của tất cả các địa chỉ hợp đồng kho tiền.

Trước khi có thể gửi tiền vào kho tiền, hợp đồng thông minh đóng vai trò là người gửi tiền trước tiên phải phê duyệt khoản định mức sử dụng của token cơ sở sẽ được ký gửi. Điều này sẽ cung cấp cho Hợp đồng thông minh của Alpaca khả năng nhận được token từ người gửi.

// JavaScript
import { ERC20 } from '../typechain/ERC20'
import { MaxUint256 } from '@ethersproject/constants'

...

const yourSmartContractAddress = 'xxx'
tokenERC20.approve(yourSmartContractAddress, MaxUint256);

Đoạn mã JavaScript ở trên là quy trình làm việc đơn giản hóa về cách phê duyệt định mức sử dụng token với số tiền tối đa có thể. Xin lưu ý rằng việc sử dụng MaxUint256 có thể gây ra rủi ro bảo mật, nên sử dụng số lượng token chính xác do người dùng nhập.

Hành động gửi tiền được thực hiện bằng cách gọi hàm deposit chỉ định số tiền gửi trong tham số amountToken. Data type của amountTokenuint256 thông số này phải được định dạng thành số thập phân (decimal) của token tiền gửi (ví dụ: BNB sử dụng 18 số thập phân, 1 BNB = 10000000000000000000 hoặc 1 * 1e18). Đối với trường hợp token tiền gửi là BNB, kho tiền sẽ xử lý việc gói BNB thành wBNB, nhưng giao dịch phải bao gồm đủ BNB được gửi dưới dạng token gốc.

// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
if (msg.value == 0) { // if no native token is sent, then it is a ERC20/BEP20 token deposit
	IERC20(tokenAddess).safeTransferFrom(address(msg.sender), address(this), amountToken);
}
// Allow transfer to vault
SafeToken.safeApprove(tokenAddess, vaultContractAddress, amountToken);
// Deposit to vault
IVault(vaultContractAddress).deposit(amountToken);

Nếu gửi tiền thành công, kho tiền sẽ tạo các token chịu lãi suất (ibTokens) và trả lại các token đã tạo đó cho người gọi. Xin lưu ý rằng số lượng token chịu lãi suất được trả lại sẽ không bằng số lượng token cơ sở được cung cấp do thiết kế của token chịu lãi suất. Người gọi hàm deposit phải theo dõi chính xác cổ phần của người dùng gửi vào kho tiền, vui lòng xem phần Tính toán Token Chịu lãi suất để được giải thích chi tiết.

Lãi từ việc cho vay sẽ được cộng dồn vào ibTokens. Để nhận được lợi nhuận từ việc cho vay, ibTokens phải được rút, đổi lại thành token cơ sở + tiền lãi đã thu được. Bạn sẽ nhận thấy rằng giá trao đổi của ibToken sẽ cao hơn khi rút tiền, điều này cho thấy lãi suất đã được tích lũy. Do đó, bạn sẽ nhận được thêm token cơ sở khi rút tiền.

Để đổi token cơ sở từ kho tiền, số lượng ibTokens được rút phải được cung cấp cho hàm withdraw trong hợp đồng Vault.

// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
IVault(vaultContractAddress).withdraw(ibTokenAmount);

Các token cơ sở sau đó sẽ được trả lại cho người gọi. Nếu token được trả lại là BNB, hợp đồng Vault sẽ mở WBNB trở lại thành BNB.

Tính toán ibToken

Token chịu lãi suất (ibToken) là token đại diện cho cổ phần trong kho tiền của người gửi tiền. ibTokens sẽ tích lũy lãi suất nhận được từ việc cho vay theo thời gian. Bất kỳ giao thức DeFi nào muốn sử dụng kho tiền của Alpaca Finance đều phải hiểu và thực hiện tính toán ibTokens một cách chính xác để phản ánh phần chia sẻ thực tế của người dùng trong kho tiền.

Do đó, tỷ lệ giữa ibToken và token cơ sở thực tế sẽ chỉ là 1:1 khi kho tiền mở lần đầu tiên, sau đó giá trị của ibToken sẽ tiếp tục tăng khi lãi suất cho vay tích lũy (Giá trị của một ibToken liên quan đến token cơ sở sẽ chỉ di chuyển một chiều lên trên. Giá trị không được giảm). Ví dụ: giả sử giá: 1 ibBNB = 1.0292 BNB có nghĩa là ký gửi 1.0292 BNB sẽ nhận lại được 1 ibBNB. Mặt khác, đổi 1 ibBNB sẽ nhận được 1.0292 BNB. BNB bổ sung từ việc đổi ibBNB là từ tiền lãi tích lũy.

Hiểu được cơ chế cơ bản này về giá trị của ibTokens là rất quan trọng, vì giao thức DeFi tích hợp với các kho tiền cho vay của Alpaca Finance có thể cần tính toán chính xác cổ phần của người dùng trong khoản tiền gửi vào kho tiền. Nếu không làm như vậy có thể gây ra rủi ro bảo mật và tổn thất tài chính. Đây là trường hợp của các cuộc tấn công vào bEarn.fiValueDeFi, trong đó các giao thức này luôn coi ibTokens là có tỷ lệ 1:1 với token được gửi vào (đọc phân tích các cuộc tấn công trên bEarn.fiValueDefi).

Ngoài ra, mặc dù Alpaca không hoạt động với các khoản vay nhanh, nhưng trong một kho tiền không thuộc Alpaca, có thể có nguy cơ thao túng giá ibToken từ một cuộc tấn công chẳng hạn như một cuộc tấn công flash loan. Nếu không phòng bị, giá của ibToken có thể bị thay đổi đáng kể trong phạm vi giao dịch của kẻ tấn công. Đó là lý do tại sao, chỉ dựa vào giá ibToken từ tính toán của hợp đồng thông minh là không đủ. Chúng tôi khuyến nghị dự án nên có một Oracle giá cung cấp tỷ lệ hiện tại của ibTokens so với token cơ sở của nó để ngăn chặn một cuộc tấn công như vậy được đề cập ở trên.

Do đó, chúng tôi sẽ chỉ cho bạn cách an toàn và chính xác để tính giá của ibTokens.

Tính toán trực tiếp từ hợp đồng thông minh

Tính toán giá token ibToken từ hợp đồng thông minh là cách đơn giản nhất, nhưng để đảm bảo an toàn, nó không phải là phương pháp duy nhất mà bạn dựa vào.

// Solidity
address vaultContractAddress = '0xd7D069493685A581d27824Fc46EdA46B7EfC0063'; // BNB Vault
IVault vault = IVault(vaultContractAddress);
uint256 ibTokenAmount = ...;
uint256 ibTokenPrice = vault.totalToken()).div(vault.totalSupply();
uint256 underlyingTokenAmount = ibTokenAmount.mul(ibTokenPrice);

Đoạn mã trên minh họa cách tính giá ibToken từ việc truy xuất giá trị của totalTokentotalSupplytừ vault tương ứng.

Lấy giá ibToken từ Alpaca API

Alpaca Finance đã cung cấp một API để truy xuất giá ibToken hiện tại bằng cách gửi yêu cầu GET REST tới end point /ibTokens để truy xuất bất kỳ giá ibToken nào. Việc tích hợp với API của Alpaca yêu cầu xác thực, vì vậy vui lòng liên hệ với chúng tôi nếu bạn muốn sử dụng dịch vụ này.

Kết quả mẫu từ API như sau:

{
    "status": {
        "code": 1000,
        "messages": [
            "OK"
        ]
    },
    "data": [
        {
            "symbol": "ibALPACA",
            "baseTokenPerShare": "1.051108636596531492",
            "lendingApr": "0.0003638488758058",
            "stakingApr": "0.0"
        },
        {
            "symbol": "ibBNB",
            "baseTokenPerShare": "1.025808940627339553",
            "lendingApr": "9.7785294844178225",
            "stakingApr": "316693.265280905443641"
        },
        {
            "symbol": "ibBUSD",
            "baseTokenPerShare": "0.972337256352625836",
            "lendingApr": "0.368330890561667",
            "stakingApr": "2269.786601379154162"
        },
        {
            "symbol": "ibUSDT",
            "baseTokenPerShare": "0.913094694500682622",
            "lendingApr": "0.0012775198722327",
            "stakingApr": "0.0"
        },
        {
            "symbol": "ibBTCB",
            "baseTokenPerShare": "1.000006160536069502",
            "lendingApr": "6.5534019786376696",
            "stakingApr": "0.0"
        },
        {
            "symbol": "ibETH",
            "baseTokenPerShare": "0.999463386510494271",
            "lendingApr": "0.0000004209960912",
            "stakingApr": "0.0"
        }
    ]
}

Giá được truy xuất từ API của Alpaca phải được cung cấp cho hợp đồng thông minh bằng cách sử dụng Oracle giá. Việc cung cấp giá thông qua đầu vào cho một lệnh gọi vào hợp đồng thông minh sẽ dễ bị tấn công từ phía khách hàng. Chúng tôi đặc biệt khuyên không nên làm điều đó. Có thể thấy một ví dụ về một Oracle giá đơn giản ở đây. Bằng cách sử dụng một Oracle giá đáng tin cậy, bạn có thể đảm bảo tính toàn vẹn và độ tin cậy của dữ liệu giá ibToken.

Chúng tôi thực sự khuyên bạn nên truy xuất giá ibToken từ cả tính toán hợp đồng thông minh và API Alpaca. Hai nguồn dữ liệu giá này nên được so sánh để ngăn chặn bất kỳ sự bất thường nào về dữ liệu có thể xảy ra. Nếu sự so sánh giữa hai nguồn có sự khác biệt đáng kể, thì dữ liệu giá nên bị loại bỏ.

Tóm lại, quy trình an toàn nhất để tính giá ibToken là như sau:

  1. Tính giá ibToken trong hợp đồng của riêng bạn.

  2. Sử dụng một Oracle ngoài chuỗi để biết giá ibToken hoặc lấy những giá đó từ API của Alpaca.

  3. So sánh 1 và 2. Nếu sự khác biệt lớn hơn n% thì hãy hoàn nguyên giao dịch.

API của Alpaca hiện chỉ nằm trong whitelist cho các giao thức và tổ chức. Để yêu cầu quyền truy cập, vui lòng gửi email cho chúng tôi theo địa chỉ requests@alpacafinance.org

Gửi ký quỹ - Staking

Alpaca Finance cung cấp các cơ hội staking cho người dùng. Các token chịu lãi suất và token LP đều có thể dùng để ký quỹ trong các pool staking của chúng tôi để nhận được lợi nhuận bổ sung dưới dạng token ALPACA. Nếu bạn đã gửi tiền và nhận được ibTokens, chúng tôi khuyên bạn nên stake các token đó vào các pool này để kiếm được phần thưởng tối đa.

Để stake các token vào các pool ký quỹ của Alpaca Finance, trước tiên cần có danh sách các pool và các token ký quỹ tương ứng của chúng. Vui lòng xem tại đây để có danh sách đầy đủ nhất về tất cả các địa chỉ hợp đồng pool. Hợp đồng của các pool thường được gọi là Fairlaunch trong codebase của chúng tôi.

Thực hiện ký quỹ bằng cách gọi hàm deposit. Các thông số như sau:

  • _for là địa chỉ của người gửi tiền.

  • _pid là id của staking pool.

  • _amount là số lượng token được gửi vào uint256 được biểu thị bằng số thập phân của nó (ví dụ: ibBNB sử dụng 18 số thập phân, 1 ibBNB = 10000000000000000000hoặc 1 * 1e18)

// Solidity
address fairlaunchContractAddress = '0xA625AB01B08ce023B2a342Dbb12a16f2C8489A8F'; // ibBNB pool
IFairLaunch fairlaunch = IFairLaunch(fairlaunchContractAddress);
fairlaunch.deposit(msg.sender, poolId, amount);

Thông tin cổ phần ký quỹ sẽ được lưu trữ bên trong trạng thái hợp đồng thông minh. Sẽ không có token nào được phát hành từ việc staking. Cổ phần của một người dùng có thể được truy xuất bằng cách gọi hàm userInfo từ Fairlaunch.

Phần thưởng từ việc ký quỹ không được tự động trả và phải được thu hoạch thủ công. Tuy nhiên, việc thực hiện gửi tiền hoặc rút tiền trên các staking pool sẽ tự động thu được bất kỳ phần thưởng nào đang chờ xử lý cho người gọi. Để thu hoạch phần thưởng từ staking pool, người gọi phải gọi hàm harvest từ hợp đồng Fairlaunch và cung cấp id pool.

// Solidity
address fairlaunchContractAddress = '0xA625AB01B08ce023B2a342Dbb12a16f2C8489A8F'; // ibBNB pool
IFairLaunch fairlaunch = IFairLaunch(fairlaunchContractAddress);
fairlaunch.harvest(poolId);

Để rút token đã ký quỹ khỏi pool, số lượng cổ phần của người dùng phải được cung cấp cho hàm withdraw trong hợp đồng Fairlaunch.

// Solidity
address fairlaunchContractAddress = '0xA625AB01B08ce023B2a342Dbb12a16f2C8489A8F'; // ibBNB pool
IFairLaunch fairlaunch = IFairLaunch(fairlaunchContractAddress);
fairlaunch.withdraw(msg.sender, poolId, amount);

Token sẽ được trả lại cho người gọi và bất kỳ phần thưởng nào đang chờ xử lý cũng sẽ tự động được thu hoạch.

Last updated