-
Notifications
You must be signed in to change notification settings - Fork 56
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
improve: Make changes after running Slither on SpokePool contracts #229
Changes from 26 commits
b9a38f8
d409fca
034e801
f4185df
6db44cd
38b3adf
cfdf07e
54e97c0
681a192
0ee774e
98b272b
dd41c7b
77b449a
c4c4771
7e2b7ed
ba9e88f
8adde77
6a9f509
2932946
c689fa2
ccec16e
c0bb1b1
b8fb099
22f5fbe
cb54ea7
5d13900
2ab13f6
c36e9d8
57855d1
bc58c17
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 |
---|---|---|
|
@@ -12,5 +12,8 @@ artifacts | |
cache-zk | ||
artifacts-zk | ||
|
||
# Upgradeability files | ||
.openzeppelin | ||
|
||
# IDE | ||
.idea |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.0; | |
import "./SpokePool.sol"; | ||
import "./interfaces/WETH9Interface.sol"; | ||
|
||
import "@eth-optimism/contracts/libraries/bridge/CrossDomainEnabled.sol"; | ||
import "@openzeppelin/contracts-upgradeable/crosschain/optimism/LibOptimismUpgradeable.sol"; | ||
import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; | ||
import "@eth-optimism/contracts/L2/messaging/IL2ERC20Bridge.sol"; | ||
|
||
|
@@ -16,13 +16,21 @@ interface SynthetixBridgeToBase { | |
/** | ||
* @notice OVM specific SpokePool. Uses OVM cross-domain-enabled logic to implement admin only access to functions. * Optimism and Boba each implement this spoke pool and set their chain specific contract addresses for l2Eth and l2Weth. | ||
*/ | ||
contract Ovm_SpokePool is CrossDomainEnabled, SpokePool { | ||
contract Ovm_SpokePool is SpokePool { | ||
// "l1Gas" parameter used in call to bridge tokens from this contract back to L1 via IL2ERC20Bridge. Currently | ||
// unused by bridge but included for future compatibility. | ||
uint32 public l1Gas = 5_000_000; | ||
uint32 public l1Gas; | ||
|
||
// ETH is an ERC20 on OVM. | ||
address public immutable l2Eth; | ||
address public l2Eth; | ||
|
||
// Address of the Optimism L2 messenger. | ||
address public messenger; | ||
|
||
// Reserve storage slots for future versions of this base contract to add state variables without | ||
// affecting the storage layout of child contracts. Decrement the size of __gap whenever state variables | ||
// are added. | ||
uint256[1000] private __gap; | ||
|
||
// Stores alternative token bridges to use for L2 tokens that don't go over the standard bridge. This is needed | ||
// to support non-standard ERC20 tokens on Optimism, such as DIA and SNX which both use custom bridges. | ||
|
@@ -38,19 +46,20 @@ contract Ovm_SpokePool is CrossDomainEnabled, SpokePool { | |
* relay hash collisions. | ||
* @param _crossDomainAdmin Cross domain admin to set. Can be changed by admin. | ||
* @param _hubPool Hub pool address to set. Can be changed by admin. | ||
* @param timerAddress Timer address to set. | ||
* @param _timerAddress Timer address to set. | ||
*/ | ||
constructor( | ||
function __OvmSpokePool_init( | ||
uint32 _initialDepositId, | ||
address _crossDomainAdmin, | ||
address _hubPool, | ||
address _l2Eth, | ||
address _wrappedNativeToken, | ||
address timerAddress | ||
) | ||
CrossDomainEnabled(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER) | ||
SpokePool(_initialDepositId, _crossDomainAdmin, _hubPool, _wrappedNativeToken, timerAddress) | ||
{ | ||
address _timerAddress | ||
) public onlyInitializing { | ||
l1Gas = 5_000_000; | ||
__SpokePool_init(_initialDepositId, _crossDomainAdmin, _hubPool, _wrappedNativeToken, _timerAddress); | ||
messenger = Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER; | ||
require(_l2Eth != address(0), "Invalid L2 ETH address"); | ||
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. Question: Slither recommends we add these zero address checks. It does add a fixed gas cost to construction but adds some safety. Thoughts? 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. I'm not sure about the value of these checks. 0 is only one possible invalid address, but there are ~infinitely many other invalid addresses as well. The only way we can really be confident that the address is set correctly is via post-deployment verification. I'm not firmly against it or anything, it just seems a bit redundant and might give a false sense of security. 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. i think I agree with your comment and will remove these zero address checks |
||
l2Eth = _l2Eth; | ||
} | ||
|
||
|
@@ -139,6 +148,7 @@ contract Ovm_SpokePool is CrossDomainEnabled, SpokePool { | |
// this logic inside a fallback method that executes when this contract receives ETH because ETH is an ERC20 | ||
// on the OVM. | ||
function _depositEthToWeth() internal { | ||
//slither-disable-next-line arbitrary-send-eth | ||
if (address(this).balance > 0) wrappedNativeToken.deposit{ value: address(this).balance }(); | ||
} | ||
|
||
|
@@ -172,5 +182,10 @@ contract Ovm_SpokePool is CrossDomainEnabled, SpokePool { | |
} | ||
|
||
// Apply OVM-specific transformation to cross domain admin address on L1. | ||
function _requireAdminSender() internal override onlyFromCrossDomainAccount(crossDomainAdmin) {} | ||
function _requireAdminSender() internal view override { | ||
require( | ||
LibOptimismUpgradeable.crossChainSender(messenger) == crossDomainAdmin, | ||
"OVM_XCHAIN: wrong sender of cross-domain message" | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity ^0.8.0; | ||
|
||
import "./Lockable.sol"; | ||
import "./interfaces/WETH9Interface.sol"; | ||
|
||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; | ||
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; | ||
import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; | ||
import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; | ||
|
||
// Polygon Registry contract that stores their addresses. | ||
interface PolygonRegistry { | ||
|
@@ -18,7 +18,7 @@ interface PolygonERC20Predicate { | |
} | ||
|
||
// ERC20s (on polygon) compatible with polygon's bridge have a withdraw method. | ||
interface PolygonIERC20 is IERC20 { | ||
interface PolygonIERC20Upgradeable is IERC20Upgradeable { | ||
function withdraw(uint256 amount) external; | ||
} | ||
|
||
|
@@ -38,9 +38,9 @@ interface MaticToken { | |
* This ultimately allows create2 to generate deterministic addresses that don't depend on the transaction count of the | ||
* sender. | ||
*/ | ||
contract PolygonTokenBridger is Lockable { | ||
using SafeERC20 for PolygonIERC20; | ||
using SafeERC20 for IERC20; | ||
contract PolygonTokenBridger is ReentrancyGuard { | ||
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. Slither had some complaints about Lockable but i figured this was a good time to use OZ's ReentrancyGuard instead 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. I don't think this contract will be in scope for the audit. Are we okay making this change? 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. good point, removed |
||
using SafeERC20Upgradeable for PolygonIERC20Upgradeable; | ||
using SafeERC20Upgradeable for IERC20Upgradeable; | ||
|
||
// Gas token for Polygon. | ||
MaticToken public constant maticToken = MaticToken(0x0000000000000000000000000000000000001010); | ||
|
@@ -90,6 +90,8 @@ contract PolygonTokenBridger is Lockable { | |
uint256 _l1ChainId, | ||
uint256 _l2ChainId | ||
) { | ||
require(_destination != address(0), "invalid dest address"); | ||
require(_l2WrappedMatic != address(0), "invalid wmatic address"); | ||
destination = _destination; | ||
l1PolygonRegistry = _l1PolygonRegistry; | ||
l1Weth = _l1Weth; | ||
|
@@ -104,7 +106,7 @@ contract PolygonTokenBridger is Lockable { | |
* @param token Token to bridge. | ||
* @param amount Amount to bridge. | ||
*/ | ||
function send(PolygonIERC20 token, uint256 amount) public nonReentrant onlyChainId(l2ChainId) { | ||
function send(PolygonIERC20Upgradeable token, uint256 amount) public nonReentrant onlyChainId(l2ChainId) { | ||
token.safeTransferFrom(msg.sender, address(this), amount); | ||
|
||
// In the wMatic case, this unwraps. For other ERC20s, this is the burn/send action. | ||
|
@@ -119,9 +121,10 @@ contract PolygonTokenBridger is Lockable { | |
* @notice Called by someone to send tokens to the destination, which should be set to the HubPool. | ||
* @param token Token to send to destination. | ||
*/ | ||
function retrieve(IERC20 token) public nonReentrant onlyChainId(l1ChainId) { | ||
function retrieve(IERC20Upgradeable token) public nonReentrant onlyChainId(l1ChainId) { | ||
if (address(token) == address(l1Weth)) { | ||
// For WETH, there is a pre-deposit step to ensure any ETH that has been sent to the contract is captured. | ||
//slither-disable-next-line arbitrary-send-eth | ||
l1Weth.deposit{ value: address(this).balance }(); | ||
} | ||
token.safeTransfer(destination, token.balanceOf(address(this))); | ||
|
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.
Should we make a shortcut for this via package.json?
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.
hmm i'm having trouble getting this to work from an npm run will look into it further