Back to Blog

Weekly Web3 Security Incident Roundup | Mar 30 – Apr 5, 2026

Code Auditing
April 8, 2026
33 min read
Key Insights

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,000e18 BUSD through a flash loan and swapped it in the pool for 19,013,120e18 PSTART.

  • Step 2: The attacker repeatedly called the contract's deposit() function to stake funds. For each deposit, the protocol calculated how much BUSD should be used to buy tokens so that the final token-to-BUSD ratio used for adding liquidity would more closely match the pool's current ratio. By repeatedly depositing, the attacker continuously injected BUSD into the pool, while the amount of PSTART remained almost unchanged. As a result, the value of PSTART kept rising. At this stage, the LP obtained through the attacker's deposits was actually being acquired at a loss.

  • Step 3: The attacker then sold the PSTART purchased in Step 1 back into the pool. Because Step 2 had increased the pool's BUSD reserves, this swap returned approximately 2,010,655e18 BUSD, generating a profit of about 10,655 BUSD in 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 redeemable BUSD amount 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.


Get Started with Phalcon Explorer

Dive into Transactions to Act Wisely

Try now for free

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 BNB for WDGG tokens through the PancakeSwap pool.

  • Step 3: After obtaining WDGG, the attacker invoked burnFrom() to burn WDGG tokens 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, the WDGG reserve 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 WBNB through a flash loan, then supplied it to Venus as collateral and borrowed a large amount of USDT. The attacker also deployed attack contract A at 0xda49 and helper contract B at 0x096a.

  • Step 2: The attack contract executed the first invest(). During this process, the protocol first used 531,489e18 USDT to purchase 234,188e18 i6, and then added 354,326e18 USDT together with 72,607e18 i6 into the pool. As a result, the pool spot price rapidly increased from about 1.05159 USDT/i6 to about 4.89287 USDT/i6, while the protocol's recorded TWAP still remained at only 1.05159.

  • Step 3: The attacker then transferred 124,014,184e18 USDT to helper contract B, which in turn called invest() with referrer = A. This step once again forced the protocol to perform a massive USDT -> i6 purchase and addLiquidity(), pushing the pool reserves to a new state corresponding to a spot price of approximately 15,528 USDT/i6. However, because no new time window had elapsed, the protocol did not update the TWAP accordingly.

  • Step 4: After the second invest() was completed, attack contract A, acting as the referrer, immediately became entitled to a referral reward denominated in USDT. The attacker then called withdraw(). The protocol used the stale TWAP to calculate the amount of i6 to be paid and transferred the tokens out of its own balance, resulting in a total payout of 5,896,508e18 i6.

  • Step 5: After receiving the i6, the attacker immediately called swapExactTokensForTokensSupportingFeeOnTransferTokens() to sell all 5,896,508e18 i6 back into the pool in exchange for 125,177,224e18 USDT. Because these i6 tokens had been settled using the stale TWAP of about 1.05159 USDT/i6, while they were sold against a pool spot price that had been pushed up by the attacker to around 15,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,802e18 USDT, 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 ETH from 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 AdvanceNonceAccount to activate the stored nonce, proceeding through proposalApprove and vaultTransactionExecute, and ultimately invoking UpdateAdmin to 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 overvalued CVT into the protocol and executed 31 rapid withdrawals over approximately 12 minutes, draining USDC, JLP, SOL, cbBTC, USDT, wETH, dSOL, WBTC, JTO, and FARTCOIN for 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 USDT and WBNB through flash loans from Moolah, borrowing from Venus and Moolah Pool (using WBNB as collateral), and flash loans from PancakeSwap V4, multiple V3 pools, and V2 pools. This capital was needed to manipulate the LML/USDT pair price.

  • Step 2: The attacker called swapAndTrans() on the LML token contract, which swapped the LML fees accumulated in the contract to USDT. This drained the LML contract's own LML balance, meaning it could no longer serve as a local token source, any subsequent reward distribution would need to pull LML from the LP pair via swapBack().

  • Step 3: The attacker swapped USDT for LML via PancakeRouter swapExactTokensForTokensSupportingFeeOnTransferTokens, with the recipient set to the dead address. The purchased LML tokens were burned rather than received by the attacker. The sole purpose was to drain LML from the pair and inflate the LML price 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 on msg.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 a transfer(rst, fte) function that sent a small amount of BNB to APower, triggering receive(), _claimReward(EOA). Inside each claim: updatePrice() was skipped (3600s cooldown not met, so stored_price remained at the historical low value), updateUser() calculated the reward using the stale low price, sendMining() transferred LML from PROOF to APower and then triggered swapBack() which replenished PROOF by pulling LML from the LP pair and calling sync(), further reducing the pair's reserves. Finally claimReward() distributed LML to the EOA, and each EOA transferred its received LML back to the attacker contract.
  • Step 5: The attacker swapped the accumulated LML back to USDT through 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,365e18 CES from a Uniswap V3 flash pool and distributed the funds to 5 helper contracts. Each helper first received 6,426e18 CES, and then called deposit(12). During this process, each helper first queried getPriceForLevel(12) and then prepared the amount of CES required for this deposit based on the current price.
  • Step 2: After all 5 helpers completed the first round of deposit, the attacker dumped 300,000 CES on the DEX, pushing the price used by the bank down from 1.067585 to 0.688542. The 5 helpers then executed withdraw one by one, redeeming the shares created earlier at the high price into CES at the now lower price. Each helper received 9,427e18 CES.
  • Step 3: After completing the first round of withdraw, the attacker swapped the acquired counterparty asset back into CES, 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 with 567,736e18 CES as 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 WBNB via a flash loan.

  • Step 2: The attacker swapped WBNB for SAS.

  • Step 3: The attacker deployed a contract and executed the attack logic in constructor(). This was used to bypass the protocol's is_contract() check, since the token contract required transfer() from to be either a whitelisted address or an EOA.

  • Step 4: The attacker transferred SAS to the pool, which triggered the sell path and accumulated sellBurn.
  • Step 5: The attacker deployed a second contract and, again inside its constructor(), initiated an ordinary transfer. With sellBurn already non-zero from Step 4, this transfer triggered function _burnFromPair(), which burned SAS directly from the LP pool and then called function sync(), reducing the SAS reserve to 1 wei.
  • Step 6: The attacker performed a reverse swap and sold the remaining SAS for 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 USDC from Morpho. The oracle mispricing alone is not enough - the wstUSR market had zero USDC liquidity (cap=0, soUSDC never 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 wstUSR into the wstUSR market as collateral and received bwstUSR-149. This is preparation for Step 5's borrow - the oracle values 13,797 wstUSR at ~15,633 (at 1.133 each), even though the attacker only paid ~1,656.

  • Step 3: Deposit ~4,222,007 USDC into soUSDC vault, receiving soUSDC shares (~91.5% of total supply). The vault routes this USDC into existing healthy markets (not the wstUSR market, since cap=0). These soUSDC shares 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 USDC directly into the wstUSR market via wstUSR_Market.deposit(receiver=soUSDC) and mint bUSDC-149 to soUSDC. The resulting bUSDC shares are credited to soUSDC's address, not the attacker's. This is the core manipulation: soUSDC's totalAssets() now includes these bUSDC shares at face value (~14,344 USDC), but no new soUSDC shares are minted because the vault's own deposit logic was never invoked - totalAssets goes up, totalShares stays the same, and the soUSDC share price inflates. At the same time, this creates USDC liquidity in the previously empty wstUSR market, which is needed for the next step.
  • Step 5: Borrow ~14,344 USDC from the wstUSR market 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 the USDC donated in Step 4 - the borrow and donation are cash-neutral. But the wstUSR market is now fully drained: all USDC has been borrowed out, leaving only an outstanding loan backed by nearly worthless wstUSR collateral. soUSDC still holds the bUSDC shares at face value in totalAssets().
  • Step 6: Redeem all soUSDC shares acquired in Step 3. The share price is now inflated from Step 4's donation, so the attacker receives ~4,235,143 USDC, ~13,136 more than the 4,222,007 deposited in Step 3. The vault tries to withdraw from the wstUSR market 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: real USDC from other soUSDC depositors' 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.


Get Started with Phalcon Security

Detect every threat, alert what matters, and block attacks.

Try now for free

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.

Sign up for the latest updates
Tracing $1.6B in TRON USDT: Inside the VerilyHK Ponzi Infrastructure
Case Studies

Tracing $1.6B in TRON USDT: Inside the VerilyHK Ponzi Infrastructure

An on-chain investigation into VerilyHK, a fraudulent platform that moved $1.6B in TRON USDT through a multi-layered fund-routing infrastructure of rotating wallets, paired payout channels, and exchange exit funnels, with traced connections to the FinCEN-sanctioned Huione Group.

Drift Protocol Incident: Multisig Governance Compromise via Durable Nonce Exploitation
Security Insights

Drift Protocol Incident: Multisig Governance Compromise via Durable Nonce Exploitation

On April 1, 2026 (UTC), Drift Protocol on Solana suffered a $285.3M loss after an attacker exploited Solana's durable nonce mechanism to delay the execution of phished multisig approvals, ultimately transferring administrative control of the protocol's 2-of-5 Squads governance with zero timelock. With full admin privileges, the attacker created a malicious collateral market (CVT), inflated its oracle price, relaxed withdrawal protections, and drained USDC, JLP, SOL, cbBTC, and other assets through 31 rapid withdrawals in approximately 12 minutes. This incident highlights how durable nonce-based delayed execution can decouple signer intent from on-chain execution, bypassing the temporal assumptions that multisig security implicitly relies on.

Weekly Web3 Security Incident Roundup | Mar 23 – Mar 29, 2026
Security Insights

Weekly Web3 Security Incident Roundup | Mar 23 – Mar 29, 2026

This BlockSec weekly security report covers eight DeFi attack incidents detected between March 23 and March 29, 2026, across Ethereum and BNB Chain, with total estimated losses of approximately $1.53M. Incidents include a $679K flawed burn mechanism exploit on the BCE token, a $512K spot-price manipulation attack on Cyrus Finance's PancakeSwap V3 liquidity withdrawal, a $133.5K flash-loan-driven referral reward manipulation on a TUR staking contract, and multiple integer overflow, reentrancy, and accounting error vulnerabilities in DeFi protocols. The report provides detailed vulnerability analysis and attack transaction breakdowns for each incident.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit