Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 7 additions & 34 deletions contracts/Arbitrum_SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,47 +45,18 @@ contract Arbitrum_SpokePool is SpokePoolInterface, SpokePool {
_;
}

/**************************************
* CROSS-CHAIN ADMIN FUNCTIONS *
**************************************/
/********************************************************
* ARBITRUM-SPECIFIC CROSS-CHAIN ADMIN FUNCTIONS *
********************************************************/

function setL2GatewayRouter(address newL2GatewayRouter) public onlyFromCrossDomainAdmin nonReentrant {
function setL2GatewayRouter(address newL2GatewayRouter) public onlyAdmin nonReentrant {
_setL2GatewayRouter(newL2GatewayRouter);
}

function whitelistToken(address l2Token, address l1Token) public onlyFromCrossDomainAdmin nonReentrant {
function whitelistToken(address l2Token, address l1Token) public onlyAdmin nonReentrant {
_whitelistToken(l2Token, l1Token);
}

function setCrossDomainAdmin(address newCrossDomainAdmin) public override onlyFromCrossDomainAdmin nonReentrant {
_setCrossDomainAdmin(newCrossDomainAdmin);
}

function setHubPool(address newHubPool) public override onlyFromCrossDomainAdmin nonReentrant {
_setHubPool(newHubPool);
}

function setEnableRoute(
address originToken,
uint256 destinationChainId,
bool enable
) public override onlyFromCrossDomainAdmin nonReentrant {
_setEnableRoute(originToken, destinationChainId, enable);
}

function setDepositQuoteTimeBuffer(uint32 buffer) public override onlyFromCrossDomainAdmin nonReentrant {
_setDepositQuoteTimeBuffer(buffer);
}

function relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot)
public
override
onlyFromCrossDomainAdmin
nonReentrant
{
_relayRootBundle(relayerRefundRoot, slowRelayRoot);
}

/**************************************
* INTERNAL FUNCTIONS *
**************************************/
Expand Down Expand Up @@ -116,4 +87,6 @@ contract Arbitrum_SpokePool is SpokePoolInterface, SpokePool {
l2Address = address(uint160(l1Address) + uint160(0x1111000000000000000000000000000000001111));
}
}

function _requireAdminSender() internal override onlyFromCrossDomainAdmin {}
}
28 changes: 3 additions & 25 deletions contracts/Ethereum_SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,12 @@ contract Ethereum_SpokePool is SpokePoolInterface, SpokePool, Ownable {
) SpokePool(msg.sender, _hubPool, _wethAddress, timerAddress) {}

/**************************************
* ADMIN FUNCTIONS *
* INTERNAL FUNCTIONS *
**************************************/

function setCrossDomainAdmin(address newCrossDomainAdmin) public override onlyOwner nonReentrant {
_setCrossDomainAdmin(newCrossDomainAdmin);
}

function setHubPool(address newHubPool) public override onlyOwner nonReentrant {
_setHubPool(newHubPool);
}

function setEnableRoute(
address originToken,
uint256 destinationChainId,
bool enable
) public override onlyOwner nonReentrant {
_setEnableRoute(originToken, destinationChainId, enable);
}

function setDepositQuoteTimeBuffer(uint32 buffer) public override onlyOwner nonReentrant {
_setDepositQuoteTimeBuffer(buffer);
}

function relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot) public override onlyOwner nonReentrant {
_relayRootBundle(relayerRefundRoot, slowRelayRoot);
}

function _bridgeTokensToHubPool(RelayerRefundLeaf memory relayerRefundLeaf) internal override {
IERC20(relayerRefundLeaf.l2TokenAddress).transfer(hubPool, relayerRefundLeaf.amountToReturn);
}

function _requireAdminSender() internal override onlyOwner {}
}
58 changes: 8 additions & 50 deletions contracts/Optimism_SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,51 +32,13 @@ contract Optimism_SpokePool is CrossDomainEnabled, SpokePoolInterface, SpokePool
SpokePool(_crossDomainAdmin, _hubPool, 0x4200000000000000000000000000000000000006, timerAddress)
{}

/**************************************
* CROSS-CHAIN ADMIN FUNCTIONS *
**************************************/

function setL1GasLimit(uint32 newl1Gas) public onlyFromCrossDomainAccount(crossDomainAdmin) {
_setL1GasLimit(newl1Gas);
}

function setCrossDomainAdmin(address newCrossDomainAdmin)
public
override
onlyFromCrossDomainAccount(crossDomainAdmin)
nonReentrant
{
_setCrossDomainAdmin(newCrossDomainAdmin);
}

function setHubPool(address newHubPool) public override onlyFromCrossDomainAccount(crossDomainAdmin) nonReentrant {
_setHubPool(newHubPool);
}
/*******************************************
* OPTIMISM-SPECIFIC ADMIN FUNCTIONS *
*******************************************/

function setEnableRoute(
address originToken,
uint256 destinationChainId,
bool enable
) public override onlyFromCrossDomainAccount(crossDomainAdmin) nonReentrant {
_setEnableRoute(originToken, destinationChainId, enable);
}

function setDepositQuoteTimeBuffer(uint32 buffer)
public
override
onlyFromCrossDomainAccount(crossDomainAdmin)
nonReentrant
{
_setDepositQuoteTimeBuffer(buffer);
}

function relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot)
public
override
onlyFromCrossDomainAccount(crossDomainAdmin)
nonReentrant
{
_relayRootBundle(relayerRefundRoot, slowRelayRoot);
function setL1GasLimit(uint32 newl1Gas) public onlyAdmin {
l1Gas = newl1Gas;
emit SetL1Gas(newl1Gas);
}

/**************************************
Expand Down Expand Up @@ -123,18 +85,12 @@ contract Optimism_SpokePool is CrossDomainEnabled, SpokePoolInterface, SpokePool
/**************************************
* INTERNAL FUNCTIONS *
**************************************/

function _depositEthToWeth() internal {
// Wrap any ETH owned by this contract so we can send expected L2 token to recipient. This is neccessary because
// this SpokePool will receive ETH from the canonical token bridge instead of WETH.
if (address(this).balance > 0) weth.deposit{ value: address(this).balance }();
}

function _setL1GasLimit(uint32 _l1Gas) internal {
l1Gas = _l1Gas;
emit SetL1Gas(l1Gas);
}

function _bridgeTokensToHubPool(RelayerRefundLeaf memory relayerRefundLeaf) internal override {
// If the token being bridged is WETH then we need to first unwrap it to ETH and then send ETH over the
// canonical bridge. On Optimism, this is address 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000.
Expand All @@ -152,4 +108,6 @@ contract Optimism_SpokePool is CrossDomainEnabled, SpokePoolInterface, SpokePool

emit OptimismTokensBridged(relayerRefundLeaf.l2TokenAddress, hubPool, relayerRefundLeaf.amountToReturn, l1Gas);
}

function _requireAdminSender() internal override onlyFromCrossDomainAccount(crossDomainAdmin) {}
}
63 changes: 39 additions & 24 deletions contracts/SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,36 +154,50 @@ abstract contract SpokePool is SpokePoolInterface, Testable, Lockable, MultiCall
_;
}

modifier onlyAdmin() {
_requireAdminSender();
_;
}

/**************************************
* ADMIN FUNCTIONS *
**************************************/

function _setCrossDomainAdmin(address newCrossDomainAdmin) internal {
require(newCrossDomainAdmin != address(0), "Bad bridge router address");
crossDomainAdmin = newCrossDomainAdmin;
emit SetXDomainAdmin(crossDomainAdmin);
function setCrossDomainAdmin(address newCrossDomainAdmin) public override onlyAdmin nonReentrant {
_setCrossDomainAdmin(newCrossDomainAdmin);
}

function _setHubPool(address newHubPool) internal {
require(newHubPool != address(0), "Bad hub pool address");
hubPool = newHubPool;
emit SetHubPool(hubPool);
function setHubPool(address newHubPool) public override onlyAdmin nonReentrant {
_setHubPool(newHubPool);
}

function _setEnableRoute(
function setEnableRoute(
address originToken,
uint256 destinationChainId,
bool enabled
) internal {
) public override onlyAdmin nonReentrant {
enabledDepositRoutes[originToken][destinationChainId] = enabled;
emit EnabledDepositRoute(originToken, destinationChainId, enabled);
}

function _setDepositQuoteTimeBuffer(uint32 _depositQuoteTimeBuffer) internal {
function setDepositQuoteTimeBuffer(uint32 _depositQuoteTimeBuffer) public override onlyAdmin nonReentrant {
depositQuoteTimeBuffer = _depositQuoteTimeBuffer;
emit SetDepositQuoteTimeBuffer(_depositQuoteTimeBuffer);
}

// This internal method should be called by an external "relayRootBundle" function that validates the
// cross domain sender is the HubPool. This validation step differs for each L2, which is why the implementation
// specifics are left to the implementor of this abstract contract.
// Once this method is executed and a distribution root is stored in this contract, then `distributeRootBundle`
// can be called to execute each leaf in the root.
function relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot) public override onlyAdmin nonReentrant {
uint32 rootBundleId = uint32(rootBundles.length);
RootBundle storage rootBundle = rootBundles.push();
rootBundle.relayerRefundRoot = relayerRefundRoot;
rootBundle.slowRelayRoot = slowRelayRoot;
emit RelayedRootBundle(rootBundleId, relayerRefundRoot, slowRelayRoot);
}

/**************************************
* DEPOSITOR FUNCTIONS *
**************************************/
Expand Down Expand Up @@ -468,6 +482,18 @@ abstract contract SpokePool is SpokePoolInterface, Testable, Lockable, MultiCall
_emitExecutedSlowRelayRoot(relayHash, fillAmountPreFees, relayData);
}

function _setCrossDomainAdmin(address newCrossDomainAdmin) internal {
require(newCrossDomainAdmin != address(0), "Bad bridge router address");
crossDomainAdmin = newCrossDomainAdmin;
emit SetXDomainAdmin(crossDomainAdmin);
}

function _setHubPool(address newHubPool) internal {
require(newHubPool != address(0), "Bad hub pool address");
hubPool = newHubPool;
emit SetHubPool(hubPool);
}

function _bridgeTokensToHubPool(SpokePoolInterface.RelayerRefundLeaf memory relayerRefundLeaf) internal virtual;

// Allow L2 to implement chain specific recovering of signers from signatures because some L2s might not support
Expand Down Expand Up @@ -510,19 +536,6 @@ abstract contract SpokePool is SpokePoolInterface, Testable, Lockable, MultiCall
}
}

// This internal method should be called by an external "relayRootBundle" function that validates the
// cross domain sender is the HubPool. This validation step differs for each L2, which is why the implementation
// specifics are left to the implementor of this abstract contract.
// Once this method is executed and a distribution root is stored in this contract, then `distributeRootBundle`
// can be called to execute each leaf in the root.
function _relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot) internal {
uint32 rootBundleId = uint32(rootBundles.length);
RootBundle storage rootBundle = rootBundles.push();
rootBundle.relayerRefundRoot = relayerRefundRoot;
rootBundle.slowRelayRoot = slowRelayRoot;
emit RelayedRootBundle(rootBundleId, relayerRefundRoot, slowRelayRoot);
}

function _fillRelay(
bytes32 relayHash,
RelayData memory relayData,
Expand Down Expand Up @@ -620,6 +633,8 @@ abstract contract SpokePool is SpokePoolInterface, Testable, Lockable, MultiCall
);
}

function _requireAdminSender() internal virtual;

// Added to enable the this contract to receive ETH. Used when unwrapping Weth.
receive() external payable {}
}
26 changes: 2 additions & 24 deletions contracts/test/MockSpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,7 @@ contract MockSpokePool is SpokePoolInterface, SpokePool {
address timerAddress
) SpokePool(_crossDomainAdmin, _hubPool, _wethAddress, timerAddress) {}

function setCrossDomainAdmin(address newCrossDomainAdmin) public override {
_setCrossDomainAdmin(newCrossDomainAdmin);
}

function setHubPool(address newHubPool) public override {
_setHubPool(newHubPool);
}

function setEnableRoute(
address originToken,
uint256 destinationChainId,
bool enable
) public override {
_setEnableRoute(originToken, destinationChainId, enable);
}

function setDepositQuoteTimeBuffer(uint32 buffer) public override {
_setDepositQuoteTimeBuffer(buffer);
}

function relayRootBundle(bytes32 relayerRefundRoot, bytes32 slowRelayRoot) public override {
_relayRootBundle(relayerRefundRoot, slowRelayRoot);
}

function _bridgeTokensToHubPool(RelayerRefundLeaf memory relayerRefundLeaf) internal override {}

function _requireAdminSender() internal override {}
}