Skip to content
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

feat: check custom gateway tokens withdrawal approval #2144

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
feat: check custom gateway tokens for withdrawal approval
  • Loading branch information
fionnachan committed Dec 16, 2024
commit cdc52f9879daa82949f7e2ef94a0946d2b1fb0e8
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Erc20Bridger } from '@arbitrum/sdk'
import { Erc20Bridger, getArbitrumNetwork } from '@arbitrum/sdk'
import { BigNumber, constants } from 'ethers'
import { ERC20__factory } from '@arbitrum/sdk/dist/lib/abi/factories/ERC20__factory'
import {
Expand All @@ -11,6 +11,7 @@ import {
TransferType
} from './BridgeTransferStarter'
import {
fetchErc20Allowance,
fetchErc20L2GatewayAddress,
getL1ERC20Address
} from '../util/TokenUtils'
Expand Down Expand Up @@ -86,6 +87,15 @@ export class Erc20WithdrawalStarter extends BridgeTransferStarter {
// no-op
}

/**
* Most tokens inherently allows the token gateway to burn whichever amount
* on the child chain for withdrawal because they inherited the
* IArbToken interface that allows the gateway to burn without allowance approval
*
* if the token does not have the bridgeBurn method, approval is required
* https://github.com/OffchainLabs/token-bridge-contracts/blob/d54877598e80a00d264d2b4353968faafd6f534d/contracts/tokenbridge/arbitrum/IArbToken.sol
*
*/
public requiresTokenApproval = async ({
amount,
signer
Expand All @@ -105,27 +115,44 @@ export class Erc20WithdrawalStarter extends BridgeTransferStarter {
this.destinationChainProvider
)

// check first if token is even eligible for allowance check on l2
const gatewayAddress = await this.getSourceChainGatewayAddress()

const sourceChainTokenBridge = getArbitrumNetwork(sourceChainId).tokenBridge

// tokens that use the standard gateways do not require approval on child chain
const standardGateways = [
sourceChainTokenBridge?.childErc20Gateway.toLowerCase(),
sourceChainTokenBridge?.childWethGateway.toLowerCase()
]

if (standardGateways.includes(gatewayAddress.toLowerCase())) {
return false
}

// the below checks are only run for tokens using custom gateway / custom custom gateway

// check if token is known to require withdrawal approval on child chain
// return true without checking if there is an existing allowance
// users might have already approved enough allowance, but it's rare
// so we can skip the check to save some calls
if (
(await tokenRequiresApprovalOnL2({
await tokenRequiresApprovalOnL2({
tokenAddressOnParentChain: destinationChainErc20Address,
parentChainId: destinationChainId,
childChainId: sourceChainId
})) &&
this.sourceChainErc20Address
})
) {
const token = ERC20__factory.connect(
this.sourceChainErc20Address,
this.sourceChainProvider
)

const gatewayAddress = await this.getSourceChainGatewayAddress()
const allowance = await token.allowance(address, gatewayAddress)

return allowance.lt(amount)
return true
}

return false
// a catch-all check for tokens not on the hardcoded list
const allowanceForSourceChainGateway = await fetchErc20Allowance({
address: this.sourceChainErc20Address,
provider: this.sourceChainProvider,
owner: address,
spender: gatewayAddress
})
return allowanceForSourceChainGateway.lt(amount)
}

public async approveTokenEstimateGas({ signer, amount }: ApproveTokenProps) {
Expand Down
8 changes: 0 additions & 8 deletions packages/arb-token-bridge-ui/src/util/L2ApprovalUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,6 @@ const L2ApproveTokens: { [chainId: number]: RequireL2ApproveToken[] } = {
l1Address: '0xd781cea0b8D5dDd0aeeD1dF7aC109C974A221B00',
l2Address: '0xe267c440dbfb1e185d506c2cc3c44eb21340e046'
}
],
// pop apex
[70700]: [
{
symbol: 'USDC.e',
l1Address: '0xaf88d065e77c8cc2239327c5edb3a432268e5831',
l2Address: '0x094ae96521f35284e04fdf023ca06fe878e307fd'
}
]
}

Expand Down
Loading