diff --git a/src/contracts/core/AVSDirectory.sol b/src/contracts/core/AVSDirectory.sol index 0e9af8741..8e932dfd8 100644 --- a/src/contracts/core/AVSDirectory.sol +++ b/src/contracts/core/AVSDirectory.sol @@ -3,10 +3,12 @@ pragma solidity ^0.8.27; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; -import "../mixins/SignatureUtils.sol"; import "../permissions/Pausable.sol"; + +import "../mixins/ReentrancyGuardMixin.sol"; +import "../mixins/SignatureUtils.sol"; + import "./AVSDirectoryStorage.sol"; contract AVSDirectory is @@ -14,7 +16,7 @@ contract AVSDirectory is OwnableUpgradeable, Pausable, AVSDirectoryStorage, - ReentrancyGuardUpgradeable, + ReentrancyGuardMixin, SignatureUtils { /** diff --git a/src/contracts/core/AllocationManager.sol b/src/contracts/core/AllocationManager.sol index 2c77cc02b..0ce9852a9 100644 --- a/src/contracts/core/AllocationManager.sol +++ b/src/contracts/core/AllocationManager.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.27; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; +import "../mixins/ReentrancyGuardMixin.sol"; import "../mixins/PermissionControllerMixin.sol"; import "../permissions/Pausable.sol"; import "../libraries/SlashingLib.sol"; @@ -16,7 +16,7 @@ contract AllocationManager is OwnableUpgradeable, Pausable, AllocationManagerStorage, - ReentrancyGuardUpgradeable, + ReentrancyGuardMixin, PermissionControllerMixin { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; diff --git a/src/contracts/core/DelegationManager.sol b/src/contracts/core/DelegationManager.sol index 2d5350b40..092e61b3b 100644 --- a/src/contracts/core/DelegationManager.sol +++ b/src/contracts/core/DelegationManager.sol @@ -3,13 +3,16 @@ pragma solidity ^0.8.27; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; +import "../permissions/Pausable.sol"; + +import "../mixins/ReentrancyGuardMixin.sol"; import "../mixins/SignatureUtils.sol"; import "../mixins/PermissionControllerMixin.sol"; -import "../permissions/Pausable.sol"; + import "../libraries/SlashingLib.sol"; import "../libraries/Snapshots.sol"; + import "./DelegationManagerStorage.sol"; /** @@ -27,7 +30,7 @@ contract DelegationManager is OwnableUpgradeable, Pausable, DelegationManagerStorage, - ReentrancyGuardUpgradeable, + ReentrancyGuardMixin, SignatureUtils, PermissionControllerMixin { diff --git a/src/contracts/core/RewardsCoordinator.sol b/src/contracts/core/RewardsCoordinator.sol index 13e2569d5..bb3c32417 100644 --- a/src/contracts/core/RewardsCoordinator.sol +++ b/src/contracts/core/RewardsCoordinator.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.27; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "../mixins/ReentrancyGuardMixin.sol"; import "../libraries/Merkle.sol"; import "../permissions/Pausable.sol"; import "./RewardsCoordinatorStorage.sol"; @@ -24,7 +24,7 @@ contract RewardsCoordinator is Initializable, OwnableUpgradeable, Pausable, - ReentrancyGuardUpgradeable, + ReentrancyGuardMixin, RewardsCoordinatorStorage, PermissionControllerMixin { diff --git a/src/contracts/core/StrategyManager.sol b/src/contracts/core/StrategyManager.sol index 3f986fede..67dee9cda 100644 --- a/src/contracts/core/StrategyManager.sol +++ b/src/contracts/core/StrategyManager.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.27; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "../mixins/ReentrancyGuardMixin.sol"; import "../mixins/SignatureUtils.sol"; import "../interfaces/IEigenPodManager.sol"; import "../permissions/Pausable.sol"; @@ -23,7 +23,7 @@ import "./StrategyManagerStorage.sol"; contract StrategyManager is Initializable, OwnableUpgradeable, - ReentrancyGuardUpgradeable, + ReentrancyGuardMixin, Pausable, StrategyManagerStorage, SignatureUtils diff --git a/src/contracts/mixins/ReentrancyGuardMixin.sol b/src/contracts/mixins/ReentrancyGuardMixin.sol new file mode 100644 index 000000000..f58600ae8 --- /dev/null +++ b/src/contracts/mixins/ReentrancyGuardMixin.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +/** + * @dev Variant of {ReentrancyGuard} that uses transient storage. + * + * NOTE: This variant only works on networks where EIP-1153 is available. + */ +abstract contract ReentrancyGuardMixin { + // keccak256(abi.encode(uint256(keccak256("eigenlayer.storage.ReentrancyGuardMixin")) - 1)) & ~bytes32(uint256(0xff)) + uint256 private constant _REENTRANCY_GUARD_SLOT = + 0x61bb794ad7a504b3613420bc192fca11ecb0ea36bf99527d17aa6bd66a5db500; + + /// @dev Unauthorized reentrant call. + error Reentrancy(); + + /// @dev Guards a function from reentrancy. + modifier nonReentrant() virtual { + uint256 s = _REENTRANCY_GUARD_SLOT; + /// @solidity memory-safe-assembly + assembly { + if tload(s) { + mstore(0x00, 0xab143c06) // `Reentrancy()`. + revert(0x1c, 0x04) + } + tstore(s, address()) + } + _; + /// @solidity memory-safe-assembly + assembly { + tstore(s, 0) + } + } +} \ No newline at end of file diff --git a/src/contracts/pods/EigenPod.sol b/src/contracts/pods/EigenPod.sol index 1066b2fbf..0e8884d61 100644 --- a/src/contracts/pods/EigenPod.sol +++ b/src/contracts/pods/EigenPod.sol @@ -2,9 +2,10 @@ pragma solidity ^0.8.27; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "../mixins/ReentrancyGuardMixin.sol"; + import "../libraries/BeaconChainProofs.sol"; import "../libraries/BytesLib.sol"; @@ -23,7 +24,7 @@ import "./EigenPodStorage.sol"; * @dev Note that all beacon chain balances are stored as gwei within the beacon chain datastructures. We choose * to account balances in terms of gwei in the EigenPod contract and convert to wei when making calls to other contracts */ -contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingConstants, EigenPodStorage { +contract EigenPod is Initializable, ReentrancyGuardMixin, EigenPodPausingConstants, EigenPodStorage { using BytesLib for bytes; using SafeERC20 for IERC20; using BeaconChainProofs for *; diff --git a/src/contracts/pods/EigenPodManager.sol b/src/contracts/pods/EigenPodManager.sol index c15b60f8f..1d454789b 100644 --- a/src/contracts/pods/EigenPodManager.sol +++ b/src/contracts/pods/EigenPodManager.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.27; import "@openzeppelin/contracts/utils/Create2.sol"; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import "@openzeppelin-upgrades/contracts/security/ReentrancyGuardUpgradeable.sol"; +import "../mixins/ReentrancyGuardMixin.sol"; import "../libraries/SlashingLib.sol"; import "../permissions/Pausable.sol"; import "./EigenPodPausingConstants.sol"; @@ -27,7 +27,7 @@ contract EigenPodManager is Pausable, EigenPodPausingConstants, EigenPodManagerStorage, - ReentrancyGuardUpgradeable + ReentrancyGuardMixin { using SlashingLib for *; using Math for *;