Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
c826fddb
Unverified
Commit
c826fddb
authored
Feb 07, 2022
by
smartcontracts
Committed by
GitHub
Feb 07, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2152 from ethereum-optimism/sc/sdk-integration-2
feat: use SDK for bridge integration tests
parents
fd6f47d3
748c04ab
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
125 additions
and
71 deletions
+125
-71
rich-lemons-wave.md
.changeset/rich-lemons-wave.md
+5
-0
warm-pears-hope.md
.changeset/warm-pears-hope.md
+5
-0
FakeL2StandardERC20.sol
integration-tests/contracts/FakeL2StandardERC20.sol
+3
-1
basic-l1-l2-communication.spec.ts
integration-tests/test/basic-l1-l2-communication.spec.ts
+0
-1
bridged-tokens.spec.ts
integration-tests/test/bridged-tokens.spec.ts
+100
-69
contracts.ts
packages/sdk/src/utils/contracts.ts
+12
-0
No files found.
.changeset/rich-lemons-wave.md
0 → 100644
View file @
c826fddb
---
'
@eth-optimism/sdk'
:
patch
---
Updates the SDK to include default bridges for the local Optimism network (31337)
.changeset/warm-pears-hope.md
0 → 100644
View file @
c826fddb
---
'
@eth-optimism/integration-tests'
:
patch
---
Updates integration tests to use the SDK for bridged token tests
integration-tests/contracts/FakeL2StandardERC20.sol
View file @
c826fddb
...
...
@@ -4,9 +4,11 @@ pragma solidity ^0.8.9;
contract FakeL2StandardERC20 {
address public immutable l1Token;
address public immutable l2Bridge;
constructor(address _l1Token) {
constructor(address _l1Token
, address _l2Bridge
) {
l1Token = _l1Token;
l2Bridge = _l2Bridge;
}
// Burn will be called by the L2 Bridge to burn the tokens we are bridging to L1
...
...
integration-tests/test/basic-l1-l2-communication.spec.ts
View file @
c826fddb
...
...
@@ -118,7 +118,6 @@ describe('Basic L1<>L2 Communication', async () => {
const
receipt
=
await
env
.
messenger
.
waitForMessageReceipt
(
transaction
)
console
.
log
(
await
env
.
messenger
.
l2Signer
.
getAddress
())
expect
(
receipt
.
transactionReceipt
.
status
).
to
.
equal
(
1
)
expect
(
await
L2SimpleStorage
.
msgSender
()).
to
.
equal
(
env
.
messenger
.
contracts
.
l2
.
L2CrossDomainMessenger
.
address
...
...
integration-tests/test/bridged-tokens.spec.ts
View file @
c826fddb
import
{
BigNumber
,
Contract
,
ContractFactory
,
utils
,
Wallet
}
from
'
ethers
'
import
{
ethers
}
from
'
hardhat
'
import
*
as
L2Artifact
from
'
@eth-optimism/contracts/artifacts/contracts/standards/L2StandardERC20.sol/L2StandardERC20.json
'
import
{
getContractFactory
}
from
'
@eth-optimism/contracts
'
import
{
MessageStatus
}
from
'
@eth-optimism/sdk
'
import
{
sleep
}
from
'
@eth-optimism/core-utils
'
import
{
expect
}
from
'
./shared/setup
'
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
withdrawalTest
}
from
'
./shared/utils
'
import
{
Direction
}
from
'
./shared/watcher-utils
'
describe
(
'
Bridged tokens
'
,
()
=>
{
let
env
:
OptimismEnv
before
(
async
()
=>
{
env
=
await
OptimismEnv
.
new
()
})
let
otherWalletL1
:
Wallet
let
otherWalletL2
:
Wallet
let
L1Factory__ERC20
:
ContractFactory
let
L1__ERC20
:
Contract
let
L2Factory__ERC20
:
ContractFactory
let
L2__ERC20
:
Contract
before
(
async
()
=>
{
env
=
await
OptimismEnv
.
new
()
const
other
=
Wallet
.
createRandom
()
otherWalletL1
=
other
.
connect
(
env
.
l1Wallet
.
provider
)
otherWalletL2
=
other
.
connect
(
env
.
l2Wallet
.
provider
)
let
tx
=
await
env
.
l1Wallet
.
sendTransaction
({
const
tx1
=
await
env
.
l1Wallet
.
sendTransaction
({
to
:
otherWalletL1
.
address
,
value
:
utils
.
parseEther
(
'
0.01
'
),
})
await
tx
.
wait
()
tx
=
await
env
.
l2Wallet
.
sendTransaction
({
await
tx
1
.
wait
()
const
tx2
=
await
env
.
l2Wallet
.
sendTransaction
({
to
:
otherWalletL2
.
address
,
value
:
utils
.
parseEther
(
'
0.01
'
),
})
await
tx
.
wait
()
await
tx2
.
wait
()
})
let
L1Factory__ERC20
:
ContractFactory
let
L2Factory__ERC20
:
ContractFactory
before
(
async
()
=>
{
L1Factory__ERC20
=
await
ethers
.
getContractFactory
(
'
ERC20
'
,
env
.
l1Wallet
)
L2Factory__ERC20
=
new
ethers
.
ContractFactory
(
L2Artifact
.
abi
,
L2Artifact
.
bytecode
)
L2Factory__ERC20
=
L2Factory__ERC20
.
connect
(
env
.
l2Wallet
)
L2Factory__ERC20
=
getContractFactory
(
'
L2StandardERC20
'
,
env
.
l2Wallet
)
})
it
(
'
should deploy an ERC20 on L1
'
,
async
()
=>
{
// This is one of the only stateful integration tests in which we don't set up a new contract
// before each test. We do this because the test is more of an "actor-based" test where we're
// going through a series of actions and confirming that the actions are performed correctly at
// every step.
let
L1__ERC20
:
Contract
let
L2__ERC20
:
Contract
before
(
async
()
=>
{
// Deploy the L1 ERC20
L1__ERC20
=
await
L1Factory__ERC20
.
deploy
(
1000000
,
'
OVM Test
'
,
8
,
'
OVM
'
)
await
L1__ERC20
.
deployed
()
})
it
(
'
should deploy a paired token on L2
'
,
async
()
=>
{
// Deploy the L2 ERC20
L2__ERC20
=
await
L2Factory__ERC20
.
deploy
(
'
0x4200000000000000000000000000000000000010
'
,
L1__ERC20
.
address
,
...
...
@@ -56,22 +59,21 @@ describe('Bridged tokens', () => {
'
OVM
'
)
await
L2__ERC20
.
deployed
()
})
it
(
'
should approve the bridge
'
,
async
()
=>
{
// Approve the L1 ERC20 to spend our money
const
tx
=
await
L1__ERC20
.
approve
(
env
.
l1Bridge
.
address
,
1000000
)
await
tx
.
wait
()
})
it
(
'
should deposit tokens into L2
'
,
async
()
=>
{
const
tx
=
await
env
.
l1Bridge
.
depositERC20
(
L1__ERC20
.
address
,
L2
__ERC20
.
address
,
1000
,
2000000
,
'
0x
'
await
env
.
messenger
.
waitForMessageReceipt
(
await
env
.
messenger
.
depositERC20
(
L1
__ERC20
.
address
,
L2__ERC20
.
address
,
1000
)
)
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L1ToL2
)
expect
(
await
L1__ERC20
.
balanceOf
(
env
.
l1Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
999000
)
)
...
...
@@ -83,6 +85,7 @@ describe('Bridged tokens', () => {
it
(
'
should transfer tokens on L2
'
,
async
()
=>
{
const
tx
=
await
L2__ERC20
.
transfer
(
otherWalletL1
.
address
,
500
)
await
tx
.
wait
()
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
500
)
)
...
...
@@ -94,14 +97,22 @@ describe('Bridged tokens', () => {
withdrawalTest
(
'
should withdraw tokens from L2 to the depositor
'
,
async
()
=>
{
const
tx
=
await
env
.
l2Bridge
.
withdraw
(
const
tx
=
await
env
.
messenger
.
withdrawERC20
(
L1__ERC20
.
address
,
L2__ERC20
.
address
,
500
,
2000000
,
'
0x
'
500
)
await
env
.
relayXDomainMessages
(
tx
)
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L2ToL1
)
// TODO: Maybe this should be built into the SDK
let
status
:
MessageStatus
while
(
status
!==
MessageStatus
.
READY_FOR_RELAY
)
{
status
=
await
env
.
messenger
.
getMessageStatus
(
tx
)
await
sleep
(
1000
)
}
await
env
.
messenger
.
finalizeMessage
(
tx
)
await
env
.
messenger
.
waitForMessageReceipt
(
tx
)
expect
(
await
L1__ERC20
.
balanceOf
(
env
.
l1Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
999500
)
)
...
...
@@ -114,11 +125,25 @@ describe('Bridged tokens', () => {
withdrawalTest
(
'
should withdraw tokens from L2 to the transfer recipient
'
,
async
()
=>
{
const
tx
=
await
env
.
l2Bridge
.
connect
(
otherWalletL2
)
.
withdraw
(
L2__ERC20
.
address
,
500
,
2000000
,
'
0x
'
)
await
env
.
relayXDomainMessages
(
tx
)
await
env
.
waitForXDomainTransaction
(
tx
,
Direction
.
L2ToL1
)
const
tx
=
await
env
.
messenger
.
withdrawERC20
(
L1__ERC20
.
address
,
L2__ERC20
.
address
,
500
,
{
signer
:
otherWalletL2
,
}
)
// TODO: Maybe this should be built into the SDK
let
status
:
MessageStatus
while
(
status
!==
MessageStatus
.
READY_FOR_RELAY
)
{
status
=
await
env
.
messenger
.
getMessageStatus
(
tx
)
await
sleep
(
1000
)
}
await
env
.
messenger
.
finalizeMessage
(
tx
)
await
env
.
messenger
.
waitForMessageReceipt
(
tx
)
expect
(
await
L1__ERC20
.
balanceOf
(
otherWalletL1
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
500
)
)
...
...
@@ -134,46 +159,52 @@ describe('Bridged tokens', () => {
withdrawalTest
(
'
should not allow an arbitrary L2 token to be withdrawn in exchange for a legitimate L1 token
'
,
async
()
=>
{
before
(
async
()
=>
{
// First deposit some of the L1 token to L2, so that there is something which could be stolen.
const
depositTx
=
await
env
.
l1Bridge
.
connect
(
env
.
l1Wallet
)
.
depositERC20
(
L1__ERC20
.
address
,
L2__ERC20
.
address
,
1000
,
2000000
,
'
0x
'
)
await
env
.
waitForXDomainTransaction
(
depositTx
,
Direction
.
L1ToL2
)
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
1000
)
// First deposit some of the L1 token to L2, so that there is something which could be stolen.
await
env
.
messenger
.
waitForMessageReceipt
(
await
env
.
messenger
.
depositERC20
(
L1__ERC20
.
address
,
L2__ERC20
.
address
,
1000
)
})
)
expect
(
await
L2__ERC20
.
balanceOf
(
env
.
l2Wallet
.
address
)).
to
.
deep
.
equal
(
BigNumber
.
from
(
1000
)
)
// Deploy a Fake L2 token, which:
// - returns the address of a legitimate L1 token from its l1Token() getter.
// - allows the L2 bridge to call its burn() function.
const
fakeToken
=
await
(
await
ethers
.
getContractFactory
(
'
FakeL2StandardERC20
'
,
env
.
l2Wallet
)
).
deploy
(
L1__ERC20
.
address
)
).
deploy
(
L1__ERC20
.
address
,
env
.
messenger
.
contracts
.
l2
.
L2StandardBridge
.
address
)
await
fakeToken
.
deployed
()
const
balBefore
=
await
L1__ERC20
.
balanceOf
(
otherWalletL1
.
address
)
// Withdraw some of the Fake L2 token, hoping to receive the same amount of the legitimate
// token on L1.
const
withdrawalTx
=
await
env
.
l2Bridge
.
connect
(
otherWalletL2
)
.
withdrawTo
(
fakeToken
.
address
,
otherWalletL1
.
address
,
500
,
1
_000_000
,
'
0x
'
)
await
env
.
relayXDomainMessages
(
withdrawalTx
)
await
env
.
waitForXDomainTransaction
(
withdrawalTx
,
Direction
.
L2ToL1
)
const
withdrawalTx
=
await
env
.
messenger
.
withdrawERC20
(
L1__ERC20
.
address
,
fakeToken
.
address
,
500
,
{
signer
:
otherWalletL2
,
}
)
// TODO: Maybe this should be built into the SDK
let
status
:
MessageStatus
while
(
status
!==
MessageStatus
.
READY_FOR_RELAY
)
{
status
=
await
env
.
messenger
.
getMessageStatus
(
withdrawalTx
)
await
sleep
(
1000
)
}
await
env
.
messenger
.
finalizeMessage
(
withdrawalTx
)
await
env
.
messenger
.
waitForMessageReceipt
(
withdrawalTx
)
// Ensure that the L1 recipient address has not received any additional L1 token balance.
expect
(
await
L1__ERC20
.
balanceOf
(
otherWalletL1
.
address
)).
to
.
deep
.
equal
(
...
...
packages/sdk/src/utils/contracts.ts
View file @
c826fddb
...
...
@@ -172,6 +172,18 @@ export const BRIDGE_ADAPTER_DATA: {
l2Bridge
:
predeploys
.
L2StandardBridge
,
},
},
31337
:
{
Standard
:
{
Adapter
:
StandardBridgeAdapter
,
l1Bridge
:
CONTRACT_ADDRESSES
[
31337
].
l1
.
L1StandardBridge
,
l2Bridge
:
predeploys
.
L2StandardBridge
,
},
ETH
:
{
Adapter
:
ETHBridgeAdapter
,
l1Bridge
:
CONTRACT_ADDRESSES
[
31337
].
l1
.
L1StandardBridge
,
l2Bridge
:
predeploys
.
L2StandardBridge
,
},
},
}
// TODO: PR is big enough as-is, will add support for SNX in another PR
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment