diff --git a/.changeset/many-wombats-hear.md b/.changeset/many-wombats-hear.md deleted file mode 100644 index c119aee4115fa..0000000000000 --- a/.changeset/many-wombats-hear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@eth-optimism/batch-submitter": patch ---- - -properly start the batch submitter instead of instantly exiting diff --git a/.changeset/slimy-tomatoes-report.md b/.changeset/slimy-tomatoes-report.md deleted file mode 100644 index 14923a5debc7a..0000000000000 --- a/.changeset/slimy-tomatoes-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@eth-optimism/specs": minor ---- - -Add a new package to contain specs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35d90dd9bba72..599f5382aaed8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,7 @@ jobs: batch-submitter: ${{ steps.packages.outputs.batch-submitter }} message-relayer: ${{ steps.packages.outputs.message-relayer }} data-transport-layer: ${{ steps.packages.outputs.data-transport-layer }} + contracts: ${{ steps.packages.outputs.contracts }} steps: - name: Checkout Repo @@ -102,6 +103,7 @@ jobs: batch-submitter: ${{ needs.release.outputs.batch-submitter }} message-relayer: ${{ needs.release.outputs.message-relayer }} data-transport-layer: ${{ needs.release.outputs.data-transport-layer }} + contracts: ${{ needs.release.outputs.contracts }} steps: - name: Checkout @@ -200,3 +202,29 @@ jobs: file: ./ops/docker/Dockerfile.data-transport-layer push: true tags: ethereumoptimism/data-transport-layer:${{ needs.builder.outputs.data-transport-layer }} + + contracts: + name: Publish Deployer Version ${{ needs.builder.outputs.contracts }} + needs: builder + if: needs.builder.outputs.contracts != '' + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_USERNAME }} + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN_SECRET }} + + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + file: ./ops/docker/Dockerfile.deployer + push: true + tags: ethereumoptimism/deployer:${{ needs.builder.outputs.contracts }} diff --git a/l2geth/core/types/transaction_signing.go b/l2geth/core/types/transaction_signing.go index a22e7fd99a9b5..842fedbd03d61 100644 --- a/l2geth/core/types/transaction_signing.go +++ b/l2geth/core/types/transaction_signing.go @@ -17,67 +17,16 @@ package types import ( - "bytes" "crypto/ecdsa" - "encoding/binary" "errors" "fmt" "math/big" - "strings" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "golang.org/x/crypto/sha3" ) -var codec abi.ABI - -func init() { - const abidata = ` - [ - { - "type": "function", - "name": "encode", - "constant": true, - "inputs": [ - { - "name": "nonce", - "type": "uint256" - }, - { - "name": "gasLimit", - "type": "uint256" - }, - { - "name": "gasPrice", - "type": "uint256" - }, - { - "name": "chainId", - "type": "uint256" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "data", - "type": "bytes" - } - ] - } - ] - ` - - var err error - codec, err = abi.JSON(strings.NewReader(abidata)) - if err != nil { - panic(fmt.Errorf("unable to create Eth Sign abi reader: %v", err)) - } -} - var ( ErrInvalidChainId = errors.New("invalid chain id for signer") ) @@ -91,7 +40,16 @@ type sigCache struct { // MakeSigner returns a Signer based on the given chain config and block number. func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer { - return NewOVMSigner(config.ChainID) + var signer Signer + switch { + case config.IsEIP155(blockNumber): + signer = NewEIP155Signer(config.ChainID) + case config.IsHomestead(blockNumber): + signer = HomesteadSigner{} + default: + signer = FrontierSigner{} + } + return signer } // SignTx signs the transaction using the given signer and private key @@ -144,97 +102,6 @@ type Signer interface { Equal(Signer) bool } -// OVMSigner implements Signers using the EIP155 rules along with a new -// `eth_sign` based signature hash. -type OVMSigner struct { - EIP155Signer -} - -func NewOVMSigner(chainId *big.Int) OVMSigner { - signer := NewEIP155Signer(chainId) - return OVMSigner{signer} -} - -func (s OVMSigner) Equal(s2 Signer) bool { - ovm, ok := s2.(OVMSigner) - return ok && ovm.chainId.Cmp(s.chainId) == 0 -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s OVMSigner) Hash(tx *Transaction) common.Hash { - if tx.IsEthSignSighash() { - msg := s.OVMSignerTemplateSighashPreimage(tx) - - hasher := sha3.NewLegacyKeccak256() - hasher.Write(msg[:]) - digest := hasher.Sum(nil) - - return common.BytesToHash(digest) - } - - return rlpHash([]interface{}{ - tx.data.AccountNonce, - tx.data.Price, - tx.data.GasLimit, - tx.data.Recipient, - tx.data.Amount, - tx.data.Payload, - s.chainId, uint(0), uint(0), - }) -} - -// Sender will ecrecover the public key that created the signature -// and then hash the public key to create an address. In the -// case of L1ToL2 transactions, Layer One did the authentication -// for us so there is no signature involved. The concept of a "from" -// is only required for bookkeeping within this codebase -func (s OVMSigner) Sender(tx *Transaction) (common.Address, error) { - qo := tx.QueueOrigin() - if qo != nil && qo.Uint64() == uint64(QueueOriginL1ToL2) { - return common.Address{}, nil - } - if !tx.Protected() { - return HomesteadSigner{}.Sender(tx) - } - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, ErrInvalidChainId - } - V := new(big.Int).Sub(tx.data.V, s.chainIdMul) - V.Sub(V, big8) - return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true) -} - -// OVMSignerTemplateSighashPreimage creates the preimage for the `eth_sign` like -// signature hash. The transaction is `ABI.encodePacked`. -func (s OVMSigner) OVMSignerTemplateSighashPreimage(tx *Transaction) []byte { - data := []interface{}{ - big.NewInt(int64(tx.data.AccountNonce)), - big.NewInt(int64(tx.data.GasLimit)), - tx.data.Price, - s.chainId, - *tx.data.Recipient, - tx.data.Payload, - } - - ret, err := codec.Pack("encode", data...) - if err != nil { - panic(fmt.Errorf("unable to pack Eth Sign data: %v", err)) - } - - hasher := sha3.NewLegacyKeccak256() - // Slice off the function selector before hashing - hasher.Write(ret[4:]) - digest := hasher.Sum(nil) - - preimage := new(bytes.Buffer) - prefix := []byte("\x19Ethereum Signed Message:\n32") - binary.Write(preimage, binary.BigEndian, prefix) - binary.Write(preimage, binary.BigEndian, digest) - - return preimage.Bytes() -} - // EIP155Transaction implements Signer using the EIP155 rules. type EIP155Signer struct { chainId, chainIdMul *big.Int diff --git a/l2geth/core/types/transaction_signing_test.go b/l2geth/core/types/transaction_signing_test.go index f0102710b1329..689fc38a9b660 100644 --- a/l2geth/core/types/transaction_signing_test.go +++ b/l2geth/core/types/transaction_signing_test.go @@ -136,100 +136,3 @@ func TestChainId(t *testing.T) { t.Error("expected no error") } } - -func TestOVMSigner(t *testing.T) { - key, _ := defaultTestKey() - - tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) - txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil, nil) - tx.SetTransactionMeta(txMeta) - - var err error - tx, err = SignTx(tx, NewOVMSigner(big.NewInt(1)), key) - if err != nil { - t.Fatal(err) - } - - _, err = Sender(NewOVMSigner(big.NewInt(2)), tx) - if err != ErrInvalidChainId { - t.Error("expected error:", ErrInvalidChainId) - } - - _, err = Sender(NewOVMSigner(big.NewInt(1)), tx) - if err != nil { - t.Error("expected no error") - } -} - -func TestOVMSignerHash(t *testing.T) { - signer := NewOVMSigner(big.NewInt(1)) - - txNil := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) - txEIP155 := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) - - hashNil := signer.Hash(txNil) - hashEIP155 := signer.Hash(txEIP155) - if hashNil != hashEIP155 { - t.Errorf("Signature hashes should be equal: %s != %s", hashNil.Hex(), hashEIP155.Hex()) - } - - // The signature hash should be different when using `SighashEthSign` - txEthSign := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) - txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil, nil) - txEthSign.SetTransactionMeta(txMeta) - - hashEthSign := signer.Hash(txEthSign) - if hashEIP155 == hashEthSign { - t.Errorf("Signature hashes should not be equal: %s == %s", hashEIP155.Hex(), hashEthSign.Hex()) - } -} - -func TestOVMSignerSender(t *testing.T) { - // Create a keypair to sign transactions with and the corresponding address - // from the public key. - key, _ := crypto.GenerateKey() - addr := crypto.PubkeyToAddress(key.PublicKey) - - // This test makes sure that both the EIP155 and EthSign signature hash - // codepaths work when using the OVMSigner. - signer := NewOVMSigner(big.NewInt(1)) - var err error - - // Create a transaction with EIP155 signature hash, sign the transaction, - // recover the address and assert that the address matches the key. - txEIP155 := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) - - txEIP155, err = SignTx(txEIP155, signer, key) - if err != nil { - t.Errorf("No error expected") - } - - recEIP155, err := signer.Sender(txEIP155) - if err != nil { - t.Errorf("No error expected") - } - - if addr != recEIP155 { - t.Errorf("Recovered address doesn't match. Got %s, expected %s", recEIP155.Hex(), addr.Hex()) - } - - // Create a transaction with EthSign signature hash, sign the transaction, - // recover the address and assert that the address matches the key. - txEthSign := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) - txMeta := NewTransactionMeta(nil, 0, nil, SighashEthSign, QueueOriginSequencer, nil, nil, nil) - txEthSign.SetTransactionMeta(txMeta) - - txEthSign, err = SignTx(txEthSign, signer, key) - if err != nil { - t.Errorf("No error expected") - } - - recEthSign, err := signer.Sender(txEthSign) - if err != nil { - t.Errorf("No error expected") - } - - if addr != recEthSign { - t.Errorf("Recovered address doesn't match. Got %s, expected %s", recEthSign.Hex(), addr.Hex()) - } -} diff --git a/l2geth/core/types/transaction_test.go b/l2geth/core/types/transaction_test.go index 8ed4da8204c81..f7d108379b677 100644 --- a/l2geth/core/types/transaction_test.go +++ b/l2geth/core/types/transaction_test.go @@ -208,7 +208,7 @@ func TestTransactionJSON(t *testing.T) { if err != nil { t.Fatalf("could not generate key: %v", err) } - signer := NewOVMSigner(common.Big1) + signer := NewEIP155Signer(common.Big1) transactions := make([]*Transaction, 0, 50) for i := uint64(0); i < 25; i++ { diff --git a/l2geth/internal/ethapi/api.go b/l2geth/internal/ethapi/api.go index 7b765cbe30bc7..d65ceff813df8 100644 --- a/l2geth/internal/ethapi/api.go +++ b/l2geth/internal/ethapi/api.go @@ -1269,7 +1269,10 @@ type RPCTransaction struct { // newRPCTransaction returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { - var signer types.Signer = types.NewOVMSigner(tx.ChainId()) + var signer types.Signer = types.FrontierSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } from, _ := types.Sender(signer, tx) v, r, s := tx.RawSignatureValues() @@ -1497,7 +1500,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha var signer types.Signer = types.FrontierSigner{} if tx.Protected() { - signer = types.NewOVMSigner(tx.ChainId()) + signer = types.NewEIP155Signer(tx.ChainId()) } from, _ := types.Sender(signer, tx) @@ -1842,7 +1845,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err for _, tx := range pending { var signer types.Signer = types.HomesteadSigner{} if tx.Protected() { - signer = types.NewOVMSigner(tx.ChainId()) + signer = types.NewEIP155Signer(tx.ChainId()) } from, _ := types.Sender(signer, tx) if _, exists := accounts[from]; exists { @@ -1870,7 +1873,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr for _, p := range pending { var signer types.Signer = types.HomesteadSigner{} if p.Protected() { - signer = types.NewOVMSigner(p.ChainId()) + signer = types.NewEIP155Signer(p.ChainId()) } wantSigHash := signer.Hash(matchTx) diff --git a/l2geth/miner/worker.go b/l2geth/miner/worker.go index 3ebc34e9d8245..d152367f4d1e5 100644 --- a/l2geth/miner/worker.go +++ b/l2geth/miner/worker.go @@ -646,7 +646,7 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { return err } env := &environment{ - signer: types.NewOVMSigner(w.chainConfig.ChainID), + signer: types.NewEIP155Signer(w.chainConfig.ChainID), state: state, ancestors: mapset.NewSet(), family: mapset.NewSet(), diff --git a/l2geth/rollup/client.go b/l2geth/rollup/client.go index 0e55550e46b03..ffa94cb8620e8 100644 --- a/l2geth/rollup/client.go +++ b/l2geth/rollup/client.go @@ -130,7 +130,7 @@ type RollupClient interface { // Client is an HTTP based RollupClient type Client struct { client *resty.Client - signer *types.OVMSigner + signer *types.EIP155Signer } // TransactionResponse represents the response from the remote server when @@ -152,7 +152,7 @@ func NewClient(url string, chainID *big.Int) *Client { client := resty.New() client.SetHostURL(url) client.SetHeader("User-Agent", "sequencer") - signer := types.NewOVMSigner(chainID) + signer := types.NewEIP155Signer(chainID) return &Client{ client: client, @@ -271,7 +271,7 @@ func (c *Client) GetLatestEnqueue() (*types.Transaction, error) { // batchedTransactionToTransaction converts a transaction into a // types.Transaction that can be consumed by the SyncService -func batchedTransactionToTransaction(res *transaction, signer *types.OVMSigner) (*types.Transaction, error) { +func batchedTransactionToTransaction(res *transaction, signer *types.EIP155Signer) (*types.Transaction, error) { // `nil` transactions are not found if res == nil { return nil, errElementNotFound @@ -538,7 +538,7 @@ func (c *Client) GetTransactionBatch(index uint64) (*Batch, []*types.Transaction // parseTransactionBatchResponse will turn a TransactionBatchResponse into a // Batch and its corresponding types.Transactions -func parseTransactionBatchResponse(txBatch *TransactionBatchResponse, signer *types.OVMSigner) (*Batch, []*types.Transaction, error) { +func parseTransactionBatchResponse(txBatch *TransactionBatchResponse, signer *types.EIP155Signer) (*Batch, []*types.Transaction, error) { if txBatch == nil { return nil, nil, nil } diff --git a/ops/docker/Dockerfile.batch-submitter b/ops/docker/Dockerfile.batch-submitter index e73a4c85780d6..b833a5af83d34 100644 --- a/ops/docker/Dockerfile.batch-submitter +++ b/ops/docker/Dockerfile.batch-submitter @@ -28,4 +28,4 @@ COPY --from=builder /optimism/packages/batch-submitter/node_modules ./node_modul # copy this over in case you want to run alongside other services COPY ./ops/scripts/batches.sh . -ENTRYPOINT ["node", "exec/run-batch-submitter.js"] +ENTRYPOINT ["npm", "run", "start"] diff --git a/ops/docker/Dockerfile.message-relayer b/ops/docker/Dockerfile.message-relayer index 969042bdbe81b..05f377879e7c0 100644 --- a/ops/docker/Dockerfile.message-relayer +++ b/ops/docker/Dockerfile.message-relayer @@ -29,4 +29,4 @@ COPY --from=builder /optimism/packages/message-relayer/node_modules ./node_modul # copy this over in case you want to run alongside other services COPY ./ops/scripts/relayer.sh . -ENTRYPOINT ["node", "exec/run-message-relayer.js"] +ENTRYPOINT ["npm", "run", "start"] diff --git a/packages/batch-submitter/CHANGELOG.md b/packages/batch-submitter/CHANGELOG.md index 067e84b792920..e932cb415f527 100644 --- a/packages/batch-submitter/CHANGELOG.md +++ b/packages/batch-submitter/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.2.2 + +### Patch Changes + +- 6d31324: Update release tag for Sentry compatability +- a2f6e83: add default metrics to all batch submitters + +## 0.2.1 + +### Patch Changes + +- ab285e4: properly start the batch submitter instead of instantly exiting + ## 0.2.0 ### Minor Changes diff --git a/packages/batch-submitter/package.json b/packages/batch-submitter/package.json index 817a6fbe72990..8d80479f956fc 100644 --- a/packages/batch-submitter/package.json +++ b/packages/batch-submitter/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/batch-submitter", - "version": "0.2.0", + "version": "0.2.2", "private": true, "description": "[Optimism] Batch submission for sequencer & aggregators", "main": "dist/index", diff --git a/packages/batch-submitter/src/batch-submitter/batch-submitter.ts b/packages/batch-submitter/src/batch-submitter/batch-submitter.ts index a6e065f0f824f..954c003a59d4a 100644 --- a/packages/batch-submitter/src/batch-submitter/batch-submitter.ts +++ b/packages/batch-submitter/src/batch-submitter/batch-submitter.ts @@ -2,7 +2,7 @@ import { Contract, Signer, utils, providers } from 'ethers' import { TransactionReceipt } from '@ethersproject/abstract-provider' import * as ynatm from '@eth-optimism/ynatm' -import { Logger } from '@eth-optimism/core-utils' +import { Logger, Metrics } from '@eth-optimism/core-utils' import { getContractFactory } from 'old-contracts' export interface RollupInfo { @@ -51,7 +51,8 @@ export abstract class BatchSubmitter { readonly maxGasPriceInGwei: number, readonly gasRetryIncrement: number, readonly gasThresholdInGwei: number, - readonly log: Logger + readonly log: Logger, + readonly metrics: Metrics ) {} public abstract _submitBatch( diff --git a/packages/batch-submitter/src/batch-submitter/index.ts b/packages/batch-submitter/src/batch-submitter/index.ts index 1d7d2dbb5ab9b..3e66fa8b8c3ee 100644 --- a/packages/batch-submitter/src/batch-submitter/index.ts +++ b/packages/batch-submitter/src/batch-submitter/index.ts @@ -2,8 +2,8 @@ export * from './batch-submitter' export * from './tx-batch-submitter' export * from './state-batch-submitter' -export const TX_BATCH_SUBMITTER_LOG_TAG = 'oe:batch-submitter:tx-chain' -export const STATE_BATCH_SUBMITTER_LOG_TAG = 'oe:batch-submitter:state-chain' +export const TX_BATCH_SUBMITTER_LOG_TAG = 'oe:batch_submitter:tx_chain' +export const STATE_BATCH_SUBMITTER_LOG_TAG = 'oe:batch_submitter:state_chain' // BLOCK_OFFSET is the number of L2 blocks we need to skip for the // batch submitter. diff --git a/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts b/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts index f23480ea19802..dde83dd87b65a 100644 --- a/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts +++ b/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts @@ -8,6 +8,7 @@ import { Bytes32, remove0x, toRpcHexString, + Metrics, } from '@eth-optimism/core-utils' /* Internal Imports */ @@ -41,6 +42,7 @@ export class StateBatchSubmitter extends BatchSubmitter { gasRetryIncrement: number, gasThresholdInGwei: number, log: Logger, + metrics: Metrics, fraudSubmissionAddress: string ) { super( @@ -59,7 +61,8 @@ export class StateBatchSubmitter extends BatchSubmitter { maxGasPriceInGwei, gasRetryIncrement, gasThresholdInGwei, - log + log, + metrics ) this.fraudSubmissionAddress = fraudSubmissionAddress } diff --git a/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts b/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts index 1e56b158cae35..c7a188b0a03e2 100644 --- a/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts +++ b/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts @@ -7,7 +7,7 @@ import { } from '@ethersproject/abstract-provider' import { getContractInterface, getContractFactory } from 'old-contracts' import { getContractInterface as getNewContractInterface } from '@eth-optimism/contracts' -import { Logger, ctcCoder } from '@eth-optimism/core-utils' +import { Logger, Metrics, ctcCoder } from '@eth-optimism/core-utils' /* Internal Imports */ import { @@ -48,6 +48,7 @@ export class TransactionBatchSubmitter extends BatchSubmitter { gasRetryIncrement: number, gasThresholdInGwei: number, log: Logger, + metrics: Metrics, disableQueueBatchAppend: boolean, autoFixBatchOptions: AutoFixBatchOptions = { fixDoublePlayedDeposits: false, @@ -70,7 +71,8 @@ export class TransactionBatchSubmitter extends BatchSubmitter { maxGasPriceInGwei, gasRetryIncrement, gasThresholdInGwei, - log + log, + metrics ) this.disableQueueBatchAppend = disableQueueBatchAppend this.autoFixBatchOptions = autoFixBatchOptions diff --git a/packages/batch-submitter/src/exec/run-batch-submitter.ts b/packages/batch-submitter/src/exec/run-batch-submitter.ts index 2da88eb8a8857..f03b76a1ed632 100644 --- a/packages/batch-submitter/src/exec/run-batch-submitter.ts +++ b/packages/batch-submitter/src/exec/run-batch-submitter.ts @@ -1,5 +1,5 @@ /* External Imports */ -import { Logger, injectL2Context } from '@eth-optimism/core-utils' +import { Logger, Metrics, injectL2Context } from '@eth-optimism/core-utils' import { exit } from 'process' import { Signer, Wallet } from 'ethers' import { JsonRpcProvider, TransactionReceipt } from '@ethersproject/providers' @@ -16,14 +16,21 @@ import { } from '..' /* Logger */ +const name = 'oe:batch_submitter:init' const log = new Logger({ - name: 'oe:batch-submitter:init', + name, sentryOptions: { - release: `@eth-optimism/batch-submitter@${process.env.npm_package_version}`, + release: `batch-submitter@${process.env.npm_package_version}`, + // @ts-ignore stackAttributeKey belongs to PinoSentryOptions, not exported + stackAttributeKey: 'err', dsn: process.env.SENTRY_DSN, tracesSampleRate: 0.05, }, }) +/* Metrics */ +const metrics = new Metrics({ + prefix: name, +}) interface RequiredEnvVars { // The HTTP provider URL for L1. @@ -158,7 +165,8 @@ export const run = async () => { MAX_GAS_PRICE_IN_GWEI, GAS_RETRY_INCREMENT, GAS_THRESHOLD_IN_GWEI, - new Logger({ name: TX_BATCH_SUBMITTER_LOG_TAG }), + log.child({ name: TX_BATCH_SUBMITTER_LOG_TAG }), + new Metrics({ prefix: TX_BATCH_SUBMITTER_LOG_TAG }), DISABLE_QUEUE_BATCH_APPEND, autoFixBatchOptions ) @@ -179,7 +187,8 @@ export const run = async () => { MAX_GAS_PRICE_IN_GWEI, GAS_RETRY_INCREMENT, GAS_THRESHOLD_IN_GWEI, - new Logger({ name: STATE_BATCH_SUBMITTER_LOG_TAG }), + log.child({ name: STATE_BATCH_SUBMITTER_LOG_TAG }), + new Metrics({ prefix: STATE_BATCH_SUBMITTER_LOG_TAG }), FRAUD_SUBMISSION_ADDRESS ) diff --git a/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts b/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts index 761307b867595..9510837d0cd79 100644 --- a/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts +++ b/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts @@ -37,6 +37,7 @@ import { ctcCoder, remove0x, Logger, + Metrics, } from '@eth-optimism/core-utils' const DECOMPRESSION_ADDRESS = '0x4200000000000000000000000000000000000008' @@ -78,6 +79,7 @@ class TransactionBatchSubmitter extends RealTransactionBatchSubmitter { return true } } +const testMetrics = new Metrics({ prefix: 'bs_test' }) describe('BatchSubmitter', () => { let signer: Signer @@ -217,6 +219,7 @@ describe('BatchSubmitter', () => { GAS_RETRY_INCREMENT, GAS_THRESHOLD_IN_GWEI, new Logger({ name: TX_BATCH_SUBMITTER_LOG_TAG }), + testMetrics, false ) @@ -432,6 +435,7 @@ describe('BatchSubmitter', () => { GAS_RETRY_INCREMENT, GAS_THRESHOLD_IN_GWEI, new Logger({ name: STATE_BATCH_SUBMITTER_LOG_TAG }), + testMetrics, '0x' + '01'.repeat(20) // placeholder for fraudSubmissionAddress ) }) diff --git a/packages/batch-submitter/test/batch-submitter/transaction-batch-submitter.spec.ts b/packages/batch-submitter/test/batch-submitter/transaction-batch-submitter.spec.ts index b719ec764985c..c2175e47cf738 100644 --- a/packages/batch-submitter/test/batch-submitter/transaction-batch-submitter.spec.ts +++ b/packages/batch-submitter/test/batch-submitter/transaction-batch-submitter.spec.ts @@ -33,6 +33,7 @@ import { ctcCoder, remove0x, Logger, + Metrics, } from '@eth-optimism/core-utils' const DECOMPRESSION_ADDRESS = '0x4200000000000000000000000000000000000008' @@ -71,6 +72,7 @@ class TransactionBatchSubmitter extends RealTransactionBatchSubmitter { return true } } +const testMetrics = new Metrics({ prefix: 'tx_bs_test' }) describe('TransactionBatchSubmitter', () => { let signer: Signer @@ -189,6 +191,7 @@ describe('TransactionBatchSubmitter', () => { GAS_RETRY_INCREMENT, GAS_THRESHOLD_IN_GWEI, new Logger({ name: TX_BATCH_SUBMITTER_LOG_TAG }), + testMetrics, false ) }) @@ -309,6 +312,7 @@ describe('TransactionBatchSubmitter', () => { GAS_RETRY_INCREMENT, GAS_THRESHOLD_IN_GWEI, new Logger({ name: TX_BATCH_SUBMITTER_LOG_TAG }), + testMetrics, false ) diff --git a/packages/contracts/CHANGELOG.md b/packages/contracts/CHANGELOG.md index e77ca2e62f2ea..ed04c974c6a15 100644 --- a/packages/contracts/CHANGELOG.md +++ b/packages/contracts/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.2.7 + +### Patch Changes + +- e3f55ad: Remove trailing whitespace from many files + ## 0.2.6 ### Patch Changes diff --git a/packages/contracts/bin/gen_safety_checker_constants.py b/packages/contracts/bin/gen_safety_checker_constants.py index 9d1d150aa562a..5aa2a0c0b3833 100755 --- a/packages/contracts/bin/gen_safety_checker_constants.py +++ b/packages/contracts/bin/gen_safety_checker_constants.py @@ -52,7 +52,7 @@ def asm(x): for j in range(i, i+0x20, 1): ret += ("%02X" % stoplist[j]) rr += ret+"),\n" - + rr = rr[:-2] + "];" print(rr) diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol index ecbf2fae8e338..58b546953248e 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol @@ -20,7 +20,7 @@ import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; /** * @title OVM_ECDSAContractAccount * @dev The ECDSA Contract Account can be used as the implementation for a ProxyEOA deployed by the - * ovmCREATEEOA operation. It enables backwards compatibility with Ethereum's Layer 1, by + * ovmCREATEEOA operation. It enables backwards compatibility with Ethereum's Layer 1, by * providing eth_sign and EIP155 formatted transaction encodings. * * Compiler used: optimistic-solc diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ProxyEOA.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ProxyEOA.sol index a74e3084693ea..02d809b717a6e 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ProxyEOA.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/accounts/OVM_ProxyEOA.sol @@ -8,9 +8,9 @@ import { Lib_Bytes32Utils } from "../../libraries/utils/Lib_Bytes32Utils.sol"; /** * @title OVM_ProxyEOA * @dev The Proxy EOA contract uses a delegate call to execute the logic in an implementation contract. - * In combination with the logic implemented in the ECDSA Contract Account, this enables a form of upgradable - * 'account abstraction' on layer 2. - * + * In combination with the logic implemented in the ECDSA Contract Account, this enables a form of upgradable + * 'account abstraction' on layer 2. + * * Compiler used: optimistic-solc * Runtime target: OVM */ diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/Abs_BaseCrossDomainMessenger.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/Abs_BaseCrossDomainMessenger.sol index d4aa9ae404dee..a5bbba67912b6 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/Abs_BaseCrossDomainMessenger.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/Abs_BaseCrossDomainMessenger.sol @@ -11,7 +11,7 @@ import { Lib_ReentrancyGuard } from "../../../libraries/utils/Lib_ReentrancyGuar /** * @title Abs_BaseCrossDomainMessenger * @dev The Base Cross Domain Messenger is an abstract contract providing the interface and common functionality used in the - * L1 and L2 Cross Domain Messengers. It can also serve as a template for developers wishing to implement a custom bridge + * L1 and L2 Cross Domain Messengers. It can also serve as a template for developers wishing to implement a custom bridge * contract to suit their needs. * * Compiler used: defined by child contract diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L1MultiMessageRelayer.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L1MultiMessageRelayer.sol index 921ca5d09c0a6..96352ad9dd8f5 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L1MultiMessageRelayer.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L1MultiMessageRelayer.sol @@ -12,7 +12,7 @@ import { Lib_AddressResolver } from "../../../libraries/resolver/Lib_AddressReso /** * @title OVM_L1MultiMessageRelayer - * @dev The L1 Multi-Message Relayer contract is a gas efficiency optimization which enables the + * @dev The L1 Multi-Message Relayer contract is a gas efficiency optimization which enables the * relayer to submit multiple messages in a single transaction to be relayed by the L1 Cross Domain * Message Sender. * @@ -26,7 +26,7 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes ***************/ constructor( address _libAddressManager - ) + ) Lib_AddressResolver(_libAddressManager) {} @@ -50,10 +50,10 @@ contract OVM_L1MultiMessageRelayer is iOVM_L1MultiMessageRelayer, Lib_AddressRes * @notice Forwards multiple cross domain messages to the L1 Cross Domain Messenger for relaying * @param _messages An array of L2 to L1 messages */ - function batchRelayMessages(L2ToL1Message[] calldata _messages) + function batchRelayMessages(L2ToL1Message[] calldata _messages) override external - onlyBatchRelayer + onlyBatchRelayer { iOVM_L1CrossDomainMessenger messenger = iOVM_L1CrossDomainMessenger(resolve("Proxy__OVM_L1CrossDomainMessenger")); for (uint256 i = 0; i < _messages.length; i++) { diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L2CrossDomainMessenger.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L2CrossDomainMessenger.sol index cddb14559c78c..97125b4581fc5 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L2CrossDomainMessenger.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L2CrossDomainMessenger.sol @@ -14,6 +14,7 @@ import { iOVM_L2ToL1MessagePasser } from "../../../iOVM/predeploys/iOVM_L2ToL1Me /* Contract Imports */ import { Abs_BaseCrossDomainMessenger } from "./Abs_BaseCrossDomainMessenger.sol"; + /** * @title OVM_L2CrossDomainMessenger * @dev The L2 Cross Domain Messenger contract sends messages from L2 to L1, and is the entry point @@ -104,6 +105,7 @@ contract OVM_L2CrossDomainMessenger is iOVM_L2CrossDomainMessenger, Abs_BaseCros block.number ) ); + relayedMessages[relayId] = true; } diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ERC20Gateway.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ERC20Gateway.sol index f439a12359aac..0d97a7a24c3fa 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ERC20Gateway.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ERC20Gateway.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// @unsupported: ovm +// @unsupported: ovm pragma solidity >0.5.0 <0.8.0; pragma experimental ABIEncoderV2; @@ -27,7 +27,7 @@ contract OVM_L1ERC20Gateway is Abs_L1TokenGateway { /******************************** * External Contract References * ********************************/ - + iOVM_ERC20 public l1ERC20; /*************** @@ -41,7 +41,7 @@ contract OVM_L1ERC20Gateway is Abs_L1TokenGateway { constructor( iOVM_ERC20 _l1ERC20, address _l2DepositedERC20, - address _l1messenger + address _l1messenger ) Abs_L1TokenGateway( _l2DepositedERC20, diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ETHGateway.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ETHGateway.sol index 5757e9587c576..8039a895fe5a1 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ETHGateway.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L1ETHGateway.sol @@ -78,7 +78,7 @@ contract OVM_L1ETHGateway is iOVM_L1ETHGateway, OVM_CrossDomainEnabled, Lib_Addr /** * @dev deposit an amount of the ETH to the caller's balance on L2 */ - function deposit() + function deposit() external override payable @@ -137,7 +137,7 @@ contract OVM_L1ETHGateway is iOVM_L1ETHGateway, OVM_CrossDomainEnabled, Lib_Addr /** * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the * L1 ETH token. - * Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized. + * Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized. * * @param _to L1 address to credit the withdrawal to * @param _amount Amount of the ETH to withdraw diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_ChainStorageContainer.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_ChainStorageContainer.sol index 1c2b56dffac3d..15936e4d2c7d7 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_ChainStorageContainer.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/chain/OVM_ChainStorageContainer.sol @@ -157,7 +157,7 @@ contract OVM_ChainStorageContainer is iOVM_ChainStorageContainer, Lib_AddressRes { return buffer.get(uint40(_index)); } - + /** * @inheritdoc iOVM_ChainStorageContainer */ diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol index 546f0fa5f0291..b88c771c030a1 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_ExecutionManager.sol @@ -536,7 +536,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { // "magic" prefix to deploy an exact copy of the code: // PUSH1 0x0D # size of this prefix in bytes // CODESIZE - // SUB # subtract prefix size from codesize + // SUB # subtract prefix size from codesize // DUP1 // PUSH1 0x0D // PUSH1 0x00 @@ -1064,9 +1064,9 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { * This function sanitizes the return types for creation messages to match calls (bool, bytes), * by being an external function which the EM can call, that mimics the success/fail case of the CREATE. * This allows for consistent handling of both types of messages in _handleExternalMessage(). - * Having this step occur as a separate call frame also allows us to easily revert the + * Having this step occur as a separate call frame also allows us to easily revert the * contract deployment in the event that the code is unsafe. - * + * * @param _gasLimit Amount of gas to be passed into this creation. * @param _creationCode Code to pass into CREATE for deployment. * @param _address OVM address being deployed to. @@ -1111,7 +1111,7 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver { if (ethAddress == address(0)) { // If the creation fails, the EVM lets us grab its revert data. This may contain a revert flag // to be used above in _handleExternalMessage, so we pass the revert data back up unmodified. - assembly { + assembly { returndatacopy(0,0,returndatasize()) revert(0, returndatasize()) } diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol index ff90584a6b64e..f671ca7dcde64 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol @@ -9,7 +9,7 @@ import { iOVM_SafetyChecker } from "../../iOVM/execution/iOVM_SafetyChecker.sol" * @dev The Safety Checker verifies that contracts deployed on L2 do not contain any * "unsafe" operations. An operation is considered unsafe if it would access state variables which * are specific to the environment (ie. L1 or L2) in which it is executed, as this could be used - * to "escape the sandbox" of the OVM, resulting in non-deterministic fraud proofs. + * to "escape the sandbox" of the OVM, resulting in non-deterministic fraud proofs. * That is, an attacker would be able to "prove fraud" on an honestly applied transaction. * Note that a "safe" contract requires opcodes to appear in a particular pattern; * omission of "unsafe" opcodes is necessary, but not sufficient. @@ -129,7 +129,7 @@ contract OVM_SafetyChecker is iOVM_SafetyChecker { if ((firstOps >> 192) == 0x3350600060045af1) { _pc += 8; // Call EM and abort execution if instructed - // CALLER PUSH1 0x00 SWAP1 GAS CALL PC PUSH1 0x0E ADD JUMPI RETURNDATASIZE PUSH1 0x00 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x00 REVERT JUMPDEST RETURNDATASIZE PUSH1 0x01 EQ ISZERO PC PUSH1 0x0a ADD JUMPI PUSH1 0x01 PUSH1 0x00 RETURN JUMPDEST + // CALLER PUSH1 0x00 SWAP1 GAS CALL PC PUSH1 0x0E ADD JUMPI RETURNDATASIZE PUSH1 0x00 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x00 REVERT JUMPDEST RETURNDATASIZE PUSH1 0x01 EQ ISZERO PC PUSH1 0x0a ADD JUMPI PUSH1 0x01 PUSH1 0x00 RETURN JUMPDEST } else if (firstOps == 0x336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760 && secondOps == 0x016000f35b) { _pc += 37; } else { diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol index 2d8a95bc13e6b..ab18163f28075 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManager.sol @@ -14,7 +14,7 @@ import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol"; * the Execution Manager and State Transitioner. It runs on L1 during the setup and execution of a fraud proof. * The same logic runs on L2, but has been implemented as a precompile in the L2 go-ethereum client * (see https://github.com/ethereum-optimism/go-ethereum/blob/master/core/vm/ovm_state_manager.go). - * + * * Compiler used: solc * Runtime target: EVM */ @@ -63,7 +63,7 @@ contract OVM_StateManager is iOVM_StateManager { **********************/ /** - * Simple authentication, this contract should only be accessible to the owner (which is expected to be the State Transitioner during `PRE_EXECUTION` + * Simple authentication, this contract should only be accessible to the owner (which is expected to be the State Transitioner during `PRE_EXECUTION` * or the OVM_ExecutionManager during transaction execution. */ modifier authenticated() { diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManagerFactory.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManagerFactory.sol index 292d3dcb66eae..19895138603ab 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManagerFactory.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_StateManagerFactory.sol @@ -12,7 +12,7 @@ import { OVM_StateManager } from "./OVM_StateManager.sol"; * @title OVM_StateManagerFactory * @dev The State Manager Factory is called by a State Transitioner's init code, to create a new * State Manager for use in the Fraud Verification process. - * + * * Compiler used: solc * Runtime target: EVM */ diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/ERC1820Registry.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/ERC1820Registry.sol index 550c9d87afe49..3c8da43e90625 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/ERC1820Registry.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/ERC1820Registry.sol @@ -26,7 +26,7 @@ interface ERC1820ImplementerInterface { /** * @title ERC1820 Pseudo-introspection Registry Contract * @author Jordi Baylina and Jacques Dafflon - * @dev This contract is the official implementation of the ERC1820 Registry + * @dev This contract is the official implementation of the ERC1820 Registry * For more details, see https://eips.ethereum.org/EIPS/eip-1820 * * Compiler used: optimistic-solc diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_DeployerWhitelist.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_DeployerWhitelist.sol index 69bc8eef43c7d..cdc6b07fb6b65 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_DeployerWhitelist.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_DeployerWhitelist.sol @@ -8,9 +8,9 @@ import { iOVM_DeployerWhitelist } from "../../iOVM/predeploys/iOVM_DeployerWhite * @title OVM_DeployerWhitelist * @dev The Deployer Whitelist is a temporary predeploy used to provide additional safety during the * initial phases of our mainnet roll out. It is owned by the Optimism team, and defines accounts - * which are allowed to deploy contracts on Layer2. The Execution Manager will only allow an + * which are allowed to deploy contracts on Layer2. The Execution Manager will only allow an * ovmCREATE or ovmCREATE2 operation to proceed if the deployer's address whitelisted. - * + * * Compiler used: optimistic-solc * Runtime target: OVM */ @@ -19,7 +19,7 @@ contract OVM_DeployerWhitelist is iOVM_DeployerWhitelist { /********************** * Contract Constants * **********************/ - + bool public initialized; bool public allowArbitraryDeployment; address override public owner; @@ -29,7 +29,7 @@ contract OVM_DeployerWhitelist is iOVM_DeployerWhitelist { /********************** * Function Modifiers * **********************/ - + /** * Blocks functions to anyone except the contract owner. */ @@ -45,7 +45,7 @@ contract OVM_DeployerWhitelist is iOVM_DeployerWhitelist { /******************** * Public Functions * ********************/ - + /** * Initializes the whitelist. * @param _owner Address of the owner for this contract. diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_ETH.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_ETH.sol index dcfb04b453f09..5ed565f996916 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_ETH.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_ETH.sol @@ -12,9 +12,9 @@ import { OVM_L2DepositedERC20 } from "../bridge/tokens/OVM_L2DepositedERC20.sol" /** * @title OVM_ETH - * @dev The ETH predeploy provides an ERC20 interface for ETH deposited to Layer 2. Note that + * @dev The ETH predeploy provides an ERC20 interface for ETH deposited to Layer 2. Note that * unlike on Layer 1, Layer 2 accounts do not have a balance field. - * + * * Compiler used: optimistic-solc * Runtime target: OVM */ @@ -22,7 +22,7 @@ contract OVM_ETH is OVM_L2DepositedERC20 { constructor( address _l2CrossDomainMessenger, address _l1ETHGateway - ) + ) OVM_L2DepositedERC20( _l2CrossDomainMessenger, "Ether", diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L1MessageSender.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L1MessageSender.sol index e6c749b87014a..21020a7990649 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L1MessageSender.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L1MessageSender.sol @@ -7,16 +7,16 @@ import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManage /** * @title OVM_L1MessageSender - * @dev The L1MessageSender is a predeploy contract running on L2. During the execution of cross + * @dev The L1MessageSender is a predeploy contract running on L2. During the execution of cross * domain transaction from L1 to L2, it returns the address of the L1 account (either an EOA or - * contract) which sent the message to L2 via the Canonical Transaction Chain's `enqueue()` + * contract) which sent the message to L2 via the Canonical Transaction Chain's `enqueue()` * function. - * - * This contract exclusively serves as a getter for the ovmL1TXORIGIN operation. This is necessary - * because there is no corresponding operation in the EVM which the the optimistic solidity compiler + * + * This contract exclusively serves as a getter for the ovmL1TXORIGIN operation. This is necessary + * because there is no corresponding operation in the EVM which the the optimistic solidity compiler * can be replaced with a call to the ExecutionManager's ovmL1TXORIGIN() function. * - * + * * Compiler used: solc * Runtime target: OVM */ @@ -37,7 +37,7 @@ contract OVM_L1MessageSender is iOVM_L1MessageSender { address _l1MessageSender ) { - // Note that on L2 msg.sender (ie. evmCALLER) will always be the Execution Manager + // Note that on L2 msg.sender (ie. evmCALLER) will always be the Execution Manager return iOVM_ExecutionManager(msg.sender).ovmL1TXORIGIN(); } } diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol index 479cd2151568c..cd9b2431bc5b5 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol @@ -6,11 +6,11 @@ import { iOVM_L2ToL1MessagePasser } from "../../iOVM/predeploys/iOVM_L2ToL1Messa /** * @title OVM_L2ToL1MessagePasser - * @dev The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the + * @dev The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the * of a message on L2. The L1 Cross Domain Messenger performs this proof in its - * _verifyStorageProof function, which verifies the existence of the transaction hash in this + * _verifyStorageProof function, which verifies the existence of the transaction hash in this * contract's `sentMessages` mapping. - * + * * Compiler used: solc * Runtime target: EVM */ @@ -37,8 +37,8 @@ contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser { override public { - // Note: although this function is public, only messages sent from the OVM_L2CrossDomainMessenger - // will be relayed by the OVM_L1CrossDomainMessenger. This is enforced by a check in + // Note: although this function is public, only messages sent from the OVM_L2CrossDomainMessenger + // will be relayed by the OVM_L1CrossDomainMessenger. This is enforced by a check in // OVM_L1CrossDomainMessenger._verifyStorageProof(). sentMessages[keccak256( abi.encodePacked( diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol index 2b2911013d877..f02ea17ac6683 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol @@ -13,12 +13,12 @@ import { Lib_ExecutionManagerWrapper } from "../../libraries/wrappers/Lib_Execut /** * @title OVM_SequencerEntrypoint - * @dev The Sequencer Entrypoint is a predeploy which, despite its name, can in fact be called by - * any account. It accepts a more efficient compressed calldata format, which it decompresses and + * @dev The Sequencer Entrypoint is a predeploy which, despite its name, can in fact be called by + * any account. It accepts a more efficient compressed calldata format, which it decompresses and * encodes to the standard EIP155 transaction format. * This contract is the implementation referenced by the Proxy Sequencer Entrypoint, thus enabling * the Optimism team to upgrade the decompression of calldata from the Sequencer. - * + * * Compiler used: optimistic-solc * Runtime target: OVM */ @@ -27,7 +27,7 @@ contract OVM_SequencerEntrypoint { /********* * Enums * *********/ - + enum TransactionType { NATIVE_ETH_TRANSACTION, ETH_SIGNED_MESSAGE diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_BondManager.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_BondManager.sol index 4b0f5df0010a8..4550fc1a7a1a0 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_BondManager.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_BondManager.sol @@ -10,11 +10,11 @@ import { iOVM_FraudVerifier } from "../../iOVM/verification/iOVM_FraudVerifier.s /** * @title OVM_BondManager - * @dev The Bond Manager contract handles deposits in the form of an ERC20 token from bonded + * @dev The Bond Manager contract handles deposits in the form of an ERC20 token from bonded * Proposers. It also handles the accounting of gas costs spent by a Verifier during the course of a - * fraud proof. In the event of a successful fraud proof, the fraudulent Proposer's bond is slashed, + * fraud proof. In the event of a successful fraud proof, the fraudulent Proposer's bond is slashed, * and the Verifier's gas costs are refunded. - * + * * Compiler used: solc * Runtime target: EVM */ @@ -109,14 +109,14 @@ contract OVM_BondManager is iOVM_BondManager, Lib_AddressResolver { bond.earliestTimestamp = timestamp; } - // if the fraud proof's dispute period does not intersect with the + // if the fraud proof's dispute period does not intersect with the // withdrawal's timestamp, then the user should not be slashed // e.g if a user at day 10 submits a withdrawal, and a fraud proof // from day 1 gets published, the user won't be slashed since day 8 (1d + 7d) // is before the user started their withdrawal. on the contrary, if the user // had started their withdrawal at, say, day 6, they would be slashed if ( - bond.withdrawalTimestamp != 0 && + bond.withdrawalTimestamp != 0 && uint256(bond.withdrawalTimestamp) > timestamp + disputePeriodSeconds && bond.state == State.WITHDRAWING ) { @@ -154,15 +154,15 @@ contract OVM_BondManager is iOVM_BondManager, Lib_AddressResolver { Bond storage bond = bonds[msg.sender]; require( - block.timestamp >= uint256(bond.withdrawalTimestamp) + disputePeriodSeconds, + block.timestamp >= uint256(bond.withdrawalTimestamp) + disputePeriodSeconds, Errors.TOO_EARLY ); require(bond.state == State.WITHDRAWING, Errors.SLASHED); - + // refunds! bond.state = State.NOT_COLLATERALIZED; bond.withdrawalTimestamp = 0; - + require( token.transfer(msg.sender, requiredCollateral), Errors.ERC20_ERR diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_FraudVerifier.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_FraudVerifier.sol index e0db75f154669..e985a6244a7d8 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_FraudVerifier.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_FraudVerifier.sol @@ -21,10 +21,10 @@ import { Abs_FraudContributor } from "./Abs_FraudContributor.sol"; /** * @title OVM_FraudVerifier - * @dev The Fraud Verifier contract coordinates the entire fraud proof verification process. + * @dev The Fraud Verifier contract coordinates the entire fraud proof verification process. * If the fraud proof was successful it prunes any state batches from State Commitment Chain * which were published after the fraudulent state root. - * + * * Compiler used: solc * Runtime target: EVM */ @@ -204,7 +204,7 @@ contract OVM_FraudVerifier is Lib_AddressResolver, Abs_FraudContributor, iOVM_Fr _postStateRoot != transitioner.getPostStateRoot(), "State transition has not been proven fraudulent." ); - + _cancelStateTransition(_postStateRootBatchHeader, _preStateRoot); // TEMPORARY: Remove the transitioner; for minnet. diff --git a/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_StateTransitionerFactory.sol b/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_StateTransitionerFactory.sol index dd117d0af0a9b..cf1c0d55c74e0 100644 --- a/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_StateTransitionerFactory.sol +++ b/packages/contracts/contracts/optimistic-ethereum/OVM/verification/OVM_StateTransitionerFactory.sol @@ -15,9 +15,9 @@ import { OVM_StateTransitioner } from "./OVM_StateTransitioner.sol"; /** * @title OVM_StateTransitionerFactory - * @dev The State Transitioner Factory is used by the Fraud Verifier to create a new State + * @dev The State Transitioner Factory is used by the Fraud Verifier to create a new State * Transitioner during the initialization of a fraud proof. - * + * * Compiler used: solc * Runtime target: EVM */ diff --git a/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_L1MultiMessageRelayer.sol b/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_L1MultiMessageRelayer.sol index a2ae03910aa1a..849acdaf6912f 100644 --- a/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_L1MultiMessageRelayer.sol +++ b/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_L1MultiMessageRelayer.sol @@ -14,5 +14,5 @@ interface iOVM_L1MultiMessageRelayer { iOVM_L1CrossDomainMessenger.L2MessageInclusionProof proof; } - function batchRelayMessages(L2ToL1Message[] calldata _messages) external; + function batchRelayMessages(L2ToL1Message[] calldata _messages) external; } diff --git a/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L1TokenGateway.sol b/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L1TokenGateway.sol index 39abd4562b31e..087684e340266 100644 --- a/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L1TokenGateway.sol +++ b/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L1TokenGateway.sol @@ -16,7 +16,7 @@ interface iOVM_L1TokenGateway { address _to, uint256 _amount ); - + event WithdrawalFinalized( address indexed _to, uint256 _amount diff --git a/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L2DepositedToken.sol b/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L2DepositedToken.sol index 3b5d932af9b3e..40088bfc2d48d 100644 --- a/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L2DepositedToken.sol +++ b/packages/contracts/contracts/optimistic-ethereum/iOVM/bridge/tokens/iOVM_L2DepositedToken.sol @@ -20,7 +20,7 @@ interface iOVM_L2DepositedToken { event DepositFinalized( address indexed _to, uint256 _amount - ); + ); /******************** diff --git a/packages/contracts/contracts/optimistic-ethereum/libraries/bridge/OVM_CrossDomainEnabled.sol b/packages/contracts/contracts/optimistic-ethereum/libraries/bridge/OVM_CrossDomainEnabled.sol index e329f90cff740..af3448090caf2 100644 --- a/packages/contracts/contracts/optimistic-ethereum/libraries/bridge/OVM_CrossDomainEnabled.sol +++ b/packages/contracts/contracts/optimistic-ethereum/libraries/bridge/OVM_CrossDomainEnabled.sol @@ -16,7 +16,7 @@ contract OVM_CrossDomainEnabled { /*************** * Constructor * - ***************/ + ***************/ constructor( address _messenger ) { @@ -46,14 +46,14 @@ contract OVM_CrossDomainEnabled { _; } - + /********************** * Internal Functions * **********************/ /** * @notice Gets the messenger, usually from storage. This function is exposed in case a child contract needs to override. - * @return The address of the cross-domain messenger contract which should be used. + * @return The address of the cross-domain messenger contract which should be used. */ function getCrossDomainMessenger() internal diff --git a/packages/contracts/contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol b/packages/contracts/contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol index 2f1cf5b74bb53..4221bc1edae78 100644 --- a/packages/contracts/contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol +++ b/packages/contracts/contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol @@ -17,10 +17,10 @@ contract Lib_ResolvedDelegateProxy { // implementation contract. For example, instead of storing these fields at // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`. // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html - // NOTE: Do not use this code in your own contract system. + // NOTE: Do not use this code in your own contract system. // There is a known flaw in this contract, and we will remove it from the repository // in the near future. Due to the very limited way that we are using it, this flaw is - // not an issue in our system. + // not an issue in our system. mapping (address => string) private implementationName; mapping (address => Lib_AddressManager) private addressManager; diff --git a/packages/contracts/contracts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol b/packages/contracts/contracts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol index 5e81c5de2ae62..72092f49b8373 100644 --- a/packages/contracts/contracts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol +++ b/packages/contracts/contracts/optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol @@ -23,7 +23,7 @@ library Lib_RLPReader { LIST_ITEM } - + /*********** * Structs * ***********/ @@ -32,12 +32,12 @@ library Lib_RLPReader { uint256 length; uint256 ptr; } - + /********************** * Internal Functions * **********************/ - + /** * Converts bytes to a reference to memory position and length. * @param _in Input bytes to convert. @@ -484,7 +484,7 @@ library Lib_RLPReader { // Short string. uint256 strLen = prefix - 0x80; - + require( _in.length > strLen, "Invalid RLP short string." diff --git a/packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_RingBuffer.sol b/packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_RingBuffer.sol index 49a65c15e8e9b..65da3fb17ed54 100644 --- a/packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_RingBuffer.sol +++ b/packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_RingBuffer.sol @@ -104,7 +104,7 @@ library Lib_RingBuffer { internal { RingBufferContext memory ctx = _self.getContext(); - + _self.push( _value, ctx.extraData @@ -124,7 +124,7 @@ library Lib_RingBuffer { internal view returns ( - bytes32 + bytes32 ) { RingBufferContext memory ctx = _self.getContext(); diff --git a/packages/contracts/contracts/optimistic-ethereum/libraries/wrappers/Lib_ExecutionManagerWrapper.sol b/packages/contracts/contracts/optimistic-ethereum/libraries/wrappers/Lib_ExecutionManagerWrapper.sol index f719246bd1b55..4ac7b377b7e9b 100644 --- a/packages/contracts/contracts/optimistic-ethereum/libraries/wrappers/Lib_ExecutionManagerWrapper.sol +++ b/packages/contracts/contracts/optimistic-ethereum/libraries/wrappers/Lib_ExecutionManagerWrapper.sol @@ -7,7 +7,7 @@ import { Lib_ErrorUtils } from "../utils/Lib_ErrorUtils.sol"; /** * @title Lib_ExecutionManagerWrapper - * + * * Compiler used: solc * Runtime target: OVM */ diff --git a/packages/contracts/contracts/optimistic-ethereum/mockOVM/verification/mockOVM_BondManager.sol b/packages/contracts/contracts/optimistic-ethereum/mockOVM/verification/mockOVM_BondManager.sol index 7f030935cd7c5..b3144882d8a93 100644 --- a/packages/contracts/contracts/optimistic-ethereum/mockOVM/verification/mockOVM_BondManager.sol +++ b/packages/contracts/contracts/optimistic-ethereum/mockOVM/verification/mockOVM_BondManager.sol @@ -78,7 +78,7 @@ contract mockOVM_BondManager is iOVM_BondManager, Lib_AddressResolver { ) override public - pure + pure returns ( uint256 ) diff --git a/packages/contracts/contracts/test-libraries/utils/TestLib_MerkleTree.sol b/packages/contracts/contracts/test-libraries/utils/TestLib_MerkleTree.sol index 30a93504b56ed..d456be298eede 100644 --- a/packages/contracts/contracts/test-libraries/utils/TestLib_MerkleTree.sol +++ b/packages/contracts/contracts/test-libraries/utils/TestLib_MerkleTree.sol @@ -14,7 +14,7 @@ contract TestLib_MerkleTree { bytes32[] memory _elements ) public - pure + pure returns ( bytes32 ) diff --git a/packages/contracts/contracts/test-libraries/utils/TestLib_RingBuffer.sol b/packages/contracts/contracts/test-libraries/utils/TestLib_RingBuffer.sol index b1bddcf7a6461..bf45bb30bfaf5 100644 --- a/packages/contracts/contracts/test-libraries/utils/TestLib_RingBuffer.sol +++ b/packages/contracts/contracts/test-libraries/utils/TestLib_RingBuffer.sol @@ -10,7 +10,7 @@ import { Lib_RingBuffer } from "../../optimistic-ethereum/libraries/utils/Lib_Ri */ contract TestLib_RingBuffer { using Lib_RingBuffer for Lib_RingBuffer.RingBuffer; - + Lib_RingBuffer.RingBuffer internal buf; function push( @@ -31,7 +31,7 @@ contract TestLib_RingBuffer { public view returns ( - bytes32 + bytes32 ) { return buf.get(_index); diff --git a/packages/contracts/package.json b/packages/contracts/package.json index a46214693fe05..88033f3ed1848 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/contracts", - "version": "0.2.6", + "version": "0.2.7", "main": "dist/index", "files": [ "dist/**/*.js", @@ -51,7 +51,7 @@ }, "devDependencies": { "@eth-optimism/hardhat-ovm": "^0.0.3", - "@eth-optimism/smock": "^1.0.2", + "@eth-optimism/smock": "^1.1.0", "@nomiclabs/hardhat-ethers": "^2.0.1", "@nomiclabs/hardhat-waffle": "^2.0.1", "@typechain/ethers-v5": "1.0.0", diff --git a/packages/contracts/test/contracts/OVM/bridge/base/OVM_L1CrossDomainMessenger.spec.ts b/packages/contracts/test/contracts/OVM/bridge/base/OVM_L1CrossDomainMessenger.spec.ts index bc88722cabf59..613ccfb2d6444 100644 --- a/packages/contracts/test/contracts/OVM/bridge/base/OVM_L1CrossDomainMessenger.spec.ts +++ b/packages/contracts/test/contracts/OVM/bridge/base/OVM_L1CrossDomainMessenger.spec.ts @@ -113,7 +113,7 @@ describe('OVM_L1CrossDomainMessenger', () => { ).to.deep.equal([ Mock__OVM_L2CrossDomainMessenger.address, BigNumber.from(gasLimit), - getXDomainCalldata(await signer.getAddress(), target, message, 0), + getXDomainCalldata(target, await signer.getAddress(), message, 0), ]) }) @@ -171,7 +171,7 @@ describe('OVM_L1CrossDomainMessenger', () => { ]) sender = await signer.getAddress() - calldata = getXDomainCalldata(sender, target, message, 0) + calldata = getXDomainCalldata(target, sender, message, 0) const precompile = '0x4200000000000000000000000000000000000000' diff --git a/packages/contracts/test/contracts/OVM/bridge/base/OVM_L2CrossDomainMessenger.spec.ts b/packages/contracts/test/contracts/OVM/bridge/base/OVM_L2CrossDomainMessenger.spec.ts index f423de1fd5ec6..fa0baf0248d6a 100644 --- a/packages/contracts/test/contracts/OVM/bridge/base/OVM_L2CrossDomainMessenger.spec.ts +++ b/packages/contracts/test/contracts/OVM/bridge/base/OVM_L2CrossDomainMessenger.spec.ts @@ -12,6 +12,7 @@ import { NON_NULL_BYTES32, NON_ZERO_ADDRESS, getXDomainCalldata, + getNextBlockNumber, } from '../../../../helpers' import { solidityKeccak256 } from 'ethers/lib/utils' @@ -88,7 +89,7 @@ describe('OVM_L2CrossDomainMessenger', () => { expect( Mock__OVM_L2ToL1MessagePasser.smocked.passMessageToL1.calls[0] ).to.deep.equal([ - getXDomainCalldata(await signer.getAddress(), target, message, 0), + getXDomainCalldata(target, await signer.getAddress(), message, 0), ]) }) @@ -192,10 +193,67 @@ describe('OVM_L2CrossDomainMessenger', () => { await OVM_L2CrossDomainMessenger.successfulMessages( solidityKeccak256( ['bytes'], - [getXDomainCalldata(await signer.getAddress(), target, message, 0)] + [getXDomainCalldata(target, sender, message, 0)] ) ) ).to.be.true }) + + it('should revert if trying to reenter `relayMessage`', async () => { + Mock__OVM_L1MessageSender.smocked.getL1MessageSender.will.return.with( + Mock__OVM_L1CrossDomainMessenger.address + ) + + const reentrantMessage = OVM_L2CrossDomainMessenger.interface.encodeFunctionData( + 'relayMessage', + [target, sender, message, 1] + ) + + // Calculate xDomainCallData used for indexing + // (within the first call to the L2 Messenger). + const xDomainCallData = getXDomainCalldata( + OVM_L2CrossDomainMessenger.address, + sender, + reentrantMessage, + 0 + ) + + // Make the call. + await OVM_L2CrossDomainMessenger.relayMessage( + OVM_L2CrossDomainMessenger.address, + sender, + reentrantMessage, + 0 + ) + + // We can't test for the nonReentrant revert string because it occurs in the second call frame, + // and target.call() won't "bubble up" the revert. So we need to use other criteria to ensure the + // right things are happening. + // Criteria 1: the reentrant message is NOT listed in successful messages. + expect( + await OVM_L2CrossDomainMessenger.successfulMessages( + solidityKeccak256(['bytes'], [xDomainCallData]) + ) + ).to.be.false + + // Criteria 2: the relayID of the reentrant message is recorded. + // Get blockNumber at time of the call. + const blockNumber = (await getNextBlockNumber(ethers.provider)) - 1 + const relayId = solidityKeccak256( + ['bytes'], + [ + ethers.utils.solidityPack( + ['bytes', 'address', 'uint256'], + [xDomainCallData, sender, blockNumber] + ), + ] + ) + + expect(await OVM_L2CrossDomainMessenger.relayedMessages(relayId)).to.be + .true + + // Criteria 3: the target contract did not receive a call. + expect(Mock__TargetContract.smocked.setTarget.calls[0]).to.be.undefined + }) }) }) diff --git a/packages/contracts/test/helpers/codec/bridge.ts b/packages/contracts/test/helpers/codec/bridge.ts index 7a70787bd6a9b..bf36d24ec924e 100644 --- a/packages/contracts/test/helpers/codec/bridge.ts +++ b/packages/contracts/test/helpers/codec/bridge.ts @@ -1,8 +1,8 @@ import { getContractInterface } from '../../../src/contract-defs' export const getXDomainCalldata = ( - sender: string, target: string, + sender: string, message: string, messageNonce: number ): string => { diff --git a/packages/core-utils/src/common/index.ts b/packages/core-utils/src/common/index.ts index 70ec4ff5b0373..4afbbaa85acb4 100644 --- a/packages/core-utils/src/common/index.ts +++ b/packages/core-utils/src/common/index.ts @@ -1,5 +1,6 @@ export * from './addresses' export * from './hex-strings' export * from './logger' +export * from './metrics' export * from './misc' export * from './common' diff --git a/packages/data-transport-layer/CHANGELOG.md b/packages/data-transport-layer/CHANGELOG.md index f0a2e4429a93d..92de7ec6b33b3 100644 --- a/packages/data-transport-layer/CHANGELOG.md +++ b/packages/data-transport-layer/CHANGELOG.md @@ -1,5 +1,11 @@ # data transport layer +## 0.2.2 + +### Patch Changes + +- 6d31324: Update release tag for Sentry compatability + ## 0.2.1 ### Patch Changes diff --git a/packages/data-transport-layer/package.json b/packages/data-transport-layer/package.json index 3f02a109eaf7c..5a8fd5182383f 100644 --- a/packages/data-transport-layer/package.json +++ b/packages/data-transport-layer/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/data-transport-layer", - "version": "0.2.1", + "version": "0.2.2", "private": true, "main": "dist/index", "files": [ diff --git a/packages/data-transport-layer/src/services/server/service.ts b/packages/data-transport-layer/src/services/server/service.ts index e2f6d9a4cb64f..49b9a51f9a415 100644 --- a/packages/data-transport-layer/src/services/server/service.ts +++ b/packages/data-transport-layer/src/services/server/service.ts @@ -107,7 +107,7 @@ export class L1TransportServer extends BaseService { this.state.app = express() Sentry.init({ dsn: this.options.sentryDsn, - release: `@eth-optimism/data-transport-layer@${process.env.npm_package_version}`, + release: `data-transport-layer@${process.env.npm_package_version}`, integrations: [ new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ diff --git a/packages/smock/CHANGELOG.md b/packages/smock/CHANGELOG.md index f6217ce75dad7..bca30f82c06ff 100644 --- a/packages/smock/CHANGELOG.md +++ b/packages/smock/CHANGELOG.md @@ -1,5 +1,11 @@ # @eth-optimism/smock +## 1.1.0 + +### Minor Changes + +- 79f812d: Adds support for hardhat ^2.2.0, required because of move to ethereumjs-vm v5. + ## 1.0.2 ### Patch Changes diff --git a/packages/smock/package.json b/packages/smock/package.json index 8432413f7e442..714fe9d0aaa86 100644 --- a/packages/smock/package.json +++ b/packages/smock/package.json @@ -3,7 +3,7 @@ "files": [ "dist/src/*" ], - "version": "1.0.2", + "version": "1.1.0", "main": "dist/src/index", "types": "dist/src/index", "license": "MIT", @@ -28,15 +28,15 @@ "bn.js": "^5.2.0" }, "devDependencies": { - "@nomiclabs/ethereumjs-vm": "4.2.2", + "@nomiclabs/ethereumjs-vm": "^4.2.2", "@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-waffle": "^2.0.1", "@types/lodash": "^4.14.161", "chai": "^4.3.0", "ethereum-waffle": "^3.3.0", - "ethers": "^5.0.32", + "ethers": "^5.0.31", "glob": "^7.1.6", - "hardhat": "^2.1.1", + "hardhat": "^2.2.1", "lodash": "^4.17.20", "prettier": "^2.2.1" } diff --git a/packages/smock/src/common/hardhat-common.ts b/packages/smock/src/common/hardhat-common.ts index fd7456666d870..dd692caf1350e 100644 --- a/packages/smock/src/common/hardhat-common.ts +++ b/packages/smock/src/common/hardhat-common.ts @@ -1,6 +1,7 @@ /* Imports: External */ import { HardhatRuntimeEnvironment } from 'hardhat/types' import { HardhatNetworkProvider } from 'hardhat/internal/hardhat-network/provider/provider' +import { fromHexString, toHexString } from '@eth-optimism/core-utils' /** * Finds the "base" Ethereum provider of the current hardhat environment. @@ -44,3 +45,35 @@ export const findBaseHardhatProvider = ( // https://github.com/nomiclabs/hardhat/blob/master/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts return provider as any } + +/** + * Converts a string into the fancy new address thing that ethereumjs-vm v5 expects while also + * maintaining backwards compatibility with ethereumjs-vm v4. + * @param address String address to convert into the fancy new address type. + * @returns Fancified address. + */ +export const toFancyAddress = (address: string): any => { + const fancyAddress = fromHexString(address) + ;(fancyAddress as any).buf = fromHexString(address) + ;(fancyAddress as any).toString = (encoding?: any) => { + if (encoding === undefined) { + return address.toLowerCase() + } else { + return fromHexString(address).toString(encoding) + } + } + return fancyAddress +} + +/** + * Same as toFancyAddress but in the opposite direction. + * @param fancyAddress Fancy address to turn into a string. + * @returns Way more boring address. + */ +export const fromFancyAddress = (fancyAddress: any): string => { + if (fancyAddress.buf) { + return toHexString(fancyAddress.buf) + } else { + return toHexString(fancyAddress) + } +} diff --git a/packages/smock/src/smockit/binding.ts b/packages/smock/src/smockit/binding.ts index e3f396ee3a541..3436d6390cffb 100644 --- a/packages/smock/src/smockit/binding.ts +++ b/packages/smock/src/smockit/binding.ts @@ -1,13 +1,24 @@ /* Imports: External */ -import { TransactionExecutionError } from 'hardhat/internal/hardhat-network/provider/errors' import { HardhatNetworkProvider } from 'hardhat/internal/hardhat-network/provider/provider' import { decodeRevertReason } from 'hardhat/internal/hardhat-network/stack-traces/revert-reasons' import { VmError } from '@nomiclabs/ethereumjs-vm/dist/exceptions' -import { toHexString, fromHexString } from '@eth-optimism/core-utils' import BN from 'bn.js' +// Handle hardhat ^2.2.0 +let TransactionExecutionError: any +try { + // tslint:disable-next-line + TransactionExecutionError = require('hardhat/internal/hardhat-network/provider/errors') + .TransactionExecutionError +} catch (err) { + // tslint:disable-next-line + TransactionExecutionError = require('hardhat/internal/core/providers/errors') + .TransactionExecutionError +} + /* Imports: Internal */ import { MockContract, SmockedVM } from './types' +import { fromFancyAddress, toFancyAddress } from '../common' /** * Checks to see if smock has been initialized already. Basically just checking to see if we've @@ -52,7 +63,7 @@ const initializeSmock = (provider: HardhatNetworkProvider): void => { return } - const target = toHexString(message.to).toLowerCase() + const target = fromFancyAddress(message.to) // Check if the target address is a smocked contract. if (!(target in vm._smockState.mocks)) { @@ -77,7 +88,7 @@ const initializeSmock = (provider: HardhatNetworkProvider): void => { // later creates a contract at that address. Not sure how to handle this case. Very open to // ideas. if (result.createdAddress) { - const created = toHexString(result.createdAddress).toLowerCase() + const created = fromFancyAddress(result.createdAddress) if (created in vm._smockState.mocks) { delete vm._smockState.mocks[created] } @@ -92,7 +103,7 @@ const initializeSmock = (provider: HardhatNetworkProvider): void => { // contracts never create new sub-calls (meaning this `afterMessage` event corresponds directly // to a `beforeMessage` event emitted during a call to a smock contract). const message = vm._smockState.messages.pop() - const target = toHexString(message.to).toLowerCase() + const target = fromFancyAddress(message.to) // Not sure if this can ever actually happen? Just being safe. if (!(target in vm._smockState.mocks)) { @@ -157,7 +168,7 @@ export const bindSmock = async ( } const vm: SmockedVM = (provider as any)._node._vm - const pStateManager = vm.pStateManager + const pStateManager = vm.pStateManager || vm.stateManager // Add mock to our list of mocks currently attached to the VM. vm._smockState.mocks[mock.address.toLowerCase()] = mock @@ -166,7 +177,7 @@ export const bindSmock = async ( // Solidity will sometimes throw if it's calling something without code (I forget the exact // scenario that causes this throw). await pStateManager.putContractCode( - fromHexString(mock.address), + toFancyAddress(mock.address), Buffer.from('00', 'hex') ) } diff --git a/packages/smock/src/smockit/smockit.ts b/packages/smock/src/smockit/smockit.ts index 6623ffe63ada6..b619d6068c322 100644 --- a/packages/smock/src/smockit/smockit.ts +++ b/packages/smock/src/smockit/smockit.ts @@ -6,6 +6,9 @@ import { toHexString, fromHexString } from '@eth-optimism/core-utils' /* Imports: Internal */ import { isArtifact, + isContract, + isContractFactory, + isInterface, MockContract, MockContractFunction, MockReturnValue, @@ -33,13 +36,19 @@ const makeContractInterfaceFromSpec = async ( return spec.interface } else if (spec instanceof ethers.utils.Interface) { return spec + } else if (isInterface(spec)) { + return spec as any + } else if (isContractFactory(spec)) { + return (spec as any).interface + } else if (isContract(spec)) { + return (spec as any).interface } else if (isArtifact(spec)) { return new ethers.utils.Interface(spec.abi) } else if (typeof spec === 'string') { try { return new ethers.utils.Interface(spec) } catch (err) { - return (await hre.ethers.getContractFactory(spec)).interface + return (await (hre as any).ethers.getContractFactory(spec)).interface } } else { return new ethers.utils.Interface(spec) @@ -150,7 +159,7 @@ export const smockit = async ( const contract = new ethers.Contract( opts.address || makeRandomAddress(), await makeContractInterfaceFromSpec(spec), - opts.provider || hre.ethers.provider // TODO: Probably check that this exists. + opts.provider || (hre as any).ethers.provider // TODO: Probably check that this exists. ) as MockContract // Start by smocking the fallback. diff --git a/packages/smock/src/smockit/types.ts b/packages/smock/src/smockit/types.ts index 85c31bb9ccd9f..8d7f45ebbef66 100644 --- a/packages/smock/src/smockit/types.ts +++ b/packages/smock/src/smockit/types.ts @@ -62,7 +62,11 @@ export interface SmockedVM { on: (event: string, callback: Function) => void - pStateManager: { + stateManager?: { + putContractCode: (address: Buffer, code: Buffer) => Promise + } + + pStateManager?: { putContractCode: (address: Buffer, code: Buffer) => Promise } } @@ -90,6 +94,30 @@ export const isMockContract = (obj: any): obj is MockContract => { ) } +export const isInterface = (obj: any): boolean => { + return ( + obj && + obj.functions !== undefined && + obj.errors !== undefined && + obj.structs !== undefined && + obj.events !== undefined && + Array.isArray(obj.fragments) + ) +} + +export const isContract = (obj: any): boolean => { + return ( + obj && + obj.functions !== undefined && + obj.estimateGas !== undefined && + obj.callStatic !== undefined + ) +} + +export const isContractFactory = (obj: any): boolean => { + return obj && obj.interface !== undefined && obj.deploy !== undefined +} + export const isArtifact = (obj: any): obj is Artifact => { return ( obj && diff --git a/packages/smock/src/smoddit/smoddit.ts b/packages/smock/src/smoddit/smoddit.ts index 180bf2a029618..19410e98fda52 100644 --- a/packages/smock/src/smoddit/smoddit.ts +++ b/packages/smock/src/smoddit/smoddit.ts @@ -6,7 +6,7 @@ import { fromHexString } from '@eth-optimism/core-utils' import { ModifiableContract, ModifiableContractFactory } from './types' import { getStorageLayout, getStorageSlots } from './storage' import { toHexString32 } from '../utils' -import { findBaseHardhatProvider } from '../common' +import { findBaseHardhatProvider, toFancyAddress } from '../common' /** * Creates a modifiable contract factory. @@ -29,10 +29,11 @@ export const smoddit = async ( } // Pull out a reference to the vm's state manager. - const pStateManager = (provider as any)._node._vm.pStateManager + const vm: any = (provider as any)._node._vm + const pStateManager = vm.pStateManager || vm.stateManager const layout = await getStorageLayout(name) - const factory = (await hre.ethers.getContractFactory( + const factory = (await (hre as any).ethers.getContractFactory( name, signer )) as ModifiableContractFactory @@ -50,7 +51,7 @@ export const smoddit = async ( const slots = getStorageSlots(layout, storage) for (const slot of slots) { await pStateManager.putContractStorage( - fromHexString(contract.address), + toFancyAddress(contract.address), fromHexString(slot.hash.toLowerCase()), fromHexString(slot.value) ) @@ -67,7 +68,7 @@ export const smoddit = async ( if ( toHexString32( await pStateManager.getContractStorage( - fromHexString(contract.address), + toFancyAddress(contract.address), fromHexString(slot.hash.toLowerCase()) ) ) !== slot.value diff --git a/packages/smock/test/smockit/function-manipulation.spec.ts b/packages/smock/test/smockit/function-manipulation.spec.ts index c8462091d02c2..de94a9bf2576b 100644 --- a/packages/smock/test/smockit/function-manipulation.spec.ts +++ b/packages/smock/test/smockit/function-manipulation.spec.ts @@ -1,5 +1,5 @@ /* Imports: External */ -import { ethers } from 'hardhat' +import hre from 'hardhat' import { expect } from 'chai' import { toPlainObject } from 'lodash' import { BigNumber } from 'ethers' @@ -8,6 +8,8 @@ import { BigNumber } from 'ethers' import { MockContract, smockit } from '../../src' describe('[smock]: function manipulation tests', () => { + const ethers = (hre as any).ethers + let mock: MockContract beforeEach(async () => { mock = await smockit('TestHelpers_BasicReturnContract') diff --git a/packages/smock/test/smockit/smock-initialization.spec.ts b/packages/smock/test/smockit/smock-initialization.spec.ts index 7c3500e815b2f..4b8a48410f911 100644 --- a/packages/smock/test/smockit/smock-initialization.spec.ts +++ b/packages/smock/test/smockit/smock-initialization.spec.ts @@ -1,11 +1,13 @@ /* Imports: External */ -import { ethers, artifacts } from 'hardhat' +import hre from 'hardhat' import { expect } from 'chai' /* Imports: Internal */ import { smockit, isMockContract } from '../../src' describe('[smock]: initialization tests', () => { + const ethers = (hre as any).ethers + describe('initialization: ethers objects', () => { it('should be able to create a SmockContract from an ethers ContractFactory', async () => { const spec = await ethers.getContractFactory('TestHelpers_EmptyContract') @@ -46,7 +48,7 @@ describe('[smock]: initialization tests', () => { }) it('should be able to create a SmockContract from a JSON contract artifact object', async () => { - const artifact = await artifacts.readArtifact( + const artifact = await hre.artifacts.readArtifact( 'TestHelpers_BasicReturnContract' ) const spec = artifact @@ -56,7 +58,7 @@ describe('[smock]: initialization tests', () => { }) it('should be able to create a SmockContract from a JSON contract ABI object', async () => { - const artifact = await artifacts.readArtifact( + const artifact = await hre.artifacts.readArtifact( 'TestHelpers_BasicReturnContract' ) const spec = artifact.abi @@ -66,7 +68,7 @@ describe('[smock]: initialization tests', () => { }) it('should be able to create a SmockContract from a JSON contract ABI string', async () => { - const artifact = await artifacts.readArtifact( + const artifact = await hre.artifacts.readArtifact( 'TestHelpers_BasicReturnContract' ) const spec = JSON.stringify(artifact.abi) diff --git a/specs/CHANGELOG.md b/specs/CHANGELOG.md new file mode 100644 index 0000000000000..2a9a7065a57e8 --- /dev/null +++ b/specs/CHANGELOG.md @@ -0,0 +1,6 @@ +# @eth-optimism/specs + +## 0.2.0 +### Minor Changes + +- 318857e: Add a new package to contain specs diff --git a/specs/package.json b/specs/package.json index af43f4d231dba..a3585bc47ed2a 100644 --- a/specs/package.json +++ b/specs/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/specs", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "private": true, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 109f41b6b46ec..07d5a890722e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -305,6 +305,76 @@ patch-package "^6.2.2" postinstall-postinstall "^2.1.0" +"@ethereumjs/block@^3.2.0", "@ethereumjs/block@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-3.2.1.tgz#c24c345e6dd6299efa4bed40979280b7dda96d3a" + integrity sha512-FCxo5KwwULne2A2Yuae4iaGGqSsRjwzXOlDhGalOFiBbLfP3hE04RHaHGw4c8vh1PfOrLauwi0dQNUBkOG3zIA== + dependencies: + "@ethereumjs/common" "^2.2.0" + "@ethereumjs/tx" "^3.1.3" + ethereumjs-util "^7.0.10" + merkle-patricia-tree "^4.1.0" + +"@ethereumjs/blockchain@^5.2.1": + version "5.2.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/blockchain/-/blockchain-5.2.1.tgz#83ed83647667265f1666f111caf065ef9d1e82b5" + integrity sha512-+hshP2qSOOFsiYvZCbaDQFG7jYTWafE8sfBi+pAsdhAHfP7BN7VLyob7qoQISgwS1s7NTR4c4+2t/woU9ahItw== + dependencies: + "@ethereumjs/block" "^3.2.0" + "@ethereumjs/common" "^2.2.0" + "@ethereumjs/ethash" "^1.0.0" + debug "^2.2.0" + ethereumjs-util "^7.0.9" + level-mem "^5.0.1" + lru-cache "^5.1.1" + rlp "^2.2.4" + semaphore-async-await "^1.5.1" + +"@ethereumjs/common@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.2.0.tgz#850a3e3e594ee707ad8d44a11e8152fb62450535" + integrity sha512-PyQiTG00MJtBRkJmv46ChZL8u2XWxNBeAthznAUIUiefxPAXjbkuiCZOuncgJS34/XkMbNc9zMt/PlgKRBElig== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.0.9" + +"@ethereumjs/ethash@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/ethash/-/ethash-1.0.0.tgz#4e77f85b37be1ade5393e8719bdabac3e796ddaa" + integrity sha512-iIqnGG6NMKesyOxv2YctB2guOVX18qMAWlj3QlZyrc+GqfzLqoihti+cVNQnyNxr7eYuPdqwLQOFuPe6g/uKjw== + dependencies: + "@types/levelup" "^4.3.0" + buffer-xor "^2.0.1" + ethereumjs-util "^7.0.7" + miller-rabin "^4.0.0" + +"@ethereumjs/tx@^3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.1.3.tgz#0e4b0ccec2f12b1f0bbbb0e7542dd79d9ec25d87" + integrity sha512-DJBu6cbwYtiPTFeCUR8DF5p+PF0jxs+0rALJZiEcTz2tiRPIEkM72GEbrkGuqzENLCzBrJHT43O0DxSYTqeo+g== + dependencies: + "@ethereumjs/common" "^2.2.0" + ethereumjs-util "^7.0.10" + +"@ethereumjs/vm@^5.3.2": + version "5.3.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/vm/-/vm-5.3.2.tgz#b4d83a3d50a7ad22d6d412cc21bbde221b3e2871" + integrity sha512-QmCUQrW6xbhgEbQh9njue4kAJdM056C+ytBFUTF/kDYa3kNDm4Qxp9HUyTlt1OCSXvDhws0qqlh8+q+pmXpN7g== + dependencies: + "@ethereumjs/block" "^3.2.1" + "@ethereumjs/blockchain" "^5.2.1" + "@ethereumjs/common" "^2.2.0" + "@ethereumjs/tx" "^3.1.3" + async-eventemitter "^0.2.4" + core-js-pure "^3.0.1" + debug "^2.2.0" + ethereumjs-util "^7.0.10" + functional-red-black-tree "^1.0.1" + mcl-wasm "^0.7.1" + merkle-patricia-tree "^4.1.0" + rustbn.js "~0.2.0" + util.promisify "^1.0.1" + "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" @@ -1479,7 +1549,7 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" -"@nomiclabs/ethereumjs-vm@4.2.2": +"@nomiclabs/ethereumjs-vm@4.2.2", "@nomiclabs/ethereumjs-vm@^4.2.2": version "4.2.2" resolved "https://registry.yarnpkg.com/@nomiclabs/ethereumjs-vm/-/ethereumjs-vm-4.2.2.tgz#2f8817113ca0fb6c44c1b870d0a809f0e026a6cc" integrity sha512-8WmX94mMcJaZ7/m7yBbyuS6B+wuOul+eF+RY9fBpGhNaUpyMR/vFIcDojqcWQ4Yafe1tMKY5LDu2yfT4NZgV4Q== @@ -2720,7 +2790,7 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -async-eventemitter@^0.2.2: +async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== @@ -4382,6 +4452,14 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +crc-32@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" + integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -5485,7 +5563,7 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum rlp "^2.0.0" safe-buffer "^5.1.1" -ethereumjs-util@^7.0.2, ethereumjs-util@^7.0.8: +ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.2, ethereumjs-util@^7.0.7, ethereumjs-util@^7.0.8, ethereumjs-util@^7.0.9: version "7.0.10" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.10.tgz#5fb7b69fa1fda0acc59634cf39d6b0291180fc1f" integrity sha512-c/xThw6A+EAnej5Xk5kOzFzyoSnw0WX0tSlZ6pAsfGVvQj3TItaDg9b1+Fz1RJXA+y2YksKwQnuzgt1eY6LKzw== @@ -5727,6 +5805,11 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -6736,6 +6819,57 @@ hardhat@^2.0.8, hardhat@^2.0.9, hardhat@^2.1.1, hardhat@^2.1.2: uuid "^3.3.2" ws "^7.2.1" +hardhat@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.2.1.tgz#bef0031b994e3f60a88d428f2097195c58cf9ed2" + integrity sha512-8s7MtGXdh0NDwQKdlA8m8QdloVIN1+hv5aFpn0G5Ljj9vfNY9kUoc0a9pMboeGbd9WrS+XrZs5YlsPgQjaW/Tg== + dependencies: + "@ethereumjs/block" "^3.2.1" + "@ethereumjs/blockchain" "^5.2.1" + "@ethereumjs/common" "^2.2.0" + "@ethereumjs/tx" "^3.1.3" + "@ethereumjs/vm" "^5.3.2" + "@sentry/node" "^5.18.1" + "@solidity-parser/parser" "^0.11.0" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + abort-controller "^3.0.0" + adm-zip "^0.4.16" + ansi-escapes "^4.3.0" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + eth-sig-util "^2.5.2" + ethereum-cryptography "^0.1.2" + ethereumjs-abi "^0.6.8" + ethereumjs-util "^7.0.10" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "^7.1.3" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + lodash "^4.17.11" + merkle-patricia-tree "^4.1.0" + mnemonist "^0.38.0" + mocha "^7.1.2" + node-fetch "^2.6.0" + qs "^6.7.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + slash "^3.0.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + "true-case-path" "^2.2.1" + tsort "0.0.1" + uuid "^3.3.2" + ws "^7.2.1" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -8398,6 +8532,11 @@ match-all@^1.2.6: resolved "https://registry.yarnpkg.com/match-all/-/match-all-1.2.6.tgz#66d276ad6b49655551e63d3a6ee53e8be0566f8d" integrity sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ== +mcl-wasm@^0.7.1: + version "0.7.6" + resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.6.tgz#c1789ebda5565d49b77d2ee195ff3e4d282f1554" + integrity sha512-cbRl3sUOkBeRY2hsM4t1EIln2TIdQBkSiTOqNTv/4Hu5KOECnMWCgjIf+a9Ebunyn22VKqkMF3zj6ejRzz7YBw== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -8554,7 +8693,7 @@ merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: rlp "^2.0.0" semaphore ">=1.0.1" -merkle-patricia-tree@^4.0.0: +merkle-patricia-tree@^4.0.0, merkle-patricia-tree@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-4.1.0.tgz#010636c4cfd68682df33a2e3186b7d0be7b98b9d" integrity sha512-vmP1J7FwIpprFMVjjSMM1JAwFce85Q+tp0TYIedYv8qaMh2oLUZ3ETXn9wbgi9S6elySzKzGa+Ai6VNKGEwSlg== @@ -10187,6 +10326,11 @@ prettier@^1.14.2, prettier@^1.16.4, prettier@^1.19.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== + private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -12605,7 +12749,7 @@ util-promisify@^2.1.0: dependencies: object.getownpropertydescriptors "^2.0.3" -util.promisify@^1.0.0: +util.promisify@^1.0.0, util.promisify@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==