Skip to content

Commit b251c10

Browse files
authored
L-01 Custom Gas Tokens Can Get Stuck In HubPool (#975)
Signed-off-by: bennett <bennett@umaproject.org>
1 parent 4c78547 commit b251c10

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter {
182182
uint256 amount,
183183
address to
184184
) external payable override {
185+
// The Hub Pool will always bridge via CCTP to a ZkStack network if CCTP is enabled for that network. Therefore, we can short-circuit ZkStack-specific logic
186+
// like pulling custom gas or getting the shared bridge address if CCTP is enabled and we are bridging USDC.
187+
if (l1Token == address(usdcToken) && _isCCTPEnabled()) {
188+
_transferUsdc(to, amount);
189+
emit TokensRelayed(l1Token, l2Token, amount, to);
190+
return;
191+
}
185192
// A bypass proxy seems to no longer be needed to avoid deposit limits. The tracking of these limits seems to be deprecated.
186193
// See: https://github.com/matter-labs/era-contracts/blob/bce4b2d0f34bd87f1aaadd291772935afb1c3bd6/l1-contracts/contracts/bridge/L1ERC20Bridge.sol#L54-L55
187194
uint256 txBaseCost = _pullCustomGas(L2_GAS_LIMIT);
@@ -225,25 +232,22 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter {
225232
})
226233
);
227234
} else if (l1Token == address(usdcToken)) {
228-
if (_isCCTPEnabled()) {
229-
_transferUsdc(to, amount);
230-
} else {
231-
IERC20(CUSTOM_GAS_TOKEN).forceApprove(USDC_SHARED_BRIDGE, txBaseCost);
232-
IERC20(l1Token).forceApprove(USDC_SHARED_BRIDGE, amount);
233-
txHash = BRIDGE_HUB.requestL2TransactionTwoBridges(
234-
BridgeHubInterface.L2TransactionRequestTwoBridgesOuter({
235-
chainId: CHAIN_ID,
236-
mintValue: txBaseCost,
237-
l2Value: 0,
238-
l2GasLimit: L2_GAS_LIMIT,
239-
l2GasPerPubdataByteLimit: L1_GAS_TO_L2_GAS_PER_PUB_DATA_LIMIT,
240-
refundRecipient: L2_REFUND_ADDRESS,
241-
secondBridgeAddress: USDC_SHARED_BRIDGE,
242-
secondBridgeValue: 0,
243-
secondBridgeCalldata: _secondBridgeCalldata(to, l1Token, amount)
244-
})
245-
);
246-
}
235+
// Since we already checked if we are bridging USDC via CCTP, if this conditional is hit, then we must be bridging USDC via the `USDC_SHARED_BRIDGE`.
236+
IERC20(CUSTOM_GAS_TOKEN).forceApprove(USDC_SHARED_BRIDGE, txBaseCost);
237+
IERC20(l1Token).forceApprove(USDC_SHARED_BRIDGE, amount);
238+
txHash = BRIDGE_HUB.requestL2TransactionTwoBridges(
239+
BridgeHubInterface.L2TransactionRequestTwoBridgesOuter({
240+
chainId: CHAIN_ID,
241+
mintValue: txBaseCost,
242+
l2Value: 0,
243+
l2GasLimit: L2_GAS_LIMIT,
244+
l2GasPerPubdataByteLimit: L1_GAS_TO_L2_GAS_PER_PUB_DATA_LIMIT,
245+
refundRecipient: L2_REFUND_ADDRESS,
246+
secondBridgeAddress: USDC_SHARED_BRIDGE,
247+
secondBridgeValue: 0,
248+
secondBridgeCalldata: _secondBridgeCalldata(to, l1Token, amount)
249+
})
250+
);
247251
} else {
248252
// An standard bridged ERC20, separate from WETH and Circle Bridged/Native USDC.
249253
IERC20(CUSTOM_GAS_TOKEN).forceApprove(sharedBridge, txBaseCost);

0 commit comments

Comments
 (0)