Repay
Instruction repay hoàn thành chu kỳ flash loan bằng cách đảm bảo các khoản tiền vay được trả lại cùng với phí phù hợp. Instruction này thực hiện hai bước thiết yếu:
Trích xuất số tiền vay: Sử dụng instruction introspection để lấy
amount_borrowedgốc từ dữ liệu của instruction borrowChuyển tiền trở lại: Tính toán
feevà chuyển số tiền vay cộng phí trở lại protocol
Instruction Introspection
Đầu tiên, chúng ta cần kiểm tra instruction đầu tiên trong transaction để trích xuất số tiền vay gốc:
let ixs = ctx.accounts.instructions.to_account_info();
let mut amount_borrowed: u64;
if let Ok(borrow_ix) = load_instruction_at_checked(0, &ixs) {
// Check the amount borrowed:
let mut borrowed_data: [u8;8] = [0u8;8];
borrowed_data.copy_from_slice(&borrow_ix.data[8..16]);
amount_borrowed = u64::from_le_bytes(borrowed_data)
} else {
return Err(ProtocolError::MissingBorrowIx.into());
}Chuyển tiền
Tiếp theo, chúng ta tính phí protocol và chuyển tổng số tiền trở lại:
// Add the fee to the amount borrowed (In our case we hardcoded it to 500 basis point)
let fee = (amount_borrowed as u128).checked_mul(500).unwrap().checked_div(10_000).ok_or(ProtocolError::Overflow)? as u64;
amount_borrowed = amount_borrowed.checked_add(fee).ok_or(ProtocolError::Overflow)?;
// Transfer the funds from the protocol to the borrower
transfer(
CpiContext::new(ctx.accounts.token_program.to_account_info(), Transfer {
from: ctx.accounts.borrower_ata.to_account_info(),
to: ctx.accounts.protocol_ata.to_account_info(),
authority: ctx.accounts.borrower.to_account_info(),
}),
amount_borrowed
)?;Phí của chúng ta được hardcode thành 500 basis point, và chúng ta thực hiện phép toán "checked" để đảm bảo rằng số tiền không bị overflow có thể bị khai thác với các số rất lớn. Ngoài ra, chúng ta chuyển đổi số tiền thành kiểu u128 cho phép nhân để ngăn overflow trung gian, sau đó chúng ta safely cast trở lại kiểu u64