Commit 3ad9f739 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #2282 from ethereum-optimism/develop

develop => master
parents a3a5b11d dfd5ac6e
---
'@eth-optimism/sdk': patch
---
Fix typo in constructor docstring
---
'@eth-optimism/sdk': major
---
Update README and bump SDK to 1.0.0
...@@ -27,6 +27,7 @@ module.exports = { ...@@ -27,6 +27,7 @@ module.exports = {
parserOptions: { parserOptions: {
project: 'tsconfig.json', project: 'tsconfig.json',
sourceType: 'module', sourceType: 'module',
allowAutomaticSingleRunInference: true,
}, },
rules: { rules: {
'@typescript-eslint/adjacent-overload-signatures': 'error', '@typescript-eslint/adjacent-overload-signatures': 'error',
...@@ -102,13 +103,9 @@ module.exports = { ...@@ -102,13 +103,9 @@ module.exports = {
'import/no-extraneous-dependencies': ['error'], 'import/no-extraneous-dependencies': ['error'],
'import/no-internal-modules': 'off', 'import/no-internal-modules': 'off',
'import/order': [ 'import/order': [
"error", 'error',
{ {
groups: [ groups: ['builtin', 'external', 'internal'],
'builtin',
'external',
'internal',
],
'newlines-between': 'always', 'newlines-between': 'always',
}, },
], ],
......
...@@ -43,8 +43,8 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics { ...@@ -43,8 +43,8 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics {
return &Metrics{ return &Metrics{
SyncHeight: promauto.NewGaugeVec(prometheus.GaugeOpts{ SyncHeight: promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "l1_sync_height", Name: "sync_height",
Help: "The max height of the indexer's last batch of L1 blocks.", Help: "The max height of the indexer's last batch of L1/L1 blocks.",
Namespace: metricsNamespace, Namespace: metricsNamespace,
}, []string{ }, []string{
"chain", "chain",
...@@ -66,7 +66,7 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics { ...@@ -66,7 +66,7 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics {
"symbol", "symbol",
}), }),
StateBatchesCount: prometheus.NewCounter(prometheus.CounterOpts{ StateBatchesCount: promauto.NewCounter(prometheus.CounterOpts{
Name: "state_batches_count", Name: "state_batches_count",
Help: "The number of state batches indexed.", Help: "The number of state batches indexed.",
Namespace: metricsNamespace, Namespace: metricsNamespace,
...@@ -101,7 +101,7 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics { ...@@ -101,7 +101,7 @@ func NewMetrics(monitoredTokens map[string]string) *Metrics {
"chain", "chain",
}), }),
CachedTokensCount: prometheus.NewCounterVec(prometheus.CounterOpts{ CachedTokensCount: promauto.NewCounterVec(prometheus.CounterOpts{
Name: "cached_tokens_count", Name: "cached_tokens_count",
Help: "How many tokens are in the cache", Help: "How many tokens are in the cache",
Namespace: metricsNamespace, Namespace: metricsNamespace,
...@@ -118,7 +118,7 @@ func (m *Metrics) SetL1SyncHeight(height uint64) { ...@@ -118,7 +118,7 @@ func (m *Metrics) SetL1SyncHeight(height uint64) {
} }
func (m *Metrics) SetL2SyncHeight(height uint64) { func (m *Metrics) SetL2SyncHeight(height uint64) {
m.SyncHeight.WithLabelValues("l1").Set(float64(height)) m.SyncHeight.WithLabelValues("l2").Set(float64(height))
} }
func (m *Metrics) RecordDeposit(addr common.Address) { func (m *Metrics) RecordDeposit(addr common.Address) {
......
{ {
"name": "indexer", "name": "@eth-optimism/indexer",
"version": "0.0.1", "version": "0.0.1",
"description": "", "private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT" "license": "MIT"
} }
...@@ -94,9 +94,9 @@ type Service struct { ...@@ -94,9 +94,9 @@ type Service struct {
latestHeader uint64 latestHeader uint64
headerSelector *ConfirmedHeaderSelector headerSelector *ConfirmedHeaderSelector
metrics *metrics.Metrics metrics *metrics.Metrics
tokenCache map[common.Address]*db.Token tokenCache map[common.Address]*db.Token
wg sync.WaitGroup wg sync.WaitGroup
} }
type IndexerStatus struct { type IndexerStatus struct {
...@@ -289,10 +289,15 @@ func (s *Service) Update(newHeader *types.Header) error { ...@@ -289,10 +289,15 @@ func (s *Service) Update(newHeader *types.Header) error {
logger.Error("Error querying state batches", "err", err) logger.Error("Error querying state batches", "err", err)
} }
for _, header := range headers { for i, header := range headers {
blockHash := header.Hash blockHash := header.Hash
number := header.Number.Uint64() number := header.Number.Uint64()
deposits := depositsByBlockHash[blockHash] deposits := depositsByBlockHash[blockHash]
batches := stateBatches[blockHash]
if len(deposits) == 0 && len(batches) == 0 && i != len(headers)-1 {
continue
}
block := &db.IndexedL1Block{ block := &db.IndexedL1Block{
Hash: blockHash, Hash: blockHash,
...@@ -313,7 +318,6 @@ func (s *Service) Update(newHeader *types.Header) error { ...@@ -313,7 +318,6 @@ func (s *Service) Update(newHeader *types.Header) error {
return err return err
} }
batches := stateBatches[blockHash]
err = s.cfg.DB.AddStateBatch(batches) err = s.cfg.DB.AddStateBatch(batches)
if err != nil { if err != nil {
logger.Error( logger.Error(
......
...@@ -69,15 +69,15 @@ func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) { ...@@ -69,15 +69,15 @@ func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
} }
type ServiceConfig struct { type ServiceConfig struct {
Context context.Context Context context.Context
Metrics *metrics.Metrics Metrics *metrics.Metrics
L2Client *l2ethclient.Client L2Client *l2ethclient.Client
ChainID *big.Int ChainID *big.Int
ConfDepth uint64 ConfDepth uint64
MaxHeaderBatchSize uint64 MaxHeaderBatchSize uint64
StartBlockNumber uint64 StartBlockNumber uint64
StartBlockHash string StartBlockHash string
DB *db.Database DB *db.Database
} }
type Service struct { type Service struct {
...@@ -89,9 +89,9 @@ type Service struct { ...@@ -89,9 +89,9 @@ type Service struct {
latestHeader uint64 latestHeader uint64
headerSelector *ConfirmedHeaderSelector headerSelector *ConfirmedHeaderSelector
metrics *metrics.Metrics metrics *metrics.Metrics
tokenCache map[common.Address]*db.Token tokenCache map[common.Address]*db.Token
wg sync.WaitGroup wg sync.WaitGroup
} }
type IndexerStatus struct { type IndexerStatus struct {
...@@ -267,11 +267,15 @@ func (s *Service) Update(newHeader *types.Header) error { ...@@ -267,11 +267,15 @@ func (s *Service) Update(newHeader *types.Header) error {
} }
} }
for _, header := range headers { for i, header := range headers {
blockHash := header.Hash() blockHash := header.Hash()
number := header.Number.Uint64() number := header.Number.Uint64()
withdrawals := withdrawalsByBlockHash[blockHash] withdrawals := withdrawalsByBlockHash[blockHash]
if len(withdrawals) == 0 && i != len(headers)-1 {
continue
}
block := &db.IndexedL2Block{ block := &db.IndexedL2Block{
Hash: blockHash, Hash: blockHash,
ParentHash: header.ParentHash, ParentHash: header.ParentHash,
......
...@@ -8,12 +8,7 @@ ...@@ -8,12 +8,7 @@
"packages/*", "packages/*",
"l2geth", "l2geth",
"integration-tests", "integration-tests",
"specs", "go/*",
"go/gas-oracle",
"go/batch-submitter",
"go/l2geth-exporter",
"go/proxyd",
"go/op-exporter",
"ops/docker/rpc-proxy", "ops/docker/rpc-proxy",
"ops/docker/hardhat" "ops/docker/hardhat"
], ],
......
...@@ -66,7 +66,6 @@ ...@@ -66,7 +66,6 @@
"devDependencies": { "devDependencies": {
"@codechecks/client": "^0.1.11", "@codechecks/client": "^0.1.11",
"@defi-wonderland/smock": "^2.0.2", "@defi-wonderland/smock": "^2.0.2",
"@eth-optimism/smock": "1.1.10",
"@nomiclabs/ethereumjs-vm": "^4.2.2", "@nomiclabs/ethereumjs-vm": "^4.2.2",
"@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^2.1.6", "@nomiclabs/hardhat-etherscan": "^2.1.6",
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract, BigNumber } from 'ethers' import { Signer, ContractFactory, Contract, BigNumber } from 'ethers'
import { smockit, MockContract } from '@eth-optimism/smock' import {
import { smock, MockContractFactory } from '@defi-wonderland/smock' smock,
MockContractFactory,
FakeContract,
} from '@defi-wonderland/smock'
import { import {
remove0x, remove0x,
toHexString, toHexString,
...@@ -56,9 +59,9 @@ describe('L1CrossDomainMessenger', () => { ...@@ -56,9 +59,9 @@ describe('L1CrossDomainMessenger', () => {
AddressManager = await makeAddressManager() AddressManager = await makeAddressManager()
}) })
let Mock__TargetContract: MockContract let Fake__TargetContract: FakeContract
let Mock__L2CrossDomainMessenger: MockContract let Fake__L2CrossDomainMessenger: FakeContract
let Mock__StateCommitmentChain: MockContract let Fake__StateCommitmentChain: FakeContract
let Factory__CanonicalTransactionChain: ContractFactory let Factory__CanonicalTransactionChain: ContractFactory
let Factory__ChainStorageContainer: ContractFactory let Factory__ChainStorageContainer: ContractFactory
...@@ -66,28 +69,28 @@ describe('L1CrossDomainMessenger', () => { ...@@ -66,28 +69,28 @@ describe('L1CrossDomainMessenger', () => {
let CanonicalTransactionChain: Contract let CanonicalTransactionChain: Contract
before(async () => { before(async () => {
Mock__TargetContract = await smockit( Fake__TargetContract = await smock.fake<Contract>(
await ethers.getContractFactory('Helper_SimpleProxy') await ethers.getContractFactory('Helper_SimpleProxy')
) )
Mock__L2CrossDomainMessenger = await smockit( Fake__L2CrossDomainMessenger = await smock.fake<Contract>(
await ethers.getContractFactory('L2CrossDomainMessenger'), await ethers.getContractFactory('L2CrossDomainMessenger'),
{ {
address: predeploys.L2CrossDomainMessenger, address: predeploys.L2CrossDomainMessenger,
} }
) )
Mock__StateCommitmentChain = await smockit( Fake__StateCommitmentChain = await smock.fake<Contract>(
await ethers.getContractFactory('StateCommitmentChain') await ethers.getContractFactory('StateCommitmentChain')
) )
await AddressManager.setAddress( await AddressManager.setAddress(
'L2CrossDomainMessenger', 'L2CrossDomainMessenger',
Mock__L2CrossDomainMessenger.address Fake__L2CrossDomainMessenger.address
) )
await setProxyTarget( await setProxyTarget(
AddressManager, AddressManager,
'StateCommitmentChain', 'StateCommitmentChain',
Mock__StateCommitmentChain Fake__StateCommitmentChain
) )
Factory__CanonicalTransactionChain = await ethers.getContractFactory( Factory__CanonicalTransactionChain = await ethers.getContractFactory(
...@@ -178,7 +181,7 @@ describe('L1CrossDomainMessenger', () => { ...@@ -178,7 +181,7 @@ describe('L1CrossDomainMessenger', () => {
['address', 'address', 'uint256', 'bytes'], ['address', 'address', 'uint256', 'bytes'],
[ [
applyL1ToL2Alias(L1CrossDomainMessenger.address), applyL1ToL2Alias(L1CrossDomainMessenger.address),
Mock__L2CrossDomainMessenger.address, Fake__L2CrossDomainMessenger.address,
gasLimit, gasLimit,
calldata, calldata,
] ]
...@@ -322,7 +325,7 @@ describe('L1CrossDomainMessenger', () => { ...@@ -322,7 +325,7 @@ describe('L1CrossDomainMessenger', () => {
.to.emit(CanonicalTransactionChain, 'TransactionEnqueued') .to.emit(CanonicalTransactionChain, 'TransactionEnqueued')
.withArgs( .withArgs(
applyL1ToL2Alias(L1CrossDomainMessenger.address), applyL1ToL2Alias(L1CrossDomainMessenger.address),
Mock__L2CrossDomainMessenger.address, Fake__L2CrossDomainMessenger.address,
newGasLimit, newGasLimit,
encodeXDomainCalldata(target, sender, message, queueIndex), encodeXDomainCalldata(target, sender, message, queueIndex),
newQueueIndex, newQueueIndex,
...@@ -388,7 +391,7 @@ describe('L1CrossDomainMessenger', () => { ...@@ -388,7 +391,7 @@ describe('L1CrossDomainMessenger', () => {
const storageKey = ethers.utils.keccak256( const storageKey = ethers.utils.keccak256(
ethers.utils.keccak256( ethers.utils.keccak256(
calldata + remove0x(Mock__L2CrossDomainMessenger.address) calldata + remove0x(Fake__L2CrossDomainMessenger.address)
) + '00'.repeat(32) ) + '00'.repeat(32)
) )
const storageGenerator = await TrieTestGenerator.fromNodes({ const storageGenerator = await TrieTestGenerator.fromNodes({
...@@ -439,8 +442,8 @@ describe('L1CrossDomainMessenger', () => { ...@@ -439,8 +442,8 @@ describe('L1CrossDomainMessenger', () => {
let proof: any let proof: any
let calldata: string let calldata: string
before(async () => { before(async () => {
target = Mock__TargetContract.address target = Fake__TargetContract.address
message = Mock__TargetContract.interface.encodeFunctionData('setTarget', [ message = Fake__TargetContract.interface.encodeFunctionData('setTarget', [
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS,
]) ])
sender = await signer.getAddress() sender = await signer.getAddress()
...@@ -455,18 +458,12 @@ describe('L1CrossDomainMessenger', () => { ...@@ -455,18 +458,12 @@ describe('L1CrossDomainMessenger', () => {
}) })
beforeEach(async () => { beforeEach(async () => {
Mock__StateCommitmentChain.smocked.verifyStateCommitment.will.return.with( Fake__StateCommitmentChain.verifyStateCommitment.returns(true)
true Fake__StateCommitmentChain.insideFraudProofWindow.returns(false)
)
Mock__StateCommitmentChain.smocked.insideFraudProofWindow.will.return.with(
false
)
}) })
it('should revert if still inside the fraud proof window', async () => { it('should revert if still inside the fraud proof window', async () => {
Mock__StateCommitmentChain.smocked.insideFraudProofWindow.will.return.with( Fake__StateCommitmentChain.insideFraudProofWindow.returns(true)
true
)
const proof1 = { const proof1 = {
stateRoot: ethers.constants.HashZero, stateRoot: ethers.constants.HashZero,
...@@ -502,9 +499,7 @@ describe('L1CrossDomainMessenger', () => { ...@@ -502,9 +499,7 @@ describe('L1CrossDomainMessenger', () => {
}) })
it('should revert if provided an invalid state root proof', async () => { it('should revert if provided an invalid state root proof', async () => {
Mock__StateCommitmentChain.smocked.verifyStateCommitment.will.return.with( Fake__StateCommitmentChain.verifyStateCommitment.returns(false)
false
)
const proof1 = { const proof1 = {
stateRoot: ethers.constants.HashZero, stateRoot: ethers.constants.HashZero,
......
...@@ -2,7 +2,12 @@ ...@@ -2,7 +2,12 @@
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract, constants } from 'ethers' import { Signer, ContractFactory, Contract, constants } from 'ethers'
import { Interface } from 'ethers/lib/utils' import { Interface } from 'ethers/lib/utils'
import { smockit, MockContract, smoddit } from '@eth-optimism/smock' import {
smock,
MockContractFactory,
FakeContract,
MockContract,
} from '@defi-wonderland/smock'
/* Internal Imports */ /* Internal Imports */
import { expect } from '../../../setup' import { expect } from '../../../setup'
...@@ -30,15 +35,15 @@ describe('L1StandardBridge', () => { ...@@ -30,15 +35,15 @@ describe('L1StandardBridge', () => {
let aliceAddress let aliceAddress
// we can just make up this string since it's on the "other" Layer // we can just make up this string since it's on the "other" Layer
let Factory__L1ERC20: ContractFactory let Factory__L1ERC20: MockContractFactory<ContractFactory>
let IL2ERC20Bridge: Interface let IL2ERC20Bridge: Interface
before(async () => { before(async () => {
;[l1MessengerImpersonator, alice, bob] = await ethers.getSigners() ;[l1MessengerImpersonator, alice, bob] = await ethers.getSigners()
await smockit(await ethers.getContractFactory('OVM_ETH')) await smock.fake<Contract>(await ethers.getContractFactory('OVM_ETH'))
// deploy an ERC20 contract on L1 // deploy an ERC20 contract on L1
Factory__L1ERC20 = await smoddit( Factory__L1ERC20 = await smock.mock(
'@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20' '@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20'
) )
...@@ -49,12 +54,12 @@ describe('L1StandardBridge', () => { ...@@ -49,12 +54,12 @@ describe('L1StandardBridge', () => {
bobsAddress = await bob.getAddress() bobsAddress = await bob.getAddress()
}) })
let L1ERC20: Contract let L1ERC20: MockContract<Contract>
let L1StandardBridge: Contract let L1StandardBridge: Contract
let Mock__L1CrossDomainMessenger: MockContract let Fake__L1CrossDomainMessenger: FakeContract
beforeEach(async () => { beforeEach(async () => {
// Get a new mock L1 messenger // Get a new mock L1 messenger
Mock__L1CrossDomainMessenger = await smockit( Fake__L1CrossDomainMessenger = await smock.fake<Contract>(
await ethers.getContractFactory('L1CrossDomainMessenger'), await ethers.getContractFactory('L1CrossDomainMessenger'),
{ address: await l1MessengerImpersonator.getAddress() } // This allows us to use an ethers override {from: Mock__L2CrossDomainMessenger.address} to mock calls { address: await l1MessengerImpersonator.getAddress() } // This allows us to use an ethers override {from: Mock__L2CrossDomainMessenger.address} to mock calls
) )
...@@ -64,16 +69,15 @@ describe('L1StandardBridge', () => { ...@@ -64,16 +69,15 @@ describe('L1StandardBridge', () => {
await ethers.getContractFactory('L1StandardBridge') await ethers.getContractFactory('L1StandardBridge')
).deploy() ).deploy()
await L1StandardBridge.initialize( await L1StandardBridge.initialize(
Mock__L1CrossDomainMessenger.address, Fake__L1CrossDomainMessenger.address,
DUMMY_L2_BRIDGE_ADDRESS DUMMY_L2_BRIDGE_ADDRESS
) )
L1ERC20 = await Factory__L1ERC20.deploy('L1ERC20', 'ERC') L1ERC20 = await Factory__L1ERC20.deploy('L1ERC20', 'ERC')
await L1ERC20.smodify.put({
_totalSupply: INITIAL_TOTAL_L1_SUPPLY, await L1ERC20.setVariable('_totalSupply', INITIAL_TOTAL_L1_SUPPLY)
_balances: { await L1ERC20.setVariable('_balances', {
[aliceAddress]: INITIAL_TOTAL_L1_SUPPLY, [aliceAddress]: INITIAL_TOTAL_L1_SUPPLY,
},
}) })
}) })
...@@ -116,7 +120,7 @@ describe('L1StandardBridge', () => { ...@@ -116,7 +120,7 @@ describe('L1StandardBridge', () => {
) )
const depositCallToMessenger = const depositCallToMessenger =
Mock__L1CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L1CrossDomainMessenger.sendMessage.getCall(0)
const depositerBalance = await ethers.provider.getBalance(depositer) const depositerBalance = await ethers.provider.getBalance(depositer)
const receipt = await res.wait() const receipt = await res.wait()
...@@ -136,11 +140,11 @@ describe('L1StandardBridge', () => { ...@@ -136,11 +140,11 @@ describe('L1StandardBridge', () => {
// Check the correct cross-chain call was sent: // Check the correct cross-chain call was sent:
// Message should be sent to the L2 bridge // Message should be sent to the L2 bridge
expect(depositCallToMessenger._target).to.equal(DUMMY_L2_BRIDGE_ADDRESS) expect(depositCallToMessenger.args[0]).to.equal(DUMMY_L2_BRIDGE_ADDRESS)
// Message data should be a call telling the L2ETHToken to finalize the deposit // Message data should be a call telling the L2ETHToken to finalize the deposit
// the L1 bridge sends the correct message to the L1 messenger // the L1 bridge sends the correct message to the L1 messenger
expect(depositCallToMessenger._message).to.equal( expect(depositCallToMessenger.args[1]).to.equal(
IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [ IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [
constants.AddressZero, constants.AddressZero,
predeploys.OVM_ETH, predeploys.OVM_ETH,
...@@ -150,7 +154,7 @@ describe('L1StandardBridge', () => { ...@@ -150,7 +154,7 @@ describe('L1StandardBridge', () => {
NON_NULL_BYTES32, NON_NULL_BYTES32,
]) ])
) )
expect(depositCallToMessenger._gasLimit).to.equal(FINALIZATION_GAS) expect(depositCallToMessenger.args[2]).to.equal(FINALIZATION_GAS)
}) })
it('depositETHTo() escrows the deposit amount and sends the correct deposit message', async () => { it('depositETHTo() escrows the deposit amount and sends the correct deposit message', async () => {
...@@ -166,7 +170,7 @@ describe('L1StandardBridge', () => { ...@@ -166,7 +170,7 @@ describe('L1StandardBridge', () => {
} }
) )
const depositCallToMessenger = const depositCallToMessenger =
Mock__L1CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L1CrossDomainMessenger.sendMessage.getCall(0)
const depositerBalance = await ethers.provider.getBalance(aliceAddress) const depositerBalance = await ethers.provider.getBalance(aliceAddress)
const receipt = await res.wait() const receipt = await res.wait()
...@@ -186,11 +190,11 @@ describe('L1StandardBridge', () => { ...@@ -186,11 +190,11 @@ describe('L1StandardBridge', () => {
// Check the correct cross-chain call was sent: // Check the correct cross-chain call was sent:
// Message should be sent to the L2 bridge // Message should be sent to the L2 bridge
expect(depositCallToMessenger._target).to.equal(DUMMY_L2_BRIDGE_ADDRESS) expect(depositCallToMessenger.args[0]).to.equal(DUMMY_L2_BRIDGE_ADDRESS)
// Message data should be a call telling the L2ETHToken to finalize the deposit // Message data should be a call telling the L2ETHToken to finalize the deposit
// the L1 bridge sends the correct message to the L1 messenger // the L1 bridge sends the correct message to the L1 messenger
expect(depositCallToMessenger._message).to.equal( expect(depositCallToMessenger.args[1]).to.equal(
IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [ IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [
constants.AddressZero, constants.AddressZero,
predeploys.OVM_ETH, predeploys.OVM_ETH,
...@@ -200,7 +204,7 @@ describe('L1StandardBridge', () => { ...@@ -200,7 +204,7 @@ describe('L1StandardBridge', () => {
NON_NULL_BYTES32, NON_NULL_BYTES32,
]) ])
) )
expect(depositCallToMessenger._gasLimit).to.equal(FINALIZATION_GAS) expect(depositCallToMessenger.args[2]).to.equal(FINALIZATION_GAS)
}) })
it('cannot depositETH from a contract account', async () => { it('cannot depositETH from a contract account', async () => {
...@@ -233,11 +237,11 @@ describe('L1StandardBridge', () => { ...@@ -233,11 +237,11 @@ describe('L1StandardBridge', () => {
await ethers.getContractFactory('L1StandardBridge') await ethers.getContractFactory('L1StandardBridge')
).deploy() ).deploy()
await L1StandardBridge.initialize( await L1StandardBridge.initialize(
Mock__L1CrossDomainMessenger.address, Fake__L1CrossDomainMessenger.address,
DUMMY_L2_BRIDGE_ADDRESS DUMMY_L2_BRIDGE_ADDRESS
) )
Mock__L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L1CrossDomainMessenger.xDomainMessageSender.returns(
'0x' + '22'.repeat(20) '0x' + '22'.repeat(20)
) )
...@@ -248,7 +252,7 @@ describe('L1StandardBridge', () => { ...@@ -248,7 +252,7 @@ describe('L1StandardBridge', () => {
1, 1,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L1CrossDomainMessenger.address, from: Fake__L1CrossDomainMessenger.address,
} }
) )
).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MSG_SENDER) ).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MSG_SENDER)
...@@ -259,7 +263,7 @@ describe('L1StandardBridge', () => { ...@@ -259,7 +263,7 @@ describe('L1StandardBridge', () => {
expect(await ethers.provider.getBalance(NON_ZERO_ADDRESS)).to.be.equal(0) expect(await ethers.provider.getBalance(NON_ZERO_ADDRESS)).to.be.equal(0)
const withdrawalAmount = 100 const withdrawalAmount = 100
Mock__L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L1CrossDomainMessenger.xDomainMessageSender.returns(
() => DUMMY_L2_BRIDGE_ADDRESS () => DUMMY_L2_BRIDGE_ADDRESS
) )
...@@ -270,7 +274,7 @@ describe('L1StandardBridge', () => { ...@@ -270,7 +274,7 @@ describe('L1StandardBridge', () => {
withdrawalAmount, withdrawalAmount,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L1CrossDomainMessenger.address, from: Fake__L1CrossDomainMessenger.address,
} }
) )
).to.be.revertedWith( ).to.be.revertedWith(
...@@ -283,7 +287,7 @@ describe('L1StandardBridge', () => { ...@@ -283,7 +287,7 @@ describe('L1StandardBridge', () => {
expect(await ethers.provider.getBalance(NON_ZERO_ADDRESS)).to.be.equal(0) expect(await ethers.provider.getBalance(NON_ZERO_ADDRESS)).to.be.equal(0)
const withdrawalAmount = 100 const withdrawalAmount = 100
Mock__L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L1CrossDomainMessenger.xDomainMessageSender.returns(
() => DUMMY_L2_BRIDGE_ADDRESS () => DUMMY_L2_BRIDGE_ADDRESS
) )
...@@ -302,7 +306,7 @@ describe('L1StandardBridge', () => { ...@@ -302,7 +306,7 @@ describe('L1StandardBridge', () => {
withdrawalAmount, withdrawalAmount,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L1CrossDomainMessenger.address, from: Fake__L1CrossDomainMessenger.address,
} }
) )
...@@ -333,7 +337,7 @@ describe('L1StandardBridge', () => { ...@@ -333,7 +337,7 @@ describe('L1StandardBridge', () => {
) )
const depositCallToMessenger = const depositCallToMessenger =
Mock__L1CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L1CrossDomainMessenger.sendMessage.getCall(0)
const depositerBalance = await L1ERC20.balanceOf(aliceAddress) const depositerBalance = await L1ERC20.balanceOf(aliceAddress)
...@@ -345,11 +349,11 @@ describe('L1StandardBridge', () => { ...@@ -345,11 +349,11 @@ describe('L1StandardBridge', () => {
// Check the correct cross-chain call was sent: // Check the correct cross-chain call was sent:
// Message should be sent to the L2 bridge // Message should be sent to the L2 bridge
expect(depositCallToMessenger._target).to.equal(DUMMY_L2_BRIDGE_ADDRESS) expect(depositCallToMessenger.args[0]).to.equal(DUMMY_L2_BRIDGE_ADDRESS)
// Message data should be a call telling the L2DepositedERC20 to finalize the deposit // Message data should be a call telling the L2DepositedERC20 to finalize the deposit
// the L1 bridge sends the correct message to the L1 messenger // the L1 bridge sends the correct message to the L1 messenger
expect(depositCallToMessenger._message).to.equal( expect(depositCallToMessenger.args[1]).to.equal(
IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [ IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [
L1ERC20.address, L1ERC20.address,
DUMMY_L2_ERC20_ADDRESS, DUMMY_L2_ERC20_ADDRESS,
...@@ -359,7 +363,7 @@ describe('L1StandardBridge', () => { ...@@ -359,7 +363,7 @@ describe('L1StandardBridge', () => {
NON_NULL_BYTES32, NON_NULL_BYTES32,
]) ])
) )
expect(depositCallToMessenger._gasLimit).to.equal(FINALIZATION_GAS) expect(depositCallToMessenger.args[2]).to.equal(FINALIZATION_GAS)
}) })
it('depositERC20To() escrows the deposit amount and sends the correct deposit message', async () => { it('depositERC20To() escrows the deposit amount and sends the correct deposit message', async () => {
...@@ -373,7 +377,7 @@ describe('L1StandardBridge', () => { ...@@ -373,7 +377,7 @@ describe('L1StandardBridge', () => {
NON_NULL_BYTES32 NON_NULL_BYTES32
) )
const depositCallToMessenger = const depositCallToMessenger =
Mock__L1CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L1CrossDomainMessenger.sendMessage.getCall(0)
const depositerBalance = await L1ERC20.balanceOf(aliceAddress) const depositerBalance = await L1ERC20.balanceOf(aliceAddress)
expect(depositerBalance).to.equal(INITIAL_TOTAL_L1_SUPPLY - depositAmount) expect(depositerBalance).to.equal(INITIAL_TOTAL_L1_SUPPLY - depositAmount)
...@@ -384,11 +388,11 @@ describe('L1StandardBridge', () => { ...@@ -384,11 +388,11 @@ describe('L1StandardBridge', () => {
// Check the correct cross-chain call was sent: // Check the correct cross-chain call was sent:
// Message should be sent to the L2DepositedERC20 on L2 // Message should be sent to the L2DepositedERC20 on L2
expect(depositCallToMessenger._target).to.equal(DUMMY_L2_BRIDGE_ADDRESS) expect(depositCallToMessenger.args[0]).to.equal(DUMMY_L2_BRIDGE_ADDRESS)
// Message data should be a call telling the L2DepositedERC20 to finalize the deposit // Message data should be a call telling the L2DepositedERC20 to finalize the deposit
// the L1 bridge sends the correct message to the L1 messenger // the L1 bridge sends the correct message to the L1 messenger
expect(depositCallToMessenger._message).to.equal( expect(depositCallToMessenger.args[1]).to.equal(
IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [ IL2ERC20Bridge.encodeFunctionData('finalizeDeposit', [
L1ERC20.address, L1ERC20.address,
DUMMY_L2_ERC20_ADDRESS, DUMMY_L2_ERC20_ADDRESS,
...@@ -398,7 +402,7 @@ describe('L1StandardBridge', () => { ...@@ -398,7 +402,7 @@ describe('L1StandardBridge', () => {
NON_NULL_BYTES32, NON_NULL_BYTES32,
]) ])
) )
expect(depositCallToMessenger._gasLimit).to.equal(FINALIZATION_GAS) expect(depositCallToMessenger.args[2]).to.equal(FINALIZATION_GAS)
}) })
it('cannot depositERC20 from a contract account', async () => { it('cannot depositERC20 from a contract account', async () => {
...@@ -414,20 +418,20 @@ describe('L1StandardBridge', () => { ...@@ -414,20 +418,20 @@ describe('L1StandardBridge', () => {
}) })
describe('Handling ERC20.transferFrom() failures that revert ', () => { describe('Handling ERC20.transferFrom() failures that revert ', () => {
let MOCK__L1ERC20: MockContract let Fake__L1ERC20: FakeContract
before(async () => { before(async () => {
// Deploy the L1 ERC20 token, Alice will receive the full initialSupply // Deploy the L1 ERC20 token, Alice will receive the full initialSupply
MOCK__L1ERC20 = await smockit( Fake__L1ERC20 = await smock.fake<Contract>(
await Factory__L1ERC20.deploy('L1ERC20', 'ERC') await Factory__L1ERC20.deploy('L1ERC20', 'ERC')
) )
MOCK__L1ERC20.smocked.transferFrom.will.revert() Fake__L1ERC20.transferFrom.reverts()
}) })
it('depositERC20(): will revert if ERC20.transferFrom() reverts', async () => { it('depositERC20(): will revert if ERC20.transferFrom() reverts', async () => {
await expect( await expect(
L1StandardBridge.connect(alice).depositERC20( L1StandardBridge.connect(alice).depositERC20(
MOCK__L1ERC20.address, Fake__L1ERC20.address,
DUMMY_L2_ERC20_ADDRESS, DUMMY_L2_ERC20_ADDRESS,
depositAmount, depositAmount,
FINALIZATION_GAS, FINALIZATION_GAS,
...@@ -439,7 +443,7 @@ describe('L1StandardBridge', () => { ...@@ -439,7 +443,7 @@ describe('L1StandardBridge', () => {
it('depositERC20To(): will revert if ERC20.transferFrom() reverts', async () => { it('depositERC20To(): will revert if ERC20.transferFrom() reverts', async () => {
await expect( await expect(
L1StandardBridge.connect(alice).depositERC20To( L1StandardBridge.connect(alice).depositERC20To(
MOCK__L1ERC20.address, Fake__L1ERC20.address,
DUMMY_L2_ERC20_ADDRESS, DUMMY_L2_ERC20_ADDRESS,
bobsAddress, bobsAddress,
depositAmount, depositAmount,
...@@ -464,18 +468,18 @@ describe('L1StandardBridge', () => { ...@@ -464,18 +468,18 @@ describe('L1StandardBridge', () => {
}) })
describe('Handling ERC20.transferFrom failures that return false', () => { describe('Handling ERC20.transferFrom failures that return false', () => {
let MOCK__L1ERC20: MockContract let Fake__L1ERC20: FakeContract
before(async () => { before(async () => {
MOCK__L1ERC20 = await smockit( Fake__L1ERC20 = await smock.fake(
await Factory__L1ERC20.deploy('L1ERC20', 'ERC') await Factory__L1ERC20.deploy('L1ERC20', 'ERC')
) )
MOCK__L1ERC20.smocked.transferFrom.will.return.with(false) Fake__L1ERC20.transferFrom.returns(false)
}) })
it('deposit(): will revert if ERC20.transferFrom() returns false', async () => { it('deposit(): will revert if ERC20.transferFrom() returns false', async () => {
await expect( await expect(
L1StandardBridge.connect(alice).depositERC20( L1StandardBridge.connect(alice).depositERC20(
MOCK__L1ERC20.address, Fake__L1ERC20.address,
DUMMY_L2_ERC20_ADDRESS, DUMMY_L2_ERC20_ADDRESS,
depositAmount, depositAmount,
FINALIZATION_GAS, FINALIZATION_GAS,
...@@ -487,7 +491,7 @@ describe('L1StandardBridge', () => { ...@@ -487,7 +491,7 @@ describe('L1StandardBridge', () => {
it('depositTo(): will revert if ERC20.transferFrom() returns false', async () => { it('depositTo(): will revert if ERC20.transferFrom() returns false', async () => {
await expect( await expect(
L1StandardBridge.depositERC20To( L1StandardBridge.depositERC20To(
MOCK__L1ERC20.address, Fake__L1ERC20.address,
DUMMY_L2_ERC20_ADDRESS, DUMMY_L2_ERC20_ADDRESS,
bobsAddress, bobsAddress,
depositAmount, depositAmount,
...@@ -514,8 +518,8 @@ describe('L1StandardBridge', () => { ...@@ -514,8 +518,8 @@ describe('L1StandardBridge', () => {
}) })
it('onlyFromCrossDomainAccount: should revert on calls from the right crossDomainMessenger, but wrong xDomainMessageSender (ie. not the L2DepositedERC20)', async () => { it('onlyFromCrossDomainAccount: should revert on calls from the right crossDomainMessenger, but wrong xDomainMessageSender (ie. not the L2DepositedERC20)', async () => {
Mock__L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L1CrossDomainMessenger.xDomainMessageSender.returns(
'0x' + '22'.repeat(20) () => NON_ZERO_ADDRESS
) )
await expect( await expect(
...@@ -527,7 +531,7 @@ describe('L1StandardBridge', () => { ...@@ -527,7 +531,7 @@ describe('L1StandardBridge', () => {
1, 1,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L1CrossDomainMessenger.address, from: Fake__L1CrossDomainMessenger.address,
} }
) )
).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MSG_SENDER) ).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MSG_SENDER)
...@@ -556,7 +560,7 @@ describe('L1StandardBridge', () => { ...@@ -556,7 +560,7 @@ describe('L1StandardBridge', () => {
// make sure no balance at start of test // make sure no balance at start of test
expect(await L1ERC20.balanceOf(NON_ZERO_ADDRESS)).to.be.equal(0) expect(await L1ERC20.balanceOf(NON_ZERO_ADDRESS)).to.be.equal(0)
Mock__L1CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L1CrossDomainMessenger.xDomainMessageSender.returns(
() => DUMMY_L2_BRIDGE_ADDRESS () => DUMMY_L2_BRIDGE_ADDRESS
) )
...@@ -567,7 +571,7 @@ describe('L1StandardBridge', () => { ...@@ -567,7 +571,7 @@ describe('L1StandardBridge', () => {
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS,
withdrawalAmount, withdrawalAmount,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ from: Mock__L1CrossDomainMessenger.address } { from: Fake__L1CrossDomainMessenger.address }
) )
expect(await L1ERC20.balanceOf(NON_ZERO_ADDRESS)).to.be.equal( expect(await L1ERC20.balanceOf(NON_ZERO_ADDRESS)).to.be.equal(
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Signer, ContractFactory, Contract } from 'ethers'
import { smoddit } from '@eth-optimism/smock' import { MockContract, smock } from '@defi-wonderland/smock'
import { expectApprox } from '@eth-optimism/core-utils' import { expectApprox } from '@eth-optimism/core-utils'
/* Internal Imports */ /* Internal Imports */
...@@ -92,7 +92,7 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -92,7 +92,7 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
}) })
// 4 Bridge // 4 Bridge
let L1ERC20: Contract let L1ERC20: MockContract<Contract>
let L1StandardBridge: Contract let L1StandardBridge: Contract
before('Deploy the bridge and setup the token', async () => { before('Deploy the bridge and setup the token', async () => {
// Deploy the Bridge // Deploy the Bridge
...@@ -105,14 +105,12 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage ...@@ -105,14 +105,12 @@ describe('[GAS BENCHMARK] Depositing via the standard bridge [ @skip-on-coverage
) )
L1ERC20 = await ( L1ERC20 = await (
await smoddit('@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20') await smock.mock('@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20')
).deploy('L1ERC20', 'ERC') ).deploy('L1ERC20', 'ERC')
const aliceAddress = await alice.getAddress() const aliceAddress = await alice.getAddress()
await L1ERC20.smodify.put({ await L1ERC20.setVariable('_totalSupply', INITIAL_TOTAL_L1_SUPPLY)
_totalSupply: INITIAL_TOTAL_L1_SUPPLY, await L1ERC20.setVariable('_balances', {
_balances: { [aliceAddress]: INITIAL_TOTAL_L1_SUPPLY,
[aliceAddress]: INITIAL_TOTAL_L1_SUPPLY,
},
}) })
}) })
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Signer, ContractFactory, Contract } from 'ethers'
import { smockit, MockContract } from '@eth-optimism/smock' import { smock, FakeContract } from '@defi-wonderland/smock'
import { import {
AppendSequencerBatchParams, AppendSequencerBatchParams,
BatchContext, BatchContext,
...@@ -46,7 +46,7 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain [ @skip-on-coverage ]', () = ...@@ -46,7 +46,7 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain [ @skip-on-coverage ]', () =
}) })
let AddressManager: Contract let AddressManager: Contract
let Mock__StateCommitmentChain: MockContract let Fake__StateCommitmentChain: FakeContract
before(async () => { before(async () => {
AddressManager = await makeAddressManager() AddressManager = await makeAddressManager()
await AddressManager.setAddress( await AddressManager.setAddress(
...@@ -54,14 +54,14 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain [ @skip-on-coverage ]', () = ...@@ -54,14 +54,14 @@ describe('[GAS BENCHMARK] CanonicalTransactionChain [ @skip-on-coverage ]', () =
await sequencer.getAddress() await sequencer.getAddress()
) )
Mock__StateCommitmentChain = await smockit( Fake__StateCommitmentChain = await smock.fake<Contract>(
await ethers.getContractFactory('StateCommitmentChain') await ethers.getContractFactory('StateCommitmentChain')
) )
await setProxyTarget( await setProxyTarget(
AddressManager, AddressManager,
'StateCommitmentChain', 'StateCommitmentChain',
Mock__StateCommitmentChain Fake__StateCommitmentChain
) )
}) })
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Signer, ContractFactory, Contract } from 'ethers'
import { smockit, MockContract } from '@eth-optimism/smock' import { smock, FakeContract } from '@defi-wonderland/smock'
import { import {
AppendSequencerBatchParams, AppendSequencerBatchParams,
encodeAppendSequencerBatch, encodeAppendSequencerBatch,
...@@ -69,7 +69,7 @@ describe('CanonicalTransactionChain', () => { ...@@ -69,7 +69,7 @@ describe('CanonicalTransactionChain', () => {
}) })
let AddressManager: Contract let AddressManager: Contract
let Mock__StateCommitmentChain: MockContract let Fake__StateCommitmentChain: FakeContract
before(async () => { before(async () => {
AddressManager = await makeAddressManager() AddressManager = await makeAddressManager()
await AddressManager.setAddress( await AddressManager.setAddress(
...@@ -77,14 +77,14 @@ describe('CanonicalTransactionChain', () => { ...@@ -77,14 +77,14 @@ describe('CanonicalTransactionChain', () => {
await sequencer.getAddress() await sequencer.getAddress()
) )
Mock__StateCommitmentChain = await smockit( Fake__StateCommitmentChain = await smock.fake<Contract>(
await ethers.getContractFactory('StateCommitmentChain') await ethers.getContractFactory('StateCommitmentChain')
) )
await setProxyTarget( await setProxyTarget(
AddressManager, AddressManager,
'StateCommitmentChain', 'StateCommitmentChain',
Mock__StateCommitmentChain Fake__StateCommitmentChain
) )
}) })
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract, constants } from 'ethers' import { Signer, ContractFactory, Contract, constants } from 'ethers'
import { smockit, MockContract } from '@eth-optimism/smock' import { smock, FakeContract } from '@defi-wonderland/smock'
/* Internal Imports */ /* Internal Imports */
import { expect } from '../../../setup' import { expect } from '../../../setup'
...@@ -25,26 +25,26 @@ describe('StateCommitmentChain', () => { ...@@ -25,26 +25,26 @@ describe('StateCommitmentChain', () => {
AddressManager = await makeAddressManager() AddressManager = await makeAddressManager()
}) })
let Mock__CanonicalTransactionChain: MockContract let Fake__CanonicalTransactionChain: FakeContract
let Mock__BondManager: MockContract let Fake__BondManager: FakeContract
before(async () => { before(async () => {
Mock__CanonicalTransactionChain = await smockit( Fake__CanonicalTransactionChain = await smock.fake<Contract>(
await ethers.getContractFactory('CanonicalTransactionChain') await ethers.getContractFactory('CanonicalTransactionChain')
) )
await setProxyTarget( await setProxyTarget(
AddressManager, AddressManager,
'CanonicalTransactionChain', 'CanonicalTransactionChain',
Mock__CanonicalTransactionChain Fake__CanonicalTransactionChain
) )
Mock__BondManager = await smockit( Fake__BondManager = await smock.fake<Contract>(
await ethers.getContractFactory('BondManager') await ethers.getContractFactory('BondManager')
) )
await setProxyTarget(AddressManager, 'BondManager', Mock__BondManager) await setProxyTarget(AddressManager, 'BondManager', Fake__BondManager)
Mock__BondManager.smocked.isCollateralized.will.return.with(true) Fake__BondManager.isCollateralized.returns(true)
await AddressManager.setAddress( await AddressManager.setAddress(
'OVM_Proposer', 'OVM_Proposer',
...@@ -114,7 +114,7 @@ describe('StateCommitmentChain', () => { ...@@ -114,7 +114,7 @@ describe('StateCommitmentChain', () => {
describe('when submitting more elements than present in the CanonicalTransactionChain', () => { describe('when submitting more elements than present in the CanonicalTransactionChain', () => {
before(() => { before(() => {
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(
batch.length - 1 batch.length - 1
) )
}) })
...@@ -130,9 +130,7 @@ describe('StateCommitmentChain', () => { ...@@ -130,9 +130,7 @@ describe('StateCommitmentChain', () => {
describe('when not submitting more elements than present in the CanonicalTransactionChain', () => { describe('when not submitting more elements than present in the CanonicalTransactionChain', () => {
before(() => { before(() => {
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
}) })
it('should append the state batch', async () => { it('should append the state batch', async () => {
...@@ -143,7 +141,7 @@ describe('StateCommitmentChain', () => { ...@@ -143,7 +141,7 @@ describe('StateCommitmentChain', () => {
describe('when a sequencer submits ', () => { describe('when a sequencer submits ', () => {
beforeEach(async () => { beforeEach(async () => {
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(
batch.length * 2 batch.length * 2
) )
...@@ -182,7 +180,7 @@ describe('StateCommitmentChain', () => { ...@@ -182,7 +180,7 @@ describe('StateCommitmentChain', () => {
}) })
describe('when the proposer has not previously staked at the BondManager', () => { describe('when the proposer has not previously staked at the BondManager', () => {
before(() => { before(() => {
Mock__BondManager.smocked.isCollateralized.will.return.with(false) Fake__BondManager.isCollateralized.returns(false)
}) })
it('should revert', async () => { it('should revert', async () => {
...@@ -207,13 +205,11 @@ describe('StateCommitmentChain', () => { ...@@ -207,13 +205,11 @@ describe('StateCommitmentChain', () => {
} }
before(() => { before(() => {
Mock__BondManager.smocked.isCollateralized.will.return.with(true) Fake__BondManager.isCollateralized.returns(true)
}) })
beforeEach(async () => { beforeEach(async () => {
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
batchHeader.extraData = ethers.utils.defaultAbiCoder.encode( batchHeader.extraData = ethers.utils.defaultAbiCoder.encode(
['uint256', 'address'], ['uint256', 'address'],
...@@ -329,9 +325,7 @@ describe('StateCommitmentChain', () => { ...@@ -329,9 +325,7 @@ describe('StateCommitmentChain', () => {
describe('when one batch element has been inserted', () => { describe('when one batch element has been inserted', () => {
beforeEach(async () => { beforeEach(async () => {
const batch = [NON_NULL_BYTES32] const batch = [NON_NULL_BYTES32]
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
}) })
...@@ -343,9 +337,7 @@ describe('StateCommitmentChain', () => { ...@@ -343,9 +337,7 @@ describe('StateCommitmentChain', () => {
describe('when 64 batch elements have been inserted in one batch', () => { describe('when 64 batch elements have been inserted in one batch', () => {
beforeEach(async () => { beforeEach(async () => {
const batch = Array(64).fill(NON_NULL_BYTES32) const batch = Array(64).fill(NON_NULL_BYTES32)
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
}) })
...@@ -357,7 +349,7 @@ describe('StateCommitmentChain', () => { ...@@ -357,7 +349,7 @@ describe('StateCommitmentChain', () => {
describe('when 32 batch elements have been inserted in each of two batches', () => { describe('when 32 batch elements have been inserted in each of two batches', () => {
beforeEach(async () => { beforeEach(async () => {
const batch = Array(32).fill(NON_NULL_BYTES32) const batch = Array(32).fill(NON_NULL_BYTES32)
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(
batch.length * 2 batch.length * 2
) )
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
...@@ -380,9 +372,7 @@ describe('StateCommitmentChain', () => { ...@@ -380,9 +372,7 @@ describe('StateCommitmentChain', () => {
describe('when one batch has been inserted', () => { describe('when one batch has been inserted', () => {
beforeEach(async () => { beforeEach(async () => {
const batch = [NON_NULL_BYTES32] const batch = [NON_NULL_BYTES32]
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
}) })
...@@ -394,7 +384,7 @@ describe('StateCommitmentChain', () => { ...@@ -394,7 +384,7 @@ describe('StateCommitmentChain', () => {
describe('when 8 batches have been inserted', () => { describe('when 8 batches have been inserted', () => {
beforeEach(async () => { beforeEach(async () => {
const batch = [NON_NULL_BYTES32] const batch = [NON_NULL_BYTES32]
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(
batch.length * 8 batch.length * 8
) )
...@@ -422,9 +412,7 @@ describe('StateCommitmentChain', () => { ...@@ -422,9 +412,7 @@ describe('StateCommitmentChain', () => {
let timestamp let timestamp
beforeEach(async () => { beforeEach(async () => {
const batch = [NON_NULL_BYTES32] const batch = [NON_NULL_BYTES32]
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
timestamp = await getEthTime(ethers.provider) timestamp = await getEthTime(ethers.provider)
}) })
...@@ -455,13 +443,11 @@ describe('StateCommitmentChain', () => { ...@@ -455,13 +443,11 @@ describe('StateCommitmentChain', () => {
const element = NON_NULL_BYTES32 const element = NON_NULL_BYTES32
before(async () => { before(async () => {
Mock__BondManager.smocked.isCollateralized.will.return.with(true) Fake__BondManager.isCollateralized.returns(true)
}) })
beforeEach(async () => { beforeEach(async () => {
Mock__CanonicalTransactionChain.smocked.getTotalElements.will.return.with( Fake__CanonicalTransactionChain.getTotalElements.returns(batch.length)
batch.length
)
await StateCommitmentChain.appendStateBatch(batch, 0) await StateCommitmentChain.appendStateBatch(batch, 0)
batchHeader.extraData = ethers.utils.defaultAbiCoder.encode( batchHeader.extraData = ethers.utils.defaultAbiCoder.encode(
['uint256', 'address'], ['uint256', 'address'],
......
/* External Imports */ /* External Imports */
import hre, { ethers } from 'hardhat' import hre, { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Signer, ContractFactory, Contract } from 'ethers'
import { smockit, MockContract } from '@eth-optimism/smock'
import { applyL1ToL2Alias } from '@eth-optimism/core-utils' import { applyL1ToL2Alias } from '@eth-optimism/core-utils'
import { smock, MockContractFactory } from '@defi-wonderland/smock' import {
smock,
MockContractFactory,
FakeContract,
} from '@defi-wonderland/smock'
/* Internal Imports */ /* Internal Imports */
import { expect } from '../../../setup' import { expect } from '../../../setup'
...@@ -20,17 +23,17 @@ describe('L2CrossDomainMessenger', () => { ...@@ -20,17 +23,17 @@ describe('L2CrossDomainMessenger', () => {
;[signer] = await ethers.getSigners() ;[signer] = await ethers.getSigners()
}) })
let Mock__TargetContract: MockContract let Fake__TargetContract: FakeContract
let Mock__L1CrossDomainMessenger: MockContract let Fake__L1CrossDomainMessenger: FakeContract
let Mock__OVM_L2ToL1MessagePasser: MockContract let Fake__OVM_L2ToL1MessagePasser: FakeContract
before(async () => { before(async () => {
Mock__TargetContract = await smockit( Fake__TargetContract = await smock.fake<Contract>(
await ethers.getContractFactory('Helper_SimpleProxy') await ethers.getContractFactory('Helper_SimpleProxy')
) )
Mock__L1CrossDomainMessenger = await smockit( Fake__L1CrossDomainMessenger = await smock.fake<Contract>(
await ethers.getContractFactory('L1CrossDomainMessenger') await ethers.getContractFactory('L1CrossDomainMessenger')
) )
Mock__OVM_L2ToL1MessagePasser = await smockit( Fake__OVM_L2ToL1MessagePasser = await smock.fake<Contract>(
await ethers.getContractFactory('OVM_L2ToL1MessagePasser'), await ethers.getContractFactory('OVM_L2ToL1MessagePasser'),
{ address: predeploys.OVM_L2ToL1MessagePasser } { address: predeploys.OVM_L2ToL1MessagePasser }
) )
...@@ -39,7 +42,7 @@ describe('L2CrossDomainMessenger', () => { ...@@ -39,7 +42,7 @@ describe('L2CrossDomainMessenger', () => {
let impersonatedL1CrossDomainMessengerSender: Signer let impersonatedL1CrossDomainMessengerSender: Signer
before(async () => { before(async () => {
const impersonatedAddress = applyL1ToL2Alias( const impersonatedAddress = applyL1ToL2Alias(
Mock__L1CrossDomainMessenger.address Fake__L1CrossDomainMessenger.address
) )
await hre.network.provider.request({ await hre.network.provider.request({
method: 'hardhat_impersonateAccount', method: 'hardhat_impersonateAccount',
...@@ -64,7 +67,7 @@ describe('L2CrossDomainMessenger', () => { ...@@ -64,7 +67,7 @@ describe('L2CrossDomainMessenger', () => {
let L2CrossDomainMessenger: Contract let L2CrossDomainMessenger: Contract
beforeEach(async () => { beforeEach(async () => {
L2CrossDomainMessenger = await Factory__L2CrossDomainMessenger.deploy( L2CrossDomainMessenger = await Factory__L2CrossDomainMessenger.deploy(
Mock__L1CrossDomainMessenger.address Fake__L1CrossDomainMessenger.address
) )
}) })
...@@ -77,7 +80,7 @@ describe('L2CrossDomainMessenger', () => { ...@@ -77,7 +80,7 @@ describe('L2CrossDomainMessenger', () => {
) )
Mock__L2CrossDomainMessenger = Mock__L2CrossDomainMessenger =
await Mock__Factory__L2CrossDomainMessenger.deploy( await Mock__Factory__L2CrossDomainMessenger.deploy(
Mock__L1CrossDomainMessenger.address Fake__L1CrossDomainMessenger.address
) )
}) })
...@@ -103,10 +106,10 @@ describe('L2CrossDomainMessenger', () => { ...@@ -103,10 +106,10 @@ describe('L2CrossDomainMessenger', () => {
).to.not.be.reverted ).to.not.be.reverted
expect( expect(
Mock__OVM_L2ToL1MessagePasser.smocked.passMessageToL1.calls[0] Fake__OVM_L2ToL1MessagePasser.passMessageToL1.getCall(0).args[0]
).to.deep.equal([ ).to.deep.equal(
encodeXDomainCalldata(target, await signer.getAddress(), message, 0), encodeXDomainCalldata(target, await signer.getAddress(), message, 0)
]) )
}) })
it('should be able to send the same message twice', async () => { it('should be able to send the same message twice', async () => {
...@@ -123,8 +126,8 @@ describe('L2CrossDomainMessenger', () => { ...@@ -123,8 +126,8 @@ describe('L2CrossDomainMessenger', () => {
let message: string let message: string
let sender: string let sender: string
before(async () => { before(async () => {
target = Mock__TargetContract.address target = Fake__TargetContract.address
message = Mock__TargetContract.interface.encodeFunctionData('setTarget', [ message = Fake__TargetContract.interface.encodeFunctionData('setTarget', [
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS,
]) ])
sender = await signer.getAddress() sender = await signer.getAddress()
...@@ -146,9 +149,9 @@ describe('L2CrossDomainMessenger', () => { ...@@ -146,9 +149,9 @@ describe('L2CrossDomainMessenger', () => {
impersonatedL1CrossDomainMessengerSender impersonatedL1CrossDomainMessengerSender
).relayMessage(target, sender, message, 0) ).relayMessage(target, sender, message, 0)
expect(Mock__TargetContract.smocked.setTarget.calls[0]).to.deep.equal([ expect(Fake__TargetContract.setTarget.getCall(0).args[0]).to.deep.equal(
NON_ZERO_ADDRESS, NON_ZERO_ADDRESS
]) )
}) })
it('the xDomainMessageSender is reset to the original value', async () => { it('the xDomainMessageSender is reset to the original value', async () => {
...@@ -179,7 +182,7 @@ describe('L2CrossDomainMessenger', () => { ...@@ -179,7 +182,7 @@ describe('L2CrossDomainMessenger', () => {
it('should not make a call if the target is the L2 MessagePasser', async () => { it('should not make a call if the target is the L2 MessagePasser', async () => {
target = predeploys.OVM_L2ToL1MessagePasser target = predeploys.OVM_L2ToL1MessagePasser
message = Mock__OVM_L2ToL1MessagePasser.interface.encodeFunctionData( message = Fake__OVM_L2ToL1MessagePasser.interface.encodeFunctionData(
'passMessageToL1(bytes)', 'passMessageToL1(bytes)',
[NON_NULL_BYTES32] [NON_NULL_BYTES32]
) )
...@@ -193,7 +196,7 @@ describe('L2CrossDomainMessenger', () => { ...@@ -193,7 +196,7 @@ describe('L2CrossDomainMessenger', () => {
// There should be no 'relayedMessage' event logged in the receipt. // There should be no 'relayedMessage' event logged in the receipt.
const logs = ( const logs = (
await Mock__OVM_L2ToL1MessagePasser.provider.getTransactionReceipt( await Fake__OVM_L2ToL1MessagePasser.provider.getTransactionReceipt(
( (
await resProm await resProm
).hash ).hash
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Signer, ContractFactory, Contract } from 'ethers'
import { import { smock, FakeContract, MockContract } from '@defi-wonderland/smock'
smockit,
MockContract,
smoddit,
ModifiableContract,
} from '@eth-optimism/smock'
import { smock } from '@defi-wonderland/smock'
/* Internal Imports */ /* Internal Imports */
import { expect } from '../../../setup' import { expect } from '../../../setup'
...@@ -47,10 +41,10 @@ describe('L2StandardBridge', () => { ...@@ -47,10 +41,10 @@ describe('L2StandardBridge', () => {
let L2StandardBridge: Contract let L2StandardBridge: Contract
let L2ERC20: Contract let L2ERC20: Contract
let Mock__L2CrossDomainMessenger: MockContract let Fake__L2CrossDomainMessenger: FakeContract
beforeEach(async () => { beforeEach(async () => {
// Get a new mock L2 messenger // Get a new mock L2 messenger
Mock__L2CrossDomainMessenger = await smockit( Fake__L2CrossDomainMessenger = await smock.fake<Contract>(
await ethers.getContractFactory('L2CrossDomainMessenger'), await ethers.getContractFactory('L2CrossDomainMessenger'),
// This allows us to use an ethers override {from: Mock__L2CrossDomainMessenger.address} to mock calls // This allows us to use an ethers override {from: Mock__L2CrossDomainMessenger.address} to mock calls
{ address: await l2MessengerImpersonator.getAddress() } { address: await l2MessengerImpersonator.getAddress() }
...@@ -59,7 +53,7 @@ describe('L2StandardBridge', () => { ...@@ -59,7 +53,7 @@ describe('L2StandardBridge', () => {
// Deploy the contract under test // Deploy the contract under test
L2StandardBridge = await ( L2StandardBridge = await (
await ethers.getContractFactory('L2StandardBridge') await ethers.getContractFactory('L2StandardBridge')
).deploy(Mock__L2CrossDomainMessenger.address, DUMMY_L1BRIDGE_ADDRESS) ).deploy(Fake__L2CrossDomainMessenger.address, DUMMY_L1BRIDGE_ADDRESS)
// Deploy an L2 ERC20 // Deploy an L2 ERC20
L2ERC20 = await ( L2ERC20 = await (
...@@ -83,7 +77,7 @@ describe('L2StandardBridge', () => { ...@@ -83,7 +77,7 @@ describe('L2StandardBridge', () => {
}) })
it('onlyFromCrossDomainAccount: should revert on calls from the right crossDomainMessenger, but wrong xDomainMessageSender (ie. not the L1L1StandardBridge)', async () => { it('onlyFromCrossDomainAccount: should revert on calls from the right crossDomainMessenger, but wrong xDomainMessageSender (ie. not the L1L1StandardBridge)', async () => {
Mock__L2CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L2CrossDomainMessenger.xDomainMessageSender.returns(
NON_ZERO_ADDRESS NON_ZERO_ADDRESS
) )
...@@ -96,7 +90,7 @@ describe('L2StandardBridge', () => { ...@@ -96,7 +90,7 @@ describe('L2StandardBridge', () => {
0, 0,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L2CrossDomainMessenger.address, from: Fake__L2CrossDomainMessenger.address,
} }
) )
).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MSG_SENDER) ).to.be.revertedWith(ERR_INVALID_X_DOMAIN_MSG_SENDER)
...@@ -118,11 +112,11 @@ describe('L2StandardBridge', () => { ...@@ -118,11 +112,11 @@ describe('L2StandardBridge', () => {
0, 0,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L2CrossDomainMessenger.address, from: Fake__L2CrossDomainMessenger.address,
} }
) )
Mock__L2CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L2CrossDomainMessenger.xDomainMessageSender.returns(
() => DUMMY_L1BRIDGE_ADDRESS () => DUMMY_L1BRIDGE_ADDRESS
) )
...@@ -134,15 +128,15 @@ describe('L2StandardBridge', () => { ...@@ -134,15 +128,15 @@ describe('L2StandardBridge', () => {
100, 100,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L2CrossDomainMessenger.address, from: Fake__L2CrossDomainMessenger.address,
} }
) )
const withdrawalCallToMessenger = const withdrawalCallToMessenger =
Mock__L2CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L2CrossDomainMessenger.sendMessage.getCall(1)
expect(withdrawalCallToMessenger._target).to.equal(DUMMY_L1BRIDGE_ADDRESS) expect(withdrawalCallToMessenger.args[0]).to.equal(DUMMY_L1BRIDGE_ADDRESS)
expect(withdrawalCallToMessenger._message).to.equal( expect(withdrawalCallToMessenger.args[1]).to.equal(
Factory__L1StandardBridge.interface.encodeFunctionData( Factory__L1StandardBridge.interface.encodeFunctionData(
'finalizeERC20Withdrawal', 'finalizeERC20Withdrawal',
[ [
...@@ -160,7 +154,7 @@ describe('L2StandardBridge', () => { ...@@ -160,7 +154,7 @@ describe('L2StandardBridge', () => {
it('should credit funds to the depositor', async () => { it('should credit funds to the depositor', async () => {
const depositAmount = 100 const depositAmount = 100
Mock__L2CrossDomainMessenger.smocked.xDomainMessageSender.will.return.with( Fake__L2CrossDomainMessenger.xDomainMessageSender.returns(
() => DUMMY_L1BRIDGE_ADDRESS () => DUMMY_L1BRIDGE_ADDRESS
) )
...@@ -172,7 +166,7 @@ describe('L2StandardBridge', () => { ...@@ -172,7 +166,7 @@ describe('L2StandardBridge', () => {
depositAmount, depositAmount,
NON_NULL_BYTES32, NON_NULL_BYTES32,
{ {
from: Mock__L2CrossDomainMessenger.address, from: Fake__L2CrossDomainMessenger.address,
} }
) )
...@@ -183,7 +177,7 @@ describe('L2StandardBridge', () => { ...@@ -183,7 +177,7 @@ describe('L2StandardBridge', () => {
describe('withdrawals', () => { describe('withdrawals', () => {
const withdrawAmount = 1_000 const withdrawAmount = 1_000
let SmoddedL2Token: ModifiableContract let Mock__L2Token: MockContract<Contract>
let Fake__OVM_ETH let Fake__OVM_ETH
...@@ -195,8 +189,8 @@ describe('L2StandardBridge', () => { ...@@ -195,8 +189,8 @@ describe('L2StandardBridge', () => {
beforeEach(async () => { beforeEach(async () => {
// Deploy a smodded gateway so we can give some balances to withdraw // Deploy a smodded gateway so we can give some balances to withdraw
SmoddedL2Token = await ( Mock__L2Token = await (
await smoddit('L2StandardERC20', alice) await smock.mock('L2StandardERC20')
).deploy( ).deploy(
L2StandardBridge.address, L2StandardBridge.address,
DUMMY_L1TOKEN_ADDRESS, DUMMY_L1TOKEN_ADDRESS,
...@@ -204,14 +198,11 @@ describe('L2StandardBridge', () => { ...@@ -204,14 +198,11 @@ describe('L2StandardBridge', () => {
'L2T' 'L2T'
) )
// Populate the initial state with a total supply and some money in alice's balance await Mock__L2Token.setVariable('_totalSupply', INITIAL_TOTAL_SUPPLY)
SmoddedL2Token.smodify.put({ await Mock__L2Token.setVariable('_balances', {
_totalSupply: INITIAL_TOTAL_SUPPLY, [aliceAddress]: ALICE_INITIAL_BALANCE,
_balances: {
[aliceAddress]: ALICE_INITIAL_BALANCE,
},
l2Bridge: L2StandardBridge.address,
}) })
await Mock__L2Token.setVariable('l2Bridge', L2StandardBridge.address)
}) })
it('withdraw() withdraws and sends the correct withdrawal message for OVM_ETH', async () => { it('withdraw() withdraws and sends the correct withdrawal message for OVM_ETH', async () => {
...@@ -223,14 +214,14 @@ describe('L2StandardBridge', () => { ...@@ -223,14 +214,14 @@ describe('L2StandardBridge', () => {
) )
const withdrawalCallToMessenger = const withdrawalCallToMessenger =
Mock__L2CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L2CrossDomainMessenger.sendMessage.getCall(0)
// Assert the correct cross-chain call was sent: // Assert the correct cross-chain call was sent:
// Message should be sent to the L1L1StandardBridge on L1 // Message should be sent to the L1L1StandardBridge on L1
expect(withdrawalCallToMessenger._target).to.equal(DUMMY_L1BRIDGE_ADDRESS) expect(withdrawalCallToMessenger.args[0]).to.equal(DUMMY_L1BRIDGE_ADDRESS)
// Message data should be a call telling the L1StandardBridge to finalize the withdrawal // Message data should be a call telling the L1StandardBridge to finalize the withdrawal
expect(withdrawalCallToMessenger._message).to.equal( expect(withdrawalCallToMessenger.args[1]).to.equal(
Factory__L1StandardBridge.interface.encodeFunctionData( Factory__L1StandardBridge.interface.encodeFunctionData(
'finalizeETHWithdrawal', 'finalizeETHWithdrawal',
[ [
...@@ -245,16 +236,16 @@ describe('L2StandardBridge', () => { ...@@ -245,16 +236,16 @@ describe('L2StandardBridge', () => {
it('withdraw() burns and sends the correct withdrawal message', async () => { it('withdraw() burns and sends the correct withdrawal message', async () => {
await L2StandardBridge.withdraw( await L2StandardBridge.withdraw(
SmoddedL2Token.address, Mock__L2Token.address,
withdrawAmount, withdrawAmount,
0, 0,
NON_NULL_BYTES32 NON_NULL_BYTES32
) )
const withdrawalCallToMessenger = const withdrawalCallToMessenger =
Mock__L2CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L2CrossDomainMessenger.sendMessage.getCall(0)
// Assert Alice's balance went down // Assert Alice's balance went down
const aliceBalance = await SmoddedL2Token.balanceOf( const aliceBalance = await Mock__L2Token.balanceOf(
await alice.getAddress() await alice.getAddress()
) )
expect(aliceBalance).to.deep.equal( expect(aliceBalance).to.deep.equal(
...@@ -262,21 +253,21 @@ describe('L2StandardBridge', () => { ...@@ -262,21 +253,21 @@ describe('L2StandardBridge', () => {
) )
// Assert totalSupply went down // Assert totalSupply went down
const newTotalSupply = await SmoddedL2Token.totalSupply() const newTotalSupply = await Mock__L2Token.totalSupply()
expect(newTotalSupply).to.deep.equal( expect(newTotalSupply).to.deep.equal(
ethers.BigNumber.from(INITIAL_TOTAL_SUPPLY - withdrawAmount) ethers.BigNumber.from(INITIAL_TOTAL_SUPPLY - withdrawAmount)
) )
// Assert the correct cross-chain call was sent: // Assert the correct cross-chain call was sent:
// Message should be sent to the L1L1StandardBridge on L1 // Message should be sent to the L1L1StandardBridge on L1
expect(withdrawalCallToMessenger._target).to.equal(DUMMY_L1BRIDGE_ADDRESS) expect(withdrawalCallToMessenger.args[0]).to.equal(DUMMY_L1BRIDGE_ADDRESS)
// Message data should be a call telling the L1L1StandardBridge to finalize the withdrawal // Message data should be a call telling the L1L1StandardBridge to finalize the withdrawal
expect(withdrawalCallToMessenger._message).to.equal( expect(withdrawalCallToMessenger.args[1]).to.equal(
Factory__L1StandardBridge.interface.encodeFunctionData( Factory__L1StandardBridge.interface.encodeFunctionData(
'finalizeERC20Withdrawal', 'finalizeERC20Withdrawal',
[ [
DUMMY_L1TOKEN_ADDRESS, DUMMY_L1TOKEN_ADDRESS,
SmoddedL2Token.address, Mock__L2Token.address,
await alice.getAddress(), await alice.getAddress(),
await alice.getAddress(), await alice.getAddress(),
withdrawAmount, withdrawAmount,
...@@ -285,22 +276,22 @@ describe('L2StandardBridge', () => { ...@@ -285,22 +276,22 @@ describe('L2StandardBridge', () => {
) )
) )
// gaslimit should be correct // gaslimit should be correct
expect(withdrawalCallToMessenger._gasLimit).to.equal(0) expect(withdrawalCallToMessenger.args[2]).to.equal(0)
}) })
it('withdrawTo() burns and sends the correct withdrawal message', async () => { it('withdrawTo() burns and sends the correct withdrawal message', async () => {
await L2StandardBridge.withdrawTo( await L2StandardBridge.withdrawTo(
SmoddedL2Token.address, Mock__L2Token.address,
await bob.getAddress(), await bob.getAddress(),
withdrawAmount, withdrawAmount,
0, 0,
NON_NULL_BYTES32 NON_NULL_BYTES32
) )
const withdrawalCallToMessenger = const withdrawalCallToMessenger =
Mock__L2CrossDomainMessenger.smocked.sendMessage.calls[0] Fake__L2CrossDomainMessenger.sendMessage.getCall(0)
// Assert Alice's balance went down // Assert Alice's balance went down
const aliceBalance = await SmoddedL2Token.balanceOf( const aliceBalance = await Mock__L2Token.balanceOf(
await alice.getAddress() await alice.getAddress()
) )
expect(aliceBalance).to.deep.equal( expect(aliceBalance).to.deep.equal(
...@@ -308,21 +299,21 @@ describe('L2StandardBridge', () => { ...@@ -308,21 +299,21 @@ describe('L2StandardBridge', () => {
) )
// Assert totalSupply went down // Assert totalSupply went down
const newTotalSupply = await SmoddedL2Token.totalSupply() const newTotalSupply = await Mock__L2Token.totalSupply()
expect(newTotalSupply).to.deep.equal( expect(newTotalSupply).to.deep.equal(
ethers.BigNumber.from(INITIAL_TOTAL_SUPPLY - withdrawAmount) ethers.BigNumber.from(INITIAL_TOTAL_SUPPLY - withdrawAmount)
) )
// Assert the correct cross-chain call was sent. // Assert the correct cross-chain call was sent.
// Message should be sent to the L1L1StandardBridge on L1 // Message should be sent to the L1L1StandardBridge on L1
expect(withdrawalCallToMessenger._target).to.equal(DUMMY_L1BRIDGE_ADDRESS) expect(withdrawalCallToMessenger.args[0]).to.equal(DUMMY_L1BRIDGE_ADDRESS)
// The message data should be a call telling the L1L1StandardBridge to finalize the withdrawal // The message data should be a call telling the L1L1StandardBridge to finalize the withdrawal
expect(withdrawalCallToMessenger._message).to.equal( expect(withdrawalCallToMessenger.args[1]).to.equal(
Factory__L1StandardBridge.interface.encodeFunctionData( Factory__L1StandardBridge.interface.encodeFunctionData(
'finalizeERC20Withdrawal', 'finalizeERC20Withdrawal',
[ [
DUMMY_L1TOKEN_ADDRESS, DUMMY_L1TOKEN_ADDRESS,
SmoddedL2Token.address, Mock__L2Token.address,
await alice.getAddress(), await alice.getAddress(),
await bob.getAddress(), await bob.getAddress(),
withdrawAmount, withdrawAmount,
...@@ -331,7 +322,7 @@ describe('L2StandardBridge', () => { ...@@ -331,7 +322,7 @@ describe('L2StandardBridge', () => {
) )
) )
// gas value is ignored and set to 0. // gas value is ignored and set to 0.
expect(withdrawalCallToMessenger._gasLimit).to.equal(0) expect(withdrawalCallToMessenger.args[2]).to.equal(0)
}) })
}) })
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Signer, ContractFactory, Contract } from 'ethers' import { Signer, ContractFactory, Contract } from 'ethers'
import { smoddit } from '@eth-optimism/smock' import {
smock,
MockContractFactory,
MockContract,
} from '@defi-wonderland/smock'
/* Internal Imports */ /* Internal Imports */
import { expect } from '../../../setup' import { expect } from '../../../setup'
...@@ -9,13 +13,13 @@ import { predeploys, getContractInterface } from '../../../../src' ...@@ -9,13 +13,13 @@ import { predeploys, getContractInterface } from '../../../../src'
describe('L2StandardTokenFactory', () => { describe('L2StandardTokenFactory', () => {
let signer: Signer let signer: Signer
let Factory__L1ERC20: ContractFactory let Factory__L1ERC20: MockContractFactory<ContractFactory>
let L1ERC20: Contract let L1ERC20: MockContract<Contract>
let L2StandardTokenFactory: Contract let L2StandardTokenFactory: Contract
before(async () => { before(async () => {
;[signer] = await ethers.getSigners() ;[signer] = await ethers.getSigners()
// deploy an ERC20 contract on L1 // deploy an ERC20 contract on L1
Factory__L1ERC20 = await smoddit( Factory__L1ERC20 = await smock.mock(
'@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20' '@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20'
) )
L1ERC20 = await Factory__L1ERC20.deploy('L1ERC20', 'ERC') L1ERC20 = await Factory__L1ERC20.deploy('L1ERC20', 'ERC')
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { ContractFactory, Contract } from 'ethers' import { ContractFactory, Contract } from 'ethers'
import { MockContract, smockit } from '@eth-optimism/smock' import { smock, FakeContract } from '@defi-wonderland/smock'
import { remove0x } from '@eth-optimism/core-utils' import { remove0x } from '@eth-optimism/core-utils'
import { keccak256 } from 'ethers/lib/utils' import { keccak256 } from 'ethers/lib/utils'
...@@ -25,9 +25,9 @@ const callPredeploy = async ( ...@@ -25,9 +25,9 @@ const callPredeploy = async (
// TODO: rewrite this test to bypass the execution manager // TODO: rewrite this test to bypass the execution manager
describe.skip('OVM_L2ToL1MessagePasser', () => { describe.skip('OVM_L2ToL1MessagePasser', () => {
let Mock__OVM_ExecutionManager: MockContract let Fake__OVM_ExecutionManager: FakeContract
before(async () => { before(async () => {
Mock__OVM_ExecutionManager = await smockit( Fake__OVM_ExecutionManager = await smock.fake<Contract>(
await ethers.getContractFactory('OVM_ExecutionManager') await ethers.getContractFactory('OVM_ExecutionManager')
) )
}) })
...@@ -38,7 +38,7 @@ describe.skip('OVM_L2ToL1MessagePasser', () => { ...@@ -38,7 +38,7 @@ describe.skip('OVM_L2ToL1MessagePasser', () => {
await ethers.getContractFactory('Helper_PredeployCaller') await ethers.getContractFactory('Helper_PredeployCaller')
).deploy() ).deploy()
Helper_PredeployCaller.setTarget(Mock__OVM_ExecutionManager.address) Helper_PredeployCaller.setTarget(Fake__OVM_ExecutionManager.address)
}) })
let Factory__OVM_L2ToL1MessagePasser: ContractFactory let Factory__OVM_L2ToL1MessagePasser: ContractFactory
...@@ -55,9 +55,7 @@ describe.skip('OVM_L2ToL1MessagePasser', () => { ...@@ -55,9 +55,7 @@ describe.skip('OVM_L2ToL1MessagePasser', () => {
describe('passMessageToL1', () => { describe('passMessageToL1', () => {
before(async () => { before(async () => {
Mock__OVM_ExecutionManager.smocked.ovmCALLER.will.return.with( Fake__OVM_ExecutionManager.ovmCALLER.returns(NON_ZERO_ADDRESS)
NON_ZERO_ADDRESS
)
}) })
for (const size of ELEMENT_TEST_SIZES) { for (const size of ELEMENT_TEST_SIZES) {
......
/* Imports: External */ /* Imports: External */
import hre from 'hardhat' import hre from 'hardhat'
import { MockContract, smockit } from '@eth-optimism/smock' import { smock, FakeContract } from '@defi-wonderland/smock'
import { Contract, Signer } from 'ethers' import { Contract, Signer } from 'ethers'
/* Imports: Internal */ /* Imports: Internal */
...@@ -13,9 +13,9 @@ describe('OVM_SequencerFeeVault', () => { ...@@ -13,9 +13,9 @@ describe('OVM_SequencerFeeVault', () => {
;[signer1] = await hre.ethers.getSigners() ;[signer1] = await hre.ethers.getSigners()
}) })
let Mock__L2StandardBridge: MockContract let Fake__L2StandardBridge: FakeContract
before(async () => { before(async () => {
Mock__L2StandardBridge = await smockit('L2StandardBridge', { Fake__L2StandardBridge = await smock.fake<Contract>('L2StandardBridge', {
address: predeploys.L2StandardBridge, address: predeploys.L2StandardBridge,
}) })
}) })
...@@ -42,13 +42,21 @@ describe('OVM_SequencerFeeVault', () => { ...@@ -42,13 +42,21 @@ describe('OVM_SequencerFeeVault', () => {
await expect(OVM_SequencerFeeVault.withdraw()).to.not.be.reverted await expect(OVM_SequencerFeeVault.withdraw()).to.not.be.reverted
expect(Mock__L2StandardBridge.smocked.withdrawTo.calls[0]).to.deep.equal([ expect(
predeploys.OVM_ETH, Fake__L2StandardBridge.withdrawTo.getCall(0).args[0]
await signer1.getAddress(), ).to.deep.equal(predeploys.OVM_ETH)
amount, expect(
0, Fake__L2StandardBridge.withdrawTo.getCall(0).args[1]
'0x', ).to.deep.equal(await signer1.getAddress())
]) expect(
Fake__L2StandardBridge.withdrawTo.getCall(0).args[2]
).to.deep.equal(amount)
expect(
Fake__L2StandardBridge.withdrawTo.getCall(0).args[3]
).to.deep.equal(0)
expect(
Fake__L2StandardBridge.withdrawTo.getCall(0).args[4]
).to.deep.equal('0x')
}) })
it('should succeed when the contract has more than sufficient balance', async () => { it('should succeed when the contract has more than sufficient balance', async () => {
...@@ -62,14 +70,21 @@ describe('OVM_SequencerFeeVault', () => { ...@@ -62,14 +70,21 @@ describe('OVM_SequencerFeeVault', () => {
}) })
await expect(OVM_SequencerFeeVault.withdraw()).to.not.be.reverted await expect(OVM_SequencerFeeVault.withdraw()).to.not.be.reverted
expect(
expect(Mock__L2StandardBridge.smocked.withdrawTo.calls[0]).to.deep.equal([ Fake__L2StandardBridge.withdrawTo.getCall(1).args[0]
predeploys.OVM_ETH, ).to.deep.equal(predeploys.OVM_ETH)
await signer1.getAddress(), expect(
amount, Fake__L2StandardBridge.withdrawTo.getCall(1).args[1]
0, ).to.deep.equal(await signer1.getAddress())
'0x', expect(
]) Fake__L2StandardBridge.withdrawTo.getCall(1).args[2]
).to.deep.equal(amount)
expect(
Fake__L2StandardBridge.withdrawTo.getCall(1).args[3]
).to.deep.equal(0)
expect(
Fake__L2StandardBridge.withdrawTo.getCall(1).args[4]
).to.deep.equal('0x')
}) })
it('should have an owner in storage slot 0x00...00', async () => { it('should have an owner in storage slot 0x00...00', async () => {
......
/* Imports: External */ /* Imports: External */
import hre from 'hardhat' import hre from 'hardhat'
import { Contract, Signer } from 'ethers' import { Contract, Signer } from 'ethers'
import { smockit } from '@eth-optimism/smock' import { smock } from '@defi-wonderland/smock'
/* Imports: Internal */ /* Imports: Internal */
import { expect } from '../../setup' import { expect } from '../../setup'
...@@ -170,11 +170,13 @@ describe('L1ChugSplashProxy', () => { ...@@ -170,11 +170,13 @@ describe('L1ChugSplashProxy', () => {
}) })
it('should throw an error if the owner has signalled an upgrade', async () => { it('should throw an error if the owner has signalled an upgrade', async () => {
const owner = await smockit(getContractInterface('iL1ChugSplashDeployer')) const owner = await smock.fake<Contract>(
getContractInterface('iL1ChugSplashDeployer')
)
const factory = await hre.ethers.getContractFactory('L1ChugSplashProxy') const factory = await hre.ethers.getContractFactory('L1ChugSplashProxy')
const proxy = await factory.deploy(owner.address) const proxy = await factory.deploy(owner.address)
owner.smocked.isUpgrading.will.return.with(true) owner.isUpgrading.returns(true)
await expect( await expect(
owner.wallet.sendTransaction({ owner.wallet.sendTransaction({
......
/* External Imports */ /* External Imports */
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Contract } from 'ethers' import { Contract } from 'ethers'
import { FakeContract } from '@defi-wonderland/smock'
export const setProxyTarget = async ( export const setProxyTarget = async (
AddressManager: Contract, AddressManager: Contract,
name: string, name: string,
target: Contract target: FakeContract
): Promise<void> => { ): Promise<void> => {
const SimpleProxy: Contract = await ( const SimpleProxy: Contract = await (
await ethers.getContractFactory('Helper_SimpleProxy') await ethers.getContractFactory('Helper_SimpleProxy')
......
ignores: [ ignores: [
"@eth-optimism/core-utils", "@eth-optimism/core-utils",
"ts-mocha", "ts-mocha",
] "typedoc",
\ No newline at end of file ]
node_modules/ node_modules/
build/ build/
docs/
...@@ -4,19 +4,33 @@ ...@@ -4,19 +4,33 @@
The `@eth-optimism/sdk` package provides a set of tools for interacting with Optimism. The `@eth-optimism/sdk` package provides a set of tools for interacting with Optimism.
## NOTICE
WARNING: This package is currently under construction.
You can definitely try to use it, but you probably won't have a good time.
Lots of pieces are missing.
We will announce the 1.0.0 release on Discord and on Twitter once it's ready, keep an eye out!
## Installation ## Installation
``` ```
npm install @eth-optimism/sdk npm install @eth-optimism/sdk
``` ```
## API ## Docs
You can find auto-generated API documentation over at [sdk.optimism.io](https://sdk.optimism.io).
## Using the SDK
### CrossChainMessenger
The [`CrossChainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/sdk/src/cross-chain-messenger.ts) class simplifies the process of moving assets and data between Ethereum and Optimism.
You can use this class to, for example, initiate a withdrawal of ERC20 tokens from Optimism back to Ethereum, accurately track when the withdrawal is ready to be finalized on Ethereum, and execute the finalization transaction after the challenge period has elapsed.
The `CrossChainMessenger` can handle deposits and withdrawals of ETH and any ERC20-compatible token.
Detailed API descriptions can be found at [sdk.optimism.io](https://sdk.optimism.io/classes/crosschainmessenger).
The `CrossChainMessenger` automatically connects to all relevant contracts so complex configuration is not necessary.
### L2Provider and related utilities
The Optimism SDK includes [various utilities](https://github.com/ethereum-optimism/optimism/blob/develop/packages/sdk/src/l2-provider.ts) for handling Optimism's [transaction fee model](https://community.optimism.io/docs/developers/build/transaction-fees/).
For instance, [`estimateTotalGasCost`](https://sdk.optimism.io/modules.html#estimateTotalGasCost) will estimate the total cost (in wei) to send at transaction on Optimism including both the L2 execution cost and the L1 data cost.
You can also use the [`asL2Provider`](https://sdk.optimism.io/modules.html#asL2Provider) function to wrap an ethers Provider object into an `L2Provider` which will have all of these helper functions attached.
### Other utilities
TODO: Fill this in once the initial package version is finished. The SDK contains other useful helper functions and constants.
For a complete list, refer to the auto-generated [SDK documentation](https://sdk.optimism.io/)
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
"lint:fix": "yarn lint:check --fix", "lint:fix": "yarn lint:check --fix",
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"test": "hardhat test", "test": "hardhat test",
"test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json" "test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json",
"autogen:docs": "typedoc --out docs src/index.ts"
}, },
"keywords": [ "keywords": [
"optimism", "optimism",
...@@ -60,6 +61,7 @@ ...@@ -60,6 +61,7 @@
"nyc": "^15.1.0", "nyc": "^15.1.0",
"prettier": "^2.3.1", "prettier": "^2.3.1",
"ts-mocha": "^8.0.0", "ts-mocha": "^8.0.0",
"typedoc": "^0.22.13",
"typescript": "^4.3.5" "typescript": "^4.3.5"
}, },
"dependencies": { "dependencies": {
......
...@@ -64,7 +64,7 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -64,7 +64,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
* *
* @param opts Options for the provider. * @param opts Options for the provider.
* @param opts.l1SignerOrProvider Signer or Provider for the L1 chain, or a JSON-RPC url. * @param opts.l1SignerOrProvider Signer or Provider for the L1 chain, or a JSON-RPC url.
* @param opts.l1SignerOrProvider Signer or Provider for the L2 chain, or a JSON-RPC url. * @param opts.l2SignerOrProvider Signer or Provider for the L2 chain, or a JSON-RPC url.
* @param opts.l1ChainId Chain ID for the L1 chain. * @param opts.l1ChainId Chain ID for the L1 chain.
* @param opts.depositConfirmationBlocks Optional number of blocks before a deposit is confirmed. * @param opts.depositConfirmationBlocks Optional number of blocks before a deposit is confirmed.
* @param opts.l1BlockTimeSeconds Optional estimated block time in seconds for the L1 chain. * @param opts.l1BlockTimeSeconds Optional estimated block time in seconds for the L1 chain.
......
...@@ -497,23 +497,6 @@ ...@@ -497,23 +497,6 @@
minimatch "^3.0.4" minimatch "^3.0.4"
strip-json-comments "^3.1.1" strip-json-comments "^3.1.1"
"@eth-optimism/core-utils@^0.5.1":
version "0.5.5"
resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.5.5.tgz#0e2bb95b23965fb51adfb8ba6841c3afd26a6411"
integrity sha512-N/uyZjHltnvnQyBOE498EGlqeYvWRUQTW6BpXhexKljEXZpnria4J4MFO9s1lJOpogLXTaS+lhM1Ic8zUNj8Pg==
dependencies:
"@ethersproject/abstract-provider" "^5.4.1"
ethers "^5.4.5"
lodash "^4.17.21"
"@eth-optimism/smock@1.1.10":
version "1.1.10"
resolved "https://registry.yarnpkg.com/@eth-optimism/smock/-/smock-1.1.10.tgz#98a6eefc994ccf707f52ab06849468f3cc57bdb7"
integrity sha512-XPx1x9odF/noTBHzIhRgL9ihhr769WgUhf9dOm6X7bjSWRAVsII3IqbdB4ssPycaoSuNSmv8HG1xTLgfgcyOYw==
dependencies:
"@eth-optimism/core-utils" "^0.5.1"
bn.js "^5.2.0"
"@ethereum-waffle/chai@^3.4.0": "@ethereum-waffle/chai@^3.4.0":
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5" resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5"
...@@ -712,7 +695,7 @@ ...@@ -712,7 +695,7 @@
"@ethersproject/properties" "^5.4.0" "@ethersproject/properties" "^5.4.0"
"@ethersproject/strings" "^5.4.0" "@ethersproject/strings" "^5.4.0"
"@ethersproject/abstract-provider@5.4.1", "@ethersproject/abstract-provider@^5.4.0", "@ethersproject/abstract-provider@^5.4.1": "@ethersproject/abstract-provider@5.4.1", "@ethersproject/abstract-provider@^5.4.0":
version "5.4.1" version "5.4.1"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz#e404309a29f771bd4d28dbafadcaa184668c2a6e" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz#e404309a29f771bd4d28dbafadcaa184668c2a6e"
integrity sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ== integrity sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ==
...@@ -4574,6 +4557,13 @@ brace-expansion@^1.1.7: ...@@ -4574,6 +4557,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0" balanced-match "^1.0.0"
concat-map "0.0.1" concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^2.3.1: braces@^2.3.1:
version "2.3.2" version "2.3.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
...@@ -7176,7 +7166,7 @@ ethers@^4.0.32, ethers@^4.0.40: ...@@ -7176,7 +7166,7 @@ ethers@^4.0.32, ethers@^4.0.40:
uuid "2.0.1" uuid "2.0.1"
xmlhttprequest "1.8.0" xmlhttprequest "1.8.0"
ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.2, ethers@^5.4.5: ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.2:
version "5.4.5" version "5.4.5"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.4.5.tgz#cec133b9f5b514dc55e2561ee7aa7218c33affd7" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.4.5.tgz#cec133b9f5b514dc55e2561ee7aa7218c33affd7"
integrity sha512-PPZ6flOAj230sXEWf/r/It6ZZ5c7EOVWx+PU87Glkbg79OtT7pLE1WgL4MRdwx6iF7HzSOvUUI+8cAmcdzo12w== integrity sha512-PPZ6flOAj230sXEWf/r/It6ZZ5c7EOVWx+PU87Glkbg79OtT7pLE1WgL4MRdwx6iF7HzSOvUUI+8cAmcdzo12w==
...@@ -8219,6 +8209,18 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, gl ...@@ -8219,6 +8209,18 @@ glob@^7.0.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, gl
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
glob@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
global-modules@^2.0.0: global-modules@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
...@@ -9697,6 +9699,11 @@ json5@^2.1.0, json5@^2.1.2, json5@^2.2.0: ...@@ -9697,6 +9699,11 @@ json5@^2.1.0, json5@^2.1.2, json5@^2.2.0:
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
jsonc-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==
jsonfile@^2.1.0: jsonfile@^2.1.0:
version "2.4.0" version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
...@@ -10418,6 +10425,11 @@ ltgt@~2.1.1: ...@@ -10418,6 +10425,11 @@ ltgt@~2.1.1:
resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34" resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.1.3.tgz#10851a06d9964b971178441c23c9e52698eece34"
integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ= integrity sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=
lunr@^2.3.9:
version "2.3.9"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
make-dir@^2.1.0: make-dir@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
...@@ -10532,6 +10544,11 @@ marked@^0.7.0: ...@@ -10532,6 +10544,11 @@ marked@^0.7.0:
resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e"
integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==
marked@^4.0.12:
version "4.0.12"
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.12.tgz#2262a4e6fd1afd2f13557726238b69a48b982f7d"
integrity sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==
match-all@^1.2.6: match-all@^1.2.6:
version "1.2.6" version "1.2.6"
resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d"
...@@ -10847,6 +10864,13 @@ minimalistic-crypto-utils@^1.0.1: ...@@ -10847,6 +10864,13 @@ minimalistic-crypto-utils@^1.0.1:
dependencies: dependencies:
brace-expansion "^1.1.7" brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
dependencies:
brace-expansion "^2.0.1"
minimist-options@4.1.0, minimist-options@^4.0.2: minimist-options@4.1.0, minimist-options@^4.0.2:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
...@@ -13700,6 +13724,15 @@ shelljs@^0.8.3: ...@@ -13700,6 +13724,15 @@ shelljs@^0.8.3:
interpret "^1.0.0" interpret "^1.0.0"
rechoir "^0.6.2" rechoir "^0.6.2"
shiki@^0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14"
integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==
dependencies:
jsonc-parser "^3.0.0"
vscode-oniguruma "^1.6.1"
vscode-textmate "5.2.0"
side-channel@^1.0.4: side-channel@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
...@@ -15138,6 +15171,17 @@ typedarray@^0.0.6: ...@@ -15138,6 +15171,17 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typedoc@^0.22.13:
version "0.22.13"
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.13.tgz#d061f8f0fb7c9d686e48814f245bddeea4564e66"
integrity sha512-NHNI7Dr6JHa/I3+c62gdRNXBIyX7P33O9TafGLd07ur3MqzcKgwTvpg18EtvCLHJyfeSthAtCLpM7WkStUmDuQ==
dependencies:
glob "^7.2.0"
lunr "^2.3.9"
marked "^4.0.12"
minimatch "^5.0.1"
shiki "^0.10.1"
typescript@^4.3.4, typescript@^4.3.5: typescript@^4.3.4, typescript@^4.3.5:
version "4.3.5" version "4.3.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
...@@ -15460,6 +15504,16 @@ verror@1.10.0: ...@@ -15460,6 +15504,16 @@ verror@1.10.0:
core-util-is "1.0.2" core-util-is "1.0.2"
extsprintf "^1.2.0" extsprintf "^1.2.0"
vscode-oniguruma@^1.6.1:
version "1.6.2"
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607"
integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==
vscode-textmate@5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e"
integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==
wcwidth@^1.0.0, wcwidth@^1.0.1: wcwidth@^1.0.0, wcwidth@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
......
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