This repository has been archived by the owner on May 26, 2023. It is now read-only.
xiaoming90 - Users deposit assets to the vault but receives no strategy token in return #16
Labels
High
A valid High severity issue
Reward
A payout will be made for this issue
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
xiaoming90
high
Users deposit assets to the vault but receives no strategy token in return
Summary
Due to a rounding error in Solidity, it is possible that a user deposits assets to the vault, but receives no strategy token in return due to issues in the following functions:
Vulnerability Detail
Within the
StrategyUtils._convertBPTClaimToStrategyTokens
function, it was observed that the numerator precision (1e8) is much smaller than the denominator precision (1e18).https://github.com/sherlock-audit/2022-12-notional/blob/main/contracts/vaults/balancer/internal/strategy/StrategyUtils.sol#L27
As a result, the
StrategyUtils._convertBPTClaimToStrategyTokens
function might return zero strategy tokens under the following two conditions:If the
totalBPTHeld
is zero (First Deposit)If the
totalBPTHeld
is zero, the code at Line 31 will be executed, and the following formula is used:During the first deposit, if the user deposits less than 1e10 BPT, Solidity will round down and
strategyTokenAmount
will be zero.If the
totalBPTHeld
is larger than zero (Subsequently Deposits)If the
totalBPTHeld
is larger than zero, the code at Line 38 will be executed, and the following formula is used:If the numerator is less than the denominator, the
strategyTokenAmount
will be zero.Therefore, it is possible that the users deposited their minted BPT to the vault, but received zero strategy tokens in return.
https://github.com/sherlock-audit/2022-12-notional/blob/main/contracts/vaults/balancer/internal/pool/Boosted3TokenPoolUtils.sol#L408
Proof-of-Concept
Assume that Alice is the first depositor, and she forwarded 10000 BPT. During the first mint, the strategy token will be minted in a 1:1 ratio. Therefore, Alice will receive 10000 strategy tokens in return. At this point in time,
totalStrategyTokenGlobal
= 10000 strategy tokens andtotalBPTHeld
is 10000 BPT.When Bob deposits to the vault after Alice, he will be subjected to the following formula:
If Bob deposits less than 1e10 BPT, Solidity will round down and
strategyTokenAmount
will be zero. Bob will receive no strategy token in return for his BPT.Another side effect of this issue is that if Alice withdraws all her strategy tokens, she will get back all her 10000 BPT plus the BPT that Bob deposited earlier.
Impact
Loss of assets for the users as they deposited their assets but receive zero strategy tokens in return.
Code Snippet
https://github.com/sherlock-audit/2022-12-notional/blob/main/contracts/vaults/balancer/internal/pool/Boosted3TokenPoolUtils.sol#L408
https://github.com/sherlock-audit/2022-12-notional/blob/main/contracts/vaults/balancer/internal/pool/TwoTokenPoolUtils.sol#L153
Tool used
Manual Review
Recommendation
Consider reverting if zero strategy token is minted. This check has been implemented in many well-known vault designs as this is a commonly known issue (e.g. Solmate)
function _deposit( ThreeTokenPoolContext memory poolContext, StrategyContext memory strategyContext, AuraStakingContext memory stakingContext, BoostedOracleContext memory oracleContext, uint256 deposit, uint256 minBPT ) internal returns (uint256 strategyTokensMinted) { uint256 bptMinted = poolContext._joinPoolAndStake({ strategyContext: strategyContext, stakingContext: stakingContext, oracleContext: oracleContext, deposit: deposit, minBPT: minBPT }); strategyTokensMinted = strategyContext._convertBPTClaimToStrategyTokens(bptMinted); + require(strategyTokensMinted != 0, "zero strategy token minted"); strategyContext.vaultState.totalBPTHeld += bptMinted; // Update global supply count strategyContext.vaultState.totalStrategyTokenGlobal += strategyTokensMinted.toUint80(); strategyContext.vaultState.setStrategyVaultState(); }
The text was updated successfully, but these errors were encountered: