#44083 [SC-Insight] Inconsistency in `CurvePoolUtil`
Description
Brief/Intro
/**
* @notice Returns the IBT and PT amounts received for burning a given amount of LP tokens
* @notice Method to be used with legacy Curve Cryptoswap pools
* @param _curvePool The address of the curve pool
* @param _lpTokenAmount The amount of the lp token to burn
* @return minAmounts The expected respective amounts of IBT and PT withdrawn from the curve pool
*/
function previewRemoveLiquidity(
address _curvePool,
uint256 _lpTokenAmount
) external view returns (uint256[2] memory minAmounts) {
address lpToken = ICurvePool(_curvePool).token();
uint256 totalSupply = IERC20(lpToken).totalSupply();
(uint256 ibtBalance, uint256 ptBalance) = _getCurvePoolBalances(_curvePool);
// decrement following what Curve is doing
if (_lpTokenAmount > APPROXIMATION_DECREMENT && totalSupply != 0) {
_lpTokenAmount -= APPROXIMATION_DECREMENT;
minAmounts = [
(ibtBalance * _lpTokenAmount) / totalSupply,
(ptBalance * _lpTokenAmount) / totalSupply
];
} else {
minAmounts = [uint256(0), uint256(0)];
}
}
/**
* @notice Returns the IBT and PT amounts received for burning a given amount of LP tokens
* @notice Method to be used with Curve Cryptoswap NG pools
* @param _curvePool The address of the curve pool
* @param _lpTokenAmount The amount of the lp token to burn
* @return minAmounts The expected respective amounts of IBT and PT withdrawn from the curve pool
*/
function previewRemoveLiquidityNG(
address _curvePool,
uint256 _lpTokenAmount
) external view returns (uint256[2] memory minAmounts) {
uint256 totalSupply = ICurveNGPool(_curvePool).totalSupply();
(uint256 ibtBalance, uint256 ptBalance) = _getCurvePoolBalances(_curvePool);
// reproduces Curve implementation
if (_lpTokenAmount == totalSupply) {
minAmounts = [ibtBalance, ptBalance];
} else if (_lpTokenAmount > APPROXIMATION_DECREMENT && totalSupply != 0) {
_lpTokenAmount -= APPROXIMATION_DECREMENT;
minAmounts = [
ibtBalance.mulDiv(_lpTokenAmount, totalSupply),
ptBalance.mulDiv(_lpTokenAmount, totalSupply)
];
} else {
minAmounts = [uint256(0), uint256(0)];
}
}
/**
* @notice Returns the IBT and PT amounts received for burning a given amount of LP tokens
* @notice Method to be used with StableSwap NG pools
* @param _curvePool The address of the curve pool
* @param _lpTokenAmount The amount of the lp token to burn
* @return minAmounts The expected respective amounts of IBT and PT withdrawn from the curve pool
*/
function previewRemoveLiquiditySNG(
address _curvePool,
uint256 _lpTokenAmount
) external view returns (uint256[] memory) {
uint256 totalSupply = IERC20(_curvePool).totalSupply();
(uint256 ibtBalance, uint256 ptBalance) = _getCurvePoolBalances(_curvePool);
// decrement following what Curve is doing
uint256[] memory minAmounts = new uint256[](2);
if (_lpTokenAmount > APPROXIMATION_DECREMENT && totalSupply != 0) {
_lpTokenAmount -= APPROXIMATION_DECREMENT;
minAmounts[0] = (ibtBalance * _lpTokenAmount) / totalSupply;
minAmounts[1] = (ptBalance * _lpTokenAmount) / totalSupply;
} else {
minAmounts[0] = 0;
minAmounts[1] = 0;
}
return minAmounts;
}Recommendation
Proof of Concept
Proof of Concept
Previous#43464 [SC-Insight] Refactoring `Router.sol` for gas savings and reducing code redundancy from two different `Router::execute()` which can result in undesirable outcomes for potentially delayed tra...Next#43912 [SC-Low] Lack of ETH Success Transfer Checks in Dispatcher.sol
Was this helpful?