過去一週(2026/03/30 - 2026/04/05),BlockSec 偵測並分析了九起攻擊事件,估計總損失約 $287M。下表彙整了這些事件,後續各小節則提供每起事件的詳細分析。
| 日期 | 事件 | 類型 | 估計損失 |
|---|---|---|---|
| 2026/03/30 | 未知協議事件 | 業務邏輯缺陷 | ~$10K |
| 2026/03/30 | WDGG 代幣事件 | 存取控制 | ~$40K |
| 2026/03/31 | i6Token 事件 | 業務邏輯缺陷 | ~$273.8K |
| 2026/04/01 | Drift Protocol 事件 | 網路釣魚攻擊 | ~$285.3M |
| 2026/04/01 | LML 質押協議事件 | 業務邏輯缺陷 | ~$950K |
| 2026/04/01 | Tactile 事件 | 價格操縱 | ~$12K |
| 2026/04/02 | SAS 代幣事件 | 業務邏輯缺陷 | ~$12K |
| 2026/04/03 | Unknown-EIP-7702 事件 | 存取控制 | ~$17.2K |
| 2026/04/03 | Silo Finance 事件 | 設定錯誤 | ~$359K |
Web3 最佳安全稽核服務
在上線前驗證設計、程式碼與業務邏輯
1. 未知協議事件
簡要摘要
2026 年 3 月 30 日,BNB Chain 上的一個未知協議因業務邏輯缺陷損失約 $10K。該協議將部分使用者存款用於購買其平台代幣 PSTART 並增加流動性,這意味著使用者實際上持有會受市場價格波動影響的 LP 部位。然而,提領時,協議並未根據當時 LP 實際可贖回的價值進行結算,而是繼續依照歷史存款額及預設規則,承諾支付固定數量的穩定幣。因此,攻擊者在透過強制投資投入資金後,能夠按預先承諾的固定價值提領,實際上將原本應由 LP 部位承擔的損失轉嫁給協議,最終實現零成本獲利。
背景
該協議的運作方式如下:使用者存入 BUSD 後,協議會自動使用部分資金購買 PSTART,再將其與剩餘的 BUSD 配對,投入流動性池。產生的 LP 份額由 Vault 保管,而協議則在內部帳本上為使用者記錄一筆承諾固定每日收益的訂單。
之後,使用者可以按固定利率領取獎勵;退出時,Vault 依照預設規則結算本金與收益,而非嚴格根據底層 LP 部位當前的實際淨資產價值贖回。
漏洞分析
此漏洞源自協議(0x587984...73a43c)不合理的設計:結算邏輯與底層資產的實際價值脫節。
使用者存入 BUSD 後,協議會使用部分資金購買 PSTART 並增加流動性,因此使用者實際持有的是價值隨市場價格波動的 LP 部位。然而,當使用者退出時,協議並未依據當時 LP 的實際可贖回價值結算,而是仍按歷史存款額及預設結算規則,承諾支付固定數量的穩定幣。
攻擊者利用此缺陷,透過閃電貸取得大量資金,隨後反覆執行 deposit()。這迫使協議持續購買 PSTART 並改變池內資產組成,從而人為推高 PSTART 價格,創造套利機會。
接著,攻擊者執行 withdraw(),按預先承諾的固定價值贖回資金,實際上將原本應由底層 LP 部位承擔的損失轉嫁給協議本身,最終實現零成本獲利。
攻擊分析
以下分析基於交易 0xf3b8...55e7。
-
步驟 1:攻擊者透過閃電貸取得約
2,000,000e18BUSD,並在池中將其兌換為19,013,120e18PSTART。 -
步驟 2:攻擊者反覆呼叫合約的
deposit()函式質押資金。每次存款時,協議都會計算應使用多少BUSD購買代幣,使最終用於增加流動性的代幣與BUSD比例更接近池內當前比例。透過反覆存款,攻擊者持續向池中注入BUSD,而PSTART的數量幾乎不變。因此,PSTART的價值持續上升。在此階段,攻擊者透過存款取得的LP實際上是以虧損方式取得的。 -
步驟 3:攻擊者隨後將步驟 1 購買的
PSTART賣回池中。由於步驟 2 增加了池中的BUSD儲備,這次兌換取得約2,010,655e18BUSD,在單次攻擊循環中獲利約10,655 BUSD。 -
步驟 4:最後,攻擊者對步驟 2 建立的所有質押部位執行
withdraw()。此時,這些部位對應資產的市場價值已遠低於初始存款價值。依照正常經濟邏輯,原本不應能夠全額贖回。然而,協議根據歷史存款額計算可贖回的BUSD數量,使攻擊者得以全額收回先前強制投資的成本,而無須承擔任何損失。

結論
此事件的根本原因在於,協議將使用者資金投入受市場價格波動影響的 LP 部位,卻仍承諾根據歷史存款價值及預設規則,以固定數量的 BUSD 結算。這造成協議的負債與其底層資產的實際價值脫節。
攻擊者利用此缺陷,反覆透過 deposit() 改變池內資產結構並推高 PSTART 價格,再透過外部部位完成套利,最後使用 withdraw() 按帳面價值贖回先前處於虧損狀態的部位。如此一來,原本應由這些部位自行承擔的損失被轉嫁給協議,最終實現無風險獲利。
2. WDGG 代幣事件
簡要摘要
2026 年 3 月 30 日,BNB Chain 上的 WDGG 代幣遭到攻擊,造成約 $40K 損失。根本原因是 burnFrom() 函式缺少存取控制。具體而言,burnFrom() 函式允許任意使用者銷毀任何地址持有的 WDGG 代幣。攻擊者藉此銷毀 PancakeSwap 池中的 WDGG 代幣,再呼叫 sync() 函式降低池中的 WDGG 儲備,隨後進行反向兌換以獲利。
背景
此事件涉及單一代幣 WDGG,這是一種每次轉帳都會收取手續費的分紅代幣。
漏洞分析
WDGG 代幣合約(0x512de7...6b90c5)對外開放 burnFrom(),卻未對呼叫者進行任何授權驗證。因此,任何地址都能銷毀任何持有者的 WDGG 代幣,包括 PancakeSwap 池本身。結合 PancakeSwap 任何人皆可呼叫的 sync()(用於使記錄的儲備量與實際餘額一致),此缺陷使池中的 WDGG 儲備量能在沒有任何正常交易的情況下被任意降低,並破壞恆定乘積不變量,讓池子暴露於價格失衡套利風險。

setWdgAddress() 中的另一項缺陷,允許任何呼叫者將任意地址設為免手續費地址,進一步提高了透過此攻擊面可取得的利潤。

攻擊分析
以下分析基於交易 0x2da5...0bd1。
- 步驟 1:攻擊者先呼叫
setWdgAddress(),將自己的地址設為免手續費地址,使後續轉帳得以避開代幣轉帳手續費。

-
步驟 2:攻擊者接著透過 PancakeSwap 池,將少量
BNB兌換為WDGG代幣。 -
步驟 3:取得
WDGG後,攻擊者呼叫burnFrom(),直接銷毀 PancakeSwap 交易對地址持有的WDGG代幣。 -
步驟 4:攻擊者隨後呼叫
sync(),迫使交易對更新儲備量,使其與遭操縱的代幣餘額一致。因此,池中的WDGG儲備量降至僅 1 wei。

- 步驟 5:在池內儲備量嚴重失衡後,攻擊者執行反向兌換,從價格失衡中獲利。

結論
此事件最終是由 WDGG 代幣合約的 burnFrom() 函式缺少存取控制所造成。因此,攻擊者得以直接銷毀 PancakeSwap 池中的代幣,透過 sync() 操縱池內儲備量,並利用由此產生的價格失衡獲利。
3. i6Token 事件
簡要摘要
2026 年 3 月 31 日,BNB Chain 上的 i6 代幣損失約 $273.8K,原因是 invest() 會改變池內即期價格,而 withdraw() 使用更新滯後的 TWAP 結算餘額,且兩者可在同一筆交易中組合執行。攻擊者透過 invest() 推高即期價格,再透過 withdraw() 按過時的 TWAP 贖回超額 i6,最後將 i6 賣回價格已被推高的池中獲利。
背景
該協議的運作方式如下。使用者呼叫 invest() 時,會存入 USDT,其中一部分用於在 PancakeSwap 購買 i6。取得的 i6 與剩餘的 USDT 隨後一起投入 USDT/i6 池作為流動性,產生的 LP 代幣則被銷毀。協議以 USDT 為單位記錄使用者與推薦人的餘額。
呼叫 withdraw() 時,協議會計算使用者以 USDT 計價的累積價值,再使用協議維護的 TWAP 價格(twapPrice)將其換算為 i6。
漏洞分析
協議合約(0x1cb36b...2a18a)的根本問題在於,invest() 在購買 i6 並增加流動性的過程中,會連帶改變 USDT/i6 池的即期價格;而 withdraw() 則使用協議維護、僅在一段時間過後才會更新的 TWAP(twapPrice),將累積的 USDT 計價餘額結算為 i6。合約中沒有任何機制阻止這兩個函式在同一筆交易中執行。
由於 invest() 可在同一筆交易中推高即期價格,而後續的 withdraw() 讀取的卻是尚未更新的 TWAP,因此兩者實際上以兩種不同價格看待同一池子狀態。透過 withdraw() 贖回的 USDT 計價餘額,會按過時且低得多的價格以 i6 支付,儘管此時每個 i6 已可在池中換得遠更多的 USDT。這一價差使協議上任何累積的 USDT 餘額,都成為內部結算價與池內即時價格之間可被利用的套利空間。
攻擊分析
以下分析基於交易 0xc1b9...2f16。
-
步驟 1:攻擊者先透過閃電貸取得
270,000 WBNB,再將其作為抵押品提供給 Venus,借入大量USDT。攻擊者也在0xda49部署攻擊合約 A,並在0x096a部署輔助合約 B。 -
步驟 2:攻擊合約執行第一次
invest()。在此過程中,協議先使用531,489e18USDT購買234,188e18i6,再將354,326e18USDT與72,607e18i6一同投入池中。因此,池內即期價格從約1.05159 USDT/i6迅速升至約4.89287 USDT/i6,而協議記錄的TWAP仍僅為1.05159。

-
步驟 3:攻擊者接著將
124,014,184e18USDT轉給輔助合約 B,由後者以referrer = A呼叫invest()。這一步再次迫使協議進行大規模USDT -> i6購買及addLiquidity(),將池內儲備推至對應即期價格約15,528 USDT/i6的新狀態。然而,由於尚未經過新的時間窗口,協議並未相應更新TWAP。 -
步驟 4:第二次
invest()完成後,作為推薦人的攻擊合約 A 立即取得以USDT計價的推薦獎勵的領取資格。攻擊者隨後呼叫withdraw()。協議使用過時的TWAP計算應支付的i6數量,並從自身餘額轉出代幣,總共支付5,896,508e18i6。 -
步驟 5:收到
i6後,攻擊者立即呼叫swapExactTokensForTokensSupportingFeeOnTransferTokens(),將全部5,896,508e18i6賣回池中,換取125,177,224e18USDT。由於這些i6是按約1.05159 USDT/i6的過時TWAP結算,卻在攻擊者已推高至約15,528 USDT/i6即期價格的池中賣出,因此攻擊者得以直接取得兩種價格之間的龐大價差。 -
步驟 6:償還閃電貸後,攻擊者留下
273,802e18USDT,即此次攻擊的實際利潤。
結論
根本原因在於,會影響即期價格的函式(invest())與以 TWAP 結算的函式(withdraw())可在單一交易中組合執行,使兩者對同一池子狀態採用不同價格。
為防止此類缺陷,結合 AMM 互動與延遲定價的協議,應避免在相關函式改變底層池即期價格的同一筆交易中,使用 TWAP 結算餘額;支付金額應以池中即時可實現的價值為基準,而非過時或推算出的價格。
4. Drift Protocol 事件
簡要摘要
2026 年 4 月 1 日(UTC),Solana 上的 Drift Protocol 遭到攻擊,損失約 $285.3M。根本原因不是智慧合約錯誤,而是多簽授權流程失效;採用 2-of-5 門檻且沒有時間鎖的安全委員會,以及 Solana 的持久 nonce 機制,更進一步放大了問題,使預先取得的多簽核准在攻擊者選擇執行前可無限期保持有效。經過數週部署,攻擊者誘導五名簽署人中的兩名,預先簽署綁定持久 nonce 帳戶的惡意治理交易,之後提交交易奪取管理員控制權,再引入偽造的抵押資產(CVT)、抬高其預言機價格、放寬提領限制,並透過 Drift Vault(JCNCMF...XJfrw)抽走真實資產。
背景
Drift Protocol 是 Solana 上支援保證金交易、借貸、現貨市場及衍生品的 DeFi 協議。其高權限操作,包括管理員變更、市場建立、預言機設定、風險參數更新及提領限額調整,均由 Squads 多簽框架治理,而非由單一私鑰控制。攻擊發生時,Drift 的安全委員會採用 2-of-5 門檻設定,且沒有時間鎖,意味著五名簽署人中任意兩人即可授權立即生效的管理操作。此系統的安全性不僅取決於簽署人私鑰的保管,也取決於整個核准流程的完整性:建立的是什麼交易、簽署人認為自己核准的是什麼,以及最終執行的指令是否與審核時的內容一致。
此外,Solana 的持久 nonce 帳戶以儲存在專用帳戶中的持久 nonce 取代短效區塊雜湊,使已簽署交易在 nonce 被推進前可無限期保持有效。此機制原本用於離線簽署及延遲提交等正當用途,卻也因簽署時間與鏈上執行時間可以分離,而引入關鍵攻擊手段。一旦簽署人核准持久 nonce 交易,除非 nonce 權限持有者手動推進該 nonce 帳戶,否則核准無法撤銷。
漏洞分析
根本原因並非智慧合約錯誤,而是 Drift 治理設定中的三項結構性弱點,共同使一次社交工程機會演變成 $285.3M 的資金流失。首先,持久 nonce 消除了簽章到期這道隱含的安全防線。在一般使用區塊雜湊的交易中,受騙簽署人的核准要麼迅速執行,要麼在短時間內無害地過期,從而限制協同利用的空間。持久 nonce 則消除了這項限制:兩名安全委員會簽署人一旦受誤導性簽署請求誘導,核准了惡意治理交易,其簽章便可無限期被利用,讓攻擊者完全掌控執行時機。
其次,管理操作沒有時間鎖,意味著預簽交易一經提交,管理員轉移便立即生效,沒有留下偵測或介入的時間窗口。第三,管理員角色的權限範圍廣泛,足以透過單一路徑建立新的抵押品市場、切換預言機來源及放寬提領限制;因此,只要成功接管治理權限,就能在無須進一步授權的情況下,將任意資產轉化為提取真實資金的工具。
攻擊分析
攻擊分為三個明確階段:攻擊前準備,攻擊者歷時數週製造虛假抵押資產,並透過誤導性簽署請求取得治理權限;治理接管,快速連續提交兩筆預簽的持久 nonce 交易,奪取管理控制權;以及資金提取,攻擊者操縱協議參數,透過協議的借貸路徑抽走真實資產。下圖呈現這三個階段的執行流程。
-
階段 1(攻擊前準備):從 3 月 11 日起,攻擊者從 Tornado Cash 提領 10
ETH,部署 CarbonVote Token(CVT)並鑄造 7.5 億枚,接著在 Raydium 提供流動性,透過對敲交易建立接近 $1 的虛假價格歷史。同時,截至 3 月 23 日,已有四個持久 nonce 帳戶建立,其中兩個與 Drift 安全委員會成員關聯,另兩個由攻擊者控制,顯示五名簽署人中至少已有兩人簽署與持久 nonce 帳戶綁定的交易。3 月 27 日,Drift 因成員變動執行預定的安全委員會遷移,使先前收集的簽章失效;然而,截至 3 月 30 日,攻擊者已在新設定下重新取得所需的門檻簽章,顯示其持續監控鏈上治理變動並即時調整。 -
階段 2(治理接管):4 月 1 日約 16:05 UTC,在 Drift 從保險基金執行一次合法測試提領約一分鐘後,攻擊者提交兩筆相隔四個 slot 的預簽持久 nonce 交易。第一筆交易(2HvMSg...2C4H)建立並核准惡意的管理員轉移提案。第二筆交易(4BKBmA...RsN1)核准並執行該提案:先以
AdvanceNonceAccount使用儲存的 nonce,接著執行proposalApprove與vaultTransactionExecute,最終呼叫UpdateAdmin,將管理控制權轉移至攻擊者控制的地址。 -
階段 3(資金提取):取得完整管理權限後,攻擊者為
CVT建立抵押品市場,切換至攻擊者控制的預言機以抬高其帳面價格,並提高或移除主要資產市場的提領限額。隨後,攻擊者將大量估值過高的CVT存入協議,並在約 12 分鐘內快速執行 31 次提領,抽走USDC、JLP、SOL、cbBTC、USDT、wETH、dSOL、WBTC、JTO及FARTCOIN,根據攻擊者的提領帳戶(HkGz4K...pZES)計算,總損失約 $285.3M。

結論
此事件的根本原因不是智慧合約漏洞或私鑰外洩,而是多簽授權流程失效,加上持久 nonce 支援延遲執行,以及沒有時間鎖的管理權限路徑。原本通常會在數分鐘內過期的預先收集核准,變得可無限期被利用;交易提交後,管理員接管與隨後的資金提取也沒有留下任何介入時間。
緩解此類風險,需要保護整個授權流程,而不只是保管簽署人私鑰;還應對高權限操作強制設定時間鎖,並將持久 nonce 等延遲執行機制視為獨立的威脅面,採用更高的簽署門檻、具時效或可撤銷的核准,以及限制簽署交易無限期有效的措施。
5. LML 質押協議事件
簡要摘要
2026 年 4 月 1 日,BNB Chain 上的 LML 質押協議遭到攻擊,損失約 $950K。根本原因是獎勵計算邏輯不一致:獎勵換算使用儲存的 LML/USDT 價格,而該價格受 3600 秒更新冷卻期限制;但支付的 LML 可按即時 AMM 價格兌換,兩者之間又沒有偏差檢查。攻擊者利用閃電貸推高池內即期價格,並透過 EIP-7702 程式碼委派,在單筆交易中為 11 個預先質押的 EOA 批次領取獎勵,按過時的儲存價格取得遠超應有數量的 LML,再透過價格已嚴重失衡的池子賣出獲利。
背景
LML 是 BNB Chain 上的質押協議,使用者透過 APower 合約質押 BNB,以賺取 LML 代幣獎勵。獎勵先以 USDT 計價,再依協議儲存的 LML/USDT 價格換算為 LML 數量後發放。儲存價格由 updatePrice() 更新,該函式讀取 AMM 即期價格,但兩次更新之間設有 3600 秒冷卻期。獎勵領取透過 APower 的 receive() 觸發,並以 msg.sender 為依據,因此只有原始質押地址才能領取自己的獎勵。
漏洞分析
質押合約(0xbe9713...adce19)的核心缺陷在於,獎勵累積與獎勵兌換分別依據同一池子的兩種不同價格,兩者之間卻沒有一致性檢查。獎勵公式 reward += (10^18 * base_reward) / stored_price 使用 _prices[] 計算 LML 支付數量;這是協議儲存的 LML/USDT 價格,只有經過 3600 秒冷卻期後才會由 updatePrice() 更新,但支付的 LML 可立即按即時 AMM 即期價格兌換。任何在冷卻期內推動即期價格的外部活動,都會使凍結的獎勵計算價格與即時賣出價格出現差距;即使差距變得不合理,合約也沒有機制拒絕領獎。



第二項結構性缺陷在於獎勵來源的補充方式。當 PROOF 合約的 LML 餘額不足以支付獎勵時,swapBack() 會呼叫 super._transfer(swapPair, PROOF, deficit),再呼叫 sync() 補足餘額:這直接從 LP 交易對的儲備中轉出 LML,並重新同步交易對記錄的狀態,而非透過一般兌換。由於此路徑繞過交易對的價格發現機制,每次觸發它的領獎都會減少交易對的 LML 儲備,並在沒有相應代幣流入的情況下進一步推動即期價格。因此,反覆領獎會機械性地擴大凍結儲存價格與即時賣出價格之間的差距。


攻擊分析
以下分析基於交易 0x805d...5b47、0x70f7...3572。
-
步驟 1:攻擊者透過 Moolah 的閃電貸、從 Venus 與 Moolah Pool 借款(以
WBNB作為抵押品),以及從 PancakeSwap V4、多個 V3 池及 V2 池取得閃電貸,籌集大量USDT與WBNB。這些資金用於操縱LML/USDT交易對價格。 -
步驟 2:攻擊者呼叫
LML代幣合約的swapAndTrans(),將合約累積的LML手續費兌換為USDT。這耗盡了LML合約自身的LML餘額,使其無法再作為就近的代幣來源;後續任何獎勵發放都必須透過swapBack()從 LP 交易對提取LML。

- 步驟 3:攻擊者透過 PancakeRouter 的
swapExactTokensForTokensSupportingFeeOnTransferTokens將USDT兌換為LML,並將接收地址設為銷毀地址。購得的LML代幣因此被銷毀,而非由攻擊者接收。此舉的唯一目的,是抽走交易對中的LML並推高 AMM 上的LML價格;攻擊者需要的是價格失衡,而不是代幣本身。

- 步驟 4:攻擊者先前已使用 11 個 EOA 地址存入質押協議。由於 APower 的
receive()依msg.sender觸發_claimReward(msg.sender),只有存款地址本身能領取獎勵。為了在單筆交易中替全部 11 個 EOA 領取獎勵,攻擊者使用 EIP-7702 為這些 EOA 設定程式碼,使攻擊者主合約能像呼叫合約一樣呼叫它們。每個 EOA 執行transfer(rst, fte)函式,向 APower 發送少量BNB,觸發receive()、_claimReward(EOA)。每次領獎時:updatePrice()被跳過(未滿 3600 秒冷卻期,因此stored_price維持歷史低價);updateUser()使用過時低價計算獎勵;sendMining()將LML從 PROOF 轉給 APower,接著觸發swapBack(),從 LP 交易對提取LML補充 PROOF 並呼叫sync(),進一步降低交易對儲備。最後,claimReward()將LML發給 EOA,各 EOA 再把收到的LML轉回攻擊合約。


-
步驟 5:攻擊者透過此時儲備已嚴重枯竭的池子,以極度膨脹的價格將累積的
LML兌換回USDT。 -
步驟 6:償還所有閃電貸、借款及費用,並轉出剩餘利潤。
結論
根本原因是質押合約中的獎勵累積與兌換不一致:支付數量依受 3600 秒冷卻期限制的儲存 LML/USDT 價格計算,卻以實際價值跟隨即時 AMM 價格的 LML 結算,且兩種價格之間沒有偏差檢查。swapBack() 的補充路徑在每次領獎時直接從 LP 交易對抽走 LML,進一步放大此缺陷;處理越多次領獎,凍結的儲存價格與即時賣出價格之間的差距就越大。
使用 AMM 衍生價格計算獎勵的質押協議,應在領獎時檢查儲存價格與當前即期價格的偏差,超過安全門檻時應回復交易;同時應避免在一般兌換路徑之外變動 LP 儲備的補充機制,因為此類機制會繞過原本可限制過時定價損害的價格發現過程。
6. Tactile 事件
簡要摘要
2026 年 4 月 1 日,Polygon 上的分級存款協議 Tactile 損失約 $12K。根本原因是其存款與提領結算邏輯不一致:存入與退出都按 CES 的當前即期價格換算,內部份額卻沒有記錄其最初鑄造時的資產價值。攻擊者藉此在存款前推高即期價格,以取得過多份額;再於提領前壓低價格,使每份額可贖回更多 CES,並透過輔助合約重複此循環以獲利。
背景
Tactile 是 Polygon 上的分級存款協議,使用者依選定的級別將 CES 存入支付合約。所需存款數量依 CES 的當前即期價格及級別設定計算,使用者則獲得代表其部位的內部記帳份額。提領時,記錄的份額會依退出時的即期價格換算回 CES,而非按最初存入的數量結算;因此,使用者餘額實際上是以受價格影響的記帳單位追蹤,而非固定資產數量。
漏洞分析
支付合約(0x9153e1...09b654)的核心缺陷在於,存款與提領在兩個不同時間點,依同一個即期價格預言機結算,卻沒有不可變的基準將兩者連結。存款時,合約讀取 getActualPrice(),依當前價格將存入的 CES 換算為內部份額;提領時,同一份額則依贖回當下的即期價格換算回 CES。
由於份額本身沒有記錄鑄造時的價格或資產數量,這兩個時間點之間的任何即期價格變動,都會直接造成存入與取出的 CES 數量不一致,使協議的記帳完全暴露於價格變動路徑,而非反映底層資產價值。

攻擊分析
以下分析基於交易 0xc321...da74。
- 步驟 1:攻擊者先從 Uniswap V3 閃電貸池借入
55,365e18CES,並將資金分配給 5 個輔助合約。每個輔助合約先收到6,426e18CES,再呼叫deposit(12)。在此過程中,每個輔助合約先查詢getPriceForLevel(12),再依當前價格準備此次存款所需的CES數量。


- 步驟 2:5 個輔助合約完成第一輪
deposit後,攻擊者在DEX上大量賣出300,000 CES,將bank使用的價格從1.067585壓低至0.688542。接著,5 個輔助合約逐一執行withdraw,把先前在高價時建立的份額,按此時較低的價格贖回為CES。每個輔助合約收到9,427e18CES。

-
步驟 3:完成第一輪
withdraw後,攻擊者將取得的交易對手資產換回CES,再次推高價格。接著,攻擊者重複步驟 2–3。 -
步驟 4:最後,經過多輪攻擊,並償還閃電貸及
166.097975017841805126 CES的閃電貸費用後,攻擊者留下567,736e18CES作為利潤。
結論
此事件的根本原因在於,Tactile 對存款與提領均依可操縱的即期價格結算,卻沒有將記帳份額錨定於存款時的資產數量或價格,使內部記帳完全暴露於進出之間的任何價格變動。
針對波動性資產發行類份額部位的協議,應將每份份額錨定於鑄造時的具體資產數量或價格,使贖回反映原始經濟價值,而非按即時預言機重新定價。若結算函式必須參考當前價格,應採用時間加權或其他抗操縱的價格來源,避免讀取可被同一筆交易中執行的交易所推動的即期價格。
7. SAS 代幣事件
簡要摘要
2026 年 4 月 2 日,BNB Chain 上的 SAS 代幣遭到攻擊,損失約 $12K。根本原因是代幣自訂轉帳邏輯中的缺陷:向 LP 池發送 SAS 只會增加全域 sellBurn 計數器,而之後任何一般轉帳都能直接從池中銷毀 SAS,並呼叫 sync() 重寫儲備量,全程無須經過 AMM 的兌換邏輯。攻擊者利用賣出操作累積 sellBurn,再觸發一筆無關的一般轉帳,從池中銷毀 SAS,將其儲備量降至 1 wei,最後將剩餘 SAS 反向兌換以獲利。
背景
SAS 是 BNB Chain 上的一種通縮代幣,在 PancakeSwap V2 池之上建有自訂轉帳邏輯。其 transfer() 函式區分兩種路徑:當轉帳目標為 LP 池時觸發的賣出路徑,會依轉帳數量增加全域 sellBurn 累加值;以及一般轉帳路徑,當 sellBurn 非零時,會直接從 LP 池銷毀 SAS,再呼叫 sync(),使儲備量與新的鏈上餘額一致。這兩條路徑原本意圖共同構成通縮機制,依累積賣壓降低池中的 SAS 儲備量。
漏洞分析
SAS 代幣合約(0xbfa266...3d91c6)的核心缺陷在於通縮機制與 transfer() 的連結方式。當 SAS 被發送至 LP 池時,合約會依轉帳數量增加全域 sellBurn 累加值。之後,只要發生任何一般轉帳,且 sellBurn 非零,合約便呼叫 _burnFromPair(),直接從 LP 池銷毀 SAS,隨後呼叫 sync(),將池內儲備量重寫為與鏈上餘額一致。
問題在於,這條銷毀並同步的路徑無須經過 AMM 的兌換邏輯,就能重寫池內儲備量。當轉入池中的代幣使 sellBurn 累積提高後,一筆無關的一般轉帳便足以觸發銷毀及同步,迫使池中的 SAS 儲備量趨近於零,造成巨大的價格失衡,再透過一般兌換將其轉化為利潤。



攻擊分析
以下分析基於交易 0x878e...adc5。
-
步驟 1:攻擊者透過閃電貸借入
WBNB。 -
步驟 2:攻擊者將
WBNB兌換為SAS。
-
步驟 3:攻擊者部署一個合約,並在
constructor()中執行攻擊邏輯。這用於繞過協議的is_contract()檢查,因為代幣合約要求transfer()的發送方必須是白名單地址或 EOA。


- 步驟 4:攻擊者將
SAS轉入池中,觸發賣出路徑並累積sellBurn。

- 步驟 5:攻擊者部署第二個合約,再次於其
constructor()中發起一般轉帳。由於步驟 4 已使sellBurn非零,這筆轉帳觸發_burnFromPair()函式,直接從 LP 池銷毀SAS,接著呼叫sync()函式,將SAS儲備量降至 1 wei。

- 步驟 6:攻擊者進行反向兌換,賣出剩餘的
SAS以獲利。
結論
此事件的根本原因是 SAS 代幣的自訂轉帳邏輯存在缺陷:一筆一般轉帳就能直接銷毀 LP 池中的 SAS,並將儲備量同步至降低後的餘額,使累積賣出活動得以轉化為池內 SAS 儲備量的任意減少,進而造成可透過一般兌換獲利的巨大價格失衡。
代幣不應在一般兌換路徑之外直接介入外部 AMM 池並改變其儲備量。若通縮設計確實需要從池中銷毀代幣,銷毀及相應的 sync() 必須綁定於嚴格控制的內部觸發條件,例如受信任的維護者或設有頻率限制的排程,而非附著於任意使用者轉帳。
8. Unknown-EIP-7702 事件
簡要摘要
2026 年 4 月 3 日,BNB Chain 上一個透過 EIP-7702 啟用委派程式碼的使用者帳戶遭抽走約 $17.2K。該委派程式碼公開了缺少適當存取控制的 pancakeV3SwapCallback() 函式。攻擊者以特製的呼叫資料直接呼叫此回呼,迫使受害者帳戶將代幣轉至攻擊者控制的地址。
背景
受害者 EOA 使用 EIP-7702 Type-4 交易設定委派程式碼,使帳戶能執行與兌換相關的邏輯。然而,委派實作中包含一個公開的 pancakeV3SwapCallback() 函式,原本應僅在合法的 PancakeSwap V3 池回呼期間被呼叫。
漏洞分析
根本原因是委派合約(0x02C809...aEDbAE)的 pancakeV3SwapCallback() 函式缺少存取控制。
正確的 UniswapV3/PancakeV3 回呼設計,必須驗證 msg.sender 是預期的標準池地址(由工廠合約、代幣交易對及費率推導,或依可信任的池清單驗證)。此案例缺少這項驗證,因此任何外部呼叫者都能直接呼叫回呼函式。
由於回呼會從承載該程式碼的帳戶執行代幣轉帳,缺少 msg.sender 檢查意味著,任何帶有正值 amount0Delta/amount1Delta 的外部呼叫都會進入回呼中的支付路徑,並從受害者帳戶轉出代幣,而無須發生實際兌換。
攻擊分析
以下分析基於交易 0x5b2c...4261。
- 步驟 1:攻擊者以特製參數直接呼叫
pancakeV3SwapCallback(),觸發回呼轉帳邏輯,將受害者的代幣轉至攻擊者控制的地址。


結論
此事件是因為在 EIP-7702 帳戶上部署兌換回呼邏輯時,未對回呼進行嚴格驗證。由於 pancakeV3SwapCallback() 缺少存取控制,任何外部呼叫者都能呼叫該回呼,並在完全沒有合法兌換發生的情況下,將代幣從受害者帳戶轉出。
對於任何實作 V3 類型回呼的合約或 EIP-7702 委派程式碼,開發者必須在回呼進入任何轉帳邏輯前,驗證 msg.sender 是標準的 PancakeV3 池地址(由可信任的工廠合約、代幣交易對及費率等級推導)。
9. Silo Finance 事件
簡要摘要
2026 年 4 月 3 日,Arbitrum 上 Silo Finance 的 soUSDC 金庫遭到攻擊,損失約 $359K。根本原因是三項缺陷交互作用:不可變更的 wstUSR 預言機在該代幣市場價格已跌至約 0.12 後,仍將其定價為約 1.133;soUSDC 的供應上限機制只限制金庫自身存款,而不限制外部存款;以及 totalAssets() 的記帳缺陷,會計入外部記入的 bUSDC 份額,卻沒有鑄造對應的 soUSDC 份額。攻擊者以 receiver=soUSDC 將 USDC 直接存入上限為零的 wstUSR 市場,推高金庫份額價格,再以估值過高的 wstUSR 抵押品借回同一筆 USDC,並按膨脹後的估值贖回先前取得的 soUSDC 份額;不足的資金則從提領佇列中其他健康市場提取。
背景
Silo Finance 是 Arbitrum 上的風險隔離借貸協議。每個 Silo 市場都是雙邊借貸交易對(例如 wstUSR/USDC):借款人存入抵押品(wstUSR)並借入借貸資產(USDC),放款人則存入 USDC 賺取利息。放款人將 USDC 存入特定市場時,會收到該市場的存款份額代幣;借款人存入抵押品時,則會收到抵押品份額代幣(例如 bwstUSR-149)。
soUSDC 是建立在多個 Silo 市場之上的 SiloVault,用於彙集 USDC 借貸。使用者將 USDC 存入 soUSDC,並取得 soUSDC 份額。金庫再根據配置管理者設定的供應上限,將存入的 USDC 分配至核准的 Silo 市場,並自行持有其存入各市場取得的 bUSDC 份額。使用者贖回 soUSDC 份額時,金庫透過 totalAssets() 計算份額價值對應的 USDC 數量;此函式逐一遍歷提領佇列中的市場,加總金庫在各市場持有的 bUSDC 份額餘額。之後,金庫從底層市場提領 USDC 支付給贖回者。
wstUSR(封裝質押 USR)是 Resolv 發行的穩定幣 USR 的質押衍生資產。Resolv 遭到攻擊後,USR 脫鉤,stUSR 也失去錨定,wstUSR 的次級市場價格跌至約 0.12。然而,wstUSR 的 Chainlink 價格資訊僅追蹤 wstUSR/stUSR 兌換率(約 1.133),協議又隱含假設 1 stUSR = 1 USD,因此預言機持續將 wstUSR 定價為約 1.133,與實際市場價格相差約 10 倍。
漏洞分析
wstUSR/USDC 市場的預言機地址在 SiloConfig 中被硬編碼為不可變更,因此無法替換。預言機合約(0x836a1a...04425e)本身是 ChainlinkV3Oracle,其底層 Chainlink 價格資訊(描述:「wstUSR / stUSR Exchange Rate」)僅追蹤 wstUSR 對 stUSR 的封裝兌換比率(約 1.133),而非次級市場價格。協議隱含假設 1 stUSR = 1 USD,因此將 wstUSR 定價為約 1.133。USR 脫鉤後,stUSR 也失去錨定,wstUSR 在公開市場跌至約 0.12,但預言機仍回報約 1.133,造成約 10 倍的高估。


協議對此風險有部分認知:soUSDC 對 wstUSR 市場的供應上限被設為 0,意味著金庫不會主動將 USDC 分配至該市場。然而,這項上限僅約束金庫自身對外發出的 deposit() 呼叫。由於 wstUSR_Market.deposit() 接受任意 receiver 參數,任何人都能直接向 wstUSR 市場存入 USDC,並將產生的 bUSDC 份額記入 soUSDC 地址,完全繞過供應上限。
這構成核心攻擊路徑。當 bUSDC 份額透過此類外部存款進入 soUSDC 的餘額時,totalAssets() 會將其計入:它逐一遍歷提領佇列中的市場,讀取金庫實際持有的份額餘額,卻不檢查該部位是否由金庫主動建立。同時,由於從未觸發金庫自身的鑄造邏輯,這些外部記入的部位並不會產生新的 soUSDC 份額。結果是 totalAssets 增加、totalShares 不變,推高 soUSDC 份額價格。




攻擊分析
以下分析基於交易 0xf77a...f3e1。
攻擊者先在次級市場以每枚約 0.12 的價格購買 wstUSR。
-
步驟 1:從 Morpho 閃電貸借入約 4,236,352
USDC。僅有預言機錯誤定價還不足以完成攻擊——wstUSR市場的USDC流動性為零(cap=0,soUSDC從未存入該市場),因此即使抵押品估值過高,也沒有資金可借。閃電貸提供了後續存款及捐贈步驟所需的資金。 -
步驟 2:將
wstUSR作為抵押品存入wstUSR市場,並取得bwstUSR-149。這是為步驟 5 的借款做準備——預言機將 13,797 枚wstUSR估值為約 15,633(每枚 1.133),儘管攻擊者實際只支付約 1,656。

- 步驟 3:將約 4,222,007
USDC存入soUSDC金庫,取得soUSDC份額(約占總供應量的 91.5%)。金庫將這些USDC分配至現有健康市場(而非供應上限為零的wstUSR市場)。這些soUSDC份額是步驟 6 提取利潤的工具——攻擊者持有的份額越多,份額價格上漲時受益越大。

- 步驟 4:透過
wstUSR_Market.deposit(receiver=soUSDC),將約 14,344USDC直接存入wstUSR市場,並將bUSDC-149鑄造給soUSDC。產生的bUSDC份額被記入soUSDC地址,而非攻擊者地址。這是核心操縱手法:soUSDC的totalAssets()此時會按面值將這些bUSDC份額計入(約 14,344USDC),但因金庫自身的存款邏輯從未被呼叫,沒有新的soUSDC份額被鑄造——totalAssets上升、totalShares不變,推高soUSDC份額價格。同時,這也在先前空無流動性的wstUSR市場中建立了下一步所需的USDC流動性。

- 步驟 5:使用步驟 2 存入的抵押品,從
wstUSR市場借入約 14,344USDC。預言機將抵押品定價為約 15,633,因此以 92% 的 maxLTV 計算,攻擊者可借入約 14,344。這使步驟 4 捐贈的USDC回到攻擊者手中——借款與捐贈在現金上互相抵銷。但此時wstUSR市場已被完全抽空:所有USDC均已借出,只剩下一筆以近乎無價值的wstUSR抵押品支持的未償貸款。soUSDC的totalAssets()仍按面值計入其持有的bUSDC份額。

- 步驟 6:贖回步驟 3 取得的全部
soUSDC份額。由於份額價格已因步驟 4 的捐贈而上漲,攻擊者收到約 4,235,143USDC,比步驟 3 存入的 4,222,007 多約 13,136。金庫嘗試從wstUSR市場提領,卻發現其流動性為零(已在步驟 5 借出),因此轉而從提領佇列中的其他健康市場補足差額。損失就在此產生:其他soUSDC存款人所在市場的真實USDC被轉出,用於支付估值膨脹後的贖回款。



- 步驟 7:償還閃電貸。
經過 32 次循環後,soUSDC 留下了位於 wstUSR 市場、帳面價值約 359K 的 bUSDC 部位,但支持這些部位的 wstUSR 抵押品價值僅為其一小部分——市場利用率達 100%,成為實際上無法收回、由剩餘 soUSDC 存款人承擔的壞帳。
結論
此事件是三項問題交互作用所造成:預言機追蹤的是質押兌換率,而非已脫鉤資產的市場價格;金庫記帳系統將外部記入的部位計入 totalAssets(),卻不鑄造對應份額;供應上限機制僅限制金庫自身的存款,不限制外部存款。SiloConfig 中預言機地址不可變更,也使問題浮現後無法進行緊急修復。
跨借貸市場彙集資產的金庫協議,應確保 totalAssets() 只計入金庫透過自身存款操作建立的部位,而非外部記入的份額餘額。預言機地址不應永久不可變更;當底層資產脫鉤時,應有緊急治理機制更新價格資訊來源。
關於 BlockSec
BlockSec 是提供全方位區塊鏈安全與加密貨幣合規服務的業者。我們打造產品與服務,協助客戶在協議與平台的完整生命週期中,執行程式碼稽核(包括智慧合約、區塊鏈及錢包)、即時攔截攻擊、分析事件、追蹤非法資金,並履行反洗錢與打擊資恐(AML/CFT)義務。
BlockSec 已在知名研討會發表多篇區塊鏈安全論文,通報數起 DeFi 應用程式的零時差攻擊,阻擋多起駭客攻擊並挽救逾 2,000 萬美元資產,同時保護了價值數十億美元的加密貨幣。
-
官方 Twitter 帳號:https://twitter.com/BlockSecTeam
-
🔗 BlockSec 稽核服務 : 提交申請



