Skip to content

Commit 37e2b93

Browse files
committed
feat: Add Reentrancy Guards (SC-1224)
1 parent 6418283 commit 37e2b93

29 files changed

+899
-123
lines changed

src/ForeignController.sol

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import { OptionsBuilder } from "layerzerolabs/oapp-evm/contracts/oapp/libs/Optio
88

99
import { IMetaMorpho, Id, MarketAllocation } from "metamorpho/interfaces/IMetaMorpho.sol";
1010

11-
import { AccessControlEnumerable } from "openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol";
11+
import { AccessControlEnumerable } from "../lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol";
12+
import { ReentrancyGuard } from "../lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol";
1213

13-
import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";
14-
import { IERC4626 } from "openzeppelin-contracts/contracts/interfaces/IERC4626.sol";
14+
import { IERC20 } from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
15+
import { IERC4626 } from "../lib/openzeppelin-contracts/contracts/interfaces/IERC4626.sol";
1516

1617
import { IPSM3 } from "spark-psm/src/interfaces/IPSM3.sol";
1718

@@ -31,7 +32,7 @@ interface ISparkVaultLike {
3132
function take(uint256 assetAmount) external;
3233
}
3334

34-
contract ForeignController is AccessControlEnumerable {
35+
contract ForeignController is ReentrancyGuard, AccessControlEnumerable {
3536

3637
using OptionsBuilder for bytes;
3738

@@ -131,8 +132,7 @@ contract ForeignController is AccessControlEnumerable {
131132
/**********************************************************************************************/
132133

133134
function setMaxSlippage(address pool, uint256 maxSlippage)
134-
external
135-
onlyRole(DEFAULT_ADMIN_ROLE)
135+
external nonReentrant onlyRole(DEFAULT_ADMIN_ROLE)
136136
{
137137
require(pool != address(0), "ForeignController/pool-zero-address");
138138

@@ -141,16 +141,14 @@ contract ForeignController is AccessControlEnumerable {
141141
}
142142

143143
function setMintRecipient(uint32 destinationDomain, bytes32 mintRecipient)
144-
external
145-
onlyRole(DEFAULT_ADMIN_ROLE)
144+
external nonReentrant onlyRole(DEFAULT_ADMIN_ROLE)
146145
{
147146
mintRecipients[destinationDomain] = mintRecipient;
148147
emit MintRecipientSet(destinationDomain, mintRecipient);
149148
}
150149

151150
function setLayerZeroRecipient(uint32 destinationEndpointId, bytes32 layerZeroRecipient)
152-
external
153-
onlyRole(DEFAULT_ADMIN_ROLE)
151+
external nonReentrant onlyRole(DEFAULT_ADMIN_ROLE)
154152
{
155153
layerZeroRecipients[destinationEndpointId] = layerZeroRecipient;
156154
emit LayerZeroRecipientSet(destinationEndpointId, layerZeroRecipient);
@@ -160,7 +158,7 @@ contract ForeignController is AccessControlEnumerable {
160158
/*** Freezer functions ***/
161159
/**********************************************************************************************/
162160

163-
function removeRelayer(address relayer) external onlyRole(FREEZER) {
161+
function removeRelayer(address relayer) external nonReentrant onlyRole(FREEZER) {
164162
_revokeRole(RELAYER, relayer);
165163
emit RelayerRemoved(relayer);
166164
}
@@ -170,8 +168,7 @@ contract ForeignController is AccessControlEnumerable {
170168
/**********************************************************************************************/
171169

172170
function transferAsset(address asset, address destination, uint256 amount)
173-
external
174-
onlyRole(RELAYER)
171+
external nonReentrant onlyRole(RELAYER)
175172
{
176173
_rateLimited(
177174
RateLimitHelpers.makeAddressAddressKey(LIMIT_ASSET_TRANSFER, asset, destination),
@@ -195,6 +192,7 @@ contract ForeignController is AccessControlEnumerable {
195192

196193
function depositPSM(address asset, uint256 amount)
197194
external
195+
nonReentrant
198196
onlyRole(RELAYER)
199197
rateLimitedAddress(LIMIT_PSM_DEPOSIT, asset, amount)
200198
returns (uint256 shares)
@@ -217,9 +215,7 @@ contract ForeignController is AccessControlEnumerable {
217215

218216
// NOTE: !!! Rate limited at end of function !!!
219217
function withdrawPSM(address asset, uint256 maxAmount)
220-
external
221-
onlyRole(RELAYER)
222-
returns (uint256 assetsWithdrawn)
218+
external nonReentrant onlyRole(RELAYER) returns (uint256 assetsWithdrawn)
223219
{
224220
// Withdraw up to `maxAmount` of `asset` in the PSM, decode the result
225221
// to get `assetsWithdrawn` (assumes the proxy has enough PSM shares).
@@ -246,6 +242,7 @@ contract ForeignController is AccessControlEnumerable {
246242

247243
function transferUSDCToCCTP(uint256 usdcAmount, uint32 destinationDomain)
248244
external
245+
nonReentrant
249246
onlyRole(RELAYER)
250247
rateLimited(LIMIT_USDC_TO_CCTP, usdcAmount)
251248
rateLimited(
@@ -282,7 +279,7 @@ contract ForeignController is AccessControlEnumerable {
282279
uint256 amount,
283280
uint32 destinationEndpointId
284281
)
285-
external payable
282+
external payable nonReentrant
286283
{
287284
_checkRole(RELAYER);
288285
_rateLimited(
@@ -328,6 +325,7 @@ contract ForeignController is AccessControlEnumerable {
328325

329326
function depositERC4626(address token, uint256 amount)
330327
external
328+
nonReentrant
331329
onlyRole(RELAYER)
332330
rateLimitedAddress(LIMIT_4626_DEPOSIT, token, amount)
333331
returns (uint256 shares)
@@ -351,12 +349,13 @@ contract ForeignController is AccessControlEnumerable {
351349

352350
require(
353351
IERC4626(token).convertToAssets(shares) >= amount * maxSlippages[token] / 1e18,
354-
"ForeignController/inflated-shares"
352+
"ForeignController/inflated-shares"
355353
);
356354
}
357355

358356
function withdrawERC4626(address token, uint256 amount)
359357
external
358+
nonReentrant
360359
onlyRole(RELAYER)
361360
rateLimitedAddress(LIMIT_4626_WITHDRAW, token, amount)
362361
returns (uint256 shares)
@@ -379,9 +378,7 @@ contract ForeignController is AccessControlEnumerable {
379378

380379
// NOTE: !!! Rate limited at end of function !!!
381380
function redeemERC4626(address token, uint256 shares)
382-
external
383-
onlyRole(RELAYER)
384-
returns (uint256 assets)
381+
external nonReentrant onlyRole(RELAYER) returns (uint256 assets)
385382
{
386383
// Redeem shares for assets from the token, decode the resulting assets.
387384
// Assumes proxy has adequate token shares.
@@ -409,6 +406,7 @@ contract ForeignController is AccessControlEnumerable {
409406

410407
function depositAave(address aToken, uint256 amount)
411408
external
409+
nonReentrant
412410
onlyRole(RELAYER)
413411
rateLimitedAddress(LIMIT_AAVE_DEPOSIT, aToken, amount)
414412
{
@@ -438,9 +436,7 @@ contract ForeignController is AccessControlEnumerable {
438436

439437
// NOTE: !!! Rate limited at end of function !!!
440438
function withdrawAave(address aToken, uint256 amount)
441-
external
442-
onlyRole(RELAYER)
443-
returns (uint256 amountWithdrawn)
439+
external nonReentrant onlyRole(RELAYER) returns (uint256 amountWithdrawn)
444440
{
445441
IAavePool pool = IAavePool(IATokenWithPool(aToken).POOL());
446442

@@ -474,6 +470,7 @@ contract ForeignController is AccessControlEnumerable {
474470

475471
function setSupplyQueueMorpho(address morphoVault, Id[] memory newSupplyQueue)
476472
external
473+
nonReentrant
477474
onlyRole(RELAYER)
478475
rateLimitExists(RateLimitHelpers.makeAddressKey(LIMIT_4626_DEPOSIT, morphoVault))
479476
{
@@ -485,6 +482,7 @@ contract ForeignController is AccessControlEnumerable {
485482

486483
function updateWithdrawQueueMorpho(address morphoVault, uint256[] calldata indexes)
487484
external
485+
nonReentrant
488486
onlyRole(RELAYER)
489487
rateLimitExists(RateLimitHelpers.makeAddressKey(LIMIT_4626_DEPOSIT, morphoVault))
490488
{
@@ -496,6 +494,7 @@ contract ForeignController is AccessControlEnumerable {
496494

497495
function reallocateMorpho(address morphoVault, MarketAllocation[] calldata allocations)
498496
external
497+
nonReentrant
499498
onlyRole(RELAYER)
500499
rateLimitExists(RateLimitHelpers.makeAddressKey(LIMIT_4626_DEPOSIT, morphoVault))
501500
{
@@ -511,6 +510,7 @@ contract ForeignController is AccessControlEnumerable {
511510

512511
function takeFromSparkVault(address sparkVault, uint256 assetAmount)
513512
external
513+
nonReentrant
514514
onlyRole(RELAYER)
515515
rateLimitedAddress(LIMIT_SPARK_VAULT_TAKE, sparkVault, assetAmount)
516516
{

0 commit comments

Comments
 (0)