-
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
Conversation
| // 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved token transfer "interaction" after any effects to follow CEI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The 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.
contracts/HubPool.sol
Outdated
| // If they try access more funds than available (i.e l1TokensToReturn > liquidReserves) this will underflow. | ||
| pooledTokens[l1Token].liquidReserves -= l1TokensToReturn; | ||
|
|
||
| ExpandedIERC20(pooledTokens[l1Token].lpToken).burnFrom(msg.sender, lpTokenAmount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rearranging for CEI
| }); | ||
|
|
||
| // Finally, delete the state pertaining to the active proposal so that another proposer can submit a new bundle. | ||
| delete rootBundleProposal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rearranging for CEI
contracts/Arbitrum_SpokePool.sol
Outdated
|
|
||
| // Apply AVM-specific transformation to cross domain admin address on L1. | ||
| function _requireAdminSender() internal override onlyFromCrossDomainAdmin {} | ||
| function _requireAdminSender() internal override onlyFromCrossDomainAdmin nonReentrant {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is an internal method. why add it here? dont we only need it on the external/public functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes i'll add a comment. Basically we don't add the nonReentrant modifier to onlyAdmin functions in the base SpokePool contract because the Polygon_SpokePool will call these methods internally via the processMessageFromRoot. The other spoke pools like Optimism_SpokePool and Arbitrum_SpokePool have their admin functions triggered by an external contract so we should be reentrancy guarding those methods. However, in the Polygon_SpokePool case we need to reentrancy guard at the processMessageFromRoot method instead of at the admin functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this isn't equivalent to adding a re-entrancy guard to the admin function, right? It guarantees that this function wasn't re-entered, but it doesn't help us if that admin function re-enters a different function since it doesn't wrap the entire method, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah good point
mrice32
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's going to be difficult to make all the spoke pool admin methods non-reentrant when they're all called in such different ways.
The issue raised by OZ specifically applies to the HubPool, not the SpokePool right? So are these changes beyond the scope of the changes being requested?
contracts/Arbitrum_SpokePool.sol
Outdated
|
|
||
| // Apply AVM-specific transformation to cross domain admin address on L1. | ||
| function _requireAdminSender() internal override onlyFromCrossDomainAdmin {} | ||
| function _requireAdminSender() internal override onlyFromCrossDomainAdmin nonReentrant {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this isn't equivalent to adding a re-entrancy guard to the admin function, right? It guarantees that this function wasn't re-entered, but it doesn't help us if that admin function re-enters a different function since it doesn't wrap the entire method, no?
mrice32
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
No description provided.