As per code comments, the calcLiquidityUnits() function is supposed to calculate:
// units = ((P (t B + T b))/(2 T B)) slipAdjustment
// P (part1 + part2) / (part3) * slipAdjustment
While part1, part2 and part3 are calculated correctly, they are combined as: uint _units = (((P part1) + part2) / part3); which is incorrect and should be: uint _units = ((P (part1 + part2)) / part3);
This incorrect calculation affects the liquidity calculations in addLiquidity() of Pools.sol and will lead to incorrect accounting. Protocol will break and funds will be lost.
Handle
0xRajeev
Vulnerability details
Impact
As per code comments, the calcLiquidityUnits() function is supposed to calculate:
// units = ((P (t B + T b))/(2 T B)) slipAdjustment // P (part1 + part2) / (part3) * slipAdjustment
While part1, part2 and part3 are calculated correctly, they are combined as: uint _units = (((P part1) + part2) / part3); which is incorrect and should be: uint _units = ((P (part1 + part2)) / part3);
This incorrect calculation affects the liquidity calculations in addLiquidity() of Pools.sol and will lead to incorrect accounting. Protocol will break and funds will be lost.
Proof of Concept
https://github.com/code-423n4/2021-04-vader/blob/3041f20c920821b89d01f652867d5207d18c8703/vader-protocol/contracts/Utils.sol#L229-L242
https://github.com/code-423n4/2021-04-vader/blob/3041f20c920821b89d01f652867d5207d18c8703/vader-protocol/contracts/Pools.sol#L69
Tools Used
Manual Analysis
Recommended Mitigation Steps
Fix the formulae used in the calculation as per code comments by changing L239 to: uint _units = ((P * (part1 + part2)) / part3);