Flashstake LP Share Inflation
Exploit Transactions
0x2b6d0af0dc513a15e325703405739057f9de6ef3f99934b957653b8a3fade4c6Victim Addresses
0xa44e79a2c9a8965e7a6fa77bf0ca8faf50e6c73eEthereumLoss Breakdown
Similar Incidents
LibertiVault Reentrant Share Inflation
38%bZx iYFI Donation Inflation
36%TomInu Reflection Pair Inflation Flashloan Exploit
33%Conic crvUSD Oracle Exploit
33%Indexed Finance DEFI5 gulp/reindex bug enables SUSHI flash-swap drain
32%Sturdy LP Oracle Manipulation
32%Root Cause Analysis
Flashstake LP Share Inflation
1. Incident Overview TL;DR
On Ethereum mainnet block 18680255, an unprivileged adversary exploited Flashstake's USDC-WETH FarmingLPToken at 0xa44e79a2c9a8965e7a6fa77bf0ca8faf50e6c73e in transaction 0x2b6d0af0dc513a15e325703405739057f9de6ef3f99934b957653b8a3fade4c6. The attacker used public Balancer and BentoBox flashloans to create two thin Sushiswap pools, deposited a small amount of USDC-WETH LP into the victim contract with attacker-chosen quote paths, minted far more fLP shares than the LP position economically justified, and then redeemed a disproportionate amount of the protocol's pooled LP through emergencyWithdraw.
The root cause is a share-pricing bug in Flashstake's FarmingLPToken. Deposit pricing trusts caller-supplied Sushiswap paths and raw router.getAmountsOut spot quotes, while redemption returns LP pro rata from the global share supply. That lets an attacker overstate the value of a tiny LP deposit, mint inflated shares, and convert those inflated shares into other users' LP principal.
2. Key Background
FarmingLPToken is a pooled wrapper around a Sushiswap LP position managed through Sushi MasterChef. Users receive fLP shares on deposit and later redeem LP according to the contract's global accounting variable withdrawableTotalLPs.
The critical design assumption is that newly minted shares must represent a fair claim on the underlying LP inventory. In this system, the deposit side values LP in SUSHI terms by splitting the LP into reserve slices and calling the Sushiswap router's getAmountsOut along path0 and path1. Because those paths are supplied by the caller, any attacker who can create or control a thin intermediate pool can manipulate the quoted SUSHI value.
This is an ACT opportunity because every dependency in the exploit path is public:
- Balancer Vault flashloans
- BentoBox flashloans
- Sushiswap pair creation and liquidity seeding
FarmingLPToken.depositFarmingLPToken.emergencyWithdraw
The relevant pre-state existed immediately before block 18680255: the victim pool already had outstanding shares and withdrawable USDC-WETH LP inventory, Sushiswap and flashloan venues were live, and the victim code was publicly deployed and verified.
3. Vulnerability Analysis & Root Cause Summary
This incident is an ATTACK case caused by attacker-controlled share valuation. The vulnerable path starts in FarmingLPToken._deposit, where the contract accepts arbitrary path0 and path1 so long as they begin with token0 or token1 and end with sushi. It then values the depositor's LP slices by forwarding those exact paths into router.getAmountsOut.
That valuation is not protocol-controlled. It is a spot quote over the current reserves of every pool on the chosen route, so a caller can mint shares from manipulated reserves instead of fair market value. The same contract later redeems LP through withdraw and emergencyWithdraw using shares * withdrawableTotalLPs / totalShares(), which assumes minted shares were honest in the first place.
The exploit therefore breaks the core invariant that each newly minted share should correspond to a fair claim on pooled LP principal. The code-level breakpoint is the share mint inside _deposit, where the contract mints the quoted SUSHI amount as shares before increasing withdrawableTotalLPs only by the actual LP deposited.
4. Detailed Root Cause Analysis
4.1 Victim Code Path
The key victim logic is the deposit-side valuation and the redemption-side pro-rata LP withdrawal.
Victim share-minting logic (FarmingLPToken):
function _deposit(
uint256 amountLP,
address[] calldata path0,
address[] calldata path1,
uint256 amountMin,
address beneficiary
) internal {
if (path0[0] != token0 || path0[path0.length - 1] != sushi) revert InvalidPath();
if (path1[0] != token1 || path1[path1.length - 1] != sushi) revert InvalidPath();
IERC20(lpToken).safeTransferFrom(msg.sender, address(this), amountLP);
uint256 total = IUniswapV2Pair(lpToken).totalSupply();
(uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(lpToken).getReserves();
uint256 amount = UniswapV2Utils.quote(router, (reserve0 * amountLP) / total, path0) +
UniswapV2Utils.quote(router, (reserve1 * amountLP) / total, path1);
_mint(beneficiary, amount);
withdrawableTotalLPs += amountLP;
}
Victim quote helper (UniswapV2Utils):
function quote(
address router,
uint256 amountIn,
address[] memory path
) internal view returns (uint256 amountOut) {
if (path.length < 2) return amountIn;
uint256[] memory amountsOut = IUniswapV2Router02(router).getAmountsOut(amountIn, path);
return amountsOut[amountsOut.length - 1];
}
Victim redemption logic (FarmingLPToken):
function emergencyWithdraw(address beneficiary) external override nonReentrant {
uint256 shares = sharesOf(msg.sender);
uint256 amountLP = (shares * withdrawableTotalLPs) / totalShares();
IMasterChef(masterChef).withdraw(pid, amountLP);
IERC20(lpToken).safeTransfer(beneficiary, amountLP);
_burn(msg.sender, shares);
withdrawableTotalLPs -= amountLP;
}
The mismatch is explicit: minting uses attacker-controlled spot routes, while redemption assumes shares were minted from a trusted valuation basis.
4.2 Exploit Sequence
The collected seed trace shows the following deterministic sequence inside transaction 0x2b6d0af0dc513a15e325703405739057f9de6ef3f99934b957653b8a3fade4c6:
- The adversary EOA
0x9d44f1a37044500064111010632a8a59003701c8calls helper contract0x4bc691601b50b3e107b89d5ea172b40a9dbc6251. - The helper takes public flashloans of
800000000USDC and500000000000000000WETH from Balancer, then400000000000000000000000SUSHI from BentoBox. - The helper creates thin Sushiswap pools:
- USDC-AST with
2000000USDC units and10000AST units - SUSHI-AST with
400000000000000000000000SUSHI and10000AST units
- USDC-AST with
- The helper mints a small USDC-WETH LP position of
25156809832LP units. - The helper calls
FarmingLPToken.depositwith manipulated paths:USDC -> AST -> SUSHIWETH -> SUSHI
- The victim contract queries
getAmountsOutover those attacker-controlled pools and mints132925896953047092702474fLP shares. - The helper immediately calls
emergencyWithdrawand receives20144470251713LP units, far above the LP amount it deposited. - The helper burns the redeemed LP and unwinds the manipulation pools, repays both flashloans, and keeps the residual profit.
Representative trace evidence from the seed transaction:
0xd9e1...::addLiquidity(USDC, AST, 2000000, 10000, ...)
0xd9e1...::addLiquidity(SUSHI, AST, 400000000000000000000000, 10000, ...)
0xd9e1...::getAmountsOut(1999999, [USDC, AST, SUSHI])
0xa44e79...::deposit(...)
emit Deposit(param0: 132925896953047092702474, param1: 25156809832, param2: 0x4Bc691...)
emit EmergencyWithdraw(param0: 127556102597101835622284, param1: 20144470251713, param2: 0x4Bc691...)
4.3 Breakpoint and Invariant Failure
The invariant is:
Newly minted fLP shares must correspond to a fair, protocol-controlled economic contribution of LP principal.
The concrete breakpoint is the _mint(beneficiary, amount) call in _deposit. The contract treats manipulated spot quotes as if they were trustworthy valuation inputs and records the resulting share count into the same supply later used for pro-rata LP redemption.
The trace and balance diff show the numerical consequence:
- LP deposited into Flashstake:
25156809832 - Shares minted:
132925896953047092702474 - LP redeemed through
emergencyWithdraw:20144470251713 - Net LP extracted beyond the depositor's own contribution:
20119313441881
This is exactly the broken-accounting step that lets attacker-inflated shares drain pooled LP inventory from pre-existing depositors.
5. Adversary Flow Analysis
The adversary cluster consists of:
- EOA
0x9d44f1a37044500064111010632a8a59003701c8, which submitted the exploit transaction and later received residual fLP shares. - Helper contract
0x4bc691601b50b3e107b89d5ea172b40a9dbc6251, which executed the flashloans, pool creation, manipulated deposit, LP redemption, unwinding, and repayment.
The primary victim is Flashstake's USDC-WETH FarmingLPToken at 0xa44e79a2c9a8965e7a6fa77bf0ca8faf50e6c73e. Sushi MasterChef at 0xc2edad668740f1aa35e4d8f227fb8e17dca888cd is a supporting protocol component because it holds the pooled LP position withdrawn during redemption.
Operationally, the attacker used a single-transaction accounting attack:
- Stage 1, funding: obtain flash liquidity from Balancer and BentoBox.
- Stage 2, setup: create attacker-controlled thin pools that satisfy the victim's only path restrictions.
- Stage 3, realization: deposit a small LP position, mint inflated shares, redeem a disproportionate amount of pooled LP, burn the LP back into USDC and WETH, repay the loans, and keep the remainder.
The transaction remained permissionless end to end. No privileged key, whitelist, governance action, or private state was required.
6. Impact & Losses
The exploit depleted the victim pool's withdrawable USDC-WETH LP inventory and transferred value to the attacker after all flashloan repayments.
Measured losses from the victim-side LP unwind were:
1599512305raw USDC units (1599.512305USDC)785691973475409634raw WETH units (0.785691973475409634WETH)
The helper contract retained positive post-repayment balances, including 1597512305 raw USDC units and 654886372151164260 raw WETH units. The seed balance diff also shows that the attacker EOA paid gas and received 5369794355945257080190 residual fLP shares transferred from the helper in the same transaction.
7. References
The validation and report are based on the following concrete sources:
- Seed exploit transaction:
0x2b6d0af0dc513a15e325703405739057f9de6ef3f99934b957653b8a3fade4c6 - Victim contract: Flashstake
FarmingLPTokenat0xa44e79a2c9a8965e7a6fa77bf0ca8faf50e6c73e - Victim LP pair: USDC-WETH Sushiswap pair at
0x397ff1542f962076d0bfe58ea045ffa2d347aca0 - Victim reward venue: Sushi MasterChef at
0xc2edad668740f1aa35e4d8f227fb8e17dca888cd - Seed trace evidence showing flashloans, manipulated pool creation,
getAmountsOut,Deposit,EmergencyWithdraw, LP burn, and profit realization - Seed balance-diff evidence showing attacker profit, victim-pair reserve depletion, and LP movement