31335 - [SC - High] getActualSupply should be used instead of total...
Submitted on May 17th 2024 at 11:44:53 UTC by @OxAnmol for Boost | Alchemix
Report ID: #31335
Report type: Smart Contract
Report severity: High
Target: https://github.com/alchemix-finance/alchemix-v2-dao/blob/main/src/RewardsDistributor.sol
Impacts:
Theft of unclaimed yield
Description
Brief/Intro
The rewardDistributor:_depositIntoBalancerPool uses totalSupply from the balance pool to calculate the expected BPT amount out. But the balancer docs recommend using getActualSupply instead of totalSupply.
Vulnerability Details
totalSupply function in the balancer doesn’t account for protocol fees and unminted tokens which means the totalSupply doesn't' correctly reflect the actual supply of BPT. The balancer recommends using getActualSupply to get the correct total supply of the BPT tokens.
https://docs.balancer.fi/concepts/advanced/valuing-bpt/valuing-bpt.html#getting-bpt-supply
https://github.com/balancer/balancer-v2-monorepo/blob/ac63d64018c6331248c7d77b9f317a06cced0243/pkg/pool-weighted/contracts/WeightedPool.sol#L332
In our case, the BPT total supply function is used to calculate the bptAmountOut
https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/RewardsDistributor.sol#L410
bptAmountOut here acts like a slippage protection for add liquidity and this parameter is very important for sandwich protection. If the total supply is used instead of getActualSupply then the bptAmountOut can be significantly low and this can be vulnerable to sandwich attacks resulting in the loss of BPT for a user.
Impact Details
Users can receive less BPT because of sandwich attacks resulting in the loss of unclaimed yield for the user. Please follow this and
this for further clarity in the issue.
References
https://github.com/alchemix-finance/alchemix-v2-dao/blob/f1007439ad3a32e412468c4c42f62f676822dc1f/src/RewardsDistributor.sol#L414
https://github.com/balancer/balancer-v2-monorepo/blob/ac63d64018c6331248c7d77b9f317a06cced0243/pkg/pool-weighted/contracts/WeightedPool.sol#L325C1-L345C1
https://docs.balancer.fi/concepts/advanced/valuing-bpt/valuing-bpt.html#getting-bpt-supply
##Recommedation use getActualSupply instead of totalSupply
Proof of Concept
Here I have added a new interface IBalancerPool, edited the RewardDistributor:_depositIntoBalancerPool in RewardDistributor and used getTotalSupply to get bptAmountOut2 The console log is used to show the difference between the two outputs.
add this test in Voting.t.sol
Console Outputs
As we can see the bptAmountOut2 calculated using getTotalSupply is greater than bptAmountOut. The difference here might seem small but this will largely depend on the trading volume of the balancer pool.
Last updated
Was this helpful?