Attack entry point
The attack entry point is the Balancer: Vault contract, and the corresponding entry function is the batchSwap function, which internally calls onSwap to perform token swaps. function onSwap( SwapRequest memory swapRequest, uint256[] memory balances, uint256 indexIn, uint256 indexOut ) external override onlyVault(swapRequest.poolId) returns (uint256) { _beforeSwapJoinExit(); _validateIndexes(indexIn, indexOut, _getTotalTokens()); uint256[] memory scalingFactors = _scalingFactors(); return swapRequest.kind == IVault.SwapKind.GIVEN_IN ? _swapGivenIn(swapRequest, balances, indexIn, indexOut, scalingFactors) : _swapGivenOut(swapRequest, balances, indexIn, indexOut, scalingFactors); } From the function parameters and restrictions, we can obtain several pieces of information: Attackers need to call this function through Vault; they cannot call it directly. The function internally calls _scalingFactors() to obtain scaling factors for scaling operations. Scaling operations are handled in either _swapGivenIn or _swapGivenOut . Attack Pattern Analysis
BPT Price Calculation Method In Balancer’s stable pool model, the price of BPT is an important reference point, which determines how many BPTs a user receives and how many assets are received per BPT. BPT Price = D / totalSupply Where D = invariant, from Curve's StableSwap model. In the pool exchange calculation: // StableMath._calcOutGivenIn function _calcOutGivenIn( uint256 amplificationParameter, uint256[] memory balances, uint256 tokenIndexIn, uint256 tokenIndexOut, uint256 tokenAmountIn, uint256 invariant ) internal pure returns (uint256) { /********************************************************************************************************** // outGivenIn token x for y - polynomial equation to solve // // ay = amount out to calculate // // by = balance token out // // y = by - ay (finalBalanceOut) // // D = invariant DD^(n+1) // // A = amplification coefficient y^2 + ( S + ---------- - D) * y - ------------- = 0 // // n = number of tokens (A * n^n) A * n^2n * P // // S = sum of final balances but y // // P = product of final balances but y // **************************************************************************************************************/ // Amount out, so we round down overall. balances[tokenIndexIn] = balances[tokenIndexIn].add(tokenAmountIn); uint256 finalBalanceOut = _getTokenBalanceGivenInvariantAndAllOtherBalances( amplificationParameter, balances invariant, // using the old D tokenIndexOut ); // No need to use checked arithmetic since `tokenAmountIn` was actually added to the same balance right before // calling `_getTokenBalanceGivenInvariantAndAllOtherBalances` which doesn't alter the balances array. balances[tokenIndexIn] = balances[tokenIndexIn] - tokenAmountIn; return balances[tokenIndexOut].sub(finalBalanceOut).sub(1); } The portion that serves as the benchmark for BPT prices is a constant value D ; that is, manipulating BPT prices requires manipulating D. Let’s analyze the calculation process of D: // StableMath._calculateInvariant function _calculateInvariant(uint256 amplificationParameter, uint256[] memory balances) internal pure returns (uint256) { /********************************************************************************************** // invariant // // D = invariant D^(n+1) // // A = amplification coefficient A n^n S + D = AD n^n + ----------- // // S = sum of balances n^n P // // P = product of balances // // n = number of tokens // **********************************************************************************************/ // Always round down, to match Vyper's arithmetic (which always truncates). uint256 sum = 0; // S in the Curve version uint256 numTokens = balances.length; for (uint256 i = 0; i prevInvariant) { if (invariant - prevInvariant In the code above, the calculation of D depends on the scaled balances array . This means that an operation is needed to change the precision of these balances, leading to an error in the calculation of D. The root cause of accuracy loss // BaseGeneralPool._swapGivenIn function _swapGivenIn( SwapRequest memory swapRequest, uint256[] memory balances, uint256 indexIn, uint256 indexOut, uint256[] memory scalingFactors ) internal virtual returns (uint256) { // Fees are subtracted before scaling, to reduce the complexity of the rounding direction analysis. swapRequest.amount = _subtractSwapFeeAmount(swapRequest.amount); _upscaleArray(balances, scalingFactors); // Key: Upscale the balance swapRequest.amount = _upscale(swapRequest.amount, scalingFactors[indexIn]); uint256 amountOut = _onSwapGivenIn(swapRequest, balances, indexIn, indexOut); // amountOut tokens are exiting the Pool, so we round down. return _downscaleDown(amountOut, scalingFactors[indexOut]); } Scaling operation: // ScalingHelpers.sol function _upscaleArray(uint256[] memory amounts, uint256[] memory scalingFactors) pure { uint256 length = amounts.length; InputHelpers.ensureInputLengthMatch(length, scalingFactors.length); for (uint256 i = 0; i As shown above, when using _upscaleArray , if the balance is very small (e.g., 8-9 wei), the down-rounding of mulDown will result in a significant loss of precision. Attack process details Phase 1: Adjust to rounding boundary Attacker: BPT → cbETH Objective: To adjust the cbETH balance to the rounding boundary (e.g., ending in 9). Assume the initial state: cbETH Balance (Original): ...00000000009 wei (last digit is 9) Phase 2: Triggering Precision Loss (Core Vulnerability) Attacker: wstETH (8 wei) → cbETH Before scaling: cbETH Balance: ...000000000009 wei wstETH input: 8 wei Execute _upscaleArray: // cbETH scaling: 9 * 1e18 / 1e18 = 9 // But if the actual value is 9.5, it becomes 9 due to rounding down. scaled_cbETH = floor(9.5) = 9 Accuracy loss: 0.5 / 9.5 = 5.3% relative error calculation exchange: Input (wstETH): 8 wei (scaled) Balance (cbETH): 9 (Incorrect, it should be 9.5) Because cbETH is undervalued, the calculated new balance will also be undervalued, leading to an error in the D calculation. D_original = f(9.5, ...) D_new = f(9, ...) Phase 3: Profiting from the depressed BPT price Attacker: Underlying asset → BPT at this time: D_new = D_original - ΔD BPT price = D_new / totalSupply The attacker above used Batch Swap to perform multiple swaps within a single transaction: First exchange: BPT → cbETH (adjust balance) Second swap: wstETH (8) → cbETH (triggers precision loss) Third exchange: Underlying assets → BPT (profit) These swaps are all within the same batch swap transaction and share the same balance state , but _upscaleArray is called to modify the balances array for each swap. The lack of a callback mechanism The main process is started by Vault, so how does this lead to the accumulation of precision loss? The answer lies in the passing mechanism of the balances array . // The logic function when Vault calls onSwap: _processGeneralPoolSwapRequest(IPoolSwapStructs.SwapRequest memory request, IGeneralPool pool) private returns (uint256 amountCalculated) { bytes32 tokenInBalance; bytes32 tokenOutBalance; // We access both token indexes without checking existence, because we will do it manually immediately after. EnumerableMap.IERC20ToBytes32Map storage poolBalances = _generalPoolsBalances[request.poolId]; uint256 indexIn = poolBalances.unchecked_indexOf(request.tokenIn); uint256 indexOut = poolBalances.unchecked_indexOf(request.tokenOut); if (indexIn == 0 || indexOut == 0) { // The tokens might not be registered because the Pool itself is not registered. We check this to provide a // more accurate revert reason. _ensureRegisteredPool(request.poolId); _revert(Errors.TOKEN_NOT_REGISTERED); } // EnumerableMap stores indices *plus one* to use the zero index as a sentinel value - because these are valid, We can undo this. indexIn -= 1; indexOut -= 1; uint256 tokenAmount = poolBalances.length(); uint256[] memory currentBalances = new uint256[](tokenAmount); request.lastChangeBlock = 0; for (uint256 i = 0; i Analyzing the code above, although Vault creates a new currentBalances array every time onSwap is called, in Batch Swap : After the first exchange, the balance is updated (but the updated value may be inaccurate due to loss of precision). The second swap continues the calculation based on the result of the first swap. Accumulated loss of precision eventually leads to a significant decrease in the invariant value D. Key issues: // BaseGeneralPool._swapGivenIn function _swapGivenIn( SwapRequest memory swapRequest, uint256[] memory balances, uint256 indexIn, uint256 indexOut, uint256[] memory scalingFactors ) internal virtual returns (uint256) { // Fees are subtracted before scaling, to reduce the complexity of the rounding direction analysis. swapRequest.amount = _subtractSwapFeeAmount(swapRequest.amount); _upscaleArray(balances, scalingFactors); // Modify the array in place. swapRequest.amount = _upscale(swapRequest.amount, scalingFactors[indexIn]); uint256 amountOut = _onSwapGivenIn(swapRequest, balances, indexIn, indexOut); // amountOut tokens are exiting the Pool, so we round down. return _downscaleDown(amountOut, scalingFactors[indexOut]); } // Although Vault passes in a new array each time, but: // 1. If the balance is very small (8-9 wei), the precision loss during scaling is significant. // 2. In Batch Swap, subsequent swaps continue calculations based on the balance that has already lost precision. // 3. It was not verified whether the change in the invariant value D was within a reasonable range. Summarize
The reasons for Balancer's attack can be summarized as follows: 1. Scaling function uses rounding down : _upscaleArray uses mulDown for scaling, which will produce a significant loss of relative precision when the balance is very small (such as 8-9 wei). 2. Invariant value calculation is sensitive to precision : The calculation of the invariant value D depends on the scaled balances array, and the precision loss will be directly passed to the calculation of D, making D smaller. 3. Lack of verification of changes in invariant values : During the exchange process, it was not verified whether the changes in the invariant value D were within a reasonable range, which allowed attackers to repeatedly exploit the loss of precision to lower the price of BPT. 4. Accumulated precision loss in batch swap : In the same batch swap, the precision loss from multiple swaps will accumulate and eventually amplify into huge financial losses. These two issues—precision loss and lack of validation—combined with the attacker's careful design of boundary conditions, resulted in this loss. This article is sourced from the internet: Balancer hacked, vulnerability analysisRecommended Articles Related: BitMart Launches Pre-Market Trading, with Monad (MON) as the First Project Launched To further enrich its trading product portfolio and enhance user engagement and asset allocation flexibility, BitMart has officially launched a new feature: pre-market trading . This innovative mechanism provides users with the opportunity to invest in projects before their official launch, helping them capture early value more efficiently and gain direct access to high-quality assets. Pre-market trading: an innovative pre-release token trading mechanism Pre-market trading is an innovative financial tool launched by BitMart based on a staking mechanism. Users can mint PreTokens by staking USDT and trade them freely in a dedicated pre-market spot market. The core logic of this model is that before the project token is officially launched, PreToken provides users with a channel for early participation, thereby achieving pre-positioning and price discovery of potential assets. Key features… # Analysis# Exchange# Token© Copyright NoticeThe copyright of the article belongs to the author, please do not reprint without permission. Pre The market has crashed, but you still have a chance to win it back. Next Tracing the Decoupling of $XUSD: Balancer Vulnerability and the Butterfly Effect of DeFi Leverage Related articles The birth of “physical BTC”: a 13-year investment miracle of 20,000 times return 6086cf14eb90bc67ca4fc62b 27,469 4 The battle between payment giants in the era of stablecoins: what are Visa and Mastercard planning? 6086cf14eb90bc67ca4fc62b 274,199 229 CoinW Research Institute Weekly Report (July 14, 2025 – July 20, 2025) 6086cf14eb90bc67ca4fc62b 28,155 1 2026 Potential Airdrop Projects Mega Collection & Tutorial (Part 3) 6086cf14eb90bc67ca4fc62b 8,302 Why is this candidate for Federal Reserve Chairman the most popular candidate?Recommended Articles 6086cf14eb90bc67ca4fc62b 23,694 1 Lighter’s upcoming TGE: A comprehensive overview of timing window, on-chain signals, and market pricing. 6086cf14eb90bc67ca4fc62b 16,625 1 No comments You must be logged in to leave a comment! Login immediately No comments... Bee.com The world's largest Web3 portal Partners CoinCarp Binance CoinMarketCap CoinGecko Coinlive Armors Download Bee Network APP and start the web3 journey White Paper Roles FAQ © 2021—2026. All Rights Reserved. Privacy Policy | Terms of Services Download Bee Network APP and start the web3 journey The world's largest Web3 portal Partners CoinCarp Binance CoinMarketCap CoinGecko Coinlive Armors White Paper Roles FAQ © 2021—2026. All Rights Reserved. Privacy Policy | Terms of Services Search SearchInSiteOnChainSocialNews Hot to you: Airdrop Hunters Data Analysis Crypto Celebrities Trap Detector English 繁體中文 简体中文 日本語 Tiếng Việt العربية 한국어 Bahasa Indonesia हिन्दी اردو Русский English
智能索引记录
-
2026-03-02 12:39:46
综合导航
成功
标题:自信的青春最美丽_800字_作文网
简介:嘘 !你听,是花开的声音,来了,沁人心脾的芳香。 哗啦啦 墙上的挂历随着日出,日落一页页被人撕下,时间,就像头顶上那片洁
-
2026-03-02 18:54:33
综合导航
成功
标题:Christmas Bridge Runner - Play The Free Game Online
简介:Christmas Bridge Runner - click to play online. Christmas Br
-
2026-03-02 20:41:21
综合导航
成功
标题:è¾¹å¸çæ¼é³_è¾¹å¸çææ_è¾¹å¸çç¹ä½_è¯ç»ç½
简介:è¯ç»ç½è¾¹å¸é¢é,ä»ç»è¾¹å¸,è¾¹å¸çæ¼é³,è¾¹å¸æ¯
-
2026-03-02 20:58:27
综合导航
成功
标题:Игры в жанре Поиск скрытых предметов для iPhone
简介:Игры в жанре Поиск скрытых предметов для iPhone
-
2026-03-02 18:46:06
综合导航
成功
标题:地球经历的几个时期最新章节_第55章 晚节不保与钟表宇宙第1页_地球经历的几个时期免费章节_恋上你看书网
简介:第55章 晚节不保与钟表宇宙第1页_地球经历的几个时期_蛮渔.CS_恋上你看书网
-
2026-03-02 20:21:59
综合导航
成功
标题:æ²®æçæ¼é³_æ²®æçææ_æ²®æçç¹ä½_è¯ç»ç½
简介:è¯ç»ç½æ²®æé¢é,ä»ç»æ²®æ,æ²®æçæ¼é³,æ²®ææ¯
-
2026-03-02 21:04:23
综合导航
成功
标题:974B-71024 Vacuum Transducer
简介:The 974B-71024 QuadMag Cold Cathode / MicroPirani / Piezo Tr
-
2026-03-02 21:00:47
综合导航
成功
标题:éé¸ çæ¼é³_éé¸ çææ_éé¸ çç¹ä½_è¯ç»ç½
简介:è¯ç»ç½éé¸ é¢é,ä»ç»éé¸ ,éé¸ çæ¼é³,éé¸ æ¯
-
2026-03-02 21:32:28
游戏娱乐
成功
标题:战斗机小游戏,战斗机小游戏大全,4399战斗机小游戏全集,4399小游戏
简介:4399战斗机小游戏大全收录了国内外战斗机类小游戏、双人战斗机小游戏、战斗机无敌版小游戏、战斗机小游戏下载。好玩就拉朋友
-
2026-03-02 21:30:58
综合导航
成功
标题:18luck新利官网利app-你玩乐的的好帮手
简介:18luck新利官网专注于为玩家打造无忧的游戏环境。其官方应用程序以简洁流畅的设计、便捷的操作体验和丰富的游戏内容,成为
-
2026-03-02 12:47:43
综合导航
成功
标题:我成了超人_栗子n号_第13章 行走的炸弹_风云中文网
简介:风云中文网提供我成了超人(栗子n号)第13章 行走的炸弹在线阅读,所有小说均免费阅读,努力打造最干净的阅读环境,24小时
-
2026-03-02 16:20:28
综合导航
成功
标题:è§é¿çæ¼é³_è§é¿çææ_è§é¿çç¹ä½_è¯ç»ç½
简介:è¯ç»ç½è§é¿é¢é,ä»ç»è§é¿,è§é¿çæ¼é³,è§é¿æ¯
-
2026-03-02 16:13:57
综合导航
成功
标题:AI智能索引 - AI智能索引
简介:AI智能索引 - 提供全网公开链接智能索引服务,快速访问目标内容,支持分类筛选和智能导航
-
2026-03-02 20:19:46
综合导航
成功
标题:æµçªçæ¼é³_æµçªçææ_æµçªçç¹ä½_è¯ç»ç½
简介:è¯ç»ç½æµçªé¢é,ä»ç»æµçª,æµçªçæ¼é³,æµçªæ¯
-
2026-03-02 21:53:42
综合导航
成功
标题:黿º²æº²çæ¼é³_黿º²æº²çææ_黿º²æº²çç¹ä½_è¯ç»ç½
简介:è¯ç»ç½é»æº²æº²é¢é,ä»ç»é»æº²æº²,黿º²æº²çæ¼é³,
-
2026-03-02 21:50:27
综合导航
成功
标题:合同取得成本和合同履约成本在财务报表中列什么项目?-高顿问答
简介:高顿为您提供报表,财务报表相关问题解答,关于合同取得成本和合同履约成本在财务报表中列什么项目?老师的解答如下:同学你好~
-
2026-03-02 15:44:29
综合导航
成功
标题:国庆中秋狂欢,解锁多重福利,助力冲刺期货从业考试!-期货从业资格-233网校
简介:距离期货从业考试已不足1月,这段黄金冲刺期,可是查漏补缺、提分抢分的关键! 举国欢庆的热闹时刻,恰好也是你追赶进度、夯实
-
2026-03-02 20:28:53
综合导航
成功
标题:Skydom - Play The Free Game Online
简介:Skydom - click to play online. Skydom is a high quality and
-
2026-03-02 16:11:58
综合导航
成功
标题:1800-06823 Coupling with bosses - VTE-FILTER GmbH
简介:Hersteller: Alfa Laval Moatti OEM Nr.: Alfa Laval Moatti 180
-
2026-03-02 18:54:41
综合导航
成功
标题:Videojuegos de puzles: sitio oficial de EA
简介:Explora los videojuegos de puzles de Electronic Arts, un dis
-
2026-03-02 20:20:06
教育培训
成功
标题:按 搜索结果列表 - Docin.com豆丁网
简介:豆丁网是面向全球的中文社会化阅读分享平台,拥有商业,教育,研究报告,行业资料,学术论文,认证考试,星座,心理学等数亿实用
-
2026-03-02 19:59:42
综合导航
成功
标题:Freddy - Chapitre 5 : l'enfant du cauchemar - Film 1989
简介:Freddy - Chapitre 5 : l
-
2026-03-02 18:51:45
金融理财
成功
标题:2020年9月基金从业第二期模考大赛比拼获奖名单公布!-基金从业-233网校
简介:233网校为参加9月26日基金从业资格考试的考生准备了2期模考大赛。每场大赛准备了基金法律法规、证券投资基金基础知识、私
-
2026-03-02 20:30:18
综合导航
成功
标题:è·µå¢çæ¼é³_è·µå¢çææ_è·µå¢çç¹ä½_è¯ç»ç½
简介:è¯ç»ç½è·µå¢é¢é,ä»ç»è·µå¢,è·µå¢çæ¼é³,è·µå¢æ¯
-
2026-03-02 12:54:00
视频影音
成功
标题:密屋陌路第04集红果短剧_在线播放[高清流畅]_爽文短剧
简介:爽文短剧_密屋陌路剧情介绍:密屋陌路是由内详执导,谢妮布·萨利赫,安德烈亚斯·皮特斯柯曼,劳伦斯·鲁波,费利克斯·克拉默
-
2026-03-02 15:26:25
综合导航
成功
标题:荤段子短信-励志一生
简介:荤段子短信_ 荤段子短信 1、俩老夫妻某日吃晚饭时突发奇想:裸餐!找找从前的感觉!脱光后老太婆道:我还有反应耶!乳房
-
2026-03-02 19:01:04
游戏娱乐
成功
标题:饥饿的小妖怪,饥饿的小妖怪小游戏,4399小游戏 www.4399.com
简介:饥饿的小妖怪在线玩,饥饿的小妖怪下载, 饥饿的小妖怪攻略秘籍.更多饥饿的小妖怪游戏尽在4399小游戏,好玩记得告诉你的朋
-
2026-03-02 22:04:27
综合导航
成功
标题:形方氏是什么意思_形方氏的词语解释-雄安文学网
简介:形方氏是什么意思?雄安文学网为您提供形方氏的的意思解释,解读形方氏的解释含义,包括基本解释和详细解释等。
-
2026-03-02 21:06:19
综合导航
成功
标题:JW Froehlich GmbH - JW Froehlich Maschinenfabrik GmbH
简介:Die JW Froehlich Maschinenfabrik GmbH ist ein traditionsreic
-
2026-03-02 16:12:48
综合导航
成功
标题:1/10/25G FMT Serie Offenes Leitungssystem - FS Deutschland
简介:FS bietet 1/10/25G FMT Serie mit kostenloser und schneller L