Skip to content

Commit 32e99fd

Browse files
committed
fix: correctly get the L2 retryable in send-to-l2, and other improvements
1 parent 19de7a2 commit 32e99fd

File tree

2 files changed

+68
-22
lines changed

2 files changed

+68
-22
lines changed

cli/commands/bridge/to-l1.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { L2GraphTokenGateway } from '../../../build/types/L2GraphTokenGateway'
99
import { BigNumber } from 'ethers'
1010
import { JsonRpcProvider } from '@ethersproject/providers'
1111
import { providers } from 'ethers'
12+
import { L2GraphToken } from '../../../build/types/L2GraphToken'
1213

1314
const FOURTEEN_DAYS_IN_SECONDS = 24 * 3600 * 14
1415

@@ -77,12 +78,17 @@ export const startSendToL1 = async (cli: CLIEnvironment, cliArgs: CLIArgs): Prom
7778
const l2AddressBook = getAddressBook(cliArgs.addressBook, l2ChainId.toString())
7879

7980
const gateway = loadAddressBookContract('L2GraphTokenGateway', l2AddressBook, l2Wallet)
80-
const l2GRT = loadAddressBookContract('L2GraphToken', l2AddressBook, l2Wallet)
81+
const l2GRT = loadAddressBookContract('L2GraphToken', l2AddressBook, l2Wallet) as L2GraphToken
8182

8283
const l1Gateway = cli.contracts['L1GraphTokenGateway']
8384
logger.info(`Will send ${cliArgs.amount} GRT to ${recipient}`)
8485
logger.info(`Using L2 gateway ${gateway.address} and L1 gateway ${l1Gateway.address}`)
8586

87+
const senderBalance = await l2GRT.balanceOf(cli.wallet.address)
88+
if (senderBalance.lt(amount)) {
89+
throw new Error('Sender balance is insufficient for the transfer')
90+
}
91+
8692
const params = [l1GRTAddress, recipient, amount, '0x']
8793
logger.info('Approving token transfer')
8894
await sendTransaction(l2Wallet, l2GRT, 'approve', [gateway.address, amount])

cli/commands/bridge/to-l2.ts

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
L1ToL2MessageGasEstimator,
1111
} from '@arbitrum/sdk'
1212
import { chainIdIsL2 } from '../../utils'
13+
import { Argv } from 'yargs'
1314

1415
const logAutoRedeemReason = (autoRedeemRec) => {
1516
if (autoRedeemRec == null) {
@@ -72,24 +73,44 @@ export const sendToL2 = async (cli: CLIEnvironment, cliArgs: CLIArgs): Promise<v
7273
'0x',
7374
)
7475

75-
// Comment from Offchain Labs' implementation:
76-
// we add a 0.05 ether "deposit" buffer to pay for execution in the gas estimation
77-
logger.info('Estimating retryable ticket gas:')
78-
const baseFee = (await cli.wallet.provider.getBlock('latest')).baseFeePerGas
79-
const gasEstimator = new L1ToL2MessageGasEstimator(l2Provider)
80-
const gasParams = await gasEstimator.estimateAll(
81-
gateway.address,
82-
l2Dest,
83-
depositCalldata,
84-
parseEther('0'),
85-
baseFee as BigNumber,
86-
gateway.address,
87-
gateway.address,
88-
cli.wallet.provider,
89-
)
90-
const maxGas = gasParams.gasLimit
91-
const gasPriceBid = gasParams.maxFeePerGas
92-
const maxSubmissionPrice = gasParams.maxSubmissionFee
76+
const senderBalance = await l1GRT.balanceOf(cli.wallet.address)
77+
if (senderBalance.lt(amount)) {
78+
throw new Error('Sender balance is insufficient for the transfer')
79+
}
80+
logger.info('Approving token transfer')
81+
await sendTransaction(cli.wallet, l1GRT, 'approve', [gateway.address, amount])
82+
83+
let maxGas: BigNumber
84+
let gasPriceBid: BigNumber
85+
let maxSubmissionPrice: BigNumber
86+
87+
if (!cliArgs.maxGas || !cliArgs.gasPrice || !cliArgs.maxSubmissionCost) {
88+
// Comment from Offchain Labs' implementation:
89+
// we add a 0.05 ether "deposit" buffer to pay for execution in the gas estimation
90+
logger.info('Estimating retryable ticket gas:')
91+
const baseFee = (await cli.wallet.provider.getBlock('latest')).baseFeePerGas
92+
const gasEstimator = new L1ToL2MessageGasEstimator(l2Provider)
93+
const gasParams = await gasEstimator.estimateAll(
94+
gateway.address,
95+
l2Dest,
96+
depositCalldata,
97+
parseEther('0'),
98+
baseFee as BigNumber,
99+
gateway.address,
100+
gateway.address,
101+
cli.wallet.provider,
102+
)
103+
maxGas = cliArgs.maxGas ? BigNumber.from(cliArgs.maxGas) : gasParams.gasLimit
104+
gasPriceBid = cliArgs.gasPrice ? BigNumber.from(cliArgs.gasPrice) : gasParams.maxFeePerGas
105+
maxSubmissionPrice = cliArgs.maxSubmissionCost
106+
? BigNumber.from(cliArgs.maxSubmissionCost)
107+
: gasParams.maxSubmissionFee
108+
} else {
109+
maxGas = BigNumber.from(cliArgs.maxGas)
110+
gasPriceBid = BigNumber.from(cliArgs.gasPrice)
111+
maxSubmissionPrice = BigNumber.from(cliArgs.maxSubmissionCost)
112+
}
113+
93114
logger.info(
94115
`Using max gas: ${maxGas}, gas price bid: ${gasPriceBid}, max submission price: ${maxSubmissionPrice}`,
95116
)
@@ -99,14 +120,13 @@ export const sendToL2 = async (cli: CLIEnvironment, cliArgs: CLIArgs): Promise<v
99120
const data = utils.defaultAbiCoder.encode(['uint256', 'bytes'], [maxSubmissionPrice, '0x'])
100121

101122
const params = [l1GRTAddress, recipient, amount, maxGas, gasPriceBid, data]
102-
logger.info('Approving token transfer')
103-
await sendTransaction(cli.wallet, l1GRT, 'approve', [gateway.address, amount])
104123
logger.info('Sending outbound transfer transaction')
105124
const receipt = await sendTransaction(cli.wallet, gateway, 'outboundTransfer', params, {
106125
value: ethValue,
107126
})
108127
const l1Receipt = new L1TransactionReceipt(receipt)
109-
const l1ToL2Message = await l1Receipt.getL1ToL2Messages(cli.wallet.connect(l2Provider))[0]
128+
const l1ToL2Messages = await l1Receipt.getL1ToL2Messages(cli.wallet.connect(l2Provider))
129+
const l1ToL2Message = l1ToL2Messages[0]
110130

111131
logger.info('Waiting for message to propagate to L2...')
112132
try {
@@ -143,6 +163,26 @@ export const redeemSendToL2 = async (cli: CLIEnvironment, cliArgs: CLIArgs): Pro
143163
export const sendToL2Command = {
144164
command: 'send-to-l2 <amount> [recipient]',
145165
describe: 'Perform an L1-to-L2 Graph Token transaction',
166+
builder: (yargs: Argv): Argv => {
167+
return yargs
168+
.option('max-gas', {
169+
description: 'Max gas for the L2 redemption attempt',
170+
requiresArg: true,
171+
type: 'string',
172+
})
173+
.option('gas-price', {
174+
description: 'Gas price for the L2 redemption attempt',
175+
requiresArg: true,
176+
type: 'string',
177+
})
178+
.option('max-submission-cost', {
179+
description: 'Max submission cost for the retryable ticket',
180+
requiresArg: true,
181+
type: 'string',
182+
})
183+
.positional('amount', { demandOption: true })
184+
.positional('recipient', { demandOption: false })
185+
},
146186
handler: async (argv: CLIArgs): Promise<void> => {
147187
return sendToL2(await loadEnv(argv), argv)
148188
},

0 commit comments

Comments
 (0)