-
Notifications
You must be signed in to change notification settings - Fork 75
improve: [L06] Add reentrancy guards to all public methods #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4d1c54b
65ef3f0
cc6853a
4c9afc7
8f10006
90e0b70
25ed799
6c6f917
f5186ac
83a3181
2907197
7aa2fa8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -310,6 +310,7 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| public | ||
| override | ||
| onlyOwner | ||
| nonReentrant | ||
| { | ||
| require(newProtocolFeeCapturePct <= 1e18, "Bad protocolFeeCapturePct"); | ||
| require(newProtocolFeeCaptureAddress != address(0), "Bad protocolFeeCaptureAddress"); | ||
|
|
@@ -351,7 +352,7 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| * @notice Sets root bundle proposal liveness period. Callable only by owner. | ||
| * @param newLiveness New liveness period. | ||
| */ | ||
| function setLiveness(uint32 newLiveness) public override onlyOwner { | ||
| function setLiveness(uint32 newLiveness) public override onlyOwner nonReentrant { | ||
| require(newLiveness > 10 minutes, "Liveness too short"); | ||
| liveness = newLiveness; | ||
| emit LivenessSet(newLiveness); | ||
|
|
@@ -383,7 +384,7 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| uint256 l2ChainId, | ||
| address adapter, | ||
| address spokePool | ||
| ) public override onlyOwner { | ||
| ) public override onlyOwner nonReentrant { | ||
| crossChainContracts[l2ChainId] = CrossChainContract(adapter, spokePool); | ||
| emit CrossChainContractsSet(l2ChainId, adapter, spokePool); | ||
| } | ||
|
|
@@ -461,7 +462,7 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| * @notice Disables LPs from providing liquidity for L1 token. Callable only by owner. | ||
| * @param l1Token Token to disable liquidity provision for. | ||
| */ | ||
| function disableL1TokenForLiquidityProvision(address l1Token) public override onlyOwner { | ||
| function disableL1TokenForLiquidityProvision(address l1Token) public override onlyOwner nonReentrant { | ||
| pooledTokens[l1Token].isEnabled = false; | ||
| emit L2TokenDisabledForLiquidityProvision(l1Token, pooledTokens[l1Token].lpToken); | ||
| } | ||
|
|
@@ -490,8 +491,8 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| // Since _exchangeRateCurrent() reads this contract's balance and updates contract state using it, it must be | ||
| // first before transferring any tokens to this contract to ensure synchronization. | ||
| uint256 lpTokensToMint = (l1TokenAmount * 1e18) / _exchangeRateCurrent(l1Token); | ||
| ExpandedIERC20(pooledTokens[l1Token].lpToken).mint(msg.sender, lpTokensToMint); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved token transfer "interaction" after any effects to follow CEI
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice. doing this + having the guard is best posible. importantly, you are doing this after the calls that modify tracking state so no risk in this change. |
||
| pooledTokens[l1Token].liquidReserves += l1TokenAmount; | ||
| ExpandedIERC20(pooledTokens[l1Token].lpToken).mint(msg.sender, lpTokensToMint); | ||
|
|
||
| if (address(weth) == l1Token && msg.value > 0) WETH9(address(l1Token)).deposit{ value: msg.value }(); | ||
| else IERC20(l1Token).safeTransferFrom(msg.sender, address(this), l1TokenAmount); | ||
|
|
@@ -518,7 +519,7 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
|
|
||
| ExpandedIERC20(pooledTokens[l1Token].lpToken).burnFrom(msg.sender, lpTokenAmount); | ||
| // Note this method does not make any liquidity utilization checks before letting the LP redeem their LP tokens. | ||
| // If they try access more funds that available (i.e l1TokensToReturn > liquidReserves) this will underflow. | ||
| // If they try access more funds than available (i.e l1TokensToReturn > liquidReserves) this will underflow. | ||
| pooledTokens[l1Token].liquidReserves -= l1TokensToReturn; | ||
|
|
||
| if (sendEth) { | ||
|
|
@@ -808,6 +809,9 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| customLiveness: liveness | ||
| }); | ||
|
|
||
| // Finally, delete the state pertaining to the active proposal so that another proposer can submit a new bundle. | ||
| delete rootBundleProposal; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rearranging for CEI |
||
|
|
||
| bondToken.safeTransferFrom(msg.sender, address(this), bondAmount); | ||
| bondToken.safeIncreaseAllowance(address(optimisticOracle), bondAmount); | ||
| optimisticOracle.disputePriceFor( | ||
|
|
@@ -820,19 +824,17 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| ); | ||
|
|
||
| emit RootBundleDisputed(msg.sender, currentTime, requestAncillaryData); | ||
|
|
||
| // Finally, delete the state pertaining to the active proposal so that another proposer can submit a new bundle. | ||
| delete rootBundleProposal; | ||
| } | ||
|
|
||
| /** | ||
| * @notice Send unclaimed accumulated protocol fees to fee capture address. | ||
| * @param l1Token Token whose protocol fees the caller wants to disburse. | ||
| */ | ||
| function claimProtocolFeesCaptured(address l1Token) public override nonReentrant { | ||
| IERC20(l1Token).safeTransfer(protocolFeeCaptureAddress, unclaimedAccumulatedProtocolFees[l1Token]); | ||
| emit ProtocolFeesCapturedClaimed(l1Token, unclaimedAccumulatedProtocolFees[l1Token]); | ||
| uint256 _unclaimedAccumulatedProtocolFees = unclaimedAccumulatedProtocolFees[l1Token]; | ||
| unclaimedAccumulatedProtocolFees[l1Token] = 0; | ||
| IERC20(l1Token).safeTransfer(protocolFeeCaptureAddress, _unclaimedAccumulatedProtocolFees); | ||
| emit ProtocolFeesCapturedClaimed(l1Token, _unclaimedAccumulatedProtocolFees); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -848,7 +850,7 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { | |
| * data in this ancillary data that is already included in the ProposeRootBundle event. | ||
| * @return ancillaryData Ancillary data that can be decoded into UTF8. | ||
| */ | ||
| function getRootBundleProposalAncillaryData() public view override returns (bytes memory ancillaryData) { | ||
| function getRootBundleProposalAncillaryData() public pure override returns (bytes memory ancillaryData) { | ||
| return ""; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.