@@ -5,18 +5,26 @@ import "./SpokePool.sol";
55import "@scroll-tech/contracts/L2/gateways/IL2GatewayRouter.sol " ;
66import "@scroll-tech/contracts/libraries/IScrollMessenger.sol " ;
77
8+ interface IL2GatewayRouterExtended is IL2GatewayRouter {
9+ function defaultERC20Gateway () external view returns (address );
10+
11+ function getERC20Gateway (address ) external view returns (address );
12+ }
13+
814/**
915 * @title Scroll_SpokePool
1016 * @notice Modified SpokePool contract deployed on Scroll to facilitate token transfers
1117 * from Scroll to the HubPool
1218 * @custom:security-contact [email protected] 1319 */
1420contract Scroll_SpokePool is SpokePool {
21+ using SafeERC20Upgradeable for IERC20Upgradeable ;
22+
1523 /**
1624 * @notice The address of the official l2GatewayRouter contract for Scroll for bridging tokens from L2 -> L1
1725 * @dev We can find these (main/test)net deployments here: https://docs.scroll.io/en/developers/scroll-contracts/#scroll-contracts
1826 */
19- IL2GatewayRouter public l2GatewayRouter;
27+ IL2GatewayRouterExtended public l2GatewayRouter;
2028
2129 /**
2230 * @notice The address of the official messenger contract for Scroll from L2 -> L1
@@ -51,7 +59,7 @@ contract Scroll_SpokePool is SpokePool {
5159 * @param _hubPool Hub pool address to set. Can be changed by admin.
5260 */
5361 function initialize (
54- IL2GatewayRouter _l2GatewayRouter ,
62+ IL2GatewayRouterExtended _l2GatewayRouter ,
5563 IScrollMessenger _l2ScrollMessenger ,
5664 uint32 _initialDepositId ,
5765 address _crossDomainAdmin ,
@@ -66,7 +74,7 @@ contract Scroll_SpokePool is SpokePool {
6674 * @notice Change the L2 Gateway Router. Changed only by admin.
6775 * @param _l2GatewayRouter New address of L2 gateway router.
6876 */
69- function setL2GatewayRouter (IL2GatewayRouter _l2GatewayRouter ) public onlyAdmin nonReentrant {
77+ function setL2GatewayRouter (IL2GatewayRouterExtended _l2GatewayRouter ) public onlyAdmin nonReentrant {
7078 _setL2GatewayRouter (_l2GatewayRouter);
7179 }
7280
@@ -88,9 +96,14 @@ contract Scroll_SpokePool is SpokePool {
8896 * @param l2TokenAddress Address of the token to bridge.
8997 */
9098 function _bridgeTokensToHubPool (uint256 amountToReturn , address l2TokenAddress ) internal virtual override {
91- // The scroll bridge handles arbitrary ERC20 tokens and is mindful of
92- // the official WETH address on-chain. We don't need to do anything specific
93- // to differentiate between WETH and a separate ERC20.
99+ // Tokens with a custom ERC20 gateway require an approval in order to withdraw.
100+ address erc20Gateway = l2GatewayRouter.getERC20Gateway (l2TokenAddress);
101+ if (erc20Gateway != l2GatewayRouter.defaultERC20Gateway ()) {
102+ IERC20Upgradeable (l2TokenAddress).safeIncreaseAllowance (erc20Gateway, amountToReturn);
103+ }
104+
105+ // The scroll bridge handles arbitrary ERC20 tokens and is mindful of the official WETH address on-chain.
106+ // We don't need to do anything specific to differentiate between WETH and a separate ERC20.
94107 // Note: This happens due to the L2GatewayRouter.getERC20Gateway() call
95108 l2GatewayRouter.withdrawERC20 (
96109 l2TokenAddress,
@@ -116,7 +129,7 @@ contract Scroll_SpokePool is SpokePool {
116129 require (_xDomainSender == crossDomainAdmin, "Sender must be admin " );
117130 }
118131
119- function _setL2GatewayRouter (IL2GatewayRouter _l2GatewayRouter ) internal {
132+ function _setL2GatewayRouter (IL2GatewayRouterExtended _l2GatewayRouter ) internal {
120133 address oldL2GatewayRouter = address (l2GatewayRouter);
121134 l2GatewayRouter = _l2GatewayRouter;
122135 emit SetL2GatewayRouter (address (_l2GatewayRouter), oldL2GatewayRouter);
0 commit comments