还款
还款指令通过确保归还借款及相应费用,完成我们的闪电贷周期。此指令执行两个关键步骤:
提取贷款金额:使用指令内省从借款指令的数据中检索原始
amount_borrowed转回资金:计算
fee并将借款金额加上费用转回协议
指令内省
首先,我们需要检查交易中的第一个指令以提取原始贷款金额:
rust
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());
}转回资金
接下来,我们计算协议费用并将总金额转回:
rust
// 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
)?;我们的费用硬编码为 500 个基点,并执行“检查”数学运算以确保金额不会溢出,从而防止使用非常大的数字进行的攻击。此外,我们将金额转换为 u128 进行乘法运算以防止中间溢出,然后安全地转换回 u64。