Commit 3df66a9a authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

sdk: fix eth withdraw bug (#3228)

* sdk: fix eth withdraw bug

Fixes the eth withdrawal bug when creating withdrawl
transactions that include value. There is no need to
send ETH on L1 when finalizing the withdrawal since
the `OptimismPortal` is holding onto the ETH that will
be unlocked and sent to the user.
co-authored-by: default avatarsmartcontracts <kelvin@optimism.io>

* sdk: cleanup code + fix hanging eth deposits
co-authored-by: default avatarsmartcontracts <kelvin@optimism.io>

* ci: run devnet on sdk changes

* lint: fix
Co-authored-by: default avatarsmartcontracts <kelvin@optimism.io>
Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent 3e51ef8c
---
'@eth-optimism/sdk': patch
---
Fix eth withdrawal bug
...@@ -460,7 +460,7 @@ jobs: ...@@ -460,7 +460,7 @@ jobs:
- run: - run:
name: Check if we should run name: Check if we should run
command: | command: |
CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "(contracts-bedrock|op-bindings|op-batcher|op-node|op-proposer|ops-bedrock)/") CHANGED=$(bash ./ops/docker/ci-builder/check-changed.sh "(contracts-bedrock|op-bindings|op-batcher|op-node|op-proposer|ops-bedrock|sdk)/")
if [[ "$CHANGED" = "FALSE" ]]; then if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt circleci step halt
fi fi
......
...@@ -5,7 +5,6 @@ import { ...@@ -5,7 +5,6 @@ import {
TransactionReceipt, TransactionReceipt,
TransactionResponse, TransactionResponse,
TransactionRequest, TransactionRequest,
Log,
} from '@ethersproject/abstract-provider' } from '@ethersproject/abstract-provider'
import { Signer } from '@ethersproject/abstract-signer' import { Signer } from '@ethersproject/abstract-signer'
import { import {
...@@ -250,13 +249,15 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -250,13 +249,15 @@ export class CrossChainMessenger implements ICrossChainMessenger {
// Try to pull out the value field, but only if the very next log is a SentMessageExtraData // Try to pull out the value field, but only if the very next log is a SentMessageExtraData
// event which was introduced in the Bedrock upgrade. // event which was introduced in the Bedrock upgrade.
let value = ethers.BigNumber.from(0) let value = ethers.BigNumber.from(0)
if (receipt.logs.length > log.logIndex + 1) { const next = receipt.logs.find((l) => {
const next = receipt.logs[log.logIndex + 1] return (
if (next.address === messenger.address) { l.logIndex === log.logIndex + 1 && l.address === messenger.address
const nextParsed = messenger.interface.parseLog(next) )
if (nextParsed.name === 'SentMessageExtension1') { })
value = nextParsed.args.value if (next) {
} const nextParsed = messenger.interface.parseLog(next)
if (nextParsed.name === 'SentMessageExtension1') {
value = nextParsed.args.value
} }
} }
...@@ -1097,7 +1098,6 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1097,7 +1098,6 @@ export class CrossChainMessenger implements ICrossChainMessenger {
latestBlockhash: block.hash, latestBlockhash: block.hash,
}, },
withdrawalProof: ethers.utils.RLP.encode(stateTrieProof.storageProof), withdrawalProof: ethers.utils.RLP.encode(stateTrieProof.storageProof),
// withdrawalProof: toHexString(rlp.encode(stateTrieProof.storageProof)),
}, },
output, output,
// TODO(tynes): use better type, typechain? // TODO(tynes): use better type, typechain?
...@@ -1333,15 +1333,6 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1333,15 +1333,6 @@ export class CrossChainMessenger implements ICrossChainMessenger {
const [proof, output, withdrawalTx] = await this.getBedrockMessageProof( const [proof, output, withdrawalTx] = await this.getBedrockMessageProof(
message message
) )
if (!opts) {
opts = {}
}
if (!opts.overrides) {
opts.overrides = {}
}
if (!opts.overrides.value) {
opts.overrides.value = withdrawalTx.value
}
return this.contracts.l1.OptimismPortal.populateTransaction.finalizeWithdrawalTransaction( return this.contracts.l1.OptimismPortal.populateTransaction.finalizeWithdrawalTransaction(
[ [
...@@ -1360,7 +1351,7 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1360,7 +1351,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
proof.outputRootProof.latestBlockhash, proof.outputRootProof.latestBlockhash,
], ],
proof.withdrawalProof, proof.withdrawalProof,
opts.overrides opts?.overrides || {}
) )
} else { } else {
// L1CrossDomainMessenger relayMessage is the only method that isn't fully backwards // L1CrossDomainMessenger relayMessage is the only method that isn't fully backwards
...@@ -1391,22 +1382,6 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1391,22 +1382,6 @@ export class CrossChainMessenger implements ICrossChainMessenger {
overrides?: PayableOverrides overrides?: PayableOverrides
} }
): Promise<TransactionRequest> => { ): Promise<TransactionRequest> => {
if (this.bedrock) {
const value = BigNumber.from(opts?.overrides?.value ?? 0)
if (!value.eq(0) && !value.eq(amount)) {
throw new Error(`amount and value mismatch`)
}
if (!opts) {
opts = {}
}
if (!opts.overrides) {
opts.overrides = {}
}
if (!opts.overrides.value) {
opts.overrides.value = value
}
}
return this.bridges.ETH.populateTransaction.deposit( return this.bridges.ETH.populateTransaction.deposit(
ethers.constants.AddressZero, ethers.constants.AddressZero,
predeploys.OVM_ETH, predeploys.OVM_ETH,
...@@ -1419,24 +1394,9 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1419,24 +1394,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
recipient?: AddressLike recipient?: AddressLike
overrides?: PayableOverrides overrides?: Overrides
} }
): Promise<TransactionRequest> => { ): Promise<TransactionRequest> => {
const value = BigNumber.from(opts?.overrides?.value ?? 0)
if (this.bedrock) {
if (!value.eq(0) && !value.eq(amount)) {
throw new Error(`amount and value mismatch`)
}
if (!opts) {
opts = {}
}
if (!opts.overrides) {
opts.overrides = {}
}
if (!opts.overrides.value) {
opts.overrides.value = value
}
}
return this.bridges.ETH.populateTransaction.withdraw( return this.bridges.ETH.populateTransaction.withdraw(
ethers.constants.AddressZero, ethers.constants.AddressZero,
predeploys.OVM_ETH, predeploys.OVM_ETH,
......
...@@ -232,7 +232,7 @@ export interface IBridgeAdapter { ...@@ -232,7 +232,7 @@ export interface IBridgeAdapter {
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
recipient?: AddressLike recipient?: AddressLike
overrides?: PayableOverrides overrides?: Overrides
} }
): Promise<TransactionRequest> ): Promise<TransactionRequest>
} }
......
...@@ -67,7 +67,7 @@ task('deposit-eth', 'Deposits WETH9 onto L2.') ...@@ -67,7 +67,7 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
: utils.parseEther('1') : utils.parseEther('1')
const withdrawAmount = args.withdrawAmount const withdrawAmount = args.withdrawAmount
? utils.parseEther(args.withdrawAmount) ? utils.parseEther(args.withdrawAmount)
: utils.parseEther(amount.div(2).toString()) : amount.div(2)
const l2Signer = new hre.ethers.Wallet( const l2Signer = new hre.ethers.Wallet(
hre.network.config.accounts[0], hre.network.config.accounts[0],
...@@ -313,14 +313,9 @@ task('deposit-eth', 'Deposits WETH9 onto L2.') ...@@ -313,14 +313,9 @@ task('deposit-eth', 'Deposits WETH9 onto L2.')
const opBalanceFinally = await signer.provider.getBalance( const opBalanceFinally = await signer.provider.getBalance(
OptimismPortal.address OptimismPortal.address
) )
// TODO(tynes): fix this bug
if (!opBalanceFinally.sub(withdrawAmount).eq(opBalanceAfter)) { if (!opBalanceFinally.add(withdrawAmount).eq(opBalanceAfter)) {
console.log('OptimismPortal balance mismatch') throw new Error('OptimismPortal balance mismatch')
console.log(`Balance before deposit: ${opBalanceBefore.toString()}`)
console.log(`Balance after deposit: ${opBalanceAfter.toString()}`)
console.log(`Balance after withdrawal: ${opBalanceFinally.toString()}`)
return
// throw new Error('OptimismPortal balance mismatch')
} }
console.log('Withdraw success') console.log('Withdraw success')
}) })
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment