Standard Gateway

The movement of ERC-20 tokens between L2 and L3 implies that each chain must have a corresponding ERC-20 token contract.

This requires developers or project builders to deploy an additional ERC-20 token contract on L3 and register the necessary information in the GatewayRouter contract to ensure proper request routing.

However, when using the Standard Gateway, these additional steps are not required, allowing immediate use of the bridge without extra configurations.

If no paired ERC-20 contract exists on L3 at the time of the first deposit request, the contract is automatically deployed.

Transactions are routed through the Standard Gateway, and the entire process is handled automatically during the initial deposit request, ensuring a seamless and efficient onboarding experience.

The dKargo Token Bridge is a dApp built using Arbitrum’s Retryable Ticket mechanism. A Retryable Ticket allows an L2 transaction to be generated and executed on L3. Through this mechanism, users can initiate L3 transactions directly from L2. The required transaction fees are paid in ERC-20 DKA on L2.

ERC-20 Deposit

The deposit process refers to transferring ERC-20 tokens from Arbitrum Chain (L2) to dKargo Chain (L3). This process is executed in multiple steps through the collaboration of the Arbitrum-deployed token bridge contract and the dKargo sequencer.

STEP 1 - Approving L2 ERC-20 Tokens & L2 ERC-20 DKA

Before transferring ERC-20 tokens from L2 to L3(dKargo), the Standard Gateway contract must be granted approval to access the user’s ERC-20 tokens on L2.

const depositAmount = parseEther('1');
const res = await tokenBridge.approveToken({
  erc20ParentAddress: parentERC20.address,
  parentSigner,
  amount:depositAmount
});

const receipt = await res.wait();      
console.log(`approve ERC20 token to L2 Standard Gateway Contract tx hash: ${receipt.transactionHash}`)

const allowance = await tokenBridge.allowanceTokenToGateway(
  parentERC20.address,
  parentSigner.address,
  parentProvider
);
console.log(`allowance amount: ${allowance}`

Additionally, since transaction fees on L3 are paid in ERC-20 DKA (Gas Token) on L2, the Standard Gateway contract must also be separately approved to access ERC-20 DKA.

const res = await tokenBridge.approveGasToken({
  erc20ParentAddress: parentERC20.address,
  parentSigner,
});

const receipt = await res.wait();      
console.log(`approve DKA token to L2 Standard Gateway Contract tx hash: ${receipt.transactionHash}`)

const allowance = await tokenBridge.allowanceGasTokenToGateway(
  parentERC20.address,
  parentSigner.address,
  parentProvider
);
console.log(`allowance amount: ${allowance}`

If null is entered instead of depositAmount as a parameter, the maximum available amount will be approved. Normally, an approval is required each time a deposit is made through the bridge. However, setting it this way allows for a one-time approval, eliminating the need for additional approvals in future transactions.

STEP 2 - Deposit Token

Once approval is complete, the outboundTransfer() method of the L2 GatewayRouter contract is called to initiate the deposit.

  • The L2 GatewayRouter routes the deposit request to the L2 Standard Gateway.

  • The Standard Gateway transfers the ERC-20 tokens to its contract and sends the required L2 ERC-20 DKA to the bridge contract as a transaction fee.

const res = await tokenBridge.deposit({
  amount: depositAmount,
  erc20ParentAddress: parentERC20.address,
  parentSigner,
  childProvider,
});

const receipt = await res.wait();      
console.log(`deposit erc20 token L2 tx hash: ${receipt.transactionHash}`)

The deposited ERC-20 tokens are then locked in the Standard Gateway contract deployed on Arbitrum, ensuring their security during the bridging process.

If this is the first deposit attempt, an ERC-20 contract is automatically deployed on L3. The deployed ERC-20 contract is implemented based on StandardArbERC20.sol..

STEP 3 - Checking Deposit Status

Transferring ERC-20 tokens to the Standard Gateway does not result in an immediate deposit on L3.

The deposit status will initially be marked as "Pending", and after approximately 10 minutes, the tokens will be minted to the recipient’s account on dKargo Chain (L3).

// The transaction remains in a pending state until the message is executed on the dKargo chain.
await receipt.waitForChildTransactionReceipt(childProvider);

The deposit status can be checked on dScanner’s L2 ➔ L3 Transactions page.

The deposit request sent to the Standard Gateway on L2 includes a message that calls bridgeMint() on the L3 ERC-20 contract. This message is verified by the sequencer and executed through the L3 Standard Gateway, triggering the minting of tokens, which are then deposited into the user’s account on L3.

Withdrawal ERC-20

The withdrawal process refers to transferring ERC-20 tokens from dKargo Chain (L3) to Arbitrum Chain (L2). This process is executed in multiple steps through the collaboration of the Arbitrum-deployed token bridge contract and the dKargo sequencer.

STEP 1 - Withdrawing ERC-20 Tokens

The ERC-20 withdrawal process is initiated by calling the outboundTransfer() method of the L3 GatewayRouter.

The L3 GatewayRouter routes the withdrawal request to the L3 Standard Gateway.

The L3 Standard Gateway burns the specified amount of ERC-20 tokens on L3. Once this is completed, an equivalent amount of L2 ERC-20 tokens, previously locked in the L2 Standard Gateway, will be released to the user according to the procedure.

const res = await tokenBridge.withdraw({
  erc20ParentAddress: parentERC20.address,
  childSigner,
  amount,
  destinationAddress: parentSigner.address,
});

const receipt = await res.wait();
console.log(`withdraw erc20 token L3 tx hash: ${receipt.transactionHash}`)

The withdrawal request sent to the L3 Standard Gateway includes a message that calls bridgeBurn() on the L3 ERC-20 contract. This message burns the requested L3 tokens. Simultaneously, it grants permission to the L2 Standard Gateway to release the equivalent amount of L2 tokens that were previously locked.

STEP 2: Checking Withdraw Status

After submitting a withdrawal request, ERC-20 tokens on L2 can only be claimed after a dispute period of approximately 6.4 days. During this period, the withdrawal status remains pending.

const message = await receipt.getChildToParentMessages(parentProvider);

// The withdrawal remains in a pending state until the 6.4-day dispute period has passed.
await message[0].waitUntilReadyToExecute(childProvider);

The withdrawal status can be checked on dScanner’s [L3 ➔ L2 Transactions] page.

STEP 3: Claiming ERC-20 Tokens

Once the dispute period ends, the user becomes eligible to claim the withdrawn ERC-20 tokens from the L2 Standard Gateway. Users can finalize the withdrawal by claiming the ERC-20 tokens via the Outbox contract.

const message = await receipt.getChildToParentMessages(parentSigner);
const res = await message[0].execute(childProvider);
const executeReceipt = await res.wait();
console.log(`claim erc20 token L2 tx hash: ${executeReceipt.transactionHash}`)

Last updated