我在比赛开始前如何分析 $107K Jupiter Lend
发布: (2026年2月8日 GMT+8 23:56)
3 分钟阅读
原文: Dev.to
Source: Dev.to
设置:10.7万美元赏金,零公开代码
当 Jupiter 宣布他们的借贷协议审计竞赛,奖励高达 10.7 万美元时,我就知道准备工作至关重要。问题是?代码尚未公开。
但你并不需要代码就可以开始分析。
攻击面映射
在触碰任何代码之前,我先绘制了所有 Solana 借贷协议共有的攻击面:
// Common lending protocol state structure
#[account]
pub struct LendingMarket {
pub authority: Pubkey,
pub token_mint: PubKey,
pub total_deposits: u64,
pub total_borrows: u64,
pub interest_rate: u64,
pub last_update_slot: u64,
// Oracle price feed – critical attack vector
pub oracle: Pubkey,
}
通过研究之前的 Solana 借贷漏洞(如 Mango、Solend 事件),我归纳出了以下几类漏洞:
- Oracle 操作 – 价格喂价能被夹击吗?
- 利率计算 – 定点数学中是否会出现精度损失?
- 清算逻辑 – 健康因子检查中是否存在竞争条件?
- 跨程序调用 – 通过 CPI 回调实现重入吗?
Jupiter 现有产品提供了其借贷设计的线索:
// Predicted account validation pattern based on Jupiter Perps
pub fn validate_position(ctx: Context) -> Result {
let position = &ctx.accounts.position;
let market = &ctx.accounts.market;
// Health factor check – where bugs often hide
let health = calculate_health_factor(
position.collateral_value,
position.borrow_value,
market.liquidation_threshold,
)?;
require!(health >= MINIMUM_HEALTH, ErrorCode::Unhealthy);
Ok(())
}
常见漏洞类别的利用模板
// Solana uses u64, precision loss is common
fn calculate_interest(principal: u64, rate: u64, time: u64) -> u64 {
// BUG: If rate * time overflows u64
// Upcast to u128 before multiplication
let result = principal
.checked_mul(rate).unwrap()
.checked_mul(time).unwrap()
.checked_div(PRECISION_FACTOR).unwrap();
result as u64
}
pub fn check_oracle_freshness(
oracle_price: &PriceAccount,
current_slot: u64,
max_staleness: u64,
) -> Result {
// CRITICAL: Many protocols forget this check
let price_slot = oracle_price.last_update_slot;
require!(
current_slot.saturating_sub(price_slot) <= max_staleness,
// (truncated in original)
);
Ok(())
}
- 攻击模式是通用的 – Oracle 问题、精度损失和竞争条件在每个借贷协议中都会出现。
- 可复用模板节省时间 – 我的模板库在 Jupiter Lend 上节省了超过 6 小时。
- 团队的编码风格会重复 – 研究同一团队的其他项目有助于预判设计选择。