This practice grants an unlimited allowance to these addresses, which could lead to potential security risks if any of these external contracts are compromised.
This approach, while reducing the need for repeated allowance transactions, increases the risk of token loss if the trusted external contracts are exploited.
An attacker who gains control over any of the external contracts with unlimited allowances could potentially drain the respective contract's token balances by transferring the approved tokens to an unauthorized address. This could result in a significant loss of funds and damage the trust in the contract's security.
function _replaceDepositToken(address oldToken_, address newToken_) private {
bool isTokenChanged_ = oldToken_ != newToken_;
- if (oldToken_ != address(0) && isTokenChanged_) {
- // Remove allowance from stETH to wstETH
- IERC20(unwrappedDepositToken).approve(oldToken_, 0);
- }
if (isTokenChanged_) {
- // Get stETH from wstETH
- address unwrappedToken_ = IWStETH(newToken_).stETH();
- // Increase allowance from stETH to wstETH. To exchange stETH for wstETH
- IERC20(unwrappedToken_).approve(newToken_, type(uint256).max);
unwrappedDepositToken = unwrappedToken_;
}
}
function sendDepositToken(
uint256 gasLimit_,
uint256 maxFeePerGas_,
uint256 maxSubmissionCost_
) external payable onlyDistribution returns (bytes memory) {
DepositTokenConfig storage config = depositTokenConfig;
// Get current stETH balance
uint256 amountUnwrappedToken_ = IERC20(unwrappedDepositToken).balanceOf(address(this));
// Wrap all stETH to wstETH
+ IERC20(unwrappedToken_).approve(config.token, amountUnwrappedToken_);
uint256 amount_ = IWStETH(config.token).wrap(amountUnwrappedToken_);
bytes memory data_ = abi.encode(maxSubmissionCost_, "");
return
IGatewayRouter(config.gateway).outboundTransfer{value: msg.value}(
config.token,
config.receiver,
amount_,
gasLimit_,
maxFeePerGas_,
data_
);
}
function swap(uint256 amountIn_, uint256 amountOutMinimum_) external onlyOwner returns (uint256) {
SwapParams memory params_ = params;
+ TransferHelper.safeApprove(params_.tokenIn, router, amountIn_);
ISwapRouter.ExactInputSingleParams memory swapParams_ = ISwapRouter.ExactInputSingleParams({
tokenIn: params_.tokenIn,
tokenOut: params_.tokenOut,
fee: params_.fee,
recipient: address(this),
deadline: block.timestamp,
amountIn: amountIn_,
amountOutMinimum: amountOutMinimum_,
sqrtPriceLimitX96: params_.sqrtPriceLimitX96
});
uint256 amountOut_ = ISwapRouter(router).exactInputSingle(swapParams_);
emit TokensSwapped(params_.tokenIn, params_.tokenOut, amountIn_, amountOut_, amountOutMinimum_);
return amountOut_;
}
function increaseLiquidityCurrentRange(
uint256 tokenId_,
uint256 depositTokenAmountAdd_,
uint256 rewardTokenAmountAdd_,
uint256 depositTokenAmountMin_,
uint256 rewardTokenAmountMin_
) external onlyOwner returns (uint128 liquidity_, uint256 amount0_, uint256 amount1_) {
uint256 amountAdd0_;
uint256 amountAdd1_;
uint256 amountMin0_;
uint256 amountMin1_;
(, , address token0_, , , , , , , , , ) = INonfungiblePositionManager(nonfungiblePositionManager).positions(
tokenId_
if (token0_ == params.tokenIn) {
amountAdd0_ = depositTokenAmountAdd_;
amountAdd1_ = rewardTokenAmountAdd_;
amountMin0_ = depositTokenAmountMin_;
amountMin1_ = rewardTokenAmountMin_;
+ TransferHelper.safeApprove(params.tokenIn, nonfungiblePositionManager, amountAdd0_);
+ TransferHelper.safeApprove(params.tokenOut, nonfungiblePositionManager, amountAdd1_);
} else {
amountAdd0_ = rewardTokenAmountAdd_;
amountAdd1_ = depositTokenAmountAdd_;
amountMin0_ = rewardTokenAmountMin_;
amountMin1_ = depositTokenAmountMin_;
+ TransferHelper.safeApprove(params.tokenOut, nonfungiblePositionManager, amountAdd0_);
+ TransferHelper.safeApprove(params.tokenIn, nonfungiblePositionManager, amountAdd1_);
}
INonfungiblePositionManager.IncreaseLiquidityParams memory params_ = INonfungiblePositionManager
.IncreaseLiquidityParams({
tokenId: tokenId_,
amount0Desired: amountAdd0_,
amount1Desired: amountAdd1_,
amount0Min: amountMin0_,
amount1Min: amountMin1_,
deadline: block.timestamp
});
(liquidity_, amount0_, amount1_) = INonfungiblePositionManager(nonfungiblePositionManager).increaseLiquidity(
params_
);
emit LiquidityIncreased(tokenId_, amount0_, amount1_, liquidity_, amountMin0_, amountMin1_);
}
function _editParams(SwapParams memory newParams_) private {
require(newParams_.tokenIn != address(0), "L2TR: invalid tokenIn");
require(newParams_.tokenOut != address(0), "L2TR: invalid tokenOut");
- TransferHelper.safeApprove(newParams_.tokenIn, router, type(uint256).max);
- TransferHelper.safeApprove(newParams_.tokenIn, nonfungiblePositionManager, type(uint256).max);
- TransferHelper.safeApprove(newParams_.tokenOut, nonfungiblePositionManager, type(uint256).max);
params = newParams_;
}