During the past week (2026/03/30 - 2026/04/05), BlockSec detected and analyzed nine attack incidents, with total estimated losses of ~$287M. The table below summarizes these incidents, and detailed analyses for each case are provided in the following subsections.
| Date | Incident | Type | Estimated Loss |
|---|---|---|---|
| 2026/03/30 | Unknown Protocol Incident | Flawed business logic | ~$10K |
| 2026/03/30 | WDGG Token Incident | Access control | ~$40K |
| 2026/03/31 | i6Token Incident | Flawed business logic | ~$273.8K |
| 2026/04/01 | Drift Protocol Incident | Phishing attack | ~$285.3M |
| 2026/04/01 | LML Staking Protocol Incident | Flawed business logic | ~$950K |
| 2026/04/01 | Tactile Incident | Price manipulation | ~$12K |
| 2026/04/02 | SAS Token Incident | Flawed business logic | ~$12K |
| 2026/04/03 | Unknown-EIP-7702 Incident | Access control | ~$17.2K |
| 2026/04/03 | Silo Finance Incident | Misconfiguration | ~$359K |
Best Security Auditor for Web3
Validate design, code, and business logic before launch
1. Unknown Protocol Incident
Brief Summary
On March 30, 2026, an unknown protocol on BNB Chain lost ~$10K due to flawed business logic. The protocol allocated part of user deposits to purchase its platform token PSTART and add liquidity, meaning users were effectively holding LP positions subject to market price fluctuations. However, upon withdrawal, the protocol did not settle based on the actual redeemable value of the LP at that time. Instead, it continued to promise a fixed amount of stablecoins based on the historical deposit and predefined rules. As a result, after committing capital through forced investment, the attacker was able to withdraw funds at a pre-agreed fixed value, effectively shifting losses that should have been borne by the LP position onto the protocol, ultimately achieving zero-cost profit.
Background
The protocol operates as follows: after a user deposits BUSD, the protocol automatically uses a portion of the funds to purchase PSTART, and then pairs it with the remaining BUSD to add liquidity into the pool. The resulting LP shares are then held in custody by the Vault, while the protocol records, on its internal ledger, an order for the user that promises a fixed daily yield.
Afterward, the user can claim rewards at a fixed interest rate, and when exiting, the Vault settles the principal and yield according to predefined rules, rather than redeeming strictly based on the current real net asset value of the underlying LP position.
Vulnerability Analysis
This vulnerability stems from an unreasonable protocol (0x587984...73a43c) design: the settlement logic is detached from the actual value of the underlying assets.
After a user deposits BUSD, the protocol uses part of it to buy PSTART and add liquidity, meaning the user's actual underlying position is an LP exposure whose value fluctuates with market prices. However, when the user exits, the protocol does not settle based on the LP's actual redeemable value at that time. Instead, it still promises to pay a fixed amount of stablecoins according to the historical deposit amount and predefined settlement rules.
The attacker exploited this flaw by using a flash loan to obtain a large amount of capital and then repeatedly executing deposit(). In doing so, the attacker forced the protocol to continuously buy PSTART and alter the asset composition of the pool, thereby artificially pushing up the PSTART price and creating an arbitrage opportunity.
The attacker then executed withdraw() and redeemed funds at the pre-promised fixed value, effectively transferring losses that should have been borne by the underlying LP position to the protocol itself, ultimately achieving zero-cost profit.
Attack Analysis
The following analysis is based on the transaction 0xf3b8...55e7.
-
Step 1: The attacker obtained approximately
2,000,000e18BUSDthrough a flash loan and swapped it in the pool for19,013,120e18PSTART. -
Step 2: The attacker repeatedly called the contract's
deposit()function to stake funds. For each deposit, the protocol calculated how muchBUSDshould be used to buy tokens so that the final token-to-BUSDratio used for adding liquidity would more closely match the pool's current ratio. By repeatedly depositing, the attacker continuously injectedBUSDinto the pool, while the amount ofPSTARTremained almost unchanged. As a result, the value ofPSTARTkept rising. At this stage, theLPobtained through the attacker's deposits was actually being acquired at a loss. -
Step 3: The attacker then sold the
PSTARTpurchased in Step 1 back into the pool. Because Step 2 had increased the pool'sBUSDreserves, this swap returned approximately2,010,655e18BUSD, generating a profit of about10,655 BUSDin a single attack cycle. -
Step 4: Finally, the attacker executed
withdraw()on all staking positions opened in Step 2. At this point, the market value of the assets corresponding to these positions was already far below their initial deposit value. Under normal economic logic, full redemption should not have been possible. However, the protocol calculated the redeemableBUSDamount based on the historical deposit amount, allowing the attacker to fully recover all previously forced investment costs without bearing any loss.

Conclusion
The root cause of this incident is that the protocol invested user funds into LP positions subject to market price fluctuations, yet still promised settlement in a fixed amount of BUSD based on historical deposit values and predefined rules. This created a disconnect between the protocol's liabilities and the real value of its underlying assets.
The attacker exploited this flaw by repeatedly using deposit() to alter the pool's asset structure and push up the price of PSTART, then completed arbitrage through an external position, and finally used withdraw() to redeem the previously loss-making positions at book value. In this way, losses that should have been borne by the positions themselves were shifted onto the protocol, ultimately enabling risk-free profit.
2. WDGG Token Incident
Brief Summary
On March 30, 2026, the WDGG token on BNB Chain was exploited, resulting in approximately $40K in losses. The root cause was missing access control in the function burnFrom(). Specifically, function burnFrom() allowed arbitrary users to burn WDGG tokens from any address. The attacker exploited this by burning WDGG tokens from the PancakeSwap pool, then invoking function sync() to reduce the pool's WDGG reserves, and subsequently performing a reverse swap to extract profit.
Background
This incident involves a single token, WDGG, which is a dividend-distributing token that charges a fee on each transfer.
Vulnerability Analysis
The WDGG token contract (0x512de7...6b90c5) exposed burnFrom() without any caller authorization. As a result, any address could burn WDGG tokens from any holder, including the PancakeSwap pool itself. Paired with PancakeSwap's publicly callable sync(), which realigns recorded reserves with actual balances, this flaw let the pool's WDGG reserve be arbitrarily reduced and the constant-product invariant broken without any legitimate trade, exposing the pool to price-imbalance arbitrage.

A secondary flaw in setWdgAddress() allowed any caller to mark an arbitrary address as fee-exempt, further maximizing the profit extractable through this attack surface.

Attack Analysis
The following analysis is based on the transaction 0x2da5...0bd1.
- Step 1: The attacker first called
setWdgAddress()to set their own address as fee-exempt, allowing subsequent transfers to bypass the token's transfer fee.

-
Step 2: The attacker then swapped a small amount of
BNBforWDGGtokens through the PancakeSwap pool. -
Step 3: After obtaining
WDGG, the attacker invokedburnFrom()to burnWDGGtokens directly from the PancakeSwap pair address. -
Step 4: The attacker subsequently called
sync(), forcing the pair to update its reserves to match the manipulated token balances. As a result, theWDGGreserve in the pool was reduced to only 1 wei.

- Step 5: With the pool reserves severely distorted, the attacker executed a reverse swap and extracted profit from the price imbalance.

Conclusion
This incident was ultimately caused by missing access control in the function burnFrom() of the WDGG token contract. As a result, an attacker was able to burn tokens directly from the PancakeSwap pool, manipulate the pool's reserves via sync(), and exploit the resulting price imbalance for profit.
3. i6Token Incident
Brief Summary
On March 31, 2026, the i6 Token on BNB Chain lost ~$273.8K because invest() moved the pool's spot price while withdraw() settled balances via a lagging TWAP, and the two could be composed in the same transaction. The attacker inflated the spot price via invest(), redeemed excess i6 at the stale TWAP through withdraw(), and sold the i6 back into the inflated pool for profit.
Background
The protocol operates as follows. When a user calls invest(), USDT is deposited and partially used to purchase i6 on PancakeSwap. The acquired i6, together with the remaining USDT, is then added as liquidity to the USDT/i6 pool, and the resulting LP tokens are burned. The protocol records user and referral balances denominated in USDT.
When withdraw() is called, the protocol calculates the user's accumulated value in USDT terms and converts it into i6 using a protocol-maintained TWAP price (twapPrice).
Vulnerability Analysis
The root cause in the protocol contract (0x1cb36b...2a18a) is that invest() mutates the USDT/i6 pool's spot price as a side effect of purchasing i6 and adding liquidity, while withdraw() settles accumulated USDT-denominated balances into i6 using a protocol-maintained TWAP (twapPrice) that only updates after a time window elapses. Nothing in the contract prevents these two functions from running in the same transaction.
Because an invest() call can inflate the spot price within the same transaction that a subsequent withdraw() reads a not-yet-updated TWAP, the two effectively see two different prices for the same pool state. A USDT-denominated balance redeemed through withdraw() is then paid out in i6 at the stale, much lower price, even though each i6 is now realizable for far more USDT in the pool itself. This gap turns any accumulated USDT balance on the protocol into an exploitable spread between internal settlement and the live pool.
Attack Analysis
The following analysis is based on the transaction 0xc1b9...2f16.
-
Step 1: The attacker first obtained
270,000 WBNBthrough a flash loan, then supplied it to Venus as collateral and borrowed a large amount ofUSDT. The attacker also deployed attack contract A at0xda49and helper contract B at0x096a. -
Step 2: The attack contract executed the first
invest(). During this process, the protocol first used531,489e18USDTto purchase234,188e18i6, and then added354,326e18USDTtogether with72,607e18i6into the pool. As a result, the pool spot price rapidly increased from about1.05159 USDT/i6to about4.89287 USDT/i6, while the protocol's recordedTWAPstill remained at only1.05159.

-
Step 3: The attacker then transferred
124,014,184e18USDTto helper contract B, which in turn calledinvest()withreferrer = A. This step once again forced the protocol to perform a massiveUSDT -> i6purchase andaddLiquidity(), pushing the pool reserves to a new state corresponding to a spot price of approximately15,528 USDT/i6. However, because no new time window had elapsed, the protocol did not update theTWAPaccordingly. -
Step 4: After the second
invest()was completed, attack contract A, acting as the referrer, immediately became entitled to a referral reward denominated inUSDT. The attacker then calledwithdraw(). The protocol used the staleTWAPto calculate the amount ofi6to be paid and transferred the tokens out of its own balance, resulting in a total payout of5,896,508e18i6. -
Step 5: After receiving the
i6, the attacker immediately calledswapExactTokensForTokensSupportingFeeOnTransferTokens()to sell all5,896,508e18i6back into the pool in exchange for125,177,224e18USDT. Because thesei6tokens had been settled using the staleTWAPof about1.05159 USDT/i6, while they were sold against a pool spot price that had been pushed up by the attacker to around15,528 USDT/i6, the attacker was able to directly realize the enormous spread between the two prices. -
Step 6: After repaying the flash loan, the attacker retained
273,802e18USDT, which was the actual profit from the attack.
Conclusion
The root cause is that a spot-price-impacting function (invest()) and a TWAP-settled function (withdraw()) could be composed within a single transaction, letting the two see different prices for the same pool state.
To prevent this class of flaw, protocols combining AMM interactions with delayed pricing should avoid settling balances at a TWAP in the same transaction that a companion function moves the underlying pool's spot price, and should instead anchor payouts to the pool's live realizable value rather than a stale or derived price.
4. Drift Protocol Incident
Brief Summary
On April 1, 2026 (UTC), Drift Protocol on Solana was compromised for approximately $285.3M. The root cause was not a smart contract bug but a breakdown in the multisig authorization process, compounded by a 2-of-5 Security Council with zero timelock and Solana's durable nonce mechanism, which let pre-collected multisig approvals remain valid indefinitely until the attacker chose to execute them. After weeks of staging, the attacker induced two of five signers to pre-sign malicious governance transactions bound to durable nonce accounts, later submitted them to seize admin control, and then introduced a fabricated collateral asset (CVT), inflated its oracle price, relaxed withdrawal limits, and drained real assets through the Drift Vault (JCNCMF...XJfrw).
Background
Drift Protocol is a DeFi protocol on Solana supporting margin trading, lending, spot markets, and derivatives. Its high-privilege operations, including admin changes, market creation, oracle configuration, risk parameter updates, and withdrawal limit adjustments, are governed by the Squads multisig framework rather than a single private key. At the time of the attack, Drift's Security Council operated under a 2-of-5 threshold configuration with zero timelock, meaning any two of five signers could authorize administrative actions with immediate effect. The security of this system depends not only on signer key custody, but also on the integrity of the full approval pipeline: what transaction was created, what signers believed they were approving, and whether the final executed instructions matched that review context.
Separately, Solana's durable nonce accounts replace the short-lived blockhash with a persistent nonce stored in a dedicated account, allowing a signed transaction to remain valid indefinitely until the nonce is advanced. This mechanism is designed for legitimate use cases such as offline signing and delayed submission, but it introduces a critical attack primitive by decoupling when a transaction is signed from when it is executed on-chain. Once a signer approves a durable nonce transaction, the approval cannot be revoked unless the nonce authority manually advances the nonce account.
Vulnerability Analysis
The root cause is not a smart contract bug but three structural weaknesses in Drift's governance configuration that together turned a social engineering opportunity into a $285.3M drain. First, durable nonces removed the implicit signature-expiry safety net. Under normal blockhash-based transactions, a tricked signer's approval either gets executed promptly or expires harmlessly within a narrow window, limiting the scope for coordinated exploitation. Durable nonces dissolve this constraint: once two Security Council signers were induced to approve malicious governance transactions through misleading signing requests, their signatures remained exploitable indefinitely, giving the attacker complete control over execution timing.
Second, the zero timelock on administrative actions meant that once the pre-signed transactions were submitted, the admin transfer took effect immediately, leaving no detection or intervention window. Third, the admin role's scope was broad enough to create new collateral markets, switch oracle sources, and relax withdrawal limits in a single privileged pathway, so a single successful governance takeover was sufficient to convert an arbitrary asset into real fund extraction without any further authorization barrier.
Attack Analysis
The attack unfolded in three distinct phases: Pre-Attack Staging, in which the attacker ran a multi-week operation to manufacture a fake collateral asset and obtain governance access through misleading signing requests; Governance Takeover, in which two pre-signed durable nonce transactions were submitted in rapid succession to seize administrative control; and Fund Extraction, in which the attacker manipulated protocol parameters and drained real assets through the protocol's lending pathways. The diagram below illustrates the execution flow across these three phases.
-
Phase 1 (Pre-Attack Staging): Beginning March 11, the attacker withdrew 10
ETHfrom Tornado Cash and deployed CarbonVote Token (CVT), minting 750 million units, then seeded liquidity on Raydium and used wash trading to build an artificial price history near $1. In parallel, by March 23 four durable nonce accounts were created, two linked to Drift Security Council members and two controlled by the attacker, indicating that at least two of five signers had already signed transactions tied to durable nonce accounts. On March 27, Drift executed a planned Security Council migration due to a member change, invalidating the previously collected signatures; however, by March 30 the attacker had re-obtained the required threshold under the new configuration, showing active monitoring of on-chain governance changes and real-time adaptation. -
Phase 2 (Governance Takeover): On April 1 at approximately 16:05 UTC, about one minute after Drift performed a legitimate test withdrawal from the insurance fund, the attacker submitted two pre-signed durable nonce transactions four slots apart. The first transaction (2HvMSg...2C4H) created and approved the malicious admin transfer proposal. The second transaction (4BKBmA...RsN1) approved and executed it, beginning with
AdvanceNonceAccountto activate the stored nonce, proceeding throughproposalApproveandvaultTransactionExecute, and ultimately invokingUpdateAdminto transfer administrative control to an attacker-controlled address. -
Phase 3 (Fund Extraction): With full admin privileges, the attacker created a collateral market for
CVT, switched to an attacker-controlled oracle to inflate its book price, and raised or removed withdrawal limits on major asset markets. The attacker then deposited a large amount of overvaluedCVTinto the protocol and executed 31 rapid withdrawals over approximately 12 minutes, drainingUSDC,JLP,SOL,cbBTC,USDT,wETH,dSOL,WBTC,JTO, andFARTCOINfor a total loss of approximately $285.3M, calculated based on the attacker's withdrawal account (HkGz4K...pZES).

Conclusion
The root cause of this incident is not a smart contract vulnerability or a key compromise, but a breakdown in the multisig authorization process combined with durable nonce-based delayed execution and a zero-timelock administrative pathway. Pre-collected approvals that would normally have expired within minutes remained indefinitely exploitable, and once submitted, the admin takeover and subsequent fund extraction left no intervention window.
Mitigating this class of risk requires securing the full authorization pipeline rather than just signer key custody, enforcing timelocks on high-privilege operations, and treating delayed execution mechanisms such as durable nonces as a distinct threat surface that demands higher signature thresholds, time-bound or revocable approvals, and restrictions against indefinitely valid signed transactions.
5. LML Staking Protocol Incident
Brief Summary
On April 1, 2026, the LML staking protocol on BNB Chain was exploited for approximately $950K. The root cause was an inconsistency in the reward calculation logic: the reward conversion read a stored LML/USDT price locked behind a 3600-second update cooldown, while the paid-out LML was redeemable at the live AMM price, with no deviation check between the two. The attacker used flash loans to inflate the pool spot price and EIP-7702 code delegation to batch-claim rewards for 11 pre-staked EOAs in a single transaction, receiving an outsized amount of LML at the stale stored price and selling it back through the now severely distorted pool for profit.
Background
LML is a staking protocol on BNB Chain where users stake BNB via the APower contract to earn LML tokens as rewards. Rewards are computed in USDT terms and then converted to LML amounts based on a protocol-stored LML/USDT price before distribution. The stored price is refreshed by updatePrice(), which reads the AMM spot price but enforces a 3600-second cooldown between updates. Reward claims are triggered through APower's receive() based on msg.sender, so only the original staking address can claim its own rewards.
Vulnerability Analysis
The core flaw in the staking contract (0xbe9713...adce19) is that reward accrual and reward redemption are anchored to two different prices of the same pool with no consistency check between them. The reward formula reward += (10^18 * base_reward) / stored_price computes the LML payout from _prices[], a protocol-stored LML/USDT price that is only refreshed by updatePrice() after a 3600-second cooldown, yet the paid-out LML is immediately redeemable at the live AMM spot price. Any external activity that moves the spot price within this cooldown window opens a gap between a frozen accrual price and a live sell price, and nothing in the contract rejects a claim when that gap becomes unreasonable.



A second structural flaw is in how the reward source is replenished. When the PROOF contract's LML balance is insufficient to pay out a claim, swapBack() refills it by calling super._transfer(swapPair, PROOF, deficit) followed by sync(), directly moving LML out of the LP pair's reserves and realigning the pair's stored state rather than going through a normal swap. Because this path bypasses the pair's price discovery, every claim that triggers it reduces the pair's LML reserves and further shifts the spot price without any offsetting token inflow, so repeated claims mechanically widen the gap between the frozen stored price and the live sell price.


Attack Analysis
The following analysis is based on the transactions 0x805d...5b47, 0x70f7...3572.
-
Step 1: The attacker aggregated a large amount of
USDTandWBNBthrough flash loans from Moolah, borrowing from Venus and Moolah Pool (usingWBNBas collateral), and flash loans from PancakeSwap V4, multiple V3 pools, and V2 pools. This capital was needed to manipulate theLML/USDTpair price. -
Step 2: The attacker called
swapAndTrans()on theLMLtoken contract, which swapped theLMLfees accumulated in the contract toUSDT. This drained theLMLcontract's ownLMLbalance, meaning it could no longer serve as a local token source, any subsequent reward distribution would need to pullLMLfrom the LP pair viaswapBack().

- Step 3: The attacker swapped
USDTforLMLvia PancakeRouterswapExactTokensForTokensSupportingFeeOnTransferTokens, with the recipient set to the dead address. The purchasedLMLtokens were burned rather than received by the attacker. The sole purpose was to drainLMLfrom the pair and inflate theLMLprice on the AMM, the attacker did not need the tokens themselves, only the price distortion.

- Step 4: The attacker had previously deposited into the staking protocol using 11 EOA addresses. Since APower's
receive()triggers_claimReward(msg.sender)based onmsg.sender, rewards can only be claimed by the depositing address itself. To claim rewards for all 11 EOAs within a single transaction, the attacker used EIP-7702 to set code on these EOAs, enabling them to be called as contracts by the attacker's main contract. Each EOA executed atransfer(rst, fte)function that sent a small amount ofBNBto APower, triggeringreceive(),_claimReward(EOA). Inside each claim:updatePrice()was skipped (3600s cooldown not met, sostored_priceremained at the historical low value),updateUser()calculated the reward using the stale low price,sendMining()transferredLMLfrom PROOF to APower and then triggeredswapBack()which replenished PROOF by pullingLMLfrom the LP pair and callingsync(), further reducing the pair's reserves. FinallyclaimReward()distributedLMLto the EOA, and each EOA transferred its receivedLMLback to the attacker contract.


-
Step 5: The attacker swapped the accumulated
LMLback toUSDTthrough the now severely drained pool at the extremely inflated price. -
Step 6: Repaid all flash loans, borrowings, and fees. Transferred the remaining profit.
Conclusion
The root cause is a mismatch between reward accrual and redemption in the staking contract: payouts are sized from a stored LML/USDT price locked behind a 3600-second cooldown, but settled in LML whose real value tracks the live AMM price, with no deviation check linking the two. The swapBack() refill path amplifies this flaw by draining LML directly from the LP pair on each claim, mechanically widening the gap between the frozen stored price and the live sell price the more claims are processed.
Staking protocols that size rewards from AMM-derived prices should enforce a deviation check between the stored price and the current spot price at claim time and revert when the gap exceeds a safe threshold, and should avoid refill mechanisms that mutate LP reserves outside of normal swap paths, since such mechanisms bypass the price discovery that would otherwise cap the damage from stale pricing.
6. Tactile Incident
Brief Summary
On April 1, 2026, Tactile, a tiered deposit protocol on Polygon, suffered a ~$12K loss. The root cause was an inconsistency in its deposit and withdrawal settlement logic: both entry and exit were converted against the current spot price of CES, and the internal share carried no record of the asset value at which it was originally minted. The attacker exploited this by inflating the spot price before depositing to obtain oversized shares, then depressing the price before withdrawing to redeem more CES per share, repeating the cycle across helper contracts to extract profit.
Background
Tactile is a tiered deposit protocol on Polygon where users deposit CES into a payment contract according to a selected tier. The required deposit amount is computed from the current spot price of CES and the tier configuration, and the user is credited with an internal accounting share representing their position. On withdrawal, the recorded share is converted back into CES using the spot price at the time of exit rather than settling against the originally deposited amount, so user balances are effectively tracked as price-dependent accounting units rather than fixed asset amounts.
Vulnerability Analysis
The core flaw in the payment contract (0x9153e1...09b654) is that deposit and withdrawal are settled against the same spot price oracle at two different moments with no immutable anchor linking them. At deposit time, the contract reads getActualPrice() and converts the deposited CES into an internal share based on the current price; at withdrawal time, the same share is converted back into CES using the spot price at the moment of redemption.
Because the share itself carries no record of the price or asset amount at which it was minted, any movement of the spot price between these two moments translates directly into a mismatch between CES paid in and CES paid out, making the protocol's accounting fully exposed to the price path rather than to the underlying asset value.

Attack Analysis
The following analysis is based on the transaction 0xc321...da74.
- Step 1: The attacker first borrowed
55,365e18CESfrom a Uniswap V3 flash pool and distributed the funds to 5 helper contracts. Each helper first received6,426e18CES, and then calleddeposit(12). During this process, each helper first queriedgetPriceForLevel(12)and then prepared the amount ofCESrequired for this deposit based on the current price.


- Step 2: After all 5 helpers completed the first round of
deposit, the attacker dumped300,000 CESon theDEX, pushing the price used by thebankdown from1.067585to0.688542. The 5 helpers then executedwithdrawone by one, redeeming the shares created earlier at the high price intoCESat the now lower price. Each helper received9,427e18CES.

-
Step 3: After completing the first round of
withdraw, the attacker swapped the acquired counterparty asset back intoCES, pushing the price back up again. The attacker then repeated Steps 2-3. -
Step 4: Finally, after multiple attack cycles, and after repaying the flash loan plus the flash fee of
166.097975017841805126 CES, the attacker was left with567,736e18CESas profit.
Conclusion
The root cause of this incident is that Tactile settled both deposit and withdrawal against a manipulable spot price without anchoring the accounting share to the asset amount or price at the time of deposit, leaving its internal accounting fully exposed to any price movement between entry and exit.
Protocols that issue share-like positions against a volatile asset should anchor each share to the concrete asset amount or price at the time of minting, so that redemption reproduces the original economic value rather than re-pricing against a live oracle. Where settlement functions must reference a current price, they should use time-weighted or otherwise manipulation-resistant sources and avoid reading the same spot price that can be moved by trades executed in the same transaction as the settlement call.
7. SAS Token Incident
Brief Summary
On April 2, 2026, the SAS token on BNB Chain was exploited for ~$12K. The root cause was a flaw in the token's custom transfer logic: sending SAS to the LP pool only incremented a global sellBurn counter, and any subsequent ordinary transfer could then burn SAS directly from the pool and call sync() to rewrite its reserves, all without going through the AMM's swap logic. The attacker exploited this by accumulating sellBurn through sells, triggering an unrelated ordinary transfer to burn SAS from the pool and push its reserve down to 1 wei, and then reverse-swapping the remaining SAS for profit.
Background
SAS is a deflationary token on BNB Chain with custom transfer logic built on top of a PancakeSwap V2 pool. Its transfer() function distinguishes between two paths: a sell path, triggered when the destination of a transfer is the LP pool, which increments a global sellBurn accumulator by the transferred amount; and an ordinary transfer path, which, when sellBurn is non-zero, burns SAS directly from the LP pool and then calls sync() to update its reserves to the new on-chain balance. The two paths are meant to work together as a deflationary mechanic that reduces the pool's SAS reserve in response to cumulative sell pressure.
Vulnerability Analysis
The core flaw in the SAS token contract (0xbfa266...3d91c6) is in how the deflationary mechanism is wired into transfer(). When SAS is sent to the LP pool, the contract increments a global sellBurn accumulator by the transferred amount. Then, on any later ordinary transfer, if sellBurn is non-zero, the contract calls _burnFromPair() to burn SAS directly from the LP pool and follows it with sync(), which rewrites the pool's reserves to match its on-chain balance.
The problem is that this burn-and-sync path rewrites the pool's reserves without going through the AMM's swap logic. Once sellBurn has been pushed up by transfers into the pool, an unrelated normal transfer is enough to trigger the burn and sync, forcing the pool's SAS reserve toward zero and creating a large price distortion that can then be harvested through a normal swap.



Attack Analysis
The following analysis is based on the transaction 0x878e...adc5.
-
Step 1: The attacker borrowed
WBNBvia a flash loan. -
Step 2: The attacker swapped
WBNBforSAS.
-
Step 3: The attacker deployed a contract and executed the attack logic in
constructor(). This was used to bypass the protocol'sis_contract()check, since the token contract requiredtransfer()from to be either a whitelisted address or an EOA.


- Step 4: The attacker transferred
SASto the pool, which triggered the sell path and accumulatedsellBurn.

- Step 5: The attacker deployed a second contract and, again inside its
constructor(), initiated an ordinary transfer. WithsellBurnalready non-zero from Step 4, this transfer triggered function_burnFromPair(), which burnedSASdirectly from the LP pool and then called functionsync(), reducing theSASreserve to 1 wei.

- Step 6: The attacker performed a reverse swap and sold the remaining
SASfor profit.
Conclusion
The root cause of this incident is a flaw in the SAS token's custom transfer logic: an ordinary transfer could directly burn SAS from the LP pool and sync its reserves to the reduced balance, letting cumulative sell activity be turned into an arbitrary reduction of the pool's SAS reserve and, from there, into a large price distortion that could then be harvested through a normal swap.
Tokens should not reach into an external AMM pool and mutate its reserves outside of normal swap paths. If a deflationary design truly requires burning from a pool, the burn and the accompanying sync() must be bound to a tightly controlled internal trigger, such as a trusted keeper or a rate-limited schedule, rather than piggybacked on arbitrary user transfers.
8. Unknown-EIP-7702 Incident
Brief Summary
On April 3, 2026, a user account on BNB Chain that had enabled delegated code via EIP-7702 was drained for ~$17.2K. The delegated code exposed a pancakeV3SwapCallback() function without proper access control. The attacker directly called this callback with crafted calldata, forcing the victim account to transfer its tokens to an attacker-controlled address.
Background
The victim EOA used an EIP-7702 Type-4 transaction to set delegated code so the account could execute swap-related logic. However, the delegated implementation included a public pancakeV3SwapCallback() function that was intended to be called only during a legitimate PancakeSwap V3 pool callback.
Vulnerability Analysis
The root cause is missing access control in the delegated contract's (0x02C809...aEDbAE) pancakeV3SwapCallback() function.
In a correct UniswapV3/PancakeV3 callback design, the callback must verify that msg.sender is the expected canonical pool (derived from factory + token pair + fee, or verified against a trusted pool list). In this case, that validation was missing, so any external caller could invoke the callback directly.
Because the callback executes token transfers from the account that hosts it, the missing msg.sender check means any external call carrying positive amount0Delta/amount1Delta enters the payment path inside the callback and moves tokens out of the victim account, with no actual swap taking place.
Attack Analysis
The following analysis is based on the transaction 0x5b2c...4261.
- Step 1: The attacker directly called
pancakeV3SwapCallback()with crafted parameters, triggering the callback transfer logic to move the victim's tokens out to attacker-controlled addresses.


Conclusion
This incident was caused by deploying swap-callback logic to an EIP-7702 account without strict callback authentication. Because pancakeV3SwapCallback() lacked access control, the callback could be invoked by any external caller and used to move tokens out of the victim account without a legitimate swap ever occurring.
For any contract or delegated EIP-7702 code that implements V3-style callbacks, developers must validate that msg.sender is the canonical PancakeV3 pool (derived from the trusted factory, token pair, and fee tier) before the callback enters any transfer logic.
9. Silo Finance Incident
Brief Summary
On April 3, 2026, the Silo Finance soUSDC vault on Arbitrum was exploited for approximately $359K. The root cause was the convergence of three defects: an immutable wstUSR oracle that still priced the token at ~1.133 even after its market price had collapsed to ~0.12, a supply cap mechanism on soUSDC that only restricted the vault's own deposits but not external ones, and a totalAssets() accounting flaw that counted externally credited bUSDC shares without minting corresponding soUSDC shares. By depositing USDC directly into the zero-cap wstUSR market with receiver=soUSDC, the attacker inflated the vault's share price, borrowed the same USDC back against overvalued wstUSR collateral, and redeemed previously acquired soUSDC shares at the inflated valuation, with the shortfall pulled from other healthy markets in the withdrawal queue.
Background
Silo Finance is a risk-isolated lending protocol on Arbitrum. Each Silo market is a two-sided lending pair (e.g., wstUSR/USDC): borrowers deposit collateral (wstUSR) and borrow the lending asset (USDC), while lenders deposit USDC and earn interest. When a lender deposits USDC into a specific market, they receive that market's deposit share token. When a borrower deposits collateral, they receive a collateral share token (e.g., bwstUSR-149).
soUSDC is a SiloVault that sits on top of multiple Silo markets to aggregate USDC lending. Users deposit USDC into soUSDC and receive soUSDC shares. The vault then routes the deposited USDC into approved Silo markets based on supply caps set by the allocator, and the vault itself holds the bUSDC shares of each market it has deposited into. When a user redeems soUSDC shares, the vault calculates how much USDC the shares are worth using totalAssets(), which iterates every market in the withdrawal queue and sums the vault's bUSDC share balance in each one. The vault then withdraws USDC from its underlying markets to pay the redeemer.
wstUSR (Wrapped Staked USR) is a staking derivative of the USR stablecoin issued by Resolv. After Resolv was exploited, USR depegged, stUSR lost its peg as well, and wstUSR's secondary market price collapsed to ~0.12. However, the Chainlink feed for wstUSR only tracked the wstUSR/stUSR exchange rate (~1.133), and the protocol implicitly assumed 1 stUSR = 1 USD, so the oracle continued pricing wstUSR at ~1.133, a ~10x gap versus market reality.
Vulnerability Analysis
The wstUSR/USDC market's oracle address is hardcoded as immutable in SiloConfig and cannot be replaced. The oracle contract (0x836a1a...04425e) itself is a ChainlinkV3Oracle whose underlying Chainlink feed (description: "wstUSR / stUSR Exchange Rate") only tracks the wstUSR to stUSR wrapping ratio (~1.133), not the secondary market price. The protocol implicitly assumes 1 stUSR = 1 USD, so it prices wstUSR at ~1.133. After USR depegged, stUSR lost its peg as well and wstUSR collapsed to ~0.12 on the open market, but the oracle continued reporting ~1.133, a ~10x overvaluation.


The protocol was partially aware of the risk: soUSDC's supply cap for the wstUSR market was set to 0, meaning the vault would never voluntarily route USDC into it. However, this cap only governs the vault's own outbound deposit() calls. Since wstUSR_Market.deposit() accepts an arbitrary receiver parameter, anyone can deposit USDC directly into the wstUSR market and credit the resulting bUSDC shares to soUSDC's address, bypassing the supply cap entirely.
This creates the core exploit path. When bUSDC shares land in soUSDC's balance through such an external deposit, totalAssets() counts them: it iterates every market in the withdrawal queue and reads the vault's actual share balance, with no check on whether the position was voluntarily entered. Meanwhile, no new soUSDC shares are minted for these externally credited positions, because the vault's own mint logic was never invoked. The result is that totalAssets increases while totalShares stays the same, inflating the soUSDC share price.




Attack Analysis
The following analysis is based on the transaction 0xf77a...f3e1.
The attacker first bought wstUSR on the secondary market at ~0.12 per token.
-
Step 1: Flash loan ~4,236,352
USDCfrom Morpho. The oracle mispricing alone is not enough - thewstUSRmarket had zeroUSDCliquidity (cap=0,soUSDCnever deposited there), so there is nothing to borrow against the overvalued collateral. The flash loan provides the capital needed for the subsequent deposit and donation steps. -
Step 2: Deposit
wstUSRinto thewstUSRmarket as collateral and receivedbwstUSR-149. This is preparation for Step 5's borrow - the oracle values 13,797wstUSRat ~15,633 (at 1.133 each), even though the attacker only paid ~1,656.

- Step 3: Deposit ~4,222,007
USDCintosoUSDCvault, receivingsoUSDCshares (~91.5% of total supply). The vault routes thisUSDCinto existing healthy markets (not thewstUSRmarket, since cap=0). ThesesoUSDCshares are the instrument for extracting profit in Step 6 - the more shares the attacker holds, the more they benefit when the share price is inflated.

- Step 4: Deposit ~14,344
USDCdirectly into thewstUSRmarket viawstUSR_Market.deposit(receiver=soUSDC)and mintbUSDC-149tosoUSDC. The resultingbUSDCshares are credited tosoUSDC's address, not the attacker's. This is the core manipulation:soUSDC'stotalAssets()now includes thesebUSDCshares at face value (~14,344USDC), but no newsoUSDCshares are minted because the vault's own deposit logic was never invoked -totalAssetsgoes up,totalSharesstays the same, and thesoUSDCshare price inflates. At the same time, this createsUSDCliquidity in the previously emptywstUSRmarket, which is needed for the next step.

- Step 5: Borrow ~14,344
USDCfrom thewstUSRmarket using the collateral deposited in Step 2. The oracle prices the collateral at ~15,633, so at 92% maxLTV the attacker can borrow ~14,344. This recovers theUSDCdonated in Step 4 - the borrow and donation are cash-neutral. But thewstUSRmarket is now fully drained: allUSDChas been borrowed out, leaving only an outstanding loan backed by nearly worthlesswstUSRcollateral.soUSDCstill holds thebUSDCshares at face value intotalAssets().

- Step 6: Redeem all
soUSDCshares acquired in Step 3. The share price is now inflated from Step 4's donation, so the attacker receives ~4,235,143USDC, ~13,136 more than the 4,222,007 deposited in Step 3. The vault tries to withdraw from thewstUSRmarket but finds zero liquidity (borrowed out in Step 5), so it pulls the shortfall from other healthy markets in the withdrawal queue. This is where the loss materializes: realUSDCfrom othersoUSDCdepositors' markets is transferred to cover the inflated redemption.



- Step 7: Repay flash loan.
After 32 loops, soUSDC is left holding bUSDC positions in the wstUSR market that are face-valued at ~359K but backed by wstUSR collateral worth a fraction of that - 100% utilization, effectively irrecoverable bad debt borne by the remaining soUSDC depositors.
Conclusion
This incident was caused by the convergence of an oracle that tracked a staking exchange rate rather than the market price of a depegged asset, a vault accounting system that counted externally credited positions in totalAssets() without minting corresponding shares, and a supply cap mechanism that only restricted the vault's own deposits but not external ones. The oracle address being immutable in SiloConfig prevented any emergency fix after the problem became apparent.
Vault protocols that aggregate across lending markets should ensure that totalAssets() only accounts for positions the vault entered through its own deposit operations, not externally credited share balances. Oracle addresses should not be permanently immutable; emergency governance mechanisms should exist for price feed updates when underlying assets depeg.
About BlockSec
BlockSec is a full-stack blockchain security and crypto compliance provider. We build products and services that help customers to perform code audit (including smart contracts, blockchain and wallets), intercept attacks in real time, analyze incidents, trace illicit funds, and meet AML/CFT obligations, across the full lifecycle of protocols and platforms.
BlockSec has published multiple blockchain security papers in prestigious conferences, reported several zero-day attacks of DeFi applications, blocked multiple hacks to rescue more than 20 million dollars, and secured billions of cryptocurrencies.
-
Official website: https://blocksec.com/
-
Official Twitter account: https://twitter.com/BlockSecTeam



