```\nfunc MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger *common.Address) (*Withdrawal, error) {\n // Attempt to parse the value\n value, err := withdrawal.Value()\n if err != nil {\n  return nil, fmt.Errorf("cannot migrate withdrawal: %w", err)\n }\n\n abi, err := bindings.L1CrossDomainMessengerMetaData.GetAbi()\n if err != nil {\n  return nil, err\n }\n\n // Migrated withdrawals are specified as version 0. Both the\n // L2ToL1MessagePasser and the CrossDomainMessenger use the same\n // versioning scheme. Both should be set to version 0\n versionedNonce := EncodeVersionedNonce(withdrawal.XDomainNonce, new(big.Int))\n // Encode the call to `relayMessage` on the `CrossDomainMessenger`.\n // The minGasLimit can safely be 0 here.\n data, err := abi.Pack(\n  "relayMessage",\n  versionedNonce,\n  withdrawal.XDomainSender,\n  withdrawal.XDomainTarget,\n  value,\n  new(big.Int), // <= THIS IS THE INNER GAS LIMIT BEING SET TO ZERO\n  []byte(withdrawal.XDomainData),\n )\n if err != nil {\n  return nil, fmt.Errorf("cannot abi encode relayMessage: %w", err)\n }\n\n gasLimit := MigrateWithdrawalGasLimit(data)\n\n w := NewWithdrawal(\n  versionedNonce,\n  &predeploys.L2CrossDomainMessengerAddr,\n  l1CrossDomainMessenger,\n  value,\n  new(big.Int).SetUint64(gasLimit), // <= THIS IS THE OUTER GAS LIMIT BEING SET\n  data,\n )\n return w, nil\n}\n```\n