From 027226b618b13d3a41f586b8d597fc92f4daafd2 Mon Sep 17 00:00:00 2001 From: Rajath Alex Date: Fri, 3 Jan 2025 09:54:25 -0500 Subject: [PATCH] fix: Rewards v2 audit fixes (#346) * fix: using SafeERC20 * docs: comment --- src/ServiceManagerBase.sol | 24 ++++++++++------------- src/unaudited/ECDSAServiceManagerBase.sol | 23 ++++++++++------------ 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/ServiceManagerBase.sol b/src/ServiceManagerBase.sol index 76a3f6ad..65a5a152 100644 --- a/src/ServiceManagerBase.sol +++ b/src/ServiceManagerBase.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.12; import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; @@ -18,6 +20,7 @@ import {BitmapUtils} from "./libraries/BitmapUtils.sol"; * @author Layr Labs, Inc. */ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { + using SafeERC20 for IERC20; using BitmapUtils for *; /// @notice when applied to a function, only allows the RegistryCoordinator to call it @@ -97,18 +100,14 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { for (uint256 i = 0; i < rewardsSubmissions.length; ++i) { // transfer token to ServiceManager and approve RewardsCoordinator to transfer again // in createAVSRewardsSubmission() call - rewardsSubmissions[i].token.transferFrom( + rewardsSubmissions[i].token.safeTransferFrom( msg.sender, address(this), rewardsSubmissions[i].amount ); - uint256 allowance = rewardsSubmissions[i].token.allowance( - address(this), - address(_rewardsCoordinator) - ); - rewardsSubmissions[i].token.approve( + rewardsSubmissions[i].token.safeIncreaseAllowance( address(_rewardsCoordinator), - rewardsSubmissions[i].amount + allowance + rewardsSubmissions[i].amount ); } @@ -152,18 +151,15 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { } // Transfer token to ServiceManager and approve RewardsCoordinator to transfer again - // in createAVSPerformanceRewardsSubmission() call - operatorDirectedRewardsSubmissions[i].token.transferFrom( + // in createOperatorDirectedAVSRewardsSubmission() call + operatorDirectedRewardsSubmissions[i].token.safeTransferFrom( msg.sender, address(this), totalAmount ); - uint256 allowance = operatorDirectedRewardsSubmissions[i] - .token - .allowance(address(this), address(_rewardsCoordinator)); - operatorDirectedRewardsSubmissions[i].token.approve( + operatorDirectedRewardsSubmissions[i].token.safeIncreaseAllowance( address(_rewardsCoordinator), - totalAmount + allowance + totalAmount ); } diff --git a/src/unaudited/ECDSAServiceManagerBase.sol b/src/unaudited/ECDSAServiceManagerBase.sol index 6ad640b4..91738da5 100644 --- a/src/unaudited/ECDSAServiceManagerBase.sol +++ b/src/unaudited/ECDSAServiceManagerBase.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.12; import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {IServiceManager} from "../interfaces/IServiceManager.sol"; @@ -17,6 +19,8 @@ abstract contract ECDSAServiceManagerBase is IServiceManager, OwnableUpgradeable { + using SafeERC20 for IERC20; + /// @notice Address of the stake registry contract, which manages registration and stake recording. address public immutable stakeRegistry; @@ -198,18 +202,14 @@ abstract contract ECDSAServiceManagerBase is IRewardsCoordinator.RewardsSubmission[] calldata rewardsSubmissions ) internal virtual { for (uint256 i = 0; i < rewardsSubmissions.length; ++i) { - rewardsSubmissions[i].token.transferFrom( + rewardsSubmissions[i].token.safeTransferFrom( msg.sender, address(this), rewardsSubmissions[i].amount ); - uint256 allowance = rewardsSubmissions[i].token.allowance( - address(this), - rewardsCoordinator - ); - rewardsSubmissions[i].token.approve( + rewardsSubmissions[i].token.safeIncreaseAllowance( rewardsCoordinator, - rewardsSubmissions[i].amount + allowance + rewardsSubmissions[i].amount ); } @@ -247,17 +247,14 @@ abstract contract ECDSAServiceManagerBase is // Transfer token to ServiceManager and approve RewardsCoordinator to transfer again // in createOperatorDirectedAVSRewardsSubmission() call - operatorDirectedRewardsSubmissions[i].token.transferFrom( + operatorDirectedRewardsSubmissions[i].token.safeTransferFrom( msg.sender, address(this), totalAmount ); - uint256 allowance = operatorDirectedRewardsSubmissions[i] - .token - .allowance(address(this), rewardsCoordinator); - operatorDirectedRewardsSubmissions[i].token.approve( + operatorDirectedRewardsSubmissions[i].token.safeIncreaseAllowance( rewardsCoordinator, - totalAmount + allowance + totalAmount ); }