Commit 251a4f62 authored by Adrian Sutton's avatar Adrian Sutton

Merge branch 'develop' into aj/remove-more-bindings

parents c2eb3847 57413031
...@@ -433,7 +433,7 @@ jobs: ...@@ -433,7 +433,7 @@ jobs:
contracts-bedrock-slither: contracts-bedrock-slither:
docker: docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
resource_class: large resource_class: xlarge
steps: steps:
- checkout - checkout
- check-changed: - check-changed:
...@@ -446,6 +446,7 @@ jobs: ...@@ -446,6 +446,7 @@ jobs:
contracts-bedrock-validate-spaces: contracts-bedrock-validate-spaces:
docker: docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
resource_class: xlarge
steps: steps:
- checkout - checkout
- attach_workspace: { at: "." } - attach_workspace: { at: "." }
...@@ -467,7 +468,7 @@ jobs: ...@@ -467,7 +468,7 @@ jobs:
op-bindings-build: op-bindings-build:
docker: docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
resource_class: large resource_class: xlarge
steps: steps:
- checkout - checkout
- run: - run:
...@@ -876,7 +877,7 @@ jobs: ...@@ -876,7 +877,7 @@ jobs:
docker: docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
- image: cimg/postgres:14.1 - image: cimg/postgres:14.1
resource_class: large resource_class: xlarge
steps: steps:
- checkout - checkout
- check-changed: - check-changed:
...@@ -952,6 +953,7 @@ jobs: ...@@ -952,6 +953,7 @@ jobs:
devnet-allocs: devnet-allocs:
docker: docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
resource_class: xlarge
steps: steps:
- checkout - checkout
- restore_cache: - restore_cache:
......
ee5d02c3ef5f55a06b069e4a70a820661a9130c8 d85718785859dc0b5a095d2302d1a20ec06ab77a
...@@ -23,10 +23,10 @@ require ( ...@@ -23,10 +23,10 @@ require (
github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-datastore v0.6.0
github.com/ipfs/go-ds-leveldb v0.5.0 github.com/ipfs/go-ds-leveldb v0.5.0
github.com/jackc/pgtype v1.14.0 github.com/jackc/pgtype v1.14.0
github.com/jackc/pgx/v5 v5.4.3 github.com/jackc/pgx/v5 v5.5.0
github.com/libp2p/go-libp2p v0.31.0 github.com/libp2p/go-libp2p v0.32.0
github.com/libp2p/go-libp2p-mplex v0.9.0 github.com/libp2p/go-libp2p-mplex v0.9.0
github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/libp2p/go-libp2p-pubsub v0.10.0
github.com/libp2p/go-libp2p-testing v0.12.0 github.com/libp2p/go-libp2p-testing v0.12.0
github.com/mattn/go-isatty v0.0.20 github.com/mattn/go-isatty v0.0.20
github.com/multiformats/go-base32 v0.1.0 github.com/multiformats/go-base32 v0.1.0
...@@ -40,10 +40,10 @@ require ( ...@@ -40,10 +40,10 @@ require (
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7 github.com/urfave/cli/v2 v2.25.7
golang.org/x/crypto v0.14.0 golang.org/x/crypto v0.14.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/exp v0.0.0-20231006140011-7918f672742d
golang.org/x/sync v0.4.0 golang.org/x/sync v0.5.0
golang.org/x/term v0.13.0 golang.org/x/term v0.13.0
golang.org/x/time v0.3.0 golang.org/x/time v0.4.0
gorm.io/driver/postgres v1.5.4 gorm.io/driver/postgres v1.5.4
gorm.io/gorm v1.25.5 gorm.io/gorm v1.25.5
) )
...@@ -98,10 +98,9 @@ require ( ...@@ -98,10 +98,9 @@ require (
github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gopacket v1.1.19 // indirect github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/graph-gophers/graphql-go v1.3.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
...@@ -118,6 +117,7 @@ require ( ...@@ -118,6 +117,7 @@ require (
github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect github.com/jbenet/goprocess v0.1.4 // indirect
...@@ -125,7 +125,7 @@ require ( ...@@ -125,7 +125,7 @@ require (
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c // indirect github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c // indirect
github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/compress v1.17.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/pretty v0.3.1 // indirect github.com/kr/pretty v0.3.1 // indirect
...@@ -145,7 +145,7 @@ require ( ...@@ -145,7 +145,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/dns v1.1.55 // indirect github.com/miekg/dns v1.1.56 // indirect
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
github.com/minio/sha256-simd v1.0.1 // indirect github.com/minio/sha256-simd v1.0.1 // indirect
...@@ -158,7 +158,7 @@ require ( ...@@ -158,7 +158,7 @@ require (
github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect github.com/multiformats/go-varint v0.0.7 // indirect
github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 // indirect
...@@ -172,9 +172,9 @@ require ( ...@@ -172,9 +172,9 @@ require (
github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect github.com/prometheus/procfs v0.11.1 // indirect
github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
github.com/quic-go/quic-go v0.38.1 // indirect github.com/quic-go/quic-go v0.39.3 // indirect
github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/quic-go/webtransport-go v0.6.0 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect github.com/rivo/uniseg v0.4.3 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect
...@@ -192,15 +192,16 @@ require ( ...@@ -192,15 +192,16 @@ require (
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.uber.org/automaxprocs v1.5.2 // indirect go.uber.org/automaxprocs v1.5.2 // indirect
go.uber.org/dig v1.17.0 // indirect go.uber.org/dig v1.17.1 // indirect
go.uber.org/fx v1.20.0 // indirect go.uber.org/fx v1.20.1 // indirect
go.uber.org/mock v0.3.0 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.25.0 // indirect go.uber.org/zap v1.26.0 // indirect
golang.org/x/mod v0.12.0 // indirect golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.13.0 // indirect golang.org/x/tools v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
......
...@@ -226,8 +226,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU ...@@ -226,8 +226,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
...@@ -265,8 +263,8 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI ...@@ -265,8 +263,8 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0=
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
...@@ -368,11 +366,13 @@ github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9 ...@@ -368,11 +366,13 @@ github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c h1:Dznn52SgVIVst9UyOT9brctYUgxs+CvVfPaC3jKrA50= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c h1:Dznn52SgVIVst9UyOT9brctYUgxs+CvVfPaC3jKrA50=
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= github.com/jackc/pgx/v5 v5.5.0 h1:NxstgwndsTRy7eq9/kqYc/BZh5w2hHJV86wjvO+1xPw=
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= github.com/jackc/pgx/v5 v5.5.0/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
...@@ -400,8 +400,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL ...@@ -400,8 +400,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
...@@ -438,14 +438,14 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y ...@@ -438,14 +438,14 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHxYg= github.com/libp2p/go-libp2p v0.32.0 h1:86I4B7nBUPIyTgw3+5Ibq6K7DdKRCuZw8URCfPc1hQM=
github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg= github.com/libp2p/go-libp2p v0.32.0/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c=
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8= github.com/libp2p/go-libp2p-mplex v0.9.0 h1:R58pDRAmuBXkYugbSSXR9wrTX3+1pFM1xP2bLuodIq8=
github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og= github.com/libp2p/go-libp2p-mplex v0.9.0/go.mod h1:ro1i4kuwiFT+uMPbIDIFkcLs1KRbNp0QwnUXM+P64Og=
github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA=
github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg=
github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY=
...@@ -493,8 +493,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk ...@@ -493,8 +493,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
...@@ -537,8 +537,8 @@ github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI1 ...@@ -537,8 +537,8 @@ github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI1
github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE=
github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA=
github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
...@@ -608,12 +608,12 @@ github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwa ...@@ -608,12 +608,12 @@ github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwa
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE= github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg=
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4= github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q=
github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU= github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY=
github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc=
github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
...@@ -727,13 +727,15 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= ...@@ -727,13 +727,15 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ= go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk=
go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0= go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
...@@ -745,8 +747,8 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= ...@@ -745,8 +747,8 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
...@@ -770,8 +772,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y ...@@ -770,8 +772,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
...@@ -783,8 +785,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= ...@@ -783,8 +785,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
...@@ -827,8 +829,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ ...@@ -827,8 +829,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
...@@ -899,8 +901,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb ...@@ -899,8 +901,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
...@@ -920,11 +922,10 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK ...@@ -920,11 +922,10 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
......
...@@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout) ...@@ -15,7 +15,7 @@ var MIPSStorageLayout = new(solc.StorageLayout)
var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a" var MIPSDeployedBin = "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063155633fe146100465780637dc0d1d01461006b578063836e7b32146100af575b600080fd5b610051634000000081565b60405163ffffffff90911681526020015b60405180910390f35b60405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610062565b6100c26100bd366004611d2e565b6100d0565b604051908152602001610062565b60006100da611c5b565b608081146100e757600080fd5b604051610600146100f757600080fd5b6084871461010457600080fd5b6101a4851461011257600080fd5b8635608052602087013560a052604087013560e090811c60c09081526044890135821c82526048890135821c61010052604c890135821c610120526050890135821c61014052605489013590911c61016052605888013560f890811c610180526059890135901c6101a052605a880135901c6101c0526102006101e0819052606288019060005b60208110156101bd57823560e01c8252600490920191602090910190600101610199565b505050806101200151156101db576101d361061b565b915050610612565b6101408101805160010167ffffffffffffffff16905260608101516000906102039082610737565b9050603f601a82901c16600281148061022257508063ffffffff166003145b156102775760006002836303ffffff1663ffffffff16901b846080015163f00000001617905061026c8263ffffffff1660021461026057601f610263565b60005b60ff16826107f3565b945050505050610612565b6101608301516000908190601f601086901c81169190601587901c16602081106102a3576102a3611da2565b602002015192508063ffffffff851615806102c457508463ffffffff16601c145b156102fb578661016001518263ffffffff16602081106102e6576102e6611da2565b6020020151925050601f600b86901c166103b7565b60208563ffffffff16101561035d578463ffffffff16600c148061032557508463ffffffff16600d145b8061033657508463ffffffff16600e145b15610347578561ffff1692506103b7565b6103568661ffff1660106108e4565b92506103b7565b60288563ffffffff1610158061037957508463ffffffff166022145b8061038a57508463ffffffff166026145b156103b7578661016001518263ffffffff16602081106103ac576103ac611da2565b602002015192508190505b60048563ffffffff16101580156103d4575060088563ffffffff16105b806103e557508463ffffffff166001145b15610404576103f685878487610957565b975050505050505050610612565b63ffffffff6000602087831610610469576104248861ffff1660106108e4565b9095019463fffffffc861661043a816001610737565b915060288863ffffffff161015801561045a57508763ffffffff16603014155b1561046757809250600093505b505b600061047789888885610b67565b63ffffffff9081169150603f8a1690891615801561049c575060088163ffffffff1610155b80156104ae5750601c8163ffffffff16105b1561058b578063ffffffff16600814806104ce57508063ffffffff166009145b15610505576104f38163ffffffff166008146104ea57856104ed565b60005b896107f3565b9b505050505050505050505050610612565b8063ffffffff16600a03610525576104f3858963ffffffff8a16156112f7565b8063ffffffff16600b03610546576104f3858963ffffffff8a1615156112f7565b8063ffffffff16600c0361055d576104f38d6113dd565b60108163ffffffff161015801561057a5750601c8163ffffffff16105b1561058b576104f381898988611914565b8863ffffffff1660381480156105a6575063ffffffff861615155b156105db5760018b61016001518763ffffffff16602081106105ca576105ca611da2565b63ffffffff90921660209290920201525b8363ffffffff1663ffffffff146105f8576105f884600184611b0e565b610604858360016112f7565b9b5050505050505050505050505b95945050505050565b60408051608051815260a051602082015260dc519181019190915260fc51604482015261011c51604882015261013c51604c82015261015c51605082015261017c5160548201526101805161019f5160588301526101a0516101bf5160598401526101d851605a840152600092610200929091606283019190855b60208110156106ba57601c8601518452602090950194600490930192600101610696565b506000835283830384a06000945080600181146106da5760039550610702565b8280156106f257600181146106fb5760029650610700565b60009650610700565b600196505b505b50505081900390207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f89190911b17919050565b60008061074383611bb2565b9050600384161561075357600080fd5b6020810190358460051c8160005b601b8110156107b95760208501943583821c6001168015610789576001811461079e576107af565b600084815260208390526040902093506107af565b600082815260208590526040902093505b5050600101610761565b5060805191508181146107d457630badf00d60005260206000fd5b5050601f94909416601c0360031b9390931c63ffffffff169392505050565b60006107fd611c5b565b60809050806060015160040163ffffffff16816080015163ffffffff1614610886576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6a756d7020696e2064656c617920736c6f74000000000000000000000000000060448201526064015b60405180910390fd5b60608101805160808301805163ffffffff9081169093528583169052908516156108dc57806008018261016001518663ffffffff16602081106108cb576108cb611da2565b63ffffffff90921660209290920201525b61061261061b565b600063ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80850183169190911c821615159160016020869003821681901b830191861691821b92911b0182610941576000610943565b815b90861663ffffffff16179250505092915050565b6000610961611c5b565b608090506000816060015160040163ffffffff16826080015163ffffffff16146109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6272616e636820696e2064656c617920736c6f74000000000000000000000000604482015260640161087d565b8663ffffffff1660041480610a0257508663ffffffff166005145b15610a7e5760008261016001518663ffffffff1660208110610a2657610a26611da2565b602002015190508063ffffffff168563ffffffff16148015610a4e57508763ffffffff166004145b80610a7657508063ffffffff168563ffffffff1614158015610a7657508763ffffffff166005145b915050610afb565b8663ffffffff16600603610a9b5760008460030b13159050610afb565b8663ffffffff16600703610ab75760008460030b139050610afb565b8663ffffffff16600103610afb57601f601087901c166000819003610ae05760008560030b1291505b8063ffffffff16600103610af95760008560030b121591505b505b606082018051608084015163ffffffff169091528115610b41576002610b268861ffff1660106108e4565b63ffffffff90811690911b8201600401166080840152610b53565b60808301805160040163ffffffff1690525b610b5b61061b565b98975050505050505050565b6000603f601a86901c16801580610b96575060088163ffffffff1610158015610b965750600f8163ffffffff16105b15610fec57603f86168160088114610bdd5760098114610be657600a8114610bef57600b8114610bf857600c8114610c0157600d8114610c0a57600e8114610c1357610c18565b60209150610c18565b60219150610c18565b602a9150610c18565b602b9150610c18565b60249150610c18565b60259150610c18565b602691505b508063ffffffff16600003610c3f5750505063ffffffff8216601f600686901c161b6112ef565b8063ffffffff16600203610c655750505063ffffffff8216601f600686901c161c6112ef565b8063ffffffff16600303610c9b57601f600688901c16610c9163ffffffff8716821c60208390036108e4565b93505050506112ef565b8063ffffffff16600403610cbd5750505063ffffffff8216601f84161b6112ef565b8063ffffffff16600603610cdf5750505063ffffffff8216601f84161c6112ef565b8063ffffffff16600703610d1257610d098663ffffffff168663ffffffff16901c876020036108e4565b925050506112ef565b8063ffffffff16600803610d2a5785925050506112ef565b8063ffffffff16600903610d425785925050506112ef565b8063ffffffff16600a03610d5a5785925050506112ef565b8063ffffffff16600b03610d725785925050506112ef565b8063ffffffff16600c03610d8a5785925050506112ef565b8063ffffffff16600f03610da25785925050506112ef565b8063ffffffff16601003610dba5785925050506112ef565b8063ffffffff16601103610dd25785925050506112ef565b8063ffffffff16601203610dea5785925050506112ef565b8063ffffffff16601303610e025785925050506112ef565b8063ffffffff16601803610e1a5785925050506112ef565b8063ffffffff16601903610e325785925050506112ef565b8063ffffffff16601a03610e4a5785925050506112ef565b8063ffffffff16601b03610e625785925050506112ef565b8063ffffffff16602003610e7b575050508282016112ef565b8063ffffffff16602103610e94575050508282016112ef565b8063ffffffff16602203610ead575050508183036112ef565b8063ffffffff16602303610ec6575050508183036112ef565b8063ffffffff16602403610edf575050508282166112ef565b8063ffffffff16602503610ef8575050508282176112ef565b8063ffffffff16602603610f11575050508282186112ef565b8063ffffffff16602703610f2b57505050828217196112ef565b8063ffffffff16602a03610f5c578460030b8660030b12610f4d576000610f50565b60015b60ff16925050506112ef565b8063ffffffff16602b03610f84578463ffffffff168663ffffffff1610610f4d576000610f50565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420696e737472756374696f6e00000000000000000000000000604482015260640161087d565b50610f84565b8063ffffffff16601c0361107057603f86166002819003611012575050508282026112ef565b8063ffffffff166020148061102d57508063ffffffff166021145b15610fe6578063ffffffff16602003611044579419945b60005b6380000000871615611066576401fffffffe600197881b169601611047565b92506112ef915050565b8063ffffffff16600f0361109257505065ffffffff0000601083901b166112ef565b8063ffffffff166020036110ce576110c68560031660080260180363ffffffff168463ffffffff16901c60ff1660086108e4565b9150506112ef565b8063ffffffff16602103611103576110c68560021660080260100363ffffffff168463ffffffff16901c61ffff1660106108e4565b8063ffffffff1660220361113257505063ffffffff60086003851602811681811b198416918316901b176112ef565b8063ffffffff1660230361114957829150506112ef565b8063ffffffff1660240361117b578460031660080260180363ffffffff168363ffffffff16901c60ff169150506112ef565b8063ffffffff166025036111ae578460021660080260100363ffffffff168363ffffffff16901c61ffff169150506112ef565b8063ffffffff166026036111e057505063ffffffff60086003851602601803811681811c198416918316901c176112ef565b8063ffffffff1660280361121657505060ff63ffffffff60086003861602601803811682811b9091188316918416901b176112ef565b8063ffffffff1660290361124d57505061ffff63ffffffff60086002861602601003811682811b9091188316918416901b176112ef565b8063ffffffff16602a0361127c57505063ffffffff60086003851602811681811c198316918416901c176112ef565b8063ffffffff16602b0361129357839150506112ef565b8063ffffffff16602e036112c557505063ffffffff60086003851602601803811681811b198316918416901b176112ef565b8063ffffffff166030036112dc57829150506112ef565b8063ffffffff16603803610f8457839150505b949350505050565b6000611301611c5b565b506080602063ffffffff861610611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f76616c6964207265676973746572000000000000000000000000000000000000604482015260640161087d565b63ffffffff8516158015906113865750825b156113ba57838161016001518663ffffffff16602081106113a9576113a9611da2565b63ffffffff90921660209290920201525b60808101805163ffffffff8082166060850152600490910116905261061261061b565b60006113e7611c5b565b506101e051604081015160808083015160a084015160c09094015191936000928392919063ffffffff8616610ffa036114615781610fff81161561143057610fff811661100003015b8363ffffffff166000036114575760e08801805163ffffffff83820116909152955061145b565b8395505b506118d3565b8563ffffffff16610fcd0361147c57634000000094506118d3565b8563ffffffff166110180361149457600194506118d3565b8563ffffffff16611096036114ca57600161012088015260ff83166101008801526114bd61061b565b9998505050505050505050565b8563ffffffff16610fa3036117365763ffffffff8316156118d3577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb63ffffffff8416016116f05760006115258363fffffffc166001610737565b60208901519091508060001a60010361159457604080516000838152336020528d83526060902091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790505b6040808a015190517fe03110e10000000000000000000000000000000000000000000000000000000081526004810183905263ffffffff9091166024820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063e03110e1906044016040805180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116599190611dd1565b91509150600386168060040382811015611671578092505b508186101561167e578591505b8260088302610100031c9250826008828460040303021b9250600180600883600403021b036001806008858560040303021b039150811981169050838119871617955050506116d58663fffffffc16600186611b0e565b60408b018051820163ffffffff169052975061173192505050565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd63ffffffff841601611725578094506118d3565b63ffffffff9450600993505b6118d3565b8563ffffffff16610fa4036118275763ffffffff831660011480611760575063ffffffff83166002145b80611771575063ffffffff83166004145b1561177e578094506118d3565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa63ffffffff8416016117255760006117be8363fffffffc166001610737565b602089015190915060038416600403838110156117d9578093505b83900360089081029290921c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600193850293841b0116911b176020880152600060408801529350836118d3565b8563ffffffff16610fd7036118d3578163ffffffff166003036118c75763ffffffff8316158061185d575063ffffffff83166005145b8061186e575063ffffffff83166003145b1561187c57600094506118d3565b63ffffffff831660011480611897575063ffffffff83166002145b806118a8575063ffffffff83166006145b806118b9575063ffffffff83166004145b1561172557600194506118d3565b63ffffffff9450601693505b6101608701805163ffffffff808816604090920191909152905185821660e09091015260808801805180831660608b015260040190911690526114bd61061b565b600061191e611c5b565b506080600063ffffffff871660100361193c575060c0810151611aa5565b8663ffffffff1660110361195b5763ffffffff861660c0830152611aa5565b8663ffffffff16601203611974575060a0810151611aa5565b8663ffffffff166013036119935763ffffffff861660a0830152611aa5565b8663ffffffff166018036119c75763ffffffff600387810b9087900b02602081901c821660c08501521660a0830152611aa5565b8663ffffffff166019036119f85763ffffffff86811681871602602081901c821660c08501521660a0830152611aa5565b8663ffffffff16601a03611a4e578460030b8660030b81611a1b57611a1b611df5565b0763ffffffff1660c0830152600385810b9087900b81611a3d57611a3d611df5565b0563ffffffff1660a0830152611aa5565b8663ffffffff16601b03611aa5578463ffffffff168663ffffffff1681611a7757611a77611df5565b0663ffffffff90811660c084015285811690871681611a9857611a98611df5565b0463ffffffff1660a08301525b63ffffffff841615611ae057808261016001518563ffffffff1660208110611acf57611acf611da2565b63ffffffff90921660209290920201525b60808201805163ffffffff80821660608601526004909101169052611b0361061b565b979650505050505050565b6000611b1983611bb2565b90506003841615611b2957600080fd5b6020810190601f8516601c0360031b83811b913563ffffffff90911b1916178460051c60005b601b811015611ba75760208401933582821c6001168015611b775760018114611b8c57611b9d565b60008581526020839052604090209450611b9d565b600082815260208690526040902094505b5050600101611b4f565b505060805250505050565b60ff8116610380026101a4810190369061052401811015611c55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f636865636b207468617420746865726520697320656e6f7567682063616c6c6460448201527f6174610000000000000000000000000000000000000000000000000000000000606482015260840161087d565b50919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091526101608101611cc1611cc6565b905290565b6040518061040001604052806020906020820280368337509192915050565b60008083601f840112611cf757600080fd5b50813567ffffffffffffffff811115611d0f57600080fd5b602083019150836020828501011115611d2757600080fd5b9250929050565b600080600080600060608688031215611d4657600080fd5b853567ffffffffffffffff80821115611d5e57600080fd5b611d6a89838a01611ce5565b90975095506020880135915080821115611d8357600080fd5b50611d9088828901611ce5565b96999598509660400135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008060408385031215611de457600080fd5b505080516020909101519092909150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea164736f6c634300080f000a"
var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:305;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:305;2534:6:135;400:55:305;382:74;;370:2;355:18;2448:99:135;211:251:305;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:305;;;1743:2;1728:18;26025:6379:135;1609:177:305;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:305;19164:28:135;;;2164:21:305;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:305;14107:30:135;;;2511:21:305;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:305;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:305;37406:29:135;;;2860:21:305;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:305;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:305;20288:41:135;;;3208:21:305;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:305;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:305;;;8234:54:135;3601:23:305;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:305;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:305;21415:72:135;;;4259:21:305;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:305;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:305:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:305;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:305;-1:-1:-1;1349:2:305;1334:18;;1321:32;;-1:-1:-1;1365:16:305;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:305;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:305:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:305;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:305:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15" var MIPSDeployedSourceMap = "1131:40054:135:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1710:45;;1745:10;1710:45;;;;;188:10:308;176:23;;;158:42;;146:2;131:18;1710:45:135;;;;;;;;2448:99;;;412:42:308;2534:6:135;400:55:308;382:74;;370:2;355:18;2448:99:135;211:251:308;26025:6379:135;;;;;;:::i;:::-;;:::i;:::-;;;1755:25:308;;;1743:2;1728:18;26025:6379:135;1609:177:308;26025:6379:135;26128:7;26171:18;;:::i;:::-;26318:4;26311:5;26308:15;26298:134;;26412:1;26409;26402:12;26298:134;26468:4;26462:11;26475:10;26459:27;26449:136;;26565:1;26562;26555:12;26449:136;26634:3;26615:17;26612:26;26602:151;;26733:1;26730;26723:12;26602:151;26798:3;26783:13;26780:22;26770:146;;26896:1;26893;26886:12;26770:146;27176:24;;27521:4;27222:20;27579:2;27280:21;;27176:24;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;;;27280:21;;;27176:24;27149:52;;27222:20;;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27153:21;27149:52;;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;27280:21;;;27176:24;27149:52;;27338:18;27222:20;28197:10;27338:18;28187:21;;;27280;;;;28295:1;28280:77;28305:2;28302:1;28299:9;28280:77;;;27176:24;;27153:21;27149:52;27222:20;;28353:1;27280:21;;;;27164:2;27338:18;;;;28323:1;28316:9;28280:77;;;28284:14;;;28435:5;:12;;;28431:71;;;28474:13;:11;:13::i;:::-;28467:20;;;;;28431:71;28516:10;;;:15;;28530:1;28516:15;;;;;28601:8;;;;-1:-1:-1;;28593:20:135;;-1:-1:-1;28593:7:135;:20::i;:::-;28579:34;-1:-1:-1;28643:10:135;28651:2;28643:10;;;;28720:1;28710:11;;;:26;;;28725:6;:11;;28735:1;28725:11;28710:26;28706:310;;;28866:13;28935:1;28913:4;28920:10;28913:17;28912:24;;;;28883:5;:12;;;28898:10;28883:25;28882:54;28866:70;;28961:40;28972:6;:11;;28982:1;28972:11;:20;;28990:2;28972:20;;;28986:1;28972:20;28961:40;;28994:6;28961:10;:40::i;:::-;28954:47;;;;;;;;28706:310;29265:15;;;;29060:9;;;;29197:4;29191:2;29183:10;;;29182:19;;;29265:15;29290:2;29282:10;;;29281:19;29265:36;;;;;;;:::i;:::-;;;;;;-1:-1:-1;29330:5:135;29354:11;;;;;:29;;;29369:6;:14;;29379:4;29369:14;29354:29;29350:832;;;29446:5;:15;;;29462:5;29446:22;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;29509:4:135;29503:2;29495:10;;;29494:19;29350:832;;;29547:4;29538:6;:13;;;29534:648;;;29668:6;:13;;29678:3;29668:13;:30;;;;29685:6;:13;;29695:3;29685:13;29668:30;:47;;;;29702:6;:13;;29712:3;29702:13;29668:47;29664:253;;;29778:4;29785:6;29778:13;29773:18;;29534:648;;29664:253;29877:21;29880:4;29887:6;29880:13;29895:2;29877;:21::i;:::-;29872:26;;29534:648;;;29951:4;29941:6;:14;;;;:32;;;;29959:6;:14;;29969:4;29959:14;29941:32;:50;;;;29977:6;:14;;29987:4;29977:14;29941:50;29937:245;;;30061:5;:15;;;30077:5;30061:22;;;;;;;;;:::i;:::-;;;;;30056:27;;30162:5;30154:13;;29937:245;30211:1;30201:6;:11;;;;:25;;;;;30225:1;30216:6;:10;;;30201:25;30200:42;;;;30231:6;:11;;30241:1;30231:11;30200:42;30196:125;;;30269:37;30282:6;30290:4;30296:5;30303:2;30269:12;:37::i;:::-;30262:44;;;;;;;;;;;30196:125;30354:13;30335:16;30506:4;30496:14;;;;30492:446;;30575:21;30578:4;30585:6;30578:13;30593:2;30575;:21::i;:::-;30569:27;;;;30633:10;30628:15;;30667:16;30628:15;30681:1;30667:7;:16::i;:::-;30661:22;;30715:4;30705:6;:14;;;;:32;;;;;30723:6;:14;;30733:4;30723:14;;30705:32;30701:223;;;30802:4;30790:16;;30904:1;30896:9;;30701:223;30512:426;30492:446;30971:10;30984:26;30992:4;30998:2;31002;31006:3;30984:7;:26::i;:::-;31013:10;30984:39;;;;-1:-1:-1;31109:4:135;31102:11;;;31141;;;:24;;;;;31164:1;31156:4;:9;;;;31141:24;:39;;;;;31176:4;31169;:11;;;31141:39;31137:860;;;31204:4;:9;;31212:1;31204:9;:22;;;;31217:4;:9;;31225:1;31217:9;31204:22;31200:144;;;31288:37;31299:4;:9;;31307:1;31299:9;:21;;31315:5;31299:21;;;31311:1;31299:21;31322:2;31288:10;:37::i;:::-;31281:44;;;;;;;;;;;;;;;31200:144;31366:4;:11;;31374:3;31366:11;31362:121;;31436:28;31445:5;31452:2;31456:7;;;;31436:8;:28::i;31362:121::-;31504:4;:11;;31512:3;31504:11;31500:121;;31574:28;31583:5;31590:2;31594:7;;;;;31574:8;:28::i;31500:121::-;31691:4;:11;;31699:3;31691:11;31687:93;;31733:28;31747:13;31733;:28::i;31687:93::-;31883:4;31875;:12;;;;:27;;;;;31898:4;31891;:11;;;31875:27;31871:112;;;31933:31;31944:4;31950:2;31954;31958:5;31933:10;:31::i;31871:112::-;32057:6;:14;;32067:4;32057:14;:28;;;;-1:-1:-1;32075:10:135;;;;;32057:28;32053:93;;;32130:1;32105:5;:15;;;32121:5;32105:22;;;;;;;;;:::i;:::-;:26;;;;:22;;;;;;:26;32053:93;32192:9;:26;;32205:13;32192:26;32188:92;;32238:27;32247:9;32258:1;32261:3;32238:8;:27::i;:::-;32361:26;32370:5;32377:3;32382:4;32361:8;:26::i;:::-;32354:33;;;;;;;;;;;;;26025:6379;;;;;;;;:::o;3087:2334::-;3634:4;3628:11;;3550:4;3353:31;3342:43;;3413:13;3353:31;3752:2;3452:13;;3342:43;3359:24;3353:31;3452:13;;;3342:43;;;;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3413:13;4180:11;3359:24;3353:31;3452:13;;;3342:43;3413:13;4275:11;3359:24;3353:31;3452:13;;;3342:43;3359:24;3353:31;3452:13;;;3342:43;3128:12;;4415:13;;3628:11;;3452:13;;;;4180:11;3128:12;4495:84;4520:2;4517:1;4514:9;4495:84;;;3369:13;3359:24;;3353:31;3342:43;;3373:2;3413:13;;;;4575:1;3452:13;;;;4538:1;4531:9;4495:84;;;4499:14;4642:1;4638:2;4631:13;4737:5;4733:2;4729:14;4722:5;4717:27;4811:1;4797:15;;4832:6;4856:1;4851:273;;;;5191:1;5181:11;;4825:369;;4851:273;4883:8;4941:22;;;;5020:1;5015:22;;;;5107:1;5097:11;;4876:234;;4941:22;4960:1;4950:11;;4941:22;;5015;5034:1;5024:11;;4876:234;;4825:369;-1:-1:-1;;;5317:14:135;;;5300:32;;5360:19;5356:30;5392:3;5388:16;;;;5353:52;;3087:2334;-1:-1:-1;3087:2334:135:o;21746:1831::-;21819:11;21930:14;21947:24;21959:11;21947;:24::i;:::-;21930:41;;22079:1;22072:5;22068:13;22065:33;;;22094:1;22091;22084:12;22065:33;22227:2;22215:15;;;22168:20;22657:5;22654:1;22650:13;22692:4;22728:1;22713:343;22738:2;22735:1;22732:9;22713:343;;;22861:2;22849:15;;;22798:20;22896:12;;;22910:1;22892:20;22933:42;;;;23001:1;22996:42;;;;22885:153;;22933:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;22942:31;;22933:42;;22996;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;23005:31;;22885:153;-1:-1:-1;;22756:1:135;22749:9;22713:343;;;22717:14;23166:4;23160:11;23145:26;;23252:7;23246:4;23243:17;23233:124;;23294:10;23291:1;23284:21;23336:2;23333:1;23326:13;23233:124;-1:-1:-1;;23484:2:135;23473:14;;;;23461:10;23457:31;23454:1;23450:39;23518:16;;;;23536:10;23514:33;;21746:1831;-1:-1:-1;;;21746:1831:135:o;18856:823::-;18925:12;19012:18;;:::i;:::-;19080:4;19071:13;;19132:5;:8;;;19143:1;19132:12;19116:28;;:5;:12;;;:28;;;19112:95;;19164:28;;;;;2182:2:308;19164:28:135;;;2164:21:308;2221:2;2201:18;;;2194:30;2260:20;2240:18;;;2233:48;2298:18;;19164:28:135;;;;;;;;19112:95;19296:8;;;;;19329:12;;;;;19318:23;;;;;;;19355:20;;;;;19296:8;19487:13;;;19483:90;;19548:6;19557:1;19548:10;19520:5;:15;;;19536:8;19520:25;;;;;;;;;:::i;:::-;:38;;;;:25;;;;;;:38;19483:90;19649:13;:11;:13::i;2645:339::-;2706:11;2770:18;;;;2779:8;;;;2770:18;;;;;;2769:25;;;;;2786:1;2833:2;:9;;;2827:16;;;;;2826:22;;2825:32;;;;;;;2887:9;;2886:15;2769:25;2944:21;;2964:1;2944:21;;;2955:6;2944:21;2929:11;;;;;:37;;-1:-1:-1;;;2645:339:135;;;;:::o;13732:2026::-;13829:12;13915:18;;:::i;:::-;13983:4;13974:13;;14015:17;14075:5;:8;;;14086:1;14075:12;14059:28;;:5;:12;;;:28;;;14055:97;;14107:30;;;;;2529:2:308;14107:30:135;;;2511:21:308;2568:2;2548:18;;;2541:30;2607:22;2587:18;;;2580:50;2647:18;;14107:30:135;2327:344:308;14055:97:135;14222:7;:12;;14233:1;14222:12;:28;;;;14238:7;:12;;14249:1;14238:12;14222:28;14218:947;;;14270:9;14282:5;:15;;;14298:6;14282:23;;;;;;;;;:::i;:::-;;;;;14270:35;;14346:2;14339:9;;:3;:9;;;:25;;;;;14352:7;:12;;14363:1;14352:12;14339:25;14338:58;;;;14377:2;14370:9;;:3;:9;;;;:25;;;;;14383:7;:12;;14394:1;14383:12;14370:25;14323:73;;14252:159;14218:947;;;14508:7;:12;;14519:1;14508:12;14504:661;;14569:1;14561:3;14555:15;;;;14540:30;;14504:661;;;14673:7;:12;;14684:1;14673:12;14669:496;;14733:1;14726:3;14720:14;;;14705:29;;14669:496;;;14854:7;:12;;14865:1;14854:12;14850:315;;14942:4;14936:2;14927:11;;;14926:20;14912:10;14969:8;;;14965:84;;15029:1;15022:3;15016:14;;;15001:29;;14965:84;15070:3;:8;;15077:1;15070:8;15066:85;;15131:1;15123:3;15117:15;;;;15102:30;;15066:85;14868:297;14850:315;15241:8;;;;;15319:12;;;;15308:23;;;;;15475:178;;;;15566:1;15540:22;15543:5;15551:6;15543:14;15559:2;15540;:22::i;:::-;:27;;;;;;;15526:42;;15535:1;15526:42;15511:57;:12;;;:57;15475:178;;;15622:12;;;;;15637:1;15622:16;15607:31;;;;15475:178;15728:13;:11;:13::i;:::-;15721:20;13732:2026;-1:-1:-1;;;;;;;;13732:2026:135:o;32450:8733::-;32537:10;32599;32607:2;32599:10;;;;32638:11;;;:44;;;32664:1;32654:6;:11;;;;:27;;;;;32678:3;32669:6;:12;;;32654:27;32634:8490;;;32723:4;32716:11;;32847:6;32907:3;32902:25;;;;32982:3;32977:25;;;;33056:3;33051:25;;;;33131:3;33126:25;;;;33205:3;33200:25;;;;33278:3;33273:25;;;;33352:3;33347:25;;;;32840:532;;32902:25;32921:4;32913:12;;32902:25;;32977;32996:4;32988:12;;32977:25;;33051;33070:4;33062:12;;33051:25;;33126;33145:4;33137:12;;33126:25;;33200;33219:4;33211:12;;33200:25;;33273;33292:4;33284:12;;33273:25;;33347;33366:4;33358:12;;32840:532;;33435:4;:12;;33443:4;33435:12;33431:4023;;-1:-1:-1;;;33486:9:135;33478:26;;33499:4;33494:1;33486:9;;;33485:18;33478:26;33471:33;;33431:4023;33572:4;:12;;33580:4;33572:12;33568:3886;;-1:-1:-1;;;33623:9:135;33615:26;;33636:4;33631:1;33623:9;;;33622:18;33615:26;33608:33;;33568:3886;33709:4;:12;;33717:4;33709:12;33705:3749;;33774:4;33769:1;33761:9;;;33760:18;33807:27;33761:9;33810:11;;;;33823:2;:10;;;33807:2;:27::i;:::-;33800:34;;;;;;;33705:3749;33903:4;:12;;33911:4;33903:12;33899:3555;;-1:-1:-1;;;33946:17:135;;;33958:4;33953:9;;33946:17;33939:24;;33899:3555;34032:4;:11;;34040:3;34032:11;34028:3426;;-1:-1:-1;;;34074:17:135;;;34086:4;34081:9;;34074:17;34067:24;;34028:3426;34160:4;:12;;34168:4;34160:12;34156:3298;;34203:21;34212:2;34206:8;;:2;:8;;;;34221:2;34216;:7;34203:2;:21::i;:::-;34196:28;;;;;;34156:3298;34473:4;:12;;34481:4;34473:12;34469:2985;;34516:2;34509:9;;;;;;34469:2985;34587:4;:12;;34595:4;34587:12;34583:2871;;34630:2;34623:9;;;;;;34583:2871;34701:4;:12;;34709:4;34701:12;34697:2757;;34744:2;34737:9;;;;;;34697:2757;34815:4;:12;;34823:4;34815:12;34811:2643;;34858:2;34851:9;;;;;;34811:2643;34932:4;:12;;34940:4;34932:12;34928:2526;;34975:2;34968:9;;;;;;34928:2526;35092:4;:12;;35100:4;35092:12;35088:2366;;35135:2;35128:9;;;;;;35088:2366;35206:4;:12;;35214:4;35206:12;35202:2252;;35249:2;35242:9;;;;;;35202:2252;35320:4;:12;;35328:4;35320:12;35316:2138;;35363:2;35356:9;;;;;;35316:2138;35434:4;:12;;35442:4;35434:12;35430:2024;;35477:2;35470:9;;;;;;35430:2024;35548:4;:12;;35556:4;35548:12;35544:1910;;35591:2;35584:9;;;;;;35544:1910;35662:4;:12;;35670:4;35662:12;35658:1796;;35705:2;35698:9;;;;;;35658:1796;35777:4;:12;;35785:4;35777:12;35773:1681;;35820:2;35813:9;;;;;;35773:1681;35890:4;:12;;35898:4;35890:12;35886:1568;;35933:2;35926:9;;;;;;35886:1568;36004:4;:12;;36012:4;36004:12;36000:1454;;36047:2;36040:9;;;;;;36000:1454;36196:4;:12;;36204:4;36196:12;36192:1262;;-1:-1:-1;;;36240:7:135;;;36232:16;;36192:1262;36317:4;:12;;36325:4;36317:12;36313:1141;;-1:-1:-1;;;36361:7:135;;;36353:16;;36313:1141;36437:4;:12;;36445:4;36437:12;36433:1021;;-1:-1:-1;;;36481:7:135;;;36473:16;;36433:1021;36558:4;:12;;36566:4;36558:12;36554:900;;-1:-1:-1;;;36602:7:135;;;36594:16;;36554:900;36678:4;:12;;36686:4;36678:12;36674:780;;-1:-1:-1;;;36722:7:135;;;36714:16;;36674:780;36797:4;:12;;36805:4;36797:12;36793:661;;-1:-1:-1;;;36841:7:135;;;36833:16;;36793:661;36917:4;:12;;36925:4;36917:12;36913:541;;-1:-1:-1;;;36961:7:135;;;36953:16;;36913:541;37037:4;:12;;37045:4;37037:12;37033:421;;-1:-1:-1;;;37082:7:135;;;37080:10;37073:17;;37033:421;37159:4;:12;;37167:4;37159:12;37155:299;;37220:2;37202:21;;37208:2;37202:21;;;:29;;37230:1;37202:29;;;37226:1;37202:29;37195:36;;;;;;;;37155:299;37301:4;:12;;37309:4;37301:12;37297:157;;37349:2;37344:7;;:2;:7;;;:15;;37358:1;37344:15;;37297:157;37406:29;;;;;2878:2:308;37406:29:135;;;2860:21:308;2917:2;2897:18;;;2890:30;2956:21;2936:18;;;2929:49;2995:18;;37406:29:135;2676:343:308;37297:157:135;32684:4784;32634:8490;;;37524:6;:14;;37534:4;37524:14;37520:3590;;37583:4;37576:11;;37658:3;37650:11;;;37646:549;;-1:-1:-1;;;37703:21:135;;;37689:36;;37646:549;37810:4;:12;;37818:4;37810:12;:28;;;;37826:4;:12;;37834:4;37826:12;37810:28;37806:389;;;37870:4;:12;;37878:4;37870:12;37866:83;;37919:3;;;37866:83;37974:8;38012:127;38024:10;38019:15;;:20;38012:127;;38104:8;38071:3;38104:8;;;;;38071:3;38012:127;;;38171:1;-1:-1:-1;38164:8:135;;-1:-1:-1;;38164:8:135;37520:3590;38262:6;:14;;38272:4;38262:14;38258:2852;;-1:-1:-1;;38307:8:135;38313:2;38307:8;;;;38300:15;;38258:2852;38382:6;:14;;38392:4;38382:14;38378:2732;;38427:42;38445:2;38450:1;38445:6;38455:1;38444:12;38439:2;:17;38431:26;;:3;:26;;;;38461:4;38430:35;38467:1;38427:2;:42::i;:::-;38420:49;;;;;38378:2732;38536:6;:14;;38546:4;38536:14;38532:2578;;38581:45;38599:2;38604:1;38599:6;38609:1;38598:12;38593:2;:17;38585:26;;:3;:26;;;;38615:6;38584:37;38623:2;38581;:45::i;38532:2578::-;38694:6;:14;;38704:4;38694:14;38690:2420;;-1:-1:-1;;38745:21:135;38764:1;38759;38754:6;;38753:12;38745:21;;38802:36;;;38873:5;38868:10;;38745:21;;;;;38867:18;38860:25;;38690:2420;38952:6;:14;;38962:4;38952:14;38948:2162;;38997:3;38990:10;;;;;38948:2162;39068:6;:14;;39078:4;39068:14;39064:2046;;39128:2;39133:1;39128:6;39138:1;39127:12;39122:2;:17;39114:26;;:3;:26;;;;39144:4;39113:35;39106:42;;;;;39064:2046;39217:6;:14;;39227:4;39217:14;39213:1897;;39277:2;39282:1;39277:6;39287:1;39276:12;39271:2;:17;39263:26;;:3;:26;;;;39293:6;39262:37;39255:44;;;;;39213:1897;39368:6;:14;;39378:4;39368:14;39364:1746;;-1:-1:-1;;39419:26:135;39443:1;39438;39433:6;;39432:12;39427:2;:17;39419:26;;39481:41;;;39557:5;39552:10;;39419:26;;;;;39551:18;39544:25;;39364:1746;39637:6;:14;;39647:4;39637:14;39633:1477;;-1:-1:-1;;39694:4:135;39688:34;39720:1;39715;39710:6;;39709:12;39704:2;:17;39688:34;;39778:27;;;39758:48;;;39836:10;;39689:9;;;39688:34;;39835:18;39828:25;;39633:1477;39921:6;:14;;39931:4;39921:14;39917:1193;;-1:-1:-1;;39978:6:135;39972:36;40006:1;40001;39996:6;;39995:12;39990:2;:17;39972:36;;40064:29;;;40044:50;;;40124:10;;39973:11;;;39972:36;;40123:18;40116:25;;39917:1193;40210:6;:14;;40220:4;40210:14;40206:904;;-1:-1:-1;;40261:20:135;40279:1;40274;40269:6;;40268:12;40261:20;;40317:36;;;40389:5;40383:11;;40261:20;;;;;40382:19;40375:26;;40206:904;40469:6;:14;;40479:4;40469:14;40465:645;;40514:2;40507:9;;;;;40465:645;40585:6;:14;;40595:4;40585:14;40581:529;;-1:-1:-1;;40636:25:135;40659:1;40654;40649:6;;40648:12;40643:2;:17;40636:25;;40697:41;;;40774:5;40768:11;;40636:25;;;;;40767:19;40760:26;;40581:529;40853:6;:14;;40863:4;40853:14;40849:261;;40898:3;40891:10;;;;;40849:261;40968:6;:14;;40978:4;40968:14;40964:146;;41013:2;41006:9;;;32450:8733;;;;;;;:::o;19960:782::-;20046:12;20133:18;;:::i;:::-;-1:-1:-1;20201:4:135;20308:2;20296:14;;;;20288:41;;;;;;;3226:2:308;20288:41:135;;;3208:21:308;3265:2;3245:18;;;3238:30;3304:16;3284:18;;;3277:44;3338:18;;20288:41:135;3024:338:308;20288:41:135;20425:14;;;;;;;:30;;;20443:12;20425:30;20421:102;;;20504:4;20475:5;:15;;;20491:9;20475:26;;;;;;;;;:::i;:::-;:33;;;;:26;;;;;;:33;20421:102;20578:12;;;;;20567:23;;;;:8;;;:23;20634:1;20619:16;;;20604:31;;;20712:13;:11;:13::i;5582:7764::-;5646:12;5732:18;;:::i;:::-;-1:-1:-1;5910:15:135;;:18;;;;5800:4;6070:18;;;;6114;;;;6158;;;;;5800:4;;5890:17;;;;6070:18;6114;6248;;;6262:4;6248:18;6244:6792;;6298:2;6327:4;6322:9;;:14;6318:144;;6438:4;6433:9;;6425:4;:18;6419:24;6318:144;6483:2;:7;;6489:1;6483:7;6479:161;;6519:10;;;;;6551:16;;;;;;;;6519:10;-1:-1:-1;6479:161:135;;;6619:2;6614:7;;6479:161;6268:386;6244:6792;;;6756:10;:18;;6770:4;6756:18;6752:6284;;1745:10;6794:14;;6752:6284;;;6892:10;:18;;6906:4;6892:18;6888:6148;;6935:1;6930:6;;6888:6148;;;7060:10;:18;;7074:4;7060:18;7056:5980;;7113:4;7098:12;;;:19;7135:26;;;:14;;;:26;7186:13;:11;:13::i;:::-;7179:20;5582:7764;-1:-1:-1;;;;;;;;;5582:7764:135:o;7056:5980::-;7325:10;:18;;7339:4;7325:18;7321:5715;;7476:14;;;7472:2723;7321:5715;7472:2723;7646:22;;;;;7642:2553;;7771:10;7784:27;7792:2;7797:10;7792:15;7809:1;7784:7;:27::i;:::-;7895:17;;;;7771:40;;-1:-1:-1;7895:17:135;7873:19;8045:14;8064:1;8039:26;8035:146;;1676:4:136;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;2098:17;;2003:19;1979:44;2025:11;1976:61;8093:65:135;;8035:146;8267:20;;;;;8234:54;;;;;;;;3540:25:308;;;8234:54:135;3601:23:308;;;3581:18;;;3574:51;8203:11:135;;;;8234:19;:6;:19;;;;3513:18:308;;8234:54:135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8202:86;;;;8515:1;8511:2;8507:10;8612:9;8609:1;8605:17;8694:6;8687:5;8684:17;8681:40;;;8714:5;8704:15;;8681:40;;8797:6;8793:2;8790:14;8787:34;;;8817:2;8807:12;;8787:34;8923:3;8918:1;8910:6;8906:14;8901:3;8897:24;8893:34;8886:41;;9023:3;9019:1;9007:9;8998:6;8995:1;8991:14;8987:30;8983:38;8979:48;8972:55;;9178:1;9174;9170;9158:9;9155:1;9151:17;9147:25;9143:33;9139:41;9305:1;9301;9297;9288:6;9276:9;9273:1;9269:17;9265:30;9261:38;9257:46;9253:54;9235:72;;9436:10;9432:15;9426:4;9422:26;9414:34;;9552:3;9544:4;9540:9;9535:3;9531:19;9528:28;9521:35;;;;9698:33;9707:2;9712:10;9707:15;9724:1;9727:3;9698:8;:33::i;:::-;9753:20;;;:38;;;;;;;;;-1:-1:-1;7642:2553:135;;-1:-1:-1;;;7642:2553:135;;9910:18;;;;;9906:289;;10080:2;10075:7;;7321:5715;;9906:289;10134:10;10129:15;;2053:3;10166:10;;9906:289;7321:5715;;;10324:10;:18;;10338:4;10324:18;10320:2716;;10478:15;;;1824:1;10478:15;;:34;;-1:-1:-1;10497:15:135;;;1859:1;10497:15;10478:34;:57;;;-1:-1:-1;10516:19:135;;;1936:1;10516:19;10478:57;10474:1593;;;10564:2;10559:7;;10320:2716;;10474:1593;10690:23;;;;;10686:1381;;10737:10;10750:27;10758:2;10763:10;10758:15;10775:1;10750:7;:27::i;:::-;10853:17;;;;10737:40;;-1:-1:-1;11096:1:135;11088:10;;11190:1;11186:17;11265:13;;;11262:32;;;11287:5;11281:11;;11262:32;11573:14;;;11379:1;11569:22;;;11565:32;;;;11462:26;11486:1;11371:10;;;11466:18;;;11462:26;11561:43;11367:20;;11669:12;11797:17;;;:23;11865:1;11842:20;;;:24;11375:2;-1:-1:-1;11375:2:135;7321:5715;;10320:2716;12269:10;:18;;12283:4;12269:18;12265:771;;12379:2;:7;;12385:1;12379:7;12375:647;;12472:14;;;;;:40;;-1:-1:-1;12490:22:135;;;1978:1;12490:22;12472:40;:62;;;-1:-1:-1;12516:18:135;;;1897:1;12516:18;12472:62;12468:404;;;12567:1;12562:6;;12375:647;;12468:404;12613:15;;;1824:1;12613:15;;:34;;-1:-1:-1;12632:15:135;;;1859:1;12632:15;12613:34;:61;;;-1:-1:-1;12651:23:135;;;2021:1;12651:23;12613:61;:84;;;-1:-1:-1;12678:19:135;;;1936:1;12678:19;12613:84;12609:263;;;12730:1;12725:6;;7321:5715;;12375:647;12923:10;12918:15;;2087:4;12955:11;;12375:647;13111:15;;;;;:23;;;;:18;;;;:23;;;;13148:15;;:23;;;:18;;;;:23;-1:-1:-1;13237:12:135;;;;13226:23;;;:8;;;:23;13293:1;13278:16;13263:31;;;;;13316:13;:11;:13::i;16084:2480::-;16178:12;16264:18;;:::i;:::-;-1:-1:-1;16332:4:135;16364:10;16472:13;;;16481:4;16472:13;16468:1705;;-1:-1:-1;16511:8:135;;;;16468:1705;;;16630:5;:13;;16639:4;16630:13;16626:1547;;16663:14;;;:8;;;:14;16626:1547;;;16793:5;:13;;16802:4;16793:13;16789:1384;;-1:-1:-1;16832:8:135;;;;16789:1384;;;16951:5;:13;;16960:4;16951:13;16947:1226;;16984:14;;;:8;;;:14;16947:1226;;;17125:5;:13;;17134:4;17125:13;17121:1052;;17252:9;17198:17;17178;;;17198;;;;17178:37;17259:2;17252:9;;;;;17234:8;;;:28;17280:22;:8;;;:22;17121:1052;;;17439:5;:13;;17448:4;17439:13;17435:738;;17506:11;17492;;;17506;;;17492:25;17561:2;17554:9;;;;;17536:8;;;:28;17582:22;:8;;;:22;17435:738;;;17763:5;:13;;17772:4;17763:13;17759:414;;17833:3;17814:23;;17820:3;17814:23;;;;;;;:::i;:::-;;17796:42;;:8;;;:42;17874:23;;;;;;;;;;;;;:::i;:::-;;17856:42;;:8;;;:42;17759:414;;;18067:5;:13;;18076:4;18067:13;18063:110;;18117:3;18111:9;;:3;:9;;;;;;;:::i;:::-;;18100:20;;;;:8;;;:20;18149:9;;;;;;;;;;;:::i;:::-;;18138:20;;:8;;;:20;18063:110;18266:14;;;;18262:85;;18329:3;18300:5;:15;;;18316:9;18300:26;;;;;;;;;:::i;:::-;:32;;;;:26;;;;;;:32;18262:85;18401:12;;;;;18390:23;;;;:8;;;:23;18457:1;18442:16;;;18427:31;;;18534:13;:11;:13::i;:::-;18527:20;16084:2480;-1:-1:-1;;;;;;;16084:2480:135:o;23913:1654::-;24089:14;24106:24;24118:11;24106;:24::i;:::-;24089:41;;24238:1;24231:5;24227:13;24224:33;;;24253:1;24250;24243:12;24224:33;24392:2;24586:15;;;24411:2;24400:14;;24388:10;24384:31;24381:1;24377:39;24542:16;;;24327:20;;24527:10;24516:22;;;24512:27;24502:38;24499:60;25028:5;25025:1;25021:13;25099:1;25084:343;25109:2;25106:1;25103:9;25084:343;;;25232:2;25220:15;;;25169:20;25267:12;;;25281:1;25263:20;25304:42;;;;25372:1;25367:42;;;;25256:153;;25304:42;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25313:31;;25304:42;;25367;22391:1;22384:12;;;22424:2;22417:13;;;22469:2;22456:16;;25376:31;;25256:153;-1:-1:-1;;25127:1:135;25120:9;25084:343;;;-1:-1:-1;;25526:4:135;25519:18;-1:-1:-1;;;;23913:1654:135:o;20946:586::-;21268:20;;;21292:7;21268:32;21261:3;:40;;;21374:14;;21429:17;;21423:24;;;21415:72;;;;;;;4277:2:308;21415:72:135;;;4259:21:308;4316:2;4296:18;;;4289:30;4355:34;4335:18;;;4328:62;4426:5;4406:18;;;4399:33;4449:19;;21415:72:135;4075:399:308;21415:72:135;21501:14;20946:586;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;467:347:308:-;518:8;528:6;582:3;575:4;567:6;563:17;559:27;549:55;;600:1;597;590:12;549:55;-1:-1:-1;623:20:308;;666:18;655:30;;652:50;;;698:1;695;688:12;652:50;735:4;727:6;723:17;711:29;;787:3;780:4;771:6;763;759:19;755:30;752:39;749:59;;;804:1;801;794:12;749:59;467:347;;;;;:::o;819:785::-;918:6;926;934;942;950;1003:2;991:9;982:7;978:23;974:32;971:52;;;1019:1;1016;1009:12;971:52;1059:9;1046:23;1088:18;1129:2;1121:6;1118:14;1115:34;;;1145:1;1142;1135:12;1115:34;1184:58;1234:7;1225:6;1214:9;1210:22;1184:58;:::i;:::-;1261:8;;-1:-1:-1;1158:84:308;-1:-1:-1;1349:2:308;1334:18;;1321:32;;-1:-1:-1;1365:16:308;;;1362:36;;;1394:1;1391;1384:12;1362:36;;1433:60;1485:7;1474:8;1463:9;1459:24;1433:60;:::i;:::-;819:785;;;;-1:-1:-1;1512:8:308;1594:2;1579:18;1566:32;;819:785;-1:-1:-1;;;;819:785:308:o;1791:184::-;1843:77;1840:1;1833:88;1940:4;1937:1;1930:15;1964:4;1961:1;1954:15;3636:245;3715:6;3723;3776:2;3764:9;3755:7;3751:23;3747:32;3744:52;;;3792:1;3789;3782:12;3744:52;-1:-1:-1;;3815:16:308;;3871:2;3856:18;;;3850:25;3815:16;;3850:25;;-1:-1:-1;3636:245:308:o;3886:184::-;3938:77;3935:1;3928:88;4035:4;4032:1;4025:15;4059:4;4056:1;4049:15"
func init() { func init() {
if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil { if err := json.Unmarshal([]byte(MIPSStorageLayoutJSON), MIPSStorageLayout); err != nil {
......
...@@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) ...@@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout)
var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a" var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b50600436106100725760003560e01c8063e03110e111610050578063e03110e114610106578063e15926111461012e578063fef2b4ed1461014357600080fd5b806361238bde146100775780638542cf50146100b5578063c0c220c9146100f3575b600080fd5b6100a26100853660046104df565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100e36100c33660046104df565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100ac565b6100a2610101366004610501565b610163565b6101196101143660046104df565b610238565b604080519283526020830191909152016100ac565b61014161013c36600461053c565b610329565b005b6100a26101513660046105b8565b60006020819052908152604090205481565b600061016f8686610432565b905061017c836008610600565b8211806101895750602083115b156101c0576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484528752808320948352938652838220558181529384905292205592915050565b6000828152600260209081526040808320848452909152812054819060ff166102c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102dd816008610600565b6102e8856020610600565b1061030657836102f9826008610600565b6103039190610618565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103485763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316176104d8818360408051600093845233602052918152606090922091527effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b9392505050565b600080604083850312156104f257600080fd5b50508035926020909101359150565b600080600080600060a0868803121561051957600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60008060006040848603121561055157600080fd5b83359250602084013567ffffffffffffffff8082111561057057600080fd5b818601915086601f83011261058457600080fd5b81358181111561059357600080fd5b8760208285010111156105a557600080fd5b6020830194508093505050509250925092565b6000602082840312156105ca57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610613576106136105d1565b500190565b60008282101561062a5761062a6105d1565b50039056fea164736f6c634300080f000a"
var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:305;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:305;;607:22;589:41;;577:2;562:18;680:66:137;449:187:305;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:305;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:305;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:305;906:62:137;;;2890:21:305;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:305:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:305;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:305:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:305;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:305;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:305;1069:19;1056:33;;-1:-1:-1;641:454:305;-1:-1:-1;641:454:305:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:305;;2017:180;-1:-1:-1;2017:180:305:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:305;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:305;;3055:125::o" var PreimageOracleDeployedSourceMap = "306:3911:137:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;537:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:308;;;401:2;386:18;537:68:137;;;;;;;;680:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:308;;607:22;589:41;;577:2;562:18;680:66:137;449:187:308;1367:1211:137;;;;;;:::i;:::-;;:::i;789:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;1274:25:308;;;1330:2;1315:18;;1308:34;;;;1247:18;789:536:137;1100:248:308;2620:1595:137;;;;;;:::i;:::-;;:::i;:::-;;419:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;1367:1211;1560:12;1665:51;1694:6;1702:13;1665:28;:51::i;:::-;1658:58;-1:-1:-1;1810:9:137;:5;1818:1;1810:9;:::i;:::-;1796:11;:23;:37;;;;1831:2;1823:5;:10;1796:37;1792:90;;;1856:15;;;;;;;;;;;;;;1792:90;1951:12;2051:4;2044:18;;;2152:3;2148:15;;;2135:29;;2184:4;2177:19;;;;2286:18;;2376:20;;;:14;:20;;;;;;:33;;;;;;;;:40;;;;2412:4;2376:40;;;;;;2426:19;;;;;;;;:32;;;;;;;;;:39;2542:21;;;;;;;;;:29;2391:4;1367:1211;-1:-1:-1;;1367:1211:137:o;789:536::-;865:12;914:20;;;:14;:20;;;;;;;;:29;;;;;;;;;865:12;;914:29;;906:62;;;;;;;2908:2:308;906:62:137;;;2890:21:308;2947:2;2927:18;;;2920:30;2986:22;2966:18;;;2959:50;3026:18;;906:62:137;;;;;;;;-1:-1:-1;1099:14:137;1116:21;;;1087:2;1116:21;;;;;;;;1167:10;1116:21;1176:1;1167:10;:::i;:::-;1151:12;:7;1161:2;1151:12;:::i;:::-;:26;1147:87;;1216:7;1203:10;:6;1212:1;1203:10;:::i;:::-;:20;;;;:::i;:::-;1193:30;;1147:87;-1:-1:-1;1290:19:137;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;789:536;;-1:-1:-1;789:536:137:o;2620:1595::-;2916:4;2903:18;2721:12;;3045:1;3035:12;;3019:29;;3016:210;;;3120:10;3117:1;3110:21;3210:1;3204:4;3197:15;3016:210;3469:3;3465:14;;;3369:4;3453:27;3500:11;3474:4;3619:16;3500:11;3601:41;3832:29;;;3836:11;3832:29;3826:36;3884:20;;;;4031:19;4024:27;4053:11;4021:44;4084:19;;;;4062:1;4084:19;;;;;;;;:32;;;;;;;;:39;;;;4119:4;4084:39;;;;;;4133:18;;;;;;;;:31;;;;;;;;;:38;;;;4181:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;2620:1595:137:o;552:449:136:-;835:11;860:19;848:32;;832:49;965:29;832:49;980:13;1676:4;1670:11;;1533:21;1787:15;;;1828:8;1822:4;1815:22;1850:27;;;1996:4;1983:18;;;2098:17;;2003:19;1979:44;2025:11;1976:61;;1455:676;965:29;958:36;552:449;-1:-1:-1;;;552:449:136:o;14:248:308:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:308;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:308:o;641:454::-;736:6;744;752;760;768;821:3;809:9;800:7;796:23;792:33;789:53;;;838:1;835;828:12;789:53;-1:-1:-1;;861:23:308;;;931:2;916:18;;903:32;;-1:-1:-1;982:2:308;967:18;;954:32;;1033:2;1018:18;;1005:32;;-1:-1:-1;1084:3:308;1069:19;1056:33;;-1:-1:-1;641:454:308;-1:-1:-1;641:454:308:o;1353:659::-;1432:6;1440;1448;1501:2;1489:9;1480:7;1476:23;1472:32;1469:52;;;1517:1;1514;1507:12;1469:52;1553:9;1540:23;1530:33;;1614:2;1603:9;1599:18;1586:32;1637:18;1678:2;1670:6;1667:14;1664:34;;;1694:1;1691;1684:12;1664:34;1732:6;1721:9;1717:22;1707:32;;1777:7;1770:4;1766:2;1762:13;1758:27;1748:55;;1799:1;1796;1789:12;1748:55;1839:2;1826:16;1865:2;1857:6;1854:14;1851:34;;;1881:1;1878;1871:12;1851:34;1926:7;1921:2;1912:6;1908:2;1904:15;1900:24;1897:37;1894:57;;;1947:1;1944;1937:12;1894:57;1978:2;1974;1970:11;1960:21;;2000:6;1990:16;;;;;1353:659;;;;;:::o;2017:180::-;2076:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:52;;;2145:1;2142;2135:12;2097:52;-1:-1:-1;2168:23:308;;2017:180;-1:-1:-1;2017:180:308:o;2384:184::-;2436:77;2433:1;2426:88;2533:4;2530:1;2523:15;2557:4;2554:1;2547:15;2573:128;2613:3;2644:1;2640:6;2637:1;2634:13;2631:39;;;2650:18;;:::i;:::-;-1:-1:-1;2686:9:308;;2573:128::o;3055:125::-;3095:4;3123:1;3120;3117:8;3114:34;;;3128:18;;:::i;:::-;-1:-1:-1;3165:9:308;;3055:125::o"
func init() { func init() {
if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil {
......
package fault
import (
"context"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
// MinimalFaultDisputeGameCaller is a minimal interface around [bindings.FaultDisputeGameCaller].
// This needs to be updated if the [bindings.FaultDisputeGameCaller] interface changes.
type MinimalFaultDisputeGameCaller interface {
ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error)
Status(opts *bind.CallOpts) (uint8, error)
ClaimDataLen(opts *bind.CallOpts) (*big.Int, error)
MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error)
ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error)
}
// loader pulls in fault dispute game claim data periodically and over subscriptions.
type loader struct {
caller MinimalFaultDisputeGameCaller
}
// NewLoader creates a new [loader].
func NewLoader(caller MinimalFaultDisputeGameCaller) *loader {
return &loader{
caller: caller,
}
}
// NewLoaderFromBindings creates a new [loader] from a [bindings.FaultDisputeGameCaller].
func NewLoaderFromBindings(fdgAddr common.Address, client bind.ContractCaller) (*loader, error) {
caller, err := bindings.NewFaultDisputeGameCaller(fdgAddr, client)
if err != nil {
return nil, err
}
return NewLoader(caller), nil
}
// GetGameStatus returns the current game status.
func (l *loader) GetGameStatus(ctx context.Context) (gameTypes.GameStatus, error) {
status, err := l.caller.Status(&bind.CallOpts{Context: ctx})
return gameTypes.GameStatus(status), err
}
// GetClaimCount returns the number of claims in the game.
func (l *loader) GetClaimCount(ctx context.Context) (uint64, error) {
count, err := l.caller.ClaimDataLen(&bind.CallOpts{Context: ctx})
if err != nil {
return 0, err
}
return count.Uint64(), nil
}
// FetchGameDepth fetches the game depth from the fault dispute game.
func (l *loader) FetchGameDepth(ctx context.Context) (uint64, error) {
callOpts := bind.CallOpts{
Context: ctx,
}
gameDepth, err := l.caller.MAXGAMEDEPTH(&callOpts)
if err != nil {
return 0, err
}
return gameDepth.Uint64(), nil
}
// fetchClaim fetches a single [Claim] with a hydrated parent.
func (l *loader) fetchClaim(ctx context.Context, arrIndex uint64) (types.Claim, error) {
callOpts := bind.CallOpts{
Context: ctx,
}
fetchedClaim, err := l.caller.ClaimData(&callOpts, new(big.Int).SetUint64(arrIndex))
if err != nil {
return types.Claim{}, err
}
claim := types.Claim{
ClaimData: types.ClaimData{
Value: fetchedClaim.Claim,
Position: types.NewPositionFromGIndex(fetchedClaim.Position),
},
Countered: fetchedClaim.Countered,
Clock: fetchedClaim.Clock.Uint64(),
ContractIndex: int(arrIndex),
ParentContractIndex: int(fetchedClaim.ParentIndex),
}
return claim, nil
}
// FetchClaims fetches all claims from the fault dispute game.
func (l *loader) FetchClaims(ctx context.Context) ([]types.Claim, error) {
// Get the current claim count.
claimCount, err := l.caller.ClaimDataLen(&bind.CallOpts{
Context: ctx,
})
if err != nil {
return nil, err
}
// Fetch each claim and build a list.
claimList := make([]types.Claim, claimCount.Uint64())
for i := uint64(0); i < claimCount.Uint64(); i++ {
claim, err := l.fetchClaim(ctx, i)
if err != nil {
return nil, err
}
claimList[i] = claim
}
return claimList, nil
}
// FetchAbsolutePrestateHash fetches the hashed absolute prestate from the fault dispute game.
func (l *loader) FetchAbsolutePrestateHash(ctx context.Context) (common.Hash, error) {
callOpts := bind.CallOpts{
Context: ctx,
}
absolutePrestate, err := l.caller.ABSOLUTEPRESTATE(&callOpts)
if err != nil {
return common.Hash{}, err
}
return absolutePrestate, nil
}
package fault
import (
"context"
"fmt"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
var (
mockClaimDataError = fmt.Errorf("claim data errored")
mockClaimLenError = fmt.Errorf("claim len errored")
mockMaxGameDepthError = fmt.Errorf("max game depth errored")
mockPrestateError = fmt.Errorf("prestate errored")
mockStatusError = fmt.Errorf("status errored")
)
// TestLoader_GetGameStatus tests fetching the game status.
func TestLoader_GetGameStatus(t *testing.T) {
tests := []struct {
name string
status uint8
expectedError bool
}{
{
name: "challenger won status",
status: uint8(gameTypes.GameStatusChallengerWon),
},
{
name: "defender won status",
status: uint8(gameTypes.GameStatusDefenderWon),
},
{
name: "in progress status",
status: uint8(gameTypes.GameStatusInProgress),
},
{
name: "error bubbled up",
expectedError: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.status = test.status
mockCaller.statusError = test.expectedError
loader := NewLoader(mockCaller)
status, err := loader.GetGameStatus(context.Background())
if test.expectedError {
require.ErrorIs(t, err, mockStatusError)
} else {
require.NoError(t, err)
require.Equal(t, gameTypes.GameStatus(test.status), status)
}
})
}
}
// TestLoader_FetchGameDepth tests fetching the game depth.
func TestLoader_FetchGameDepth(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.maxGameDepth = 10
loader := NewLoader(mockCaller)
depth, err := loader.FetchGameDepth(context.Background())
require.NoError(t, err)
require.Equal(t, uint64(10), depth)
})
t.Run("Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.maxGameDepthError = true
loader := NewLoader(mockCaller)
depth, err := loader.FetchGameDepth(context.Background())
require.ErrorIs(t, mockMaxGameDepthError, err)
require.Equal(t, depth, uint64(0))
})
}
// TestLoader_FetchAbsolutePrestateHash tests fetching the absolute prestate hash.
func TestLoader_FetchAbsolutePrestateHash(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
loader := NewLoader(mockCaller)
prestate, err := loader.FetchAbsolutePrestateHash(context.Background())
require.NoError(t, err)
require.ElementsMatch(t, common.HexToHash("0xdEad"), prestate)
})
t.Run("Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.prestateError = true
loader := NewLoader(mockCaller)
prestate, err := loader.FetchAbsolutePrestateHash(context.Background())
require.Error(t, err)
require.ElementsMatch(t, common.Hash{}, prestate)
})
}
// TestLoader_FetchClaims tests fetching claims.
func TestLoader_FetchClaims(t *testing.T) {
t.Run("Succeeds", func(t *testing.T) {
mockCaller := newMockCaller()
expectedClaims := mockCaller.returnClaims
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.NoError(t, err)
require.ElementsMatch(t, []types.Claim{
{
ClaimData: types.ClaimData{
Value: expectedClaims[0].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[0].Position),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 0,
},
{
ClaimData: types.ClaimData{
Value: expectedClaims[1].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[1].Position),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 1,
ParentContractIndex: 0,
},
{
ClaimData: types.ClaimData{
Value: expectedClaims[2].Claim,
Position: types.NewPositionFromGIndex(expectedClaims[2].Position),
},
Countered: false,
Clock: uint64(0),
ContractIndex: 2,
ParentContractIndex: 1,
},
}, claims)
})
t.Run("Claim Data Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.claimDataError = true
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.ErrorIs(t, err, mockClaimDataError)
require.Empty(t, claims)
})
t.Run("Claim Len Errors", func(t *testing.T) {
mockCaller := newMockCaller()
mockCaller.claimLenError = true
loader := NewLoader(mockCaller)
claims, err := loader.FetchClaims(context.Background())
require.ErrorIs(t, err, mockClaimLenError)
require.Empty(t, claims)
})
}
type mockCaller struct {
claimDataError bool
claimLenError bool
maxGameDepthError bool
prestateError bool
statusError bool
maxGameDepth uint64
currentIndex uint64
status uint8
returnClaims []struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}
}
func newMockCaller() *mockCaller {
return &mockCaller{
returnClaims: []struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}{
{
Claim: [32]byte{0x00},
Position: big.NewInt(1),
Countered: false,
Clock: big.NewInt(0),
},
{
Claim: [32]byte{0x01},
Position: big.NewInt(2),
Countered: false,
Clock: big.NewInt(0),
ParentIndex: 0,
},
{
Claim: [32]byte{0x02},
Position: big.NewInt(3),
Countered: false,
Clock: big.NewInt(0),
ParentIndex: 1,
},
},
}
}
func (m *mockCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
if m.claimDataError {
return struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}{}, mockClaimDataError
}
returnClaim := m.returnClaims[arg0.Uint64()]
m.currentIndex++
return returnClaim, nil
}
func (m *mockCaller) Status(opts *bind.CallOpts) (uint8, error) {
if m.statusError {
return 0, mockStatusError
}
return m.status, nil
}
func (m *mockCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
if m.claimLenError {
return big.NewInt(0), mockClaimLenError
}
return big.NewInt(int64(len(m.returnClaims))), nil
}
func (m *mockCaller) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) {
if m.maxGameDepthError {
return nil, mockMaxGameDepthError
}
return big.NewInt(int64(m.maxGameDepth)), nil
}
func (m *mockCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) {
if m.prestateError {
return [32]byte{}, mockPrestateError
}
return common.HexToHash("0xdEad"), nil
}
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
var ( var (
ErrIndexTooLarge = errors.New("index is larger than the maximum index") ErrIndexTooLarge = errors.New("index is larger than the maximum index")
absolutePrestate = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060")
) )
// AlphabetTraceProvider is a [TraceProvider] that provides claims for specific // AlphabetTraceProvider is a [TraceProvider] that provides claims for specific
...@@ -36,11 +37,7 @@ func NewTraceProvider(state string, depth uint64) *AlphabetTraceProvider { ...@@ -36,11 +37,7 @@ func NewTraceProvider(state string, depth uint64) *AlphabetTraceProvider {
func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Position) ([]byte, []byte, *types.PreimageOracleData, error) { func (ap *AlphabetTraceProvider) GetStepData(ctx context.Context, i types.Position) ([]byte, []byte, *types.PreimageOracleData, error) {
traceIndex := i.TraceIndex(int(ap.depth)) traceIndex := i.TraceIndex(int(ap.depth))
if traceIndex.Cmp(common.Big0) == 0 { if traceIndex.Cmp(common.Big0) == 0 {
prestate, err := ap.AbsolutePreState(ctx) return absolutePrestate, []byte{}, nil, nil
if err != nil {
return nil, nil, nil, err
}
return prestate, []byte{}, nil, nil
} }
// We want the pre-state which is the value prior to the one requested // We want the pre-state which is the value prior to the one requested
traceIndex = traceIndex.Sub(traceIndex, big.NewInt(1)) traceIndex = traceIndex.Sub(traceIndex, big.NewInt(1))
...@@ -67,17 +64,8 @@ func (ap *AlphabetTraceProvider) Get(ctx context.Context, i types.Position) (com ...@@ -67,17 +64,8 @@ func (ap *AlphabetTraceProvider) Get(ctx context.Context, i types.Position) (com
return alphabetStateHash(claimBytes), nil return alphabetStateHash(claimBytes), nil
} }
// AbsolutePreState returns the absolute pre-state for the alphabet trace. func (ap *AlphabetTraceProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) {
func (ap *AlphabetTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { hash := common.BytesToHash(crypto.Keccak256(absolutePrestate))
return common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060"), nil
}
func (ap *AlphabetTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) {
prestate, err := ap.AbsolutePreState(ctx)
if err != nil {
return common.Hash{}, err
}
hash := common.BytesToHash(crypto.Keccak256(prestate))
hash[0] = mipsevm.VMStatusUnfinished hash[0] = mipsevm.VMStatusUnfinished
return hash, nil return hash, nil
} }
......
...@@ -124,7 +124,7 @@ func (p *CannonTraceProvider) GetStepData(ctx context.Context, pos types.Positio ...@@ -124,7 +124,7 @@ func (p *CannonTraceProvider) GetStepData(ctx context.Context, pos types.Positio
return value, data, oracleData, nil return value, data, oracleData, nil
} }
func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, error) { func (p *CannonTraceProvider) absolutePreState() ([]byte, error) {
state, err := parseState(p.prestate) state, err := parseState(p.prestate)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot load absolute pre-state: %w", err) return nil, fmt.Errorf("cannot load absolute pre-state: %w", err)
...@@ -132,8 +132,8 @@ func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, err ...@@ -132,8 +132,8 @@ func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, err
return state.EncodeWitness(), nil return state.EncodeWitness(), nil
} }
func (p *CannonTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (common.Hash, error) { func (p *CannonTraceProvider) AbsolutePreStateCommitment(_ context.Context) (common.Hash, error) {
state, err := p.AbsolutePreState(ctx) state, err := p.absolutePreState()
if err != nil { if err != nil {
return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err) return common.Hash{}, fmt.Errorf("cannot load absolute pre-state: %w", err)
} }
......
...@@ -216,28 +216,28 @@ func TestGetStepData(t *testing.T) { ...@@ -216,28 +216,28 @@ func TestGetStepData(t *testing.T) {
}) })
} }
func TestAbsolutePreState(t *testing.T) { func TestAbsolutePreStateCommitment(t *testing.T) {
dataDir := t.TempDir() dataDir := t.TempDir()
prestate := "state.json" prestate := "state.json"
t.Run("StateUnavailable", func(t *testing.T) { t.Run("StateUnavailable", func(t *testing.T) {
provider, _ := setupWithTestData(t, "/dir/does/not/exist", prestate) provider, _ := setupWithTestData(t, "/dir/does/not/exist", prestate)
_, err := provider.AbsolutePreState(context.Background()) _, err := provider.AbsolutePreStateCommitment(context.Background())
require.ErrorIs(t, err, os.ErrNotExist) require.ErrorIs(t, err, os.ErrNotExist)
}) })
t.Run("InvalidStateFile", func(t *testing.T) { t.Run("InvalidStateFile", func(t *testing.T) {
setupPreState(t, dataDir, "invalid.json") setupPreState(t, dataDir, "invalid.json")
provider, _ := setupWithTestData(t, dataDir, prestate) provider, _ := setupWithTestData(t, dataDir, prestate)
_, err := provider.AbsolutePreState(context.Background()) _, err := provider.AbsolutePreStateCommitment(context.Background())
require.ErrorContains(t, err, "invalid mipsevm state") require.ErrorContains(t, err, "invalid mipsevm state")
}) })
t.Run("ExpectedAbsolutePreState", func(t *testing.T) { t.Run("ExpectedAbsolutePreState", func(t *testing.T) {
setupPreState(t, dataDir, "state.json") setupPreState(t, dataDir, "state.json")
provider, _ := setupWithTestData(t, dataDir, prestate) provider, _ := setupWithTestData(t, dataDir, prestate)
preState, err := provider.AbsolutePreState(context.Background()) actual, err := provider.AbsolutePreStateCommitment(context.Background())
require.NoError(t, err) require.NoError(t, err)
state := mipsevm.State{ state := mipsevm.State{
Memory: mipsevm.NewMemory(), Memory: mipsevm.NewMemory(),
...@@ -253,7 +253,9 @@ func TestAbsolutePreState(t *testing.T) { ...@@ -253,7 +253,9 @@ func TestAbsolutePreState(t *testing.T) {
Step: 0, Step: 0,
Registers: [32]uint32{}, Registers: [32]uint32{},
} }
require.Equal(t, []byte(state.EncodeWitness()), preState) expected, err := state.EncodeWitness().StateHash()
require.NoError(t, err)
require.Equal(t, expected, actual)
}) })
} }
......
...@@ -56,11 +56,6 @@ func (s *SplitTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (ha ...@@ -56,11 +56,6 @@ func (s *SplitTraceProvider) AbsolutePreStateCommitment(ctx context.Context) (ha
return s.bottomProvider.AbsolutePreStateCommitment(ctx) return s.bottomProvider.AbsolutePreStateCommitment(ctx)
} }
// AbsolutePreState routes the AbsolutePreState request to the lowest internal [types.TraceProvider].
func (s *SplitTraceProvider) AbsolutePreState(ctx context.Context) (preimage []byte, err error) {
return s.bottomProvider.AbsolutePreState(ctx)
}
// GetStepData routes the GetStepData request to the lowest internal [types.TraceProvider]. // GetStepData routes the GetStepData request to the lowest internal [types.TraceProvider].
func (s *SplitTraceProvider) GetStepData(ctx context.Context, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) { func (s *SplitTraceProvider) GetStepData(ctx context.Context, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) {
ancestorDepth, provider := s.providerForDepth(uint64(pos.Depth())) ancestorDepth, provider := s.providerForDepth(uint64(pos.Depth()))
......
...@@ -64,24 +64,6 @@ func TestAbsolutePreStateCommitment(t *testing.T) { ...@@ -64,24 +64,6 @@ func TestAbsolutePreStateCommitment(t *testing.T) {
}) })
} }
func TestAbsolutePreState(t *testing.T) {
t.Run("ErrorBubblesUp", func(t *testing.T) {
mockOutputProvider := mockTraceProvider{absolutePreStateError: mockGetError}
splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40)
_, err := splitProvider.AbsolutePreState(context.Background())
require.ErrorIs(t, err, mockGetError)
})
t.Run("ReturnsCorrectPreimageData", func(t *testing.T) {
expectedPreimage := []byte{1, 2, 3, 4}
mockOutputProvider := mockTraceProvider{preImageData: expectedPreimage}
splitProvider := newSplitTraceProvider(t, nil, &mockOutputProvider, 40)
output, err := splitProvider.AbsolutePreState(context.Background())
require.NoError(t, err)
require.Equal(t, expectedPreimage, output)
})
}
func TestGetStepData(t *testing.T) { func TestGetStepData(t *testing.T) {
t.Run("ErrorBubblesUp", func(t *testing.T) { t.Run("ErrorBubblesUp", func(t *testing.T) {
mockOutputProvider := mockTraceProvider{getStepDataError: mockGetError} mockOutputProvider := mockTraceProvider{getStepDataError: mockGetError}
......
...@@ -69,9 +69,6 @@ type TraceProvider interface { ...@@ -69,9 +69,6 @@ type TraceProvider interface {
// The prestate returned from GetStepData for trace 10 should be the pre-image of the claim from trace 9 // The prestate returned from GetStepData for trace 10 should be the pre-image of the claim from trace 9
GetStepData(ctx context.Context, i Position) (prestate []byte, proofData []byte, preimageData *PreimageOracleData, err error) GetStepData(ctx context.Context, i Position) (prestate []byte, proofData []byte, preimageData *PreimageOracleData, err error)
// AbsolutePreState is the pre-image value of the trace that transitions to the trace value at index 0
AbsolutePreState(ctx context.Context) (preimage []byte, err error)
// AbsolutePreStateCommitment is the commitment of the pre-image value of the trace that transitions to the trace value at index 0 // AbsolutePreStateCommitment is the commitment of the pre-image value of the trace that transitions to the trace value at index 0
AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error) AbsolutePreStateCommitment(ctx context.Context) (hash common.Hash, err error)
} }
......
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
"time" "time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
...@@ -356,25 +355,6 @@ func (g *FaultGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) { ...@@ -356,25 +355,6 @@ func (g *FaultGameHelper) ResolveClaim(ctx context.Context, claimIdx int64) {
g.require.NoError(err, "ResolveClaim transaction was not OK") g.require.NoError(err, "ResolveClaim transaction was not OK")
} }
// ResolveAllClaims resolves all subgames
// This function does not resolve the game. That's the responsibility of challengers
func (g *FaultGameHelper) ResolveAllClaims(ctx context.Context) {
loader := fault.NewLoader(g.game)
claims, err := loader.FetchClaims(ctx)
g.require.NoError(err, "Failed to fetch claims")
subgames := make(map[int]bool)
for i := len(claims) - 1; i > 0; i-- {
subgames[claims[i].ParentContractIndex] = true
// Subgames containing only one node are implicitly resolved
// i.e. uncountered and claims at MAX_DEPTH
if !subgames[i] {
continue
}
g.ResolveClaim(ctx, int64(i))
}
g.ResolveClaim(ctx, 0)
}
func (g *FaultGameHelper) gameData(ctx context.Context) string { func (g *FaultGameHelper) gameData(ctx context.Context) string {
opts := &bind.CallOpts{Context: ctx} opts := &bind.CallOpts{Context: ctx}
maxDepth := int(g.MaxDepth(ctx)) maxDepth := int(g.MaxDepth(ctx))
......
...@@ -142,7 +142,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l ...@@ -142,7 +142,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l
if err != nil { if err != nil {
return fmt.Errorf("failed to join blocks gossip topic: %w", err) return fmt.Errorf("failed to join blocks gossip topic: %w", err)
} }
log.Info("started p2p host", "addrs", n.host.Addrs(), "peerID", n.host.ID().Pretty()) log.Info("started p2p host", "addrs", n.host.Addrs(), "peerID", n.host.ID().String())
tcpPort, err := FindActiveTCPPort(n.host) tcpPort, err := FindActiveTCPPort(n.host)
if err != nil { if err != nil {
......
...@@ -26,36 +26,36 @@ Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882) ...@@ -26,36 +26,36 @@ Bytes_toNibbles_Test:test_toNibbles_expectedResult128Bytes_works() (gas: 78882)
Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992) Bytes_toNibbles_Test:test_toNibbles_expectedResult5Bytes_works() (gas: 3992)
Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 823) Bytes_toNibbles_Test:test_toNibbles_zeroLengthInput_works() (gas: 823)
Constants_Test:test_eip1967Constants_succeeds() (gas: 453) Constants_Test:test_eip1967Constants_succeeds() (gas: 453)
CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20435) CrossDomainMessenger_BaseGas_Test:test_baseGas_succeeds() (gas: 20481)
CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8461) CrossDomainOwnable2_Test:test_onlyOwner_notMessenger_reverts() (gas: 8539)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57494) CrossDomainOwnable2_Test:test_onlyOwner_notOwner2_reverts() (gas: 57515)
CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16610) CrossDomainOwnable2_Test:test_onlyOwner_notOwner_reverts() (gas: 16655)
CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73522) CrossDomainOwnable2_Test:test_onlyOwner_succeeds() (gas: 73600)
CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10554) CrossDomainOwnable3_Test:test_constructor_succeeds() (gas: 10605)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28289) CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notMessenger_reverts() (gas: 28363)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 73970) CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner2_reverts() (gas: 74040)
CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32000) CrossDomainOwnable3_Test:test_crossDomainOnlyOwner_notOwner_reverts() (gas: 32096)
CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91527) CrossDomainOwnable3_Test:test_crossDomainTransferOwnership_succeeds() (gas: 91581)
CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13215) CrossDomainOwnable3_Test:test_localOnlyOwner_notOwner_reverts() (gas: 13260)
CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35242) CrossDomainOwnable3_Test:test_localOnlyOwner_succeeds() (gas: 35271)
CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52084) CrossDomainOwnable3_Test:test_localTransferOwnership_succeeds() (gas: 52164)
CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48610) CrossDomainOwnable3_Test:test_transferOwnershipNoLocal_succeeds() (gas: 48712)
CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12037) CrossDomainOwnable3_Test:test_transferOwnership_noLocalZeroAddress_reverts() (gas: 12090)
CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13437) CrossDomainOwnable3_Test:test_transferOwnership_notOwner_reverts() (gas: 13460)
CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12081) CrossDomainOwnable3_Test:test_transferOwnership_zeroAddress_reverts() (gas: 12155)
CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81417) CrossDomainOwnableThroughPortal_Test:test_depositTransaction_crossDomainOwner_succeeds() (gas: 81556)
CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597) CrossDomainOwnable_Test:test_onlyOwner_notOwner_reverts() (gas: 10597)
CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883) CrossDomainOwnable_Test:test_onlyOwner_succeeds() (gas: 34883)
DelayedVetoable_Getters_Test:test_getters() (gas: 24466) DelayedVetoable_Getters_Test:test_getters() (gas: 24620)
DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36220) DelayedVetoable_Getters_TestFail:test_getters_notZeroAddress_reverts() (gas: 36289)
DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 21867) DelayedVetoable_HandleCall_TestFail:test_handleCall_unauthorizedInitiation_reverts() (gas: 15165)
DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582) DeployerWhitelist_Test:test_owner_succeeds() (gas: 7582)
DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395) DeployerWhitelist_Test:test_storageSlots_succeeds() (gas: 33395)
DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12581) DisputeGameFactory_Owner_Test:test_owner_succeeds() (gas: 12611)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16042) DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_reverts() (gas: 16143)
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44301) DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44346)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15974)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18738)
Drippie_Test:test_create_calledTwice_reverts() (gas: 168953) Drippie_Test:test_create_calledTwice_reverts() (gas: 168953)
Drippie_Test:test_create_succeeds() (gas: 183401) Drippie_Test:test_create_succeeds() (gas: 183401)
Drippie_Test:test_drip_amount_succeeds() (gas: 285353) Drippie_Test:test_drip_amount_succeeds() (gas: 285353)
...@@ -89,218 +89,219 @@ FaucetTest:test_nonAdmin_drip_fails() (gas: 262520) ...@@ -89,218 +89,219 @@ FaucetTest:test_nonAdmin_drip_fails() (gas: 262520)
FaucetTest:test_receive_succeeds() (gas: 17401) FaucetTest:test_receive_succeeds() (gas: 17401)
FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145) FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145)
FaucetTest:test_withdraw_succeeds() (gas: 78359) FaucetTest:test_withdraw_succeeds() (gas: 78359)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 660000) FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 660030)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 666860) FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 666890)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 663563) FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 663593)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 666736) FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 666766)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 666049) FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 666079)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 652764) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 652788)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 658252) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 658276)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655614) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 655638)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656552) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 656576)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656003) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 656027)
FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642642) FaultDisputeGame_Test:test_addLocalData_static_succeeds() (gas: 642441)
FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10409) FaultDisputeGame_Test:test_createdAt_succeeds() (gas: 10476)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32328) FaultDisputeGame_Test:test_extraData_succeeds() (gas: 32422)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32777) FaultDisputeGame_Test:test_gameData_succeeds() (gas: 32857)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8265) FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8302)
FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57646) FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 57779)
FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 210650) FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 213868)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228466) FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228488)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594025) FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 594294)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23175) FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 23200)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13300) FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13325)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147367) FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 147396)
FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556831) FaultDisputeGame_Test:test_move_duplicateClaimsDifferentSubgames_succeeds() (gas: 556844)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585853) FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 585884)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10980) FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 11019)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24644) FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24674)
FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 151915) FaultDisputeGame_Test:test_move_simpleAttack_succeeds() (gas: 152017)
FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269432) FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 269483)
FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272334) FaultDisputeGame_Test:test_resolve_claimAlreadyResolved_reverts() (gas: 272368)
FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586606) FaultDisputeGame_Test:test_resolve_claimAtMaxDepthAlreadyResolved_reverts() (gas: 586621)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9754) FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9785)
FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309015) FaultDisputeGame_Test:test_resolve_outOfOrderResolution_reverts() (gas: 309002)
FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139090) FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 139125)
FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15884) FaultDisputeGame_Test:test_resolve_rootUncontestedButUnresolved_reverts() (gas: 15923)
FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18428) FaultDisputeGame_Test:test_resolve_rootUncontestedClockNotExpired_succeeds() (gas: 18431)
FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51410) FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 51487)
FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498406) FaultDisputeGame_Test:test_resolve_stepReached_succeeds() (gas: 498467)
FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443357) FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 443396)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8232) FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8247)
FeeVault_Test:test_constructor_succeeds() (gas: 18185) FeeVault_Test:test_constructor_baseFeeVault_succeeds() (gas: 17428)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354421) FeeVault_Test:test_constructor_l1FeeVault_succeeds() (gas: 17396)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952628) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 354511)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 542325) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2952674)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4054518) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 544927)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 443561) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4057119)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3489288) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 446161)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 42714) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3491910)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 90658) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45337)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75076) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 88797)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 75697) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68320)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143181) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68973)
GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8325) GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 143295)
GasPriceOracle_Test:test_decimals_succeeds() (gas: 6167) GasPriceOracle_Test:test_baseFee_succeeds() (gas: 8348)
GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8294) GasPriceOracle_Test:test_decimals_succeeds() (gas: 6234)
GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10656) GasPriceOracle_Test:test_gasPrice_succeeds() (gas: 8340)
GasPriceOracle_Test:test_overhead_succeeds() (gas: 10636) GasPriceOracle_Test:test_l1BaseFee_succeeds() (gas: 10724)
GasPriceOracle_Test:test_scalar_succeeds() (gas: 10677) GasPriceOracle_Test:test_overhead_succeeds() (gas: 10681)
GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5910) GasPriceOracle_Test:test_scalar_succeeds() (gas: 10678)
GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5911) GasPriceOracle_Test:test_setGasPrice_doesNotExist_reverts() (gas: 5934)
GovernanceToken_Test:test_approve_succeeds() (gas: 133293) GasPriceOracle_Test:test_setL1BaseFee_doesNotExist_reverts() (gas: 5954)
GovernanceToken_Test:test_burnFrom_succeeds() (gas: 122733) GovernanceToken_Test:test_approve_succeeds() (gas: 138001)
GovernanceToken_Test:test_burn_succeeds() (gas: 114588) GovernanceToken_Test:test_burnFrom_succeeds() (gas: 127560)
GovernanceToken_Test:test_constructor_succeeds() (gas: 21298) GovernanceToken_Test:test_burn_succeeds() (gas: 119092)
GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 137008) GovernanceToken_Test:test_constructor_succeeds() (gas: 23757)
GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 137118) GovernanceToken_Test:test_decreaseAllowance_succeeds() (gas: 141912)
GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 17030) GovernanceToken_Test:test_increaseAllowance_succeeds() (gas: 142066)
GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 108592) GovernanceToken_Test:test_mint_fromNotOwner_reverts() (gas: 21421)
GovernanceToken_Test:test_transferFrom_succeeds() (gas: 146273) GovernanceToken_Test:test_mint_fromOwner_succeeds() (gas: 110895)
GovernanceToken_Test:test_transfer_succeeds() (gas: 138108) GovernanceToken_Test:test_transferFrom_succeeds() (gas: 151318)
Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 633) GovernanceToken_Test:test_transfer_succeeds() (gas: 142845)
Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 98390) Hashing_hashDepositSource_Test:test_hashDepositSource_succeeds() (gas: 700)
Initializer_Test:test_cannotReinitializeL1_succeeds() (gas: 101030)
L1BlockNumberTest:test_fallback_succeeds() (gas: 18655) L1BlockNumberTest:test_fallback_succeeds() (gas: 18655)
L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10625) L1BlockNumberTest:test_getL1BlockNumber_succeeds() (gas: 10625)
L1BlockNumberTest:test_receive_succeeds() (gas: 25384) L1BlockNumberTest:test_receive_succeeds() (gas: 25384)
L1BlockTest:test_basefee_succeeds() (gas: 7554) L1BlockTest:test_basefee_succeeds() (gas: 7599)
L1BlockTest:test_hash_succeeds() (gas: 7576) L1BlockTest:test_hash_succeeds() (gas: 7738)
L1BlockTest:test_number_succeeds() (gas: 7629) L1BlockTest:test_number_succeeds() (gas: 7674)
L1BlockTest:test_sequenceNumber_succeeds() (gas: 7630) L1BlockTest:test_sequenceNumber_succeeds() (gas: 7676)
L1BlockTest:test_timestamp_succeeds() (gas: 7640) L1BlockTest:test_timestamp_succeeds() (gas: 7663)
L1BlockTest:test_updateValues_succeeds() (gas: 60482) L1BlockTest:test_updateValues_succeeds() (gas: 63327)
L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24781) L1CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 24803)
L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49384) L1CrossDomainMessenger_Test:test_relayMessage_legacyOldReplay_reverts() (gas: 49407)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239657) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailureThenSuccess_reverts() (gas: 239750)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233416) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterFailure_succeeds() (gas: 233442)
L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126344) L1CrossDomainMessenger_Test:test_relayMessage_legacyRetryAfterSuccess_reverts() (gas: 126347)
L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79599) L1CrossDomainMessenger_Test:test_relayMessage_legacy_succeeds() (gas: 79644)
L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227456) L1CrossDomainMessenger_Test:test_relayMessage_retryAfterFailure_succeeds() (gas: 227503)
L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76590) L1CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 76636)
L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60779) L1CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 60822)
L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12343) L1CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 12388)
L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33133) L1CrossDomainMessenger_Test:test_replayMessage_withValue_reverts() (gas: 33178)
L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392933) L1CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 392934)
L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669172) L1CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 1669270)
L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87853) L1CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 87957)
L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24253) L1CrossDomainMessenger_Test:test_xDomainSender_notSet_reverts() (gas: 24282)
L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62686) L1ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 62759)
L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37285) L1ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 37376)
L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455269) L1ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 455270)
L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 70997) L1ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 71000)
L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35681) L1ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 35752)
L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60561) L1ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 60589)
L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35204) L1ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 35188)
L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 454966) L1ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 455010)
L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70823) L1ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 70870)
L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18861) L1ERC721Bridge_Test:test_constructor_succeeds() (gas: 18927)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29475) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notEscrowed_reverts() (gas: 29495)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27220) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27239)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23241) L1ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23305)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 24990) L1ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 25035)
L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425245) L1ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 425309)
L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 514756) L1StandardBridge_BridgeETHTo_Test:test_bridgeETHTo_succeeds() (gas: 517214)
L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 501934) L1StandardBridge_BridgeETH_Test:test_bridgeETH_succeeds() (gas: 504458)
L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 720272) L1StandardBridge_DepositERC20To_Test:test_depositERC20To_succeeds() (gas: 723450)
L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 717849) L1StandardBridge_DepositERC20_Test:test_depositERC20_succeeds() (gas: 720986)
L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 22276) L1StandardBridge_DepositERC20_TestFail:test_depositERC20_notEoa_reverts() (gas: 24955)
L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 514789) L1StandardBridge_DepositETHTo_Test:test_depositETHTo_succeeds() (gas: 517311)
L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 502006) L1StandardBridge_DepositETH_Test:test_depositETH_succeeds() (gas: 504597)
L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 40759) L1StandardBridge_DepositETH_TestFail:test_depositETH_notEoa_reverts() (gas: 43427)
L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 54102) L1StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 57849)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 36551) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 40320)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 36738) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 40461)
L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 36623) L1StandardBridge_FinalizeBridgeETH_TestFail:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 40347)
L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 498144) L1StandardBridge_FinalizeERC20Withdrawal_Test:test_finalizeERC20Withdrawal_succeeds() (gas: 503457)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 33452) L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notMessenger_reverts() (gas: 37182)
L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 34118) L1StandardBridge_FinalizeERC20Withdrawal_TestFail:test_finalizeERC20Withdrawal_notOtherBridge_reverts() (gas: 37849)
L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 64673) L1StandardBridge_FinalizeETHWithdrawal_Test:test_finalizeETHWithdrawal_succeeds() (gas: 70062)
L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 28383) L1StandardBridge_Getter_Test:test_getters_succeeds() (gas: 32693)
L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 27239) L1StandardBridge_Initialize_Test:test_initialize_succeeds() (gas: 30416)
L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 615130) L1StandardBridge_Receive_Test:test_receive_succeeds() (gas: 617691)
L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8477) L2CrossDomainMessenger_Test:test_messageVersion_succeeds() (gas: 8521)
L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191078) L2CrossDomainMessenger_Test:test_relayMessage_retry_succeeds() (gas: 191101)
L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48913) L2CrossDomainMessenger_Test:test_relayMessage_succeeds() (gas: 48936)
L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31136) L2CrossDomainMessenger_Test:test_relayMessage_toSystemContract_reverts() (gas: 31159)
L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11689) L2CrossDomainMessenger_Test:test_relayMessage_v2_reverts() (gas: 11756)
L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 123957) L2CrossDomainMessenger_Test:test_sendMessage_succeeds() (gas: 124025)
L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135812) L2CrossDomainMessenger_Test:test_sendMessage_twice_succeeds() (gas: 135887)
L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49230) L2CrossDomainMessenger_Test:test_xDomainMessageSender_reset_succeeds() (gas: 49311)
L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10590) L2CrossDomainMessenger_Test:test_xDomainSender_senderNotSet_reverts() (gas: 10686)
L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 31453) L2ERC721Bridge_Test:test_bridgeERC721To_localTokenZeroAddress_reverts() (gas: 26498)
L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 26854) L2ERC721Bridge_Test:test_bridgeERC721To_remoteTokenZeroAddress_reverts() (gas: 21837)
L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 157156) L2ERC721Bridge_Test:test_bridgeERC721To_succeeds() (gas: 152123)
L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 34489) L2ERC721Bridge_Test:test_bridgeERC721To_wrongOwner_reverts() (gas: 29472)
L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 27183) L2ERC721Bridge_Test:test_bridgeERC721_fromContract_reverts() (gas: 22216)
L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 29305) L2ERC721Bridge_Test:test_bridgeERC721_localTokenZeroAddress_reverts() (gas: 24332)
L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 24641) L2ERC721Bridge_Test:test_bridgeERC721_remoteTokenZeroAddress_reverts() (gas: 19674)
L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 154746) L2ERC721Bridge_Test:test_bridgeERC721_succeeds() (gas: 149764)
L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 34271) L2ERC721Bridge_Test:test_bridgeERC721_wrongOwner_reverts() (gas: 29304)
L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 21004) L2ERC721Bridge_Test:test_constructor_succeeds() (gas: 14660)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 38661) L2ERC721Bridge_Test:test_finalizeBridgeERC721_alreadyExists_reverts() (gas: 33650)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 246925) L2ERC721Bridge_Test:test_finalizeBridgeERC721_interfaceNotCompliant_reverts() (gas: 241398)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 27208) L2ERC721Bridge_Test:test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() (gas: 22193)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 23274) L2ERC721Bridge_Test:test_finalizeBridgeERC721_notViaLocalMessenger_reverts() (gas: 18282)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 27124) L2ERC721Bridge_Test:test_finalizeBridgeERC721_selfToken_reverts() (gas: 22113)
L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 179976) L2ERC721Bridge_Test:test_finalizeBridgeERC721_succeeds() (gas: 174514)
L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 23902) L2OutputOracleUpgradeable_Test:test_initValuesOnImpl_succeeds() (gas: 32612)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 46800) L2OutputOracleUpgradeable_Test:test_initValuesOnProxy_succeeds() (gas: 56622)
L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 15216) L2OutputOracleUpgradeable_Test:test_initializeImpl_alreadyInitialized_reverts() (gas: 24782)
L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 20216) L2OutputOracleUpgradeable_Test:test_initializeProxy_alreadyInitialized_reverts() (gas: 26380)
L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 187875) L2OutputOracleUpgradeable_Test:test_upgrading_succeeds() (gas: 191207)
L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 39022) L2OutputOracle_constructor_Test:test_constructor_l2BlockTimeZero_reverts() (gas: 44322)
L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 39032) L2OutputOracle_constructor_Test:test_constructor_submissionInterval_reverts() (gas: 44354)
L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 51777) L2OutputOracle_constructor_Test:test_constructor_succeeds() (gas: 61377)
L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12353) L2OutputOracle_constructor_Test:test_initialize_badTimestamp_reverts() (gas: 12388)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 217031) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_afterLatest_reverts() (gas: 226825)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 113258) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_finalized_reverts() (gas: 118642)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21018) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_ifNotChallenger_reverts() (gas: 21053)
L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 111651) L2OutputOracle_deleteOutputs_Test:test_deleteL2Outputs_nonExistent_reverts() (gas: 117047)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 307411) L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_multipleOutputs_succeeds() (gas: 318242)
L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 185564) L2OutputOracle_deleteOutputs_Test:test_deleteOutputs_singleOutput_succeeds() (gas: 193258)
L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 38198) L2OutputOracle_getter_Test:test_computeL2Timestamp_succeeds() (gas: 44553)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 269700) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() (gas: 277477)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17892) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_noOutputsExis_reverts() (gas: 17960)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 98188) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_previousBlock_succeeds() (gas: 103519)
L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 98096) L2OutputOracle_getter_Test:test_getL2OutputIndexAfter_sameBlock_succeeds() (gas: 103427)
L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 104600) L2OutputOracle_getter_Test:test_getL2Output_succeeds() (gas: 109954)
L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 99129) L2OutputOracle_getter_Test:test_latestBlockNumber_succeeds() (gas: 104504)
L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17447) L2OutputOracle_getter_Test:test_nextBlockNumber_succeeds() (gas: 17492)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 28812) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_emptyOutput_reverts() (gas: 34166)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 30792) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_futureTimetamp_reverts() (gas: 34240)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 27928) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_notProposer_reverts() (gas: 26076)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 103242) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_proposeAnotherOutput_succeeds() (gas: 109323)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 30526) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unexpectedBlockNumber_reverts() (gas: 33945)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 31526) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_unmatchedBlockhash_reverts() (gas: 34946)
L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 31129) L2OutputOracle_proposeL2Output_Test:test_proposeL2Output_wrongFork_reverts() (gas: 34466)
L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 97442) L2OutputOracle_proposeL2Output_Test:test_proposeWithBlockhashAndHeight_succeeds() (gas: 100845)
L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392297) L2StandardBridge_BridgeERC20To_Test:test_bridgeERC20To_succeeds() (gas: 392327)
L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392530) L2StandardBridge_BridgeERC20To_Test:test_withdrawTo_withdrawingERC20_succeeds() (gas: 392560)
L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387821) L2StandardBridge_BridgeERC20_Test:test_bridgeERC20_succeeds() (gas: 387960)
L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396094) L2StandardBridge_BridgeERC20_Test:test_bridgeLegacyERC20_succeeds() (gas: 396237)
L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396456) L2StandardBridge_BridgeERC20_Test:test_withdrawLegacyERC20_succeeds() (gas: 396580)
L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251807) L2StandardBridge_BridgeERC20_Test:test_withdraw_notEOA_reverts() (gas: 251901)
L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388103) L2StandardBridge_BridgeERC20_Test:test_withdraw_withdrawingERC20_succeeds() (gas: 388241)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26132) L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_incorrectValue_reverts() (gas: 26200)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26400) L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToMessenger_reverts() (gas: 26422)
L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26159) L2StandardBridge_Bridge_Test:test_finalizeBridgeETH_sendToSelf_reverts() (gas: 26227)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96091) L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingERC20_succeeds() (gas: 96126)
L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 94945) L2StandardBridge_Bridge_Test:test_finalizeDeposit_depositingETH_succeeds() (gas: 95023)
L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45528) L2StandardBridge_FinalizeBridgeETH_Test:test_finalizeBridgeETH_succeeds() (gas: 45610)
L2StandardBridge_Test:test_initialize_succeeds() (gas: 26316) L2StandardBridge_Test:test_initialize_succeeds() (gas: 28938)
L2StandardBridge_Test:test_receive_succeeds() (gas: 177125) L2StandardBridge_Test:test_receive_succeeds() (gas: 177147)
L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143366) L2StandardBridge_Test:test_withdraw_ether_succeeds() (gas: 143411)
L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16552) L2StandardBridge_Test:test_withdraw_insufficientValue_reverts() (gas: 16586)
LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10702) LegacyERC20ETH_Test:test_approve_doesNotExist_reverts() (gas: 10745)
LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10637) LegacyERC20ETH_Test:test_burn_doesNotExist_reverts() (gas: 10705)
LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6341) LegacyERC20ETH_Test:test_crossDomain_succeeds() (gas: 6400)
LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10724) LegacyERC20ETH_Test:test_decreaseAllowance_doesNotExist_reverts() (gas: 10747)
LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10690) LegacyERC20ETH_Test:test_increaseAllowance_doesNotExist_reverts() (gas: 10757)
LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15420) LegacyERC20ETH_Test:test_metadata_succeeds() (gas: 15795)
LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10627) LegacyERC20ETH_Test:test_mint_doesNotExist_reverts() (gas: 10672)
LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 12957) LegacyERC20ETH_Test:test_transferFrom_doesNotExist_reverts() (gas: 13002)
LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10755) LegacyERC20ETH_Test:test_transfer_doesNotExist_reverts() (gas: 10801)
LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34524) LegacyMessagePasser_Test:test_passMessageToL1_succeeds() (gas: 34629)
LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689) LibPosition_Test:test_pos_correctness_succeeds() (gas: 38689)
LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531) LivenessGuard_CheckAfterExecution_TestFails:test_checkAfterExecution_callerIsNotSafe_revert() (gas: 8531)
LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535) LivenessGuard_CheckTx_Test:test_checkTransaction_succeeds() (gas: 233535)
...@@ -329,81 +330,81 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRece ...@@ -329,81 +330,81 @@ LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasShownLivenessRece
LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047) LivenessModule_RemoveOwners_TestFail:test_removeOwners_ownerHasSignedRecently_reverts() (gas: 615047)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252) LivenessModule_RemoveOwners_TestFail:test_removeOwners_swapToFallbackOwner_reverts() (gas: 1278252)
LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954) LivenessModule_RemoveOwners_TestFail:test_removeOwners_wrongPreviousOwner_reverts() (gas: 73954)
MIPS_Test:test_add_succeeds() (gas: 122866) MIPS_Test:test_add_succeeds() (gas: 123021)
MIPS_Test:test_addiSign_succeeds() (gas: 122857) MIPS_Test:test_addiSign_succeeds() (gas: 122946)
MIPS_Test:test_addi_succeeds() (gas: 123054) MIPS_Test:test_addi_succeeds() (gas: 123166)
MIPS_Test:test_addu_succeeds() (gas: 122908) MIPS_Test:test_addu_succeeds() (gas: 123041)
MIPS_Test:test_addui_succeeds() (gas: 123116) MIPS_Test:test_addui_succeeds() (gas: 123162)
MIPS_Test:test_and_succeeds() (gas: 122927) MIPS_Test:test_and_succeeds() (gas: 123017)
MIPS_Test:test_andi_succeeds() (gas: 122860) MIPS_Test:test_andi_succeeds() (gas: 122949)
MIPS_Test:test_beq_succeeds() (gas: 203293) MIPS_Test:test_beq_succeeds() (gas: 203427)
MIPS_Test:test_bgez_succeeds() (gas: 122153) MIPS_Test:test_bgez_succeeds() (gas: 122265)
MIPS_Test:test_bgtz_succeeds() (gas: 122074) MIPS_Test:test_bgtz_succeeds() (gas: 122205)
MIPS_Test:test_blez_succeeds() (gas: 122030) MIPS_Test:test_blez_succeeds() (gas: 122142)
MIPS_Test:test_bltz_succeeds() (gas: 122173) MIPS_Test:test_bltz_succeeds() (gas: 122262)
MIPS_Test:test_bne_succeeds() (gas: 122239) MIPS_Test:test_bne_succeeds() (gas: 122351)
MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86448) MIPS_Test:test_branch_inDelaySlot_fails() (gas: 86536)
MIPS_Test:test_brk_succeeds() (gas: 122543) MIPS_Test:test_brk_succeeds() (gas: 122655)
MIPS_Test:test_clo_succeeds() (gas: 122595) MIPS_Test:test_clo_succeeds() (gas: 122707)
MIPS_Test:test_clone_succeeds() (gas: 122496) MIPS_Test:test_clone_succeeds() (gas: 122563)
MIPS_Test:test_clz_succeeds() (gas: 123066) MIPS_Test:test_clz_succeeds() (gas: 123177)
MIPS_Test:test_div_succeeds() (gas: 123045) MIPS_Test:test_div_succeeds() (gas: 123134)
MIPS_Test:test_divu_succeeds() (gas: 123030) MIPS_Test:test_divu_succeeds() (gas: 123142)
MIPS_Test:test_exit_succeeds() (gas: 122545) MIPS_Test:test_exit_succeeds() (gas: 122657)
MIPS_Test:test_fcntl_succeeds() (gas: 204775) MIPS_Test:test_fcntl_succeeds() (gas: 204842)
MIPS_Test:test_illegal_instruction_fails() (gas: 91911) MIPS_Test:test_illegal_instruction_fails() (gas: 92045)
MIPS_Test:test_invalid_root_fails() (gas: 436085) MIPS_Test:test_invalid_root_fails() (gas: 436216)
MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121183) MIPS_Test:test_jal_nonzeroRegion_succeeds() (gas: 121273)
MIPS_Test:test_jal_succeeds() (gas: 121172) MIPS_Test:test_jal_succeeds() (gas: 121217)
MIPS_Test:test_jalr_succeeds() (gas: 122291) MIPS_Test:test_jalr_succeeds() (gas: 122425)
MIPS_Test:test_jr_succeeds() (gas: 121985) MIPS_Test:test_jr_succeeds() (gas: 122096)
MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85816) MIPS_Test:test_jump_inDelaySlot_fails() (gas: 85928)
MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120927) MIPS_Test:test_jump_nonzeroRegion_succeeds() (gas: 120972)
MIPS_Test:test_jump_succeeds() (gas: 120857) MIPS_Test:test_jump_succeeds() (gas: 120969)
MIPS_Test:test_lb_succeeds() (gas: 128098) MIPS_Test:test_lb_succeeds() (gas: 128187)
MIPS_Test:test_lbu_succeeds() (gas: 127996) MIPS_Test:test_lbu_succeeds() (gas: 128085)
MIPS_Test:test_lh_succeeds() (gas: 128119) MIPS_Test:test_lh_succeeds() (gas: 128229)
MIPS_Test:test_lhu_succeeds() (gas: 128036) MIPS_Test:test_lhu_succeeds() (gas: 128103)
MIPS_Test:test_ll_succeeds() (gas: 128258) MIPS_Test:test_ll_succeeds() (gas: 128303)
MIPS_Test:test_lui_succeeds() (gas: 122139) MIPS_Test:test_lui_succeeds() (gas: 122293)
MIPS_Test:test_lw_succeeds() (gas: 127887) MIPS_Test:test_lw_succeeds() (gas: 127976)
MIPS_Test:test_lwl_succeeds() (gas: 242938) MIPS_Test:test_lwl_succeeds() (gas: 243161)
MIPS_Test:test_lwr_succeeds() (gas: 243226) MIPS_Test:test_lwr_succeeds() (gas: 243428)
MIPS_Test:test_mfhi_succeeds() (gas: 122500) MIPS_Test:test_mfhi_succeeds() (gas: 122634)
MIPS_Test:test_mflo_succeeds() (gas: 122629) MIPS_Test:test_mflo_succeeds() (gas: 122718)
MIPS_Test:test_mmap_succeeds() (gas: 119528) MIPS_Test:test_mmap_succeeds() (gas: 119637)
MIPS_Test:test_movn_succeeds() (gas: 203965) MIPS_Test:test_movn_succeeds() (gas: 204054)
MIPS_Test:test_movz_succeeds() (gas: 203833) MIPS_Test:test_movz_succeeds() (gas: 203923)
MIPS_Test:test_mthi_succeeds() (gas: 122544) MIPS_Test:test_mthi_succeeds() (gas: 122678)
MIPS_Test:test_mtlo_succeeds() (gas: 122652) MIPS_Test:test_mtlo_succeeds() (gas: 122741)
MIPS_Test:test_mul_succeeds() (gas: 122144) MIPS_Test:test_mul_succeeds() (gas: 122256)
MIPS_Test:test_mult_succeeds() (gas: 122848) MIPS_Test:test_mult_succeeds() (gas: 122959)
MIPS_Test:test_multu_succeeds() (gas: 122885) MIPS_Test:test_multu_succeeds() (gas: 123018)
MIPS_Test:test_nor_succeeds() (gas: 122977) MIPS_Test:test_nor_succeeds() (gas: 123109)
MIPS_Test:test_or_succeeds() (gas: 122934) MIPS_Test:test_or_succeeds() (gas: 123024)
MIPS_Test:test_ori_succeeds() (gas: 122937) MIPS_Test:test_ori_succeeds() (gas: 123026)
MIPS_Test:test_preimage_read_succeeds() (gas: 235349) MIPS_Test:test_preimage_read_succeeds() (gas: 235502)
MIPS_Test:test_preimage_write_succeeds() (gas: 127485) MIPS_Test:test_preimage_write_succeeds() (gas: 127574)
MIPS_Test:test_prestate_exited_succeeds() (gas: 113726) MIPS_Test:test_prestate_exited_succeeds() (gas: 113835)
MIPS_Test:test_sb_succeeds() (gas: 161369) MIPS_Test:test_sb_succeeds() (gas: 161547)
MIPS_Test:test_sc_succeeds() (gas: 161552) MIPS_Test:test_sc_succeeds() (gas: 161752)
MIPS_Test:test_sh_succeeds() (gas: 161406) MIPS_Test:test_sh_succeeds() (gas: 161606)
MIPS_Test:test_sll_succeeds() (gas: 122105) MIPS_Test:test_sll_succeeds() (gas: 122238)
MIPS_Test:test_sllv_succeeds() (gas: 122334) MIPS_Test:test_sllv_succeeds() (gas: 122402)
MIPS_Test:test_slt_succeeds() (gas: 205160) MIPS_Test:test_slt_succeeds() (gas: 205250)
MIPS_Test:test_sltu_succeeds() (gas: 123151) MIPS_Test:test_sltu_succeeds() (gas: 123285)
MIPS_Test:test_sra_succeeds() (gas: 122356) MIPS_Test:test_sra_succeeds() (gas: 122468)
MIPS_Test:test_srav_succeeds() (gas: 122624) MIPS_Test:test_srav_succeeds() (gas: 122758)
MIPS_Test:test_srl_succeeds() (gas: 122187) MIPS_Test:test_srl_succeeds() (gas: 122276)
MIPS_Test:test_srlv_succeeds() (gas: 122352) MIPS_Test:test_srlv_succeeds() (gas: 122506)
MIPS_Test:test_step_abi_succeeds() (gas: 58467) MIPS_Test:test_step_abi_succeeds() (gas: 58532)
MIPS_Test:test_sub_succeeds() (gas: 122961) MIPS_Test:test_sub_succeeds() (gas: 123007)
MIPS_Test:test_subu_succeeds() (gas: 122958) MIPS_Test:test_subu_succeeds() (gas: 123070)
MIPS_Test:test_sw_succeeds() (gas: 161381) MIPS_Test:test_sw_succeeds() (gas: 161604)
MIPS_Test:test_swl_succeeds() (gas: 161442) MIPS_Test:test_swl_succeeds() (gas: 161621)
MIPS_Test:test_swr_succeeds() (gas: 161517) MIPS_Test:test_swr_succeeds() (gas: 161696)
MIPS_Test:test_xor_succeeds() (gas: 122962) MIPS_Test:test_xor_succeeds() (gas: 123029)
MIPS_Test:test_xori_succeeds() (gas: 123014) MIPS_Test:test_xori_succeeds() (gas: 123147)
MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733) MerkleTrie_get_Test:test_get_corruptedProof_reverts() (gas: 5733)
MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889) MerkleTrie_get_Test:test_get_extraProofElements_reverts() (gas: 58889)
MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845) MerkleTrie_get_Test:test_get_invalidDataRemainder_reverts() (gas: 35845)
...@@ -425,77 +426,77 @@ MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802) ...@@ -425,77 +426,77 @@ MerkleTrie_get_Test:test_get_validProof9_succeeds() (gas: 48802)
MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50730) MerkleTrie_get_Test:test_get_wrongKeyProof_reverts() (gas: 50730)
MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41684) MerkleTrie_get_Test:test_get_zeroBranchValueLength_reverts() (gas: 41684)
MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632) MerkleTrie_get_Test:test_get_zeroLengthKey_reverts() (gas: 3632)
MintManager_constructor_Test:test_constructor_succeeds() (gas: 10579) MintManager_constructor_Test:test_constructor_succeeds() (gas: 10623)
MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148117) MintManager_mint_Test:test_mint_afterPeriodElapsed_succeeds() (gas: 148184)
MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140433) MintManager_mint_Test:test_mint_beforePeriodElapsed_reverts() (gas: 140479)
MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 10987) MintManager_mint_Test:test_mint_fromNotOwner_reverts() (gas: 11054)
MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137219) MintManager_mint_Test:test_mint_fromOwner_succeeds() (gas: 137330)
MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142523) MintManager_mint_Test:test_mint_moreThanCap_reverts() (gas: 142590)
MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 10974) MintManager_upgrade_Test:test_upgrade_fromNotOwner_reverts() (gas: 11041)
MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23434) MintManager_upgrade_Test:test_upgrade_fromOwner_succeeds() (gas: 23509)
MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11003) MintManager_upgrade_Test:test_upgrade_toZeroAddress_reverts() (gas: 11070)
Multichain:test_script_succeeds() (gas: 3078) Multichain:test_script_succeeds() (gas: 3078)
OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7621) OptimismMintableERC20_Test:test_bridge_succeeds() (gas: 7695)
OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11164) OptimismMintableERC20_Test:test_burn_notBridge_reverts() (gas: 11209)
OptimismMintableERC20_Test:test_burn_succeeds() (gas: 50996) OptimismMintableERC20_Test:test_burn_succeeds() (gas: 51050)
OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7787) OptimismMintableERC20_Test:test_erc165_supportsInterface_succeeds() (gas: 7832)
OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7621) OptimismMintableERC20_Test:test_l1Token_succeeds() (gas: 7717)
OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7621) OptimismMintableERC20_Test:test_l2Bridge_succeeds() (gas: 7672)
OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14322) OptimismMintableERC20_Test:test_legacy_succeeds() (gas: 14518)
OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11165) OptimismMintableERC20_Test:test_mint_notBridge_reverts() (gas: 11187)
OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63544) OptimismMintableERC20_Test:test_mint_succeeds() (gas: 63633)
OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7667) OptimismMintableERC20_Test:test_remoteToken_succeeds() (gas: 7718)
OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8381) OptimismMintableERC721Factory_Test:test_constructor_succeeds() (gas: 8402)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800045) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_sameTwice_reverts() (gas: 8937393460516800078)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316169) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_succeeds() (gas: 2316523)
OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9493) OptimismMintableERC721Factory_Test:test_createOptimismMintableERC721_zeroRemoteToken_reverts() (gas: 9542)
OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136966) OptimismMintableERC721_Test:test_burn_notBridge_reverts() (gas: 136967)
OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118832) OptimismMintableERC721_Test:test_burn_succeeds() (gas: 118874)
OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24162) OptimismMintableERC721_Test:test_constructor_succeeds() (gas: 24516)
OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11121) OptimismMintableERC721_Test:test_safeMint_notBridge_reverts() (gas: 11209)
OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140547) OptimismMintableERC721_Test:test_safeMint_succeeds() (gas: 140599)
OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9005) OptimismMintableERC721_Test:test_supportsInterfaces_succeeds() (gas: 9028)
OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163441) OptimismMintableERC721_Test:test_tokenURI_succeeds() (gas: 163605)
OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9760) OptimismMintableTokenFactory_Test:test_bridge_succeeds() (gas: 9856)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142536) OptimismMintableTokenFactory_Test:test_createStandardL2TokenWithDecimals_succeeds() (gas: 1142627)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9570) OptimismMintableTokenFactory_Test:test_createStandardL2Token_remoteIsZero_reverts() (gas: 9621)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764385) OptimismMintableTokenFactory_Test:test_createStandardL2Token_sameTwice_reverts() (gas: 8937393460516764416)
OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142527) OptimismMintableTokenFactory_Test:test_createStandardL2Token_succeeds() (gas: 1142596)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 11178) OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 14593)
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16111) OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 16206)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26781) OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_succeeds() (gas: 26711)
OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 191521) OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_succeeds() (gas: 186086)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178667) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 178734)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182306) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 182285)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41780) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 41781)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 173953) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 174020)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181161) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 181245)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154740) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 154785)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219208) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 219305)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220983) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 220962)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38706) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_paused_reverts() (gas: 38751)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209679) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_succeeds() (gas: 209658)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162676) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 8797746687696162678)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171302) OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 171369)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85805) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85806)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111317) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidWithdrawalProof_reverts() (gas: 111361)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52973) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 52996)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58846) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_paused_reverts() (gas: 58892)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297494) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() (gas: 297539)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227596) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() (gas: 227641)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166699) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 166744)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154430) OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() (gas: 154475)
OptimismPortal_Test:test_constructor_succeeds() (gas: 28164) OptimismPortal_Test:test_constructor_succeeds() (gas: 33454)
OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14281) OptimismPortal_Test:test_depositTransaction_contractCreation_reverts() (gas: 14300)
OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512200) OptimismPortal_Test:test_depositTransaction_largeData_reverts() (gas: 512218)
OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14528) OptimismPortal_Test:test_depositTransaction_smallGasLimit_reverts() (gas: 14556)
OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127594) OptimismPortal_Test:test_isOutputFinalized_succeeds() (gas: 127617)
OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17597) OptimismPortal_Test:test_minimumGasLimit_succeeds() (gas: 17639)
OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487) OptimismPortal_Test:test_pause_onlyGuardian_reverts() (gas: 24487)
OptimismPortal_Test:test_pause_succeeds() (gas: 27344) OptimismPortal_Test:test_pause_succeeds() (gas: 27329)
OptimismPortal_Test:test_receive_succeeds() (gas: 127564) OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 40883)
OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31514) OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 31580)
OptimismPortal_Test:test_unpause_succeeds() (gas: 27451) OptimismPortal_Test:test_unpause_succeeds() (gas: 27349)
OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407) OptimistAllowlistTest:test_constructor_succeeds() (gas: 16407)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49650)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254) OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49254)
...@@ -549,10 +550,10 @@ PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76076) ...@@ -549,10 +550,10 @@ PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76076)
PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718) PreimageOracle_Test:test_loadLocalData_multipleContexts_succeeds() (gas: 147718)
PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905) PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75905)
PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882) PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8882)
ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 52181) ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 41623)
ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 32301) ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 45024)
ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15508) ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15531)
ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15520) ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15587)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440) ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 36440)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675) ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084) ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084)
...@@ -661,33 +662,33 @@ ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816) ...@@ -661,33 +662,33 @@ ResourceMetering_Test:test_meter_useMax_succeeds() (gas: 20020816)
ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549) ResourceMetering_Test:test_meter_useMoreThanMax_reverts() (gas: 19549)
SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598) SafeCall_Test:test_callWithMinGas_noLeakageHigh_succeeds() (gas: 1021670598)
SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688) SafeCall_Test:test_callWithMinGas_noLeakageLow_succeeds() (gas: 1095190688)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 78333) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2_succeeds() (gas: 80640)
SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 46791) SequencerFeeVault_L2Withdrawal_Test:test_withdraw_toL2recipientReverts_fails() (gas: 48926)
SequencerFeeVault_Test:test_constructor_succeeds() (gas: 5526) SequencerFeeVault_Test:test_constructor_succeeds() (gas: 7705)
SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 5464) SequencerFeeVault_Test:test_minWithdrawalAmount_succeeds() (gas: 12816)
SequencerFeeVault_Test:test_receive_succeeds() (gas: 17373) SequencerFeeVault_Test:test_receive_succeeds() (gas: 17395)
SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9332) SequencerFeeVault_Test:test_withdraw_notEnough_reverts() (gas: 9399)
SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 171675) SequencerFeeVault_Test:test_withdraw_toL1_succeeds() (gas: 618343)
SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11549) SetPrevBaseFee_Test:test_setPrevBaseFee_succeeds() (gas: 11595)
StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 49936) StandardBridge_Stateless_Test:test_isCorrectTokenPair_succeeds() (gas: 50181)
StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33072) StandardBridge_Stateless_Test:test_isOptimismMintableERC20_succeeds() (gas: 33142)
Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31821, ~: 31821) Storage_Roundtrip_Test:test_setGetAddress_succeeds(bytes32,address) (runs: 64, μ: 31510, ~: 31821)
Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598) Storage_Roundtrip_Test:test_setGetBytes32_succeeds(bytes32,bytes32) (runs: 64, μ: 31598, ~: 31598)
Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664) Storage_Roundtrip_Test:test_setGetUint_succeeds(bytes32,uint256) (runs: 64, μ: 30731, ~: 31664)
SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 71972) SystemConfig_Initialize_Test:test_initialize_events_succeeds() (gas: 88188)
SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 81247) SystemConfig_Initialize_Test:test_initialize_startBlockNoop_reverts() (gas: 77253)
SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 65143) SystemConfig_Initialize_Test:test_initialize_startBlockOverride_succeeds() (gas: 81116)
SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 64968) SystemConfig_Initialize_Test:test_initialize_values_succeeds() (gas: 88501)
SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 57177) SystemConfig_Initialize_TestFail:test_initialize_lowGasLimit_reverts() (gas: 59900)
SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15607) SystemConfig_Setters_TestFail:test_setBatcherHash_notOwner_reverts() (gas: 15675)
SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15577) SystemConfig_Setters_TestFail:test_setGasConfig_notOwner_reverts() (gas: 15644)
SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15676) SystemConfig_Setters_TestFail:test_setGasLimit_notOwner_reverts() (gas: 15743)
SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18541) SystemConfig_Setters_TestFail:test_setResourceConfig_badMinMax_reverts() (gas: 18592)
SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21142) SystemConfig_Setters_TestFail:test_setResourceConfig_badPrecision_reverts() (gas: 21216)
SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22146) SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: 22264)
SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16799) SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 16867)
SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18578) SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 18629)
SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15590) SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 15658)
TransactorTest:test_call_succeeds() (gas: 26709) TransactorTest:test_call_succeeds() (gas: 26709)
TransactorTest:test_call_unauthorized_reverts() (gas: 18117) TransactorTest:test_call_unauthorized_reverts() (gas: 18117)
TransactorTest:test_constructor_succeeds() (gas: 9739) TransactorTest:test_constructor_succeeds() (gas: 9739)
......
...@@ -59,4 +59,3 @@ runs = 512 ...@@ -59,4 +59,3 @@ runs = 512
[profile.lite] [profile.lite]
optimizer = false optimizer = false
# `CrossDomainMessenger` Invariants # `CrossDomainMessenger` Invariants
## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert. ## A call to `relayMessage` should succeed if at least the minimum gas limit can be supplied to the target context, there is enough gas to complete execution of `relayMessage` after the target context's execution is finished, and the target context did not revert.
**Test:** [`CrossDomainMessenger.t.sol#L136`](../test/invariants/CrossDomainMessenger.t.sol#L136) **Test:** [`CrossDomainMessenger.t.sol#L137`](../test/invariants/CrossDomainMessenger.t.sol#L137)
There are two minimum gas limits here: There are two minimum gas limits here:
- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. - The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit.
- The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract. - The inner min gas limit is for the call from the `L1CrossDomainMessenger` to the target contract.
## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished. ## A call to `relayMessage` should assign the message hash to the `failedMessages` mapping if not enough gas is supplied to forward `minGasLimit` to the target context or if there is not enough gas to complete execution of `relayMessage` after the target context's execution is finished.
**Test:** [`CrossDomainMessenger.t.sol#L169`](../test/invariants/CrossDomainMessenger.t.sol#L169) **Test:** [`CrossDomainMessenger.t.sol#L170`](../test/invariants/CrossDomainMessenger.t.sol#L170)
There are two minimum gas limits here: There are two minimum gas limits here:
- The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit. - The outer min gas limit is for the call from the `OptimismPortal` to the `L1CrossDomainMessenger`, and it can be retrieved by calling the xdm's `baseGas` function with the `message` and inner limit.
......
# `OptimismPortal` Invariants # `OptimismPortal` Invariants
## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`. ## Deposits of any value should always succeed unless `_to` = `address(0)` or `_isCreation` = `true`.
**Test:** [`OptimismPortal.t.sol#L148`](../test/invariants/OptimismPortal.t.sol#L148) **Test:** [`OptimismPortal.t.sol#L151`](../test/invariants/OptimismPortal.t.sol#L151)
All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed. All deposits, barring creation transactions and transactions sent to `address(0)`, should always succeed.
## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed. ## `finalizeWithdrawalTransaction` should revert if the finalization period has not elapsed.
**Test:** [`OptimismPortal.t.sol#L171`](../test/invariants/OptimismPortal.t.sol#L171) **Test:** [`OptimismPortal.t.sol#L174`](../test/invariants/OptimismPortal.t.sol#L174)
A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed. A withdrawal that has been proven should not be able to be finalized until after the finalization period has elapsed.
## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized. ## `finalizeWithdrawalTransaction` should revert if the withdrawal has already been finalized.
**Test:** [`OptimismPortal.t.sol#L201`](../test/invariants/OptimismPortal.t.sol#L201) **Test:** [`OptimismPortal.t.sol#L204`](../test/invariants/OptimismPortal.t.sol#L204)
Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice. Ensures that there is no chain of calls that can be made that allows a withdrawal to be finalized twice.
## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. ## A withdrawal should **always** be able to be finalized `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.
**Test:** [`OptimismPortal.t.sol#L230`](../test/invariants/OptimismPortal.t.sol#L230) **Test:** [`OptimismPortal.t.sol#L233`](../test/invariants/OptimismPortal.t.sol#L233)
This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven. This invariant asserts that there is no chain of calls that can be made that will prevent a withdrawal from being finalized exactly `FINALIZATION_PERIOD_SECONDS` after it was successfully proven.
\ No newline at end of file
...@@ -4,19 +4,21 @@ pragma solidity 0.8.15; ...@@ -4,19 +4,21 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { Types } from "src/libraries/Types.sol";
// Free function for setting the prevBaseFee param in the OptimismPortal. // Free function for setting the prevBaseFee param in the OptimismPortal.
function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) { function setPrevBaseFee(Vm _vm, address _op, uint128 _prevBaseFee) {
_vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee)); _vm.store(address(_op), bytes32(uint256(1)), bytes32((block.number << 192) | _prevBaseFee));
} }
contract SetPrevBaseFee_Test is Portal_Initializer { contract SetPrevBaseFee_Test is CommonTest {
function test_setPrevBaseFee_succeeds() external { function test_setPrevBaseFee_succeeds() external {
setPrevBaseFee(vm, address(op), 100 gwei); setPrevBaseFee(vm, address(optimismPortal), 100 gwei);
(uint128 prevBaseFee,, uint64 prevBlockNum) = op.params(); (uint128 prevBaseFee,, uint64 prevBlockNum) = optimismPortal.params();
assertEq(uint256(prevBaseFee), 100 gwei); assertEq(uint256(prevBaseFee), 100 gwei);
assertEq(uint256(prevBlockNum), block.number); assertEq(uint256(prevBlockNum), block.number);
} }
...@@ -27,7 +29,7 @@ contract SetPrevBaseFee_Test is Portal_Initializer { ...@@ -27,7 +29,7 @@ contract SetPrevBaseFee_Test is Portal_Initializer {
// so that they are nothing more than the call we want measure the gas cost of. // so that they are nothing more than the call we want measure the gas cost of.
// In order to achieve this we make no assertions, and handle everything else in the setUp() // In order to achieve this we make no assertions, and handle everything else in the setUp()
// function. // function.
contract GasBenchMark_OptimismPortal is Portal_Initializer { contract GasBenchMark_OptimismPortal is CommonTest {
// Reusable default values for a test withdrawal // Reusable default values for a test withdrawal
Types.WithdrawalTransaction _defaultTx; Types.WithdrawalTransaction _defaultTx;
...@@ -61,61 +63,64 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer { ...@@ -61,61 +63,64 @@ contract GasBenchMark_OptimismPortal is Portal_Initializer {
messagePasserStorageRoot: _storageRoot, messagePasserStorageRoot: _storageRoot,
latestBlockhash: bytes32(uint256(0)) latestBlockhash: bytes32(uint256(0))
}); });
_proposedBlockNumber = oracle.nextBlockNumber(); _proposedBlockNumber = l2OutputOracle.nextBlockNumber();
_proposedOutputIndex = oracle.nextOutputIndex(); _proposedOutputIndex = l2OutputOracle.nextOutputIndex();
} }
// Get the system into a nice ready-to-use state. // Get the system into a nice ready-to-use state.
function setUp() public virtual override { function setUp() public virtual override {
// Configure the oracle to return the output root we've prepared. // Configure the oracle to return the output root we've prepared.
vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1);
vm.prank(oracle.PROPOSER()); vm.prank(l2OutputOracle.PROPOSER());
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(
l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS()
+ 1
);
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF); vm.deal(address(optimismPortal), 0xFFFFFFFF);
} }
function test_depositTransaction_benchmark() external { function test_depositTransaction_benchmark() external {
op.depositTransaction{ value: NON_ZERO_VALUE }( optimismPortal.depositTransaction{ value: 100 }(
NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA address(1), 0, 50000, false, hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000"
); );
} }
function test_depositTransaction_benchmark_1() external { function test_depositTransaction_benchmark_1() external {
setPrevBaseFee(vm, address(op), 1 gwei); setPrevBaseFee(vm, address(optimismPortal), 1 gwei);
op.depositTransaction{ value: NON_ZERO_VALUE }( optimismPortal.depositTransaction{ value: 100 }(
NON_ZERO_ADDRESS, ZERO_VALUE, NON_ZERO_GASLIMIT, false, NON_ZERO_DATA address(1), 0, 50000, false, hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000"
); );
} }
function test_proveWithdrawalTransaction_benchmark() external { function test_proveWithdrawalTransaction_benchmark() external {
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
} }
} }
contract GasBenchMark_L1CrossDomainMessenger is Messenger_Initializer { contract GasBenchMark_L1CrossDomainMessenger is Bridge_Initializer {
function test_sendMessage_benchmark_0() external { function test_sendMessage_benchmark_0() external {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 1 gwei); setPrevBaseFee(vm, address(optimismPortal), 1 gwei);
// The amount of data typically sent during a bridge deposit. // The amount of data typically sent during a bridge deposit.
bytes memory data = bytes memory data =
hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Messenger.sendMessage(bob, data, uint32(100)); l1CrossDomainMessenger.sendMessage(bob, data, uint32(100));
} }
function test_sendMessage_benchmark_1() external { function test_sendMessage_benchmark_1() external {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 10 gwei); setPrevBaseFee(vm, address(optimismPortal), 10 gwei);
// The amount of data typically sent during a bridge deposit. // The amount of data typically sent during a bridge deposit.
bytes memory data = bytes memory data =
hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Messenger.sendMessage(bob, data, uint32(100)); l1CrossDomainMessenger.sendMessage(bob, data, uint32(100));
} }
} }
...@@ -124,28 +129,28 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { ...@@ -124,28 +129,28 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {
super.setUp(); super.setUp();
deal(address(L1Token), alice, 100000, true); deal(address(L1Token), alice, 100000, true);
vm.startPrank(alice, alice); vm.startPrank(alice, alice);
L1Token.approve(address(L1Bridge), type(uint256).max); L1Token.approve(address(l1StandardBridge), type(uint256).max);
} }
function test_depositETH_benchmark_0() external { function test_depositETH_benchmark_0() external {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 1 gwei); setPrevBaseFee(vm, address(optimismPortal), 1 gwei);
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Bridge.depositETH{ value: 500 }(50000, hex""); l1StandardBridge.depositETH{ value: 500 }(50000, hex"");
} }
function test_depositETH_benchmark_1() external { function test_depositETH_benchmark_1() external {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 10 gwei); setPrevBaseFee(vm, address(optimismPortal), 10 gwei);
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Bridge.depositETH{ value: 500 }(50000, hex""); l1StandardBridge.depositETH{ value: 500 }(50000, hex"");
} }
function test_depositERC20_benchmark_0() external { function test_depositERC20_benchmark_0() external {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 1 gwei); setPrevBaseFee(vm, address(optimismPortal), 1 gwei);
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Bridge.bridgeERC20({ l1StandardBridge.bridgeERC20({
_localToken: address(L1Token), _localToken: address(L1Token),
_remoteToken: address(L2Token), _remoteToken: address(L2Token),
_amount: 100, _amount: 100,
...@@ -156,9 +161,9 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { ...@@ -156,9 +161,9 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {
function test_depositERC20_benchmark_1() external { function test_depositERC20_benchmark_1() external {
vm.pauseGasMetering(); vm.pauseGasMetering();
setPrevBaseFee(vm, address(op), 10 gwei); setPrevBaseFee(vm, address(optimismPortal), 10 gwei);
vm.resumeGasMetering(); vm.resumeGasMetering();
L1Bridge.bridgeERC20({ l1StandardBridge.bridgeERC20({
_localToken: address(L1Token), _localToken: address(L1Token),
_remoteToken: address(L2Token), _remoteToken: address(L2Token),
_amount: 100, _amount: 100,
...@@ -171,35 +176,36 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer { ...@@ -171,35 +176,36 @@ contract GasBenchMark_L1StandardBridge_Deposit is Bridge_Initializer {
contract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer { contract GasBenchMark_L1StandardBridge_Finalize is Bridge_Initializer {
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
deal(address(L1Token), address(L1Bridge), 100, true); deal(address(L1Token), address(l1StandardBridge), 100, true);
vm.mockCall( vm.mockCall(
address(L1Bridge.messenger()), address(l1StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.startPrank(address(L1Bridge.messenger())); vm.startPrank(address(l1StandardBridge.messenger()));
vm.deal(address(L1Bridge.messenger()), 100); vm.deal(address(l1StandardBridge.messenger()), 100);
} }
function test_finalizeETHWithdrawal_benchmark() external { function test_finalizeETHWithdrawal_benchmark() external {
// TODO: Make this more accurate. It is underestimating the cost because it pranks // TODO: Make this more accurate. It is underestimating the cost because it pranks
// the call coming from the messenger, which bypasses the portal // the call coming from the messenger, which bypasses the portal
// and oracle. // and oracle.
L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); l1StandardBridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex"");
} }
} }
contract GasBenchMark_L2OutputOracle is L2OutputOracle_Initializer { contract GasBenchMark_L2OutputOracle is CommonTest {
uint256 nextBlockNumber; uint256 nextBlockNumber;
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
nextBlockNumber = oracle.nextBlockNumber(); nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
address proposer = cfg.l2OutputOracleProposer();
vm.startPrank(proposer); vm.startPrank(proposer);
} }
function test_proposeL2Output_benchmark() external { function test_proposeL2Output_benchmark() external {
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
} }
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Test, StdUtils } from "forge-std/Test.sol";
import { Vm } from "forge-std/Vm.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { L2StandardBridge } from "src/L2/L2StandardBridge.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol";
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";
import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol";
import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol";
import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol";
import { FeeVault } from "src/universal/FeeVault.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Proxy } from "src/universal/Proxy.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { ResolvedDelegateProxy } from "src/legacy/ResolvedDelegateProxy.sol";
import { AddressManager } from "src/legacy/AddressManager.sol";
import { L1ChugSplashProxy } from "src/legacy/L1ChugSplashProxy.sol";
import { IL1ChugSplashDeployer } from "src/legacy/L1ChugSplashProxy.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol";
import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { Constants } from "src/libraries/Constants.sol";
import { FFIInterface } from "test/setup/FFIInterface.sol";
contract CommonTest is Test {
address alice = address(128);
address bob = address(256);
address multisig = address(512);
address immutable ZERO_ADDRESS = address(0);
address immutable NON_ZERO_ADDRESS = address(1);
uint256 immutable NON_ZERO_VALUE = 100;
uint256 immutable ZERO_VALUE = 0;
uint64 immutable NON_ZERO_GASLIMIT = 50000;
bytes32 nonZeroHash = keccak256(abi.encode("NON_ZERO"));
bytes NON_ZERO_DATA = hex"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000";
event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
/// @dev OpenZeppelin Ownable.sol transferOwnership event
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
FFIInterface ffi;
function setUp() public virtual {
// Give alice and bob some ETH
vm.deal(alice, 1 << 16);
vm.deal(bob, 1 << 16);
vm.deal(multisig, 1 << 16);
vm.label(alice, "alice");
vm.label(bob, "bob");
vm.label(multisig, "multisig");
// Make sure we have a non-zero base fee
vm.fee(1000000000);
ffi = new FFIInterface();
}
function emitTransactionDeposited(
address _from,
address _to,
uint256 _mint,
uint256 _value,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
)
internal
{
emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data));
}
}
contract L2OutputOracle_Initializer is CommonTest {
// Test target
L2OutputOracle oracle;
L2OutputOracle oracleImpl;
L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
// Constructor arguments
address internal proposer = 0x000000000000000000000000000000000000AbBa;
address internal owner = 0x000000000000000000000000000000000000ACDC;
uint256 internal submissionInterval = 1800;
uint256 internal l2BlockTime = 2;
uint256 internal startingBlockNumber = 200;
uint256 internal startingTimestamp = 1000;
uint256 internal finalizationPeriodSeconds = 7 days;
address guardian;
// Test data
uint256 initL1Time;
event OutputProposed(
bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp
);
event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);
// Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output
function warpToProposeTime(uint256 _nextBlockNumber) public {
vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);
}
/// @dev Helper function to propose an output.
function proposeAnotherOutput() public {
bytes32 proposedOutput2 = keccak256(abi.encode());
uint256 nextBlockNumber = oracle.nextBlockNumber();
uint256 nextOutputIndex = oracle.nextOutputIndex();
warpToProposeTime(nextBlockNumber);
uint256 proposedNumber = oracle.latestBlockNumber();
// Ensure the submissionInterval is enforced
assertEq(nextBlockNumber, proposedNumber + submissionInterval);
vm.roll(nextBlockNumber + 1);
vm.expectEmit(true, true, true, true);
emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);
vm.prank(proposer);
oracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);
}
function setUp() public virtual override {
super.setUp();
guardian = makeAddr("guardian");
// By default the first block has timestamp and number zero, which will cause underflows in the
// tests, so we'll move forward to these block values.
initL1Time = startingTimestamp + 1;
vm.warp(initL1Time);
vm.roll(startingBlockNumber);
// Deploy the L2OutputOracle and transfer owernship to the proposer
oracleImpl = new L2OutputOracle({
_submissionInterval: submissionInterval,
_l2BlockTime: l2BlockTime,
_finalizationPeriodSeconds: finalizationPeriodSeconds
});
Proxy proxy = new Proxy(multisig);
vm.prank(multisig);
proxy.upgradeToAndCall(
address(oracleImpl),
abi.encodeCall(L2OutputOracle.initialize, (startingBlockNumber, startingTimestamp, proposer, owner))
);
oracle = L2OutputOracle(address(proxy));
vm.label(address(oracle), "L2OutputOracle");
// Set the L2ToL1MessagePasser at the correct address
vm.etch(Predeploys.L2_TO_L1_MESSAGE_PASSER, address(new L2ToL1MessagePasser()).code);
vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser");
}
}
contract Portal_Initializer is L2OutputOracle_Initializer {
// Test target
OptimismPortal internal opImpl;
OptimismPortal internal op;
SystemConfig systemConfig;
event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);
event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to);
function setUp() public virtual override {
super.setUp();
Proxy systemConfigProxy = new Proxy(multisig);
SystemConfig systemConfigImpl = new SystemConfig();
vm.prank(multisig);
systemConfigProxy.upgradeToAndCall(
address(systemConfigImpl),
abi.encodeCall(
SystemConfig.initialize,
(
address(1), //_owner,
0, //_overhead,
10000, //_scalar,
bytes32(0), //_batcherHash,
30_000_000, //_gasLimit,
address(0), //_unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), //_config,
0, //_startBlock
address(0xff), // _batchInbox
SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: address(0),
l1ERC721Bridge: address(0),
l1StandardBridge: address(0),
l2OutputOracle: address(oracle),
optimismPortal: address(op),
optimismMintableERC20Factory: address(0)
})
)
)
);
systemConfig = SystemConfig(address(systemConfigProxy));
opImpl = new OptimismPortal();
Proxy proxy = new Proxy(multisig);
vm.prank(multisig);
proxy.upgradeToAndCall(
address(opImpl), abi.encodeCall(OptimismPortal.initialize, (oracle, guardian, systemConfig, false))
);
op = OptimismPortal(payable(address(proxy)));
vm.label(address(op), "OptimismPortal");
}
}
contract Messenger_Initializer is Portal_Initializer {
AddressManager internal addressManager;
L1CrossDomainMessenger internal L1Messenger;
L2CrossDomainMessenger internal L2Messenger = L2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
event SentMessageExtension1(address indexed sender, uint256 value);
event MessagePassed(
uint256 indexed nonce,
address indexed sender,
address indexed target,
uint256 value,
uint256 gasLimit,
bytes data,
bytes32 withdrawalHash
);
event RelayedMessage(bytes32 indexed msgHash);
event FailedRelayedMessage(bytes32 indexed msgHash);
event TransactionDeposited(
address indexed from,
address indexed to,
uint256 mint,
uint256 value,
uint64 gasLimit,
bool isCreation,
bytes data
);
event WhatHappened(bool success, bytes returndata);
function setUp() public virtual override {
super.setUp();
// Deploy the address manager
vm.prank(multisig);
addressManager = new AddressManager();
// Setup implementation
L1CrossDomainMessenger L1MessengerImpl = new L1CrossDomainMessenger();
// Setup the address manager and proxy
vm.prank(multisig);
addressManager.setAddress("OVM_L1CrossDomainMessenger", address(L1MessengerImpl));
ResolvedDelegateProxy proxy = new ResolvedDelegateProxy(
addressManager,
"OVM_L1CrossDomainMessenger"
);
L1Messenger = L1CrossDomainMessenger(address(proxy));
L1Messenger.initialize(op);
vm.etch(Predeploys.L2_CROSS_DOMAIN_MESSENGER, address(new L2CrossDomainMessenger(address(L1Messenger))).code);
L2Messenger.initialize();
// Label addresses
vm.label(address(addressManager), "AddressManager");
vm.label(address(L1MessengerImpl), "L1CrossDomainMessenger_Impl");
vm.label(address(L1Messenger), "L1CrossDomainMessenger_Proxy");
vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH");
vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger");
vm.label(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), "L1CrossDomainMessenger_aliased");
}
}
contract Bridge_Initializer is Messenger_Initializer {
L1StandardBridge L1Bridge;
L2StandardBridge L2Bridge;
OptimismMintableERC20Factory L2TokenFactory;
OptimismMintableERC20Factory L1TokenFactory;
ERC20 L1Token;
ERC20 BadL1Token;
OptimismMintableERC20 L2Token;
LegacyMintableERC20 LegacyL2Token;
ERC20 NativeL2Token;
ERC20 BadL2Token;
OptimismMintableERC20 RemoteL1Token;
event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data);
event ERC20DepositInitiated(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event ERC20WithdrawalFinalized(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event WithdrawalInitiated(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event DepositFinalized(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event DepositFailed(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);
event ERC20BridgeInitiated(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 amount,
bytes data
);
event ERC20BridgeFinalized(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 amount,
bytes data
);
function setUp() public virtual override {
super.setUp();
vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge");
vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory");
// Deploy the L1 bridge and initialize it with the address of the
// L1CrossDomainMessenger
L1ChugSplashProxy proxy = new L1ChugSplashProxy(multisig);
vm.mockCall(multisig, abi.encodeWithSelector(IL1ChugSplashDeployer.isUpgrading.selector), abi.encode(true));
vm.startPrank(multisig);
proxy.setCode(address(new L1StandardBridge()).code);
vm.clearMockedCalls();
address L1Bridge_Impl = proxy.getImplementation();
vm.stopPrank();
L1Bridge = L1StandardBridge(payable(address(proxy)));
L1Bridge.initialize({ _messenger: L1Messenger });
vm.label(address(proxy), "L1StandardBridge_Proxy");
vm.label(address(L1Bridge_Impl), "L1StandardBridge_Impl");
// Deploy the L2StandardBridge, move it to the correct predeploy
// address and then initialize it. It is safe to call initialize directly
// on the proxy because the bytecode was set in state with `etch`.
vm.etch(Predeploys.L2_STANDARD_BRIDGE, address(new L2StandardBridge(StandardBridge(payable(proxy)))).code);
L2Bridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));
L2Bridge.initialize();
// Set up the L2 mintable token factory
OptimismMintableERC20Factory factory = new OptimismMintableERC20Factory();
vm.etch(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, address(factory).code);
L2TokenFactory = OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);
L2TokenFactory.initialize(Predeploys.L2_STANDARD_BRIDGE);
vm.etch(Predeploys.LEGACY_ERC20_ETH, address(new LegacyERC20ETH()).code);
L1Token = new ERC20("Native L1 Token", "L1T");
LegacyL2Token = new LegacyMintableERC20({
_l2Bridge: address(L2Bridge),
_l1Token: address(L1Token),
_name: string.concat("LegacyL2-", L1Token.name()),
_symbol: string.concat("LegacyL2-", L1Token.symbol())
});
vm.label(address(LegacyL2Token), "LegacyMintableERC20");
// Deploy the L2 ERC20 now
L2Token = OptimismMintableERC20(
L2TokenFactory.createStandardL2Token(
address(L1Token),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
)
);
BadL2Token = OptimismMintableERC20(
L2TokenFactory.createStandardL2Token(
address(1),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
)
);
NativeL2Token = new ERC20("Native L2 Token", "L2T");
Proxy factoryProxy = new Proxy(multisig);
OptimismMintableERC20Factory L1TokenFactoryImpl = new OptimismMintableERC20Factory();
vm.prank(multisig);
factoryProxy.upgradeToAndCall(
address(L1TokenFactoryImpl), abi.encodeCall(OptimismMintableERC20Factory.initialize, address(L1Bridge))
);
L1TokenFactory = OptimismMintableERC20Factory(address(factoryProxy));
RemoteL1Token = OptimismMintableERC20(
L1TokenFactory.createStandardL2Token(
address(NativeL2Token),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
)
);
BadL1Token = OptimismMintableERC20(
L1TokenFactory.createStandardL2Token(
address(1),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
)
);
}
}
contract ERC721Bridge_Initializer is Bridge_Initializer {
L1ERC721Bridge L1NFTBridge;
L2ERC721Bridge L2NFTBridge;
function setUp() public virtual override {
super.setUp();
// Deploy the L1ERC721Bridge.
L1ERC721Bridge l1BridgeImpl = new L1ERC721Bridge();
Proxy l1BridgeProxy = new Proxy(multisig);
vm.prank(multisig);
l1BridgeProxy.upgradeToAndCall(
address(l1BridgeImpl), abi.encodeCall(L1ERC721Bridge.initialize, (CrossDomainMessenger(L1Messenger)))
);
L1NFTBridge = L1ERC721Bridge(address(l1BridgeProxy));
// Deploy the implementation for the L2ERC721Bridge and etch it into the predeploy address.
L2ERC721Bridge l2BridgeImpl = new L2ERC721Bridge(address(L1NFTBridge));
Proxy l2BridgeProxy = new Proxy(multisig);
vm.etch(Predeploys.L2_ERC721_BRIDGE, address(l2BridgeProxy).code);
// set the storage slot for admin
bytes32 OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
vm.store(Predeploys.L2_ERC721_BRIDGE, OWNER_KEY, bytes32(uint256(uint160(multisig))));
vm.prank(multisig);
Proxy(payable(Predeploys.L2_ERC721_BRIDGE)).upgradeToAndCall(
address(l2BridgeImpl), abi.encodeCall(L2ERC721Bridge.initialize, ())
);
// Set up a reference to the L2ERC721Bridge.
L2NFTBridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
// Label the L1 and L2 bridges.
vm.label(address(L1NFTBridge), "L1ERC721Bridge");
vm.label(address(L2NFTBridge), "L2ERC721Bridge");
}
}
contract FeeVault_Initializer is Bridge_Initializer {
SequencerFeeVault vault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));
address constant recipient = address(1024);
event Withdrawal(uint256 value, address to, address from);
event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork);
}
...@@ -3,28 +3,28 @@ pragma solidity 0.8.15; ...@@ -3,28 +3,28 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { Messenger_Initializer, Test } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { CallerCaller, Reverter } from "test/mocks/Callers.sol";
import { Reverter, CallerCaller } from "test/mocks/Callers.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
// CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2 // CrossDomainMessenger_Test is for testing functionality which is common to both the L1 and L2
// CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract. // CrossDomainMessenger contracts. For simplicity, we use the L1 Messenger as the test contract.
contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { contract CrossDomainMessenger_BaseGas_Test is Bridge_Initializer {
/// @dev Ensure that baseGas passes for the max value of _minGasLimit, /// @dev Ensure that baseGas passes for the max value of _minGasLimit,
/// this is about 4 Billion. /// this is about 4 Billion.
function test_baseGas_succeeds() external view { function test_baseGas_succeeds() external view {
L1Messenger.baseGas(hex"ff", type(uint32).max); l1CrossDomainMessenger.baseGas(hex"ff", type(uint32).max);
} }
/// @dev Fuzz for other values which might cause a revert in baseGas. /// @dev Fuzz for other values which might cause a revert in baseGas.
function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view { function testFuzz_baseGas_succeeds(uint32 _minGasLimit) external view {
L1Messenger.baseGas(hex"ff", _minGasLimit); l1CrossDomainMessenger.baseGas(hex"ff", _minGasLimit);
} }
/// @notice The baseGas function should always return a value greater than /// @notice The baseGas function should always return a value greater than
...@@ -33,8 +33,8 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { ...@@ -33,8 +33,8 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
/// gas to the OptimismPortal. /// gas to the OptimismPortal.
function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external { function testFuzz_baseGas_portalMinGasLimit_succeeds(bytes memory _data, uint32 _minGasLimit) external {
vm.assume(_data.length <= type(uint64).max); vm.assume(_data.length <= type(uint64).max);
uint64 baseGas = L1Messenger.baseGas(_data, _minGasLimit); uint64 baseGas = l1CrossDomainMessenger.baseGas(_data, _minGasLimit);
uint64 minGasLimit = op.minimumGasLimit(uint64(_data.length)); uint64 minGasLimit = optimismPortal.minimumGasLimit(uint64(_data.length));
assertTrue(baseGas >= minGasLimit); assertTrue(baseGas >= minGasLimit);
} }
} }
...@@ -45,18 +45,18 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer { ...@@ -45,18 +45,18 @@ contract CrossDomainMessenger_BaseGas_Test is Messenger_Initializer {
contract ExternalRelay is Test { contract ExternalRelay is Test {
address internal op; address internal op;
address internal fuzzedSender; address internal fuzzedSender;
L1CrossDomainMessenger internal L1Messenger; L1CrossDomainMessenger internal l1CrossDomainMessenger;
event FailedRelayedMessage(bytes32 indexed msgHash); event FailedRelayedMessage(bytes32 indexed msgHash);
constructor(L1CrossDomainMessenger _l1Messenger, address _op) { constructor(L1CrossDomainMessenger _l1Messenger, address _op) {
L1Messenger = _l1Messenger; l1CrossDomainMessenger = _l1Messenger;
op = _op; op = _op;
} }
/// @notice Internal helper function to relay a message and perform assertions. /// @notice Internal helper function to relay a message and perform assertions.
function _internalRelay(address _innerSender) internal { function _internalRelay(address _innerSender) internal {
address initialSender = L1Messenger.xDomainMessageSender(); address initialSender = l1CrossDomainMessenger.xDomainMessageSender();
bytes memory callMessage = getCallData(); bytes memory callMessage = getCallData();
...@@ -73,7 +73,7 @@ contract ExternalRelay is Test { ...@@ -73,7 +73,7 @@ contract ExternalRelay is Test {
emit FailedRelayedMessage(hash); emit FailedRelayedMessage(hash);
vm.prank(address(op)); vm.prank(address(op));
L1Messenger.relayMessage({ l1CrossDomainMessenger.relayMessage({
_nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
_sender: _innerSender, _sender: _innerSender,
_target: address(this), _target: address(this),
...@@ -82,9 +82,9 @@ contract ExternalRelay is Test { ...@@ -82,9 +82,9 @@ contract ExternalRelay is Test {
_message: callMessage _message: callMessage
}); });
assertTrue(L1Messenger.failedMessages(hash)); assertTrue(l1CrossDomainMessenger.failedMessages(hash));
assertFalse(L1Messenger.successfulMessages(hash)); assertFalse(l1CrossDomainMessenger.successfulMessages(hash));
assertEq(initialSender, L1Messenger.xDomainMessageSender()); assertEq(initialSender, l1CrossDomainMessenger.xDomainMessageSender());
} }
/// @notice externalCallWithMinGas is called by the CrossDomainMessenger. /// @notice externalCallWithMinGas is called by the CrossDomainMessenger.
...@@ -111,7 +111,7 @@ contract ExternalRelay is Test { ...@@ -111,7 +111,7 @@ contract ExternalRelay is Test {
/// @title CrossDomainMessenger_RelayMessage_Test /// @title CrossDomainMessenger_RelayMessage_Test
/// @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function. /// @notice Fuzz tests re-entrancy into the CrossDomainMessenger relayMessage function.
contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { contract CrossDomainMessenger_RelayMessage_Test is Bridge_Initializer {
// Storage slot of the l2Sender // Storage slot of the l2Sender
uint256 constant senderSlotIndex = 50; uint256 constant senderSlotIndex = 50;
...@@ -119,7 +119,7 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { ...@@ -119,7 +119,7 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
er = new ExternalRelay(L1Messenger, address(op)); er = new ExternalRelay(l1CrossDomainMessenger, address(optimismPortal));
} }
/// @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via /// @dev This test mocks an OptimismPortal call to the L1CrossDomainMessenger via
...@@ -151,9 +151,9 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { ...@@ -151,9 +151,9 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
}); });
// set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage({ l1CrossDomainMessenger.relayMessage({
_nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), _nonce: Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }),
_sender: sender, _sender: sender,
_target: target, _target: target,
...@@ -162,11 +162,11 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer { ...@@ -162,11 +162,11 @@ contract CrossDomainMessenger_RelayMessage_Test is Messenger_Initializer {
_message: callMessage _message: callMessage
}); });
assertTrue(L1Messenger.successfulMessages(hash)); assertTrue(l1CrossDomainMessenger.successfulMessages(hash));
assertEq(L1Messenger.failedMessages(hash), false); assertEq(l1CrossDomainMessenger.failedMessages(hash), false);
// Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER` // Ensures that the `xDomainMsgSender` is set back to `Predeploys.L2_CROSS_DOMAIN_MESSENGER`
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); l1CrossDomainMessenger.xDomainMessageSender();
} }
} }
...@@ -4,7 +4,7 @@ pragma solidity 0.8.15; ...@@ -4,7 +4,7 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { VmSafe } from "forge-std/Vm.sol"; import { VmSafe } from "forge-std/Vm.sol";
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { Portal_Initializer } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
...@@ -46,7 +46,7 @@ contract CrossDomainOwnable_Test is Test { ...@@ -46,7 +46,7 @@ contract CrossDomainOwnable_Test is Test {
} }
} }
contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer { contract CrossDomainOwnableThroughPortal_Test is CommonTest {
XDomainSetter setter; XDomainSetter setter;
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
...@@ -63,7 +63,7 @@ contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer { ...@@ -63,7 +63,7 @@ contract CrossDomainOwnableThroughPortal_Test is Portal_Initializer {
vm.recordLogs(); vm.recordLogs();
vm.prank(alice); vm.prank(alice);
op.depositTransaction({ optimismPortal.depositTransaction({
_to: address(setter), _to: address(setter),
_value: 0, _value: 0,
_gasLimit: 30_000, _gasLimit: 30_000,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries // Libraries
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
...@@ -10,10 +10,10 @@ import { Encoding } from "src/libraries/Encoding.sol"; ...@@ -10,10 +10,10 @@ import { Encoding } from "src/libraries/Encoding.sol";
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol"; import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Target contract dependencies // Target contract dependencies
import { AddressAliasHelper } from "../src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
// Target contract // Target contract
import { CrossDomainOwnable2 } from "../src/L2/CrossDomainOwnable2.sol"; import { CrossDomainOwnable2 } from "src/L2/CrossDomainOwnable2.sol";
contract XDomainSetter2 is CrossDomainOwnable2 { contract XDomainSetter2 is CrossDomainOwnable2 {
uint256 public value; uint256 public value;
...@@ -23,7 +23,7 @@ contract XDomainSetter2 is CrossDomainOwnable2 { ...@@ -23,7 +23,7 @@ contract XDomainSetter2 is CrossDomainOwnable2 {
} }
} }
contract CrossDomainOwnable2_Test is Messenger_Initializer { contract CrossDomainOwnable2_Test is Bridge_Initializer {
XDomainSetter2 setter; XDomainSetter2 setter;
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
...@@ -44,9 +44,9 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { ...@@ -44,9 +44,9 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
// set the xDomainMsgSender storage slot // set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204)); bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice)); bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));
vm.store(address(L2Messenger), key, value); vm.store(address(l2CrossDomainMessenger), key, value);
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("CrossDomainOwnable2: caller is not the owner"); vm.expectRevert("CrossDomainOwnable2: caller is not the owner");
setter.set(1); setter.set(1);
} }
...@@ -69,8 +69,10 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { ...@@ -69,8 +69,10 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit FailedRelayedMessage(hash); emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message); l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
);
assertEq(setter.value(), 0); assertEq(setter.value(), 0);
} }
...@@ -81,8 +83,8 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer { ...@@ -81,8 +83,8 @@ contract CrossDomainOwnable2_Test is Messenger_Initializer {
// Simulate the L2 execution where the call is coming from // Simulate the L2 execution where the call is coming from
// the L1CrossDomainMessenger // the L1CrossDomainMessenger
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
L2Messenger.relayMessage( l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(1, 1), Encoding.encodeVersionedNonce(1, 1),
owner, owner,
address(setter), address(setter),
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest, Messenger_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries // Libraries
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
...@@ -23,7 +23,7 @@ contract XDomainSetter3 is CrossDomainOwnable3 { ...@@ -23,7 +23,7 @@ contract XDomainSetter3 is CrossDomainOwnable3 {
} }
} }
contract CrossDomainOwnable3_Test is Messenger_Initializer { contract CrossDomainOwnable3_Test is Bridge_Initializer {
XDomainSetter3 setter; XDomainSetter3 setter;
/// @dev CrossDomainOwnable3.sol transferOwnership event /// @dev CrossDomainOwnable3.sol transferOwnership event
...@@ -73,9 +73,9 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { ...@@ -73,9 +73,9 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
// set the xDomainMsgSender storage slot // set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204)); bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob); bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);
vm.store(address(L2Messenger), key, value); vm.store(address(l2CrossDomainMessenger), key, value);
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("CrossDomainOwnable3: caller is not the owner"); vm.expectRevert("CrossDomainOwnable3: caller is not the owner");
setter.set(1); setter.set(1);
} }
...@@ -109,11 +109,13 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { ...@@ -109,11 +109,13 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
// It should be a failed message. The revert is caught, // It should be a failed message. The revert is caught,
// so we cannot expectRevert here. // so we cannot expectRevert here.
vm.expectEmit(true, true, true, true, address(L2Messenger)); vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger));
emit FailedRelayedMessage(hash); emit FailedRelayedMessage(hash);
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message); l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(nonce, 1), sender, target, value, minGasLimit, message
);
assertEq(setter.value(), 0); assertEq(setter.value(), 0);
} }
...@@ -212,8 +214,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer { ...@@ -212,8 +214,8 @@ contract CrossDomainOwnable3_Test is Messenger_Initializer {
// Simulate the L2 execution where the call is coming from // Simulate the L2 execution where the call is coming from
// the L1CrossDomainMessenger // the L1CrossDomainMessenger
vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger))); vm.prank(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)));
L2Messenger.relayMessage( l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(1, 1), Encoding.encodeVersionedNonce(1, 1),
bob, bob,
address(setter), address(setter),
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { DelayedVetoable } from "src/L1/DelayedVetoable.sol"; import { DelayedVetoable } from "src/L1/DelayedVetoable.sol";
contract DelayedVetoable_Init is CommonTest { contract DelayedVetoable_Init is CommonTest {
...@@ -146,7 +146,7 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init { ...@@ -146,7 +146,7 @@ contract DelayedVetoable_HandleCall_TestFail is DelayedVetoable_Init {
/// @dev Only the initiator can initiate a call. /// @dev Only the initiator can initiate a call.
function test_handleCall_unauthorizedInitiation_reverts() external { function test_handleCall_unauthorizedInitiation_reverts() external {
vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, initiator, address(this))); vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, initiator, address(this)));
(bool success,) = address(delayedVetoable).call(NON_ZERO_DATA); (bool success,) = address(delayedVetoable).call(hex"00001234");
assertTrue(success); assertTrue(success);
} }
......
...@@ -8,9 +8,9 @@ import { Test } from "forge-std/Test.sol"; ...@@ -8,9 +8,9 @@ import { Test } from "forge-std/Test.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { Proxy } from "src/universal/Proxy.sol"; import { Proxy } from "src/universal/Proxy.sol";
import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
contract DisputeGameFactory_Init is L2OutputOracle_Initializer { contract DisputeGameFactory_Init is CommonTest {
DisputeGameFactory factory; DisputeGameFactory factory;
FakeClone fakeClone; FakeClone fakeClone;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
......
...@@ -37,9 +37,9 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { ...@@ -37,9 +37,9 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
vm.warp(1690906994); vm.warp(1690906994);
// Propose 2 mock outputs // Propose 2 mock outputs
vm.startPrank(oracle.PROPOSER()); vm.startPrank(l2OutputOracle.PROPOSER());
for (uint256 i; i < 2; i++) { for (uint256 i; i < 2; i++) {
oracle.proposeL2Output(bytes32(i + 1), oracle.nextBlockNumber(), blockhash(i), i); l2OutputOracle.proposeL2Output(bytes32(i + 1), l2OutputOracle.nextBlockNumber(), blockhash(i), i);
// Advance 1 block // Advance 1 block
vm.roll(block.number + 1); vm.roll(block.number + 1);
...@@ -52,7 +52,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { ...@@ -52,7 +52,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
blockOracle.checkpoint(); blockOracle.checkpoint();
// Set the extra data for the game creation // Set the extra data for the game creation
extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, block.number - 1); extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, block.number - 1);
// Deploy an implementation of the fault game // Deploy an implementation of the fault game
gameImpl = new FaultDisputeGame( gameImpl = new FaultDisputeGame(
...@@ -61,7 +61,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init { ...@@ -61,7 +61,7 @@ contract FaultDisputeGame_Init is DisputeGameFactory_Init {
4, 4,
Duration.wrap(7 days), Duration.wrap(7 days),
new AlphabetVM(absolutePrestate), new AlphabetVM(absolutePrestate),
oracle, l2OutputOracle,
blockOracle blockOracle
); );
// Register the game implementation with the factory. // Register the game implementation with the factory.
...@@ -127,7 +127,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -127,7 +127,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
function test_initialize_l1HeadTooOld_reverts() public { function test_initialize_l1HeadTooOld_reverts() public {
// Store a mock block hash for the genesis block. The timestamp will default to 0. // Store a mock block hash for the genesis block. The timestamp will default to 0.
vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1))); vm.store(address(gameImpl.BLOCK_ORACLE()), keccak256(abi.encode(0, 0)), bytes32(uint256(1)));
bytes memory _extraData = abi.encode(oracle.SUBMISSION_INTERVAL() * 2, 0); bytes memory _extraData = abi.encode(l2OutputOracle.SUBMISSION_INTERVAL() * 2, 0);
vm.expectRevert(L1HeadTooOld.selector); vm.expectRevert(L1HeadTooOld.selector);
factory.create(GAME_TYPE, ROOT_CLAIM, _extraData); factory.create(GAME_TYPE, ROOT_CLAIM, _extraData);
...@@ -139,8 +139,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -139,8 +139,9 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
/// For now, it is critical that the first proposed output root of an OP stack /// For now, it is critical that the first proposed output root of an OP stack
/// chain is done so by an honest party. /// chain is done so by an honest party.
function test_initialize_firstOutput_reverts() public { function test_initialize_firstOutput_reverts() public {
uint256 submissionInterval = l2OutputOracle.submissionInterval();
vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11)); vm.expectRevert(abi.encodeWithSignature("Panic(uint256)", 0x11));
factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(1800, block.number - 1)); factory.create(GAME_TYPE, ROOT_CLAIM, abi.encode(submissionInterval, block.number - 1));
} }
/// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome. /// @dev Tests that the `create` function reverts when the rootClaim does not disagree with the outcome.
...@@ -159,12 +160,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -159,12 +160,12 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
// Starting // Starting
(FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) = (FaultDisputeGame.OutputProposal memory startingProp, FaultDisputeGame.OutputProposal memory disputedProp) =
gameProxy.proposals(); gameProxy.proposals();
Types.OutputProposal memory starting = oracle.getL2Output(startingProp.index); Types.OutputProposal memory starting = l2OutputOracle.getL2Output(startingProp.index);
assertEq(startingProp.index, 0); assertEq(startingProp.index, 0);
assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber); assertEq(startingProp.l2BlockNumber, starting.l2BlockNumber);
assertEq(Hash.unwrap(startingProp.outputRoot), starting.outputRoot); assertEq(Hash.unwrap(startingProp.outputRoot), starting.outputRoot);
// Disputed // Disputed
Types.OutputProposal memory disputed = oracle.getL2Output(disputedProp.index); Types.OutputProposal memory disputed = l2OutputOracle.getL2Output(disputedProp.index);
assertEq(disputedProp.index, 1); assertEq(disputedProp.index, 1);
assertEq(disputedProp.l2BlockNumber, disputed.l2BlockNumber); assertEq(disputedProp.l2BlockNumber, disputed.l2BlockNumber);
assertEq(Hash.unwrap(disputedProp.outputRoot), disputed.outputRoot); assertEq(Hash.unwrap(disputedProp.outputRoot), disputed.outputRoot);
......
...@@ -2,49 +2,24 @@ ...@@ -2,49 +2,24 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { BaseFeeVault } from "src/L2/BaseFeeVault.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol";
// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
// Target contract dependencies
import { FeeVault } from "src/universal/FeeVault.sol";
// Target contract // Target contract
import { L1FeeVault } from "src/L2/L1FeeVault.sol"; import { FeeVault } from "src/universal/FeeVault.sol";
// Test the implementations of the FeeVault // Test the implementations of the FeeVault
contract FeeVault_Test is Bridge_Initializer { contract FeeVault_Test is Bridge_Initializer {
BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT)); /// @dev Tests that the constructor sets the correct values.
L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT)); function test_constructor_l1FeeVault_succeeds() external {
assertEq(l1FeeVault.RECIPIENT(), cfg.l1FeeVaultRecipient());
uint256 constant otherMinimumWithdrawalAmount = 10 ether; assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.l1FeeVaultMinimumWithdrawalAmount());
assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2));
/// @dev Sets up the test suite.
function setUp() public override {
super.setUp();
vm.etch(
Predeploys.BASE_FEE_VAULT,
address(new BaseFeeVault(alice, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code
);
vm.etch(
Predeploys.L1_FEE_VAULT,
address(new L1FeeVault(bob, otherMinimumWithdrawalAmount, FeeVault.WithdrawalNetwork.L2)).code
);
vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault");
vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault");
} }
/// @dev Tests that the constructor sets the correct values. /// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() external { function test_constructor_baseFeeVault_succeeds() external {
assertEq(baseFeeVault.RECIPIENT(), alice); assertEq(baseFeeVault.RECIPIENT(), cfg.baseFeeVaultRecipient());
assertEq(l1FeeVault.RECIPIENT(), bob); assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.baseFeeVaultMinimumWithdrawalAmount());
assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE);
assertEq(l1FeeVault.MIN_WITHDRAWAL_AMOUNT(), otherMinimumWithdrawalAmount);
assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1)); assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L1));
assertEq(uint8(l1FeeVault.WITHDRAWAL_NETWORK()), uint8(FeeVault.WithdrawalNetwork.L2));
} }
} }
...@@ -2,22 +2,13 @@ ...@@ -2,22 +2,13 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract dependencies
import { L1Block } from "src/L2/L1Block.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
// Target contract
import { GasPriceOracle } from "src/L2/GasPriceOracle.sol";
contract GasPriceOracle_Test is CommonTest { contract GasPriceOracle_Test is CommonTest {
event OverheadUpdated(uint256); event OverheadUpdated(uint256);
event ScalarUpdated(uint256); event ScalarUpdated(uint256);
event DecimalsUpdated(uint256); event DecimalsUpdated(uint256);
GasPriceOracle gasOracle;
L1Block l1Block;
address depositor; address depositor;
// The initial L1 context values // The initial L1 context values
...@@ -33,17 +24,9 @@ contract GasPriceOracle_Test is CommonTest { ...@@ -33,17 +24,9 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
// place the L1Block contract at the predeploy address
vm.etch(Predeploys.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);
l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);
depositor = l1Block.DEPOSITOR_ACCOUNT(); depositor = l1Block.DEPOSITOR_ACCOUNT();
// We are not setting the gas oracle at its predeploy
// address for simplicity purposes. Nothing in this test
// requires it to be at a particular address
gasOracle = new GasPriceOracle();
vm.prank(depositor); vm.prank(depositor);
l1Block.setL1BlockValues({ l1Block.setL1BlockValues({
_number: number, _number: number,
...@@ -59,43 +42,43 @@ contract GasPriceOracle_Test is CommonTest { ...@@ -59,43 +42,43 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `l1BaseFee` is set correctly. /// @dev Tests that `l1BaseFee` is set correctly.
function test_l1BaseFee_succeeds() external { function test_l1BaseFee_succeeds() external {
assertEq(gasOracle.l1BaseFee(), basefee); assertEq(gasPriceOracle.l1BaseFee(), basefee);
} }
/// @dev Tests that `gasPrice` is set correctly. /// @dev Tests that `gasPrice` is set correctly.
function test_gasPrice_succeeds() external { function test_gasPrice_succeeds() external {
vm.fee(100); vm.fee(100);
uint256 gasPrice = gasOracle.gasPrice(); uint256 gasPrice = gasPriceOracle.gasPrice();
assertEq(gasPrice, 100); assertEq(gasPrice, 100);
} }
/// @dev Tests that `baseFee` is set correctly. /// @dev Tests that `baseFee` is set correctly.
function test_baseFee_succeeds() external { function test_baseFee_succeeds() external {
vm.fee(64); vm.fee(64);
uint256 gasPrice = gasOracle.baseFee(); uint256 gasPrice = gasPriceOracle.baseFee();
assertEq(gasPrice, 64); assertEq(gasPrice, 64);
} }
/// @dev Tests that `scalar` is set correctly. /// @dev Tests that `scalar` is set correctly.
function test_scalar_succeeds() external { function test_scalar_succeeds() external {
assertEq(gasOracle.scalar(), l1FeeScalar); assertEq(gasPriceOracle.scalar(), l1FeeScalar);
} }
/// @dev Tests that `overhead` is set correctly. /// @dev Tests that `overhead` is set correctly.
function test_overhead_succeeds() external { function test_overhead_succeeds() external {
assertEq(gasOracle.overhead(), l1FeeOverhead); assertEq(gasPriceOracle.overhead(), l1FeeOverhead);
} }
/// @dev Tests that `decimals` is set correctly. /// @dev Tests that `decimals` is set correctly.
function test_decimals_succeeds() external { function test_decimals_succeeds() external {
assertEq(gasOracle.decimals(), 6); assertEq(gasPriceOracle.decimals(), 6);
assertEq(gasOracle.DECIMALS(), 6); assertEq(gasPriceOracle.DECIMALS(), 6);
} }
/// @dev Tests that `setGasPrice` reverts since it was removed in bedrock. /// @dev Tests that `setGasPrice` reverts since it was removed in bedrock.
function test_setGasPrice_doesNotExist_reverts() external { function test_setGasPrice_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = (bool success, bytes memory returndata) =
address(gasOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1)); address(gasPriceOracle).call(abi.encodeWithSignature("setGasPrice(uint256)", 1));
assertEq(success, false); assertEq(success, false);
assertEq(returndata, hex""); assertEq(returndata, hex"");
...@@ -104,7 +87,7 @@ contract GasPriceOracle_Test is CommonTest { ...@@ -104,7 +87,7 @@ contract GasPriceOracle_Test is CommonTest {
/// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock. /// @dev Tests that `setL1BaseFee` reverts since it was removed in bedrock.
function test_setL1BaseFee_doesNotExist_reverts() external { function test_setL1BaseFee_doesNotExist_reverts() external {
(bool success, bytes memory returndata) = (bool success, bytes memory returndata) =
address(gasOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1)); address(gasPriceOracle).call(abi.encodeWithSignature("setL1BaseFee(uint256)", 1));
assertEq(success, false); assertEq(success, false);
assertEq(returndata, hex""); assertEq(returndata, hex"");
......
...@@ -2,41 +2,37 @@ ...@@ -2,41 +2,37 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract
import { GovernanceToken } from "src/governance/GovernanceToken.sol";
contract GovernanceToken_Test is CommonTest { contract GovernanceToken_Test is CommonTest {
address constant owner = address(0x1234); address owner;
address constant rando = address(0x5678); address rando;
GovernanceToken internal gov;
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
vm.prank(owner); owner = governanceToken.owner();
gov = new GovernanceToken(); rando = makeAddr("rando");
} }
/// @dev Tests that the constructor sets the correct initial state. /// @dev Tests that the constructor sets the correct initial state.
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(gov.owner(), owner); assertEq(governanceToken.owner(), owner);
assertEq(gov.name(), "Optimism"); assertEq(governanceToken.name(), "Optimism");
assertEq(gov.symbol(), "OP"); assertEq(governanceToken.symbol(), "OP");
assertEq(gov.decimals(), 18); assertEq(governanceToken.decimals(), 18);
assertEq(gov.totalSupply(), 0); assertEq(governanceToken.totalSupply(), 0);
} }
/// @dev Tests that the owner can successfully call `mint`. /// @dev Tests that the owner can successfully call `mint`.
function test_mint_fromOwner_succeeds() external { function test_mint_fromOwner_succeeds() external {
// Mint 100 tokens. // Mint 100 tokens.
vm.prank(owner); vm.prank(owner);
gov.mint(owner, 100); governanceToken.mint(owner, 100);
// Balances have updated correctly. // Balances have updated correctly.
assertEq(gov.balanceOf(owner), 100); assertEq(governanceToken.balanceOf(owner), 100);
assertEq(gov.totalSupply(), 100); assertEq(governanceToken.totalSupply(), 100);
} }
/// @dev Tests that `mint` reverts when called by a non-owner. /// @dev Tests that `mint` reverts when called by a non-owner.
...@@ -44,130 +40,130 @@ contract GovernanceToken_Test is CommonTest { ...@@ -44,130 +40,130 @@ contract GovernanceToken_Test is CommonTest {
// Mint 100 tokens as rando. // Mint 100 tokens as rando.
vm.prank(rando); vm.prank(rando);
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
gov.mint(owner, 100); governanceToken.mint(owner, 100);
// Balance does not update. // Balance does not update.
assertEq(gov.balanceOf(owner), 0); assertEq(governanceToken.balanceOf(owner), 0);
assertEq(gov.totalSupply(), 0); assertEq(governanceToken.totalSupply(), 0);
} }
/// @dev Tests that the owner can successfully call `burn`. /// @dev Tests that the owner can successfully call `burn`.
function test_burn_succeeds() external { function test_burn_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando burns their tokens. // Rando burns their tokens.
vm.prank(rando); vm.prank(rando);
gov.burn(50); governanceToken.burn(50);
// Balances have updated correctly. // Balances have updated correctly.
assertEq(gov.balanceOf(rando), 50); assertEq(governanceToken.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 50); assertEq(governanceToken.totalSupply(), 50);
} }
/// @dev Tests that the owner can successfully call `burnFrom`. /// @dev Tests that the owner can successfully call `burnFrom`.
function test_burnFrom_succeeds() external { function test_burnFrom_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando approves owner to burn 50 tokens. // Rando approves owner to burn 50 tokens.
vm.prank(rando); vm.prank(rando);
gov.approve(owner, 50); governanceToken.approve(owner, 50);
// Owner burns 50 tokens from rando. // Owner burns 50 tokens from rando.
vm.prank(owner); vm.prank(owner);
gov.burnFrom(rando, 50); governanceToken.burnFrom(rando, 50);
// Balances have updated correctly. // Balances have updated correctly.
assertEq(gov.balanceOf(rando), 50); assertEq(governanceToken.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 50); assertEq(governanceToken.totalSupply(), 50);
} }
/// @dev Tests that `transfer` correctly transfers tokens. /// @dev Tests that `transfer` correctly transfers tokens.
function test_transfer_succeeds() external { function test_transfer_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando transfers 50 tokens to owner. // Rando transfers 50 tokens to owner.
vm.prank(rando); vm.prank(rando);
gov.transfer(owner, 50); governanceToken.transfer(owner, 50);
// Balances have updated correctly. // Balances have updated correctly.
assertEq(gov.balanceOf(owner), 50); assertEq(governanceToken.balanceOf(owner), 50);
assertEq(gov.balanceOf(rando), 50); assertEq(governanceToken.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 100); assertEq(governanceToken.totalSupply(), 100);
} }
/// @dev Tests that `approve` correctly sets allowances. /// @dev Tests that `approve` correctly sets allowances.
function test_approve_succeeds() external { function test_approve_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando approves owner to spend 50 tokens. // Rando approves owner to spend 50 tokens.
vm.prank(rando); vm.prank(rando);
gov.approve(owner, 50); governanceToken.approve(owner, 50);
// Allowances have updated. // Allowances have updated.
assertEq(gov.allowance(rando, owner), 50); assertEq(governanceToken.allowance(rando, owner), 50);
} }
/// @dev Tests that `transferFrom` correctly transfers tokens. /// @dev Tests that `transferFrom` correctly transfers tokens.
function test_transferFrom_succeeds() external { function test_transferFrom_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando approves owner to spend 50 tokens. // Rando approves owner to spend 50 tokens.
vm.prank(rando); vm.prank(rando);
gov.approve(owner, 50); governanceToken.approve(owner, 50);
// Owner transfers 50 tokens from rando to owner. // Owner transfers 50 tokens from rando to owner.
vm.prank(owner); vm.prank(owner);
gov.transferFrom(rando, owner, 50); governanceToken.transferFrom(rando, owner, 50);
// Balances have updated correctly. // Balances have updated correctly.
assertEq(gov.balanceOf(owner), 50); assertEq(governanceToken.balanceOf(owner), 50);
assertEq(gov.balanceOf(rando), 50); assertEq(governanceToken.balanceOf(rando), 50);
assertEq(gov.totalSupply(), 100); assertEq(governanceToken.totalSupply(), 100);
} }
/// @dev Tests that `increaseAllowance` correctly increases allowances. /// @dev Tests that `increaseAllowance` correctly increases allowances.
function test_increaseAllowance_succeeds() external { function test_increaseAllowance_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando approves owner to spend 50 tokens. // Rando approves owner to spend 50 tokens.
vm.prank(rando); vm.prank(rando);
gov.approve(owner, 50); governanceToken.approve(owner, 50);
// Rando increases allowance by 50 tokens. // Rando increases allowance by 50 tokens.
vm.prank(rando); vm.prank(rando);
gov.increaseAllowance(owner, 50); governanceToken.increaseAllowance(owner, 50);
// Allowances have updated. // Allowances have updated.
assertEq(gov.allowance(rando, owner), 100); assertEq(governanceToken.allowance(rando, owner), 100);
} }
/// @dev Tests that `decreaseAllowance` correctly decreases allowances. /// @dev Tests that `decreaseAllowance` correctly decreases allowances.
function test_decreaseAllowance_succeeds() external { function test_decreaseAllowance_succeeds() external {
// Mint 100 tokens to rando. // Mint 100 tokens to rando.
vm.prank(owner); vm.prank(owner);
gov.mint(rando, 100); governanceToken.mint(rando, 100);
// Rando approves owner to spend 100 tokens. // Rando approves owner to spend 100 tokens.
vm.prank(rando); vm.prank(rando);
gov.approve(owner, 100); governanceToken.approve(owner, 100);
// Rando decreases allowance by 50 tokens. // Rando decreases allowance by 50 tokens.
vm.prank(rando); vm.prank(rando);
gov.decreaseAllowance(owner, 50); governanceToken.decreaseAllowance(owner, 50);
// Allowances have updated. // Allowances have updated.
assertEq(gov.allowance(rando, owner), 50); assertEq(governanceToken.allowance(rando, owner), 50);
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { console } from "forge-std/console.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol";
...@@ -13,19 +12,19 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol"; ...@@ -13,19 +12,19 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol";
/// @dev Ensures that the `initialize()` function on contracts cannot be called more than /// @dev Ensures that the `initialize()` function on contracts cannot be called more than
/// once. This contract inherits from `ERC721Bridge_Initializer` because it is the /// once. This contract inherits from `ERC721Bridge_Initializer` because it is the
/// deepest contract in the inheritance chain for setting up the system contracts. /// deepest contract in the inheritance chain for setting up the system contracts.
contract Initializer_Test is ERC721Bridge_Initializer { contract Initializer_Test is Bridge_Initializer {
function test_cannotReinitializeL1_succeeds() public { function test_cannotReinitializeL1_succeeds() public {
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L1Messenger.initialize(OptimismPortal(payable(address(0)))); l1CrossDomainMessenger.initialize(OptimismPortal(payable(address(0))));
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L1Bridge.initialize(CrossDomainMessenger(address(0))); l1StandardBridge.initialize(CrossDomainMessenger(address(0)));
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
oracle.initialize(0, 0, address(0), address(0)); l2OutputOracle.initialize(0, 0, address(0), address(0));
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
op.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false); optimismPortal.initialize(L2OutputOracle(address(0)), address(0), SystemConfig(address(0)), false);
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
systemConfig.initialize({ systemConfig.initialize({
...@@ -56,6 +55,6 @@ contract Initializer_Test is ERC721Bridge_Initializer { ...@@ -56,6 +55,6 @@ contract Initializer_Test is ERC721Bridge_Initializer {
}); });
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L1NFTBridge.initialize(CrossDomainMessenger(address(0))); l1ERC721Bridge.initialize(CrossDomainMessenger(address(0)));
} }
} }
...@@ -2,27 +2,25 @@ ...@@ -2,27 +2,25 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract // Target contract
import { L1Block } from "src/L2/L1Block.sol"; import { L1Block } from "src/L2/L1Block.sol";
contract L1BlockTest is CommonTest { contract L1BlockTest is CommonTest {
L1Block lb;
address depositor; address depositor;
bytes32 immutable NON_ZERO_HASH = keccak256(abi.encode(1));
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
lb = new L1Block();
depositor = lb.DEPOSITOR_ACCOUNT(); depositor = l1Block.DEPOSITOR_ACCOUNT();
vm.prank(depositor); vm.prank(depositor);
lb.setL1BlockValues({ l1Block.setL1BlockValues({
_number: uint64(1), _number: uint64(1),
_timestamp: uint64(2), _timestamp: uint64(2),
_basefee: 3, _basefee: 3,
_hash: NON_ZERO_HASH, _hash: keccak256(abi.encode(block.number)),
_sequenceNumber: uint64(4), _sequenceNumber: uint64(4),
_batcherHash: bytes32(0), _batcherHash: bytes32(0),
_l1FeeOverhead: 2, _l1FeeOverhead: 2,
...@@ -44,46 +42,46 @@ contract L1BlockTest is CommonTest { ...@@ -44,46 +42,46 @@ contract L1BlockTest is CommonTest {
external external
{ {
vm.prank(depositor); vm.prank(depositor);
lb.setL1BlockValues(n, t, b, h, s, bt, fo, fs); l1Block.setL1BlockValues(n, t, b, h, s, bt, fo, fs);
assertEq(lb.number(), n); assertEq(l1Block.number(), n);
assertEq(lb.timestamp(), t); assertEq(l1Block.timestamp(), t);
assertEq(lb.basefee(), b); assertEq(l1Block.basefee(), b);
assertEq(lb.hash(), h); assertEq(l1Block.hash(), h);
assertEq(lb.sequenceNumber(), s); assertEq(l1Block.sequenceNumber(), s);
assertEq(lb.batcherHash(), bt); assertEq(l1Block.batcherHash(), bt);
assertEq(lb.l1FeeOverhead(), fo); assertEq(l1Block.l1FeeOverhead(), fo);
assertEq(lb.l1FeeScalar(), fs); assertEq(l1Block.l1FeeScalar(), fs);
} }
/// @dev Tests that `number` returns the correct value. /// @dev Tests that `number` returns the correct value.
function test_number_succeeds() external { function test_number_succeeds() external {
assertEq(lb.number(), uint64(1)); assertEq(l1Block.number(), uint64(1));
} }
/// @dev Tests that `timestamp` returns the correct value. /// @dev Tests that `timestamp` returns the correct value.
function test_timestamp_succeeds() external { function test_timestamp_succeeds() external {
assertEq(lb.timestamp(), uint64(2)); assertEq(l1Block.timestamp(), uint64(2));
} }
/// @dev Tests that `basefee` returns the correct value. /// @dev Tests that `basefee` returns the correct value.
function test_basefee_succeeds() external { function test_basefee_succeeds() external {
assertEq(lb.basefee(), 3); assertEq(l1Block.basefee(), 3);
} }
/// @dev Tests that `hash` returns the correct value. /// @dev Tests that `hash` returns the correct value.
function test_hash_succeeds() external { function test_hash_succeeds() external {
assertEq(lb.hash(), NON_ZERO_HASH); assertEq(l1Block.hash(), keccak256(abi.encode(block.number)));
} }
/// @dev Tests that `sequenceNumber` returns the correct value. /// @dev Tests that `sequenceNumber` returns the correct value.
function test_sequenceNumber_succeeds() external { function test_sequenceNumber_succeeds() external {
assertEq(lb.sequenceNumber(), uint64(4)); assertEq(l1Block.sequenceNumber(), uint64(4));
} }
/// @dev Tests that `setL1BlockValues` can set max values. /// @dev Tests that `setL1BlockValues` can set max values.
function test_updateValues_succeeds() external { function test_updateValues_succeeds() external {
vm.prank(depositor); vm.prank(depositor);
lb.setL1BlockValues({ l1Block.setL1BlockValues({
_number: type(uint64).max, _number: type(uint64).max,
_timestamp: type(uint64).max, _timestamp: type(uint64).max,
_basefee: type(uint256).max, _basefee: type(uint256).max,
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Messenger_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { L2OutputOracle_Initializer } from "test/L2OutputOracle.t.sol";
import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol";
// Libraries // Libraries
...@@ -15,7 +14,7 @@ import { Encoding } from "src/libraries/Encoding.sol"; ...@@ -15,7 +14,7 @@ import { Encoding } from "src/libraries/Encoding.sol";
// Target contract dependencies // Target contract dependencies
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
contract L1CrossDomainMessenger_Test is Messenger_Initializer { contract L1CrossDomainMessenger_Test is Bridge_Initializer {
/// @dev The receiver address /// @dev The receiver address
address recipient = address(0xabbaacdc); address recipient = address(0xabbaacdc);
...@@ -24,8 +23,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -24,8 +23,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
/// @dev Tests that the version can be decoded from the message nonce. /// @dev Tests that the version can be decoded from the message nonce.
function test_messageVersion_succeeds() external { function test_messageVersion_succeeds() external {
(, uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce()); (, uint16 version) = Encoding.decodeVersionedNonce(l1CrossDomainMessenger.messageNonce());
assertEq(version, L1Messenger.MESSAGE_VERSION()); assertEq(version, l1CrossDomainMessenger.MESSAGE_VERSION());
} }
/// @dev Tests that the sendMessage function is able to send a single message. /// @dev Tests that the sendMessage function is able to send a single message.
...@@ -34,55 +33,57 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -34,55 +33,57 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
function test_sendMessage_succeeds() external { function test_sendMessage_succeeds() external {
// deposit transaction on the optimism portal should be called // deposit transaction on the optimism portal should be called
vm.expectCall( vm.expectCall(
address(op), address(optimismPortal),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, OptimismPortal.depositTransaction.selector,
Predeploys.L2_CROSS_DOMAIN_MESSENGER, Predeploys.L2_CROSS_DOMAIN_MESSENGER,
0, 0,
L1Messenger.baseGas(hex"ff", 100), l1CrossDomainMessenger.baseGas(hex"ff", 100),
false, false,
Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff") Encoding.encodeCrossDomainMessage(
l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff"
)
) )
); );
// TransactionDeposited event // TransactionDeposited event
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emitTransactionDeposited( emitTransactionDeposited(
AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)), AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)),
Predeploys.L2_CROSS_DOMAIN_MESSENGER, Predeploys.L2_CROSS_DOMAIN_MESSENGER,
0, 0,
0, 0,
L1Messenger.baseGas(hex"ff", 100), l1CrossDomainMessenger.baseGas(hex"ff", 100),
false, false,
Encoding.encodeCrossDomainMessage(L1Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff") Encoding.encodeCrossDomainMessage(l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff")
); );
// SentMessage event // SentMessage event
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit SentMessage(recipient, alice, hex"ff", L1Messenger.messageNonce(), 100); emit SentMessage(recipient, alice, hex"ff", l1CrossDomainMessenger.messageNonce(), 100);
// SentMessageExtension1 event // SentMessageExtension1 event
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit SentMessageExtension1(alice, 0); emit SentMessageExtension1(alice, 0);
vm.prank(alice); vm.prank(alice);
L1Messenger.sendMessage(recipient, hex"ff", uint32(100)); l1CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100));
} }
/// @dev Tests that the sendMessage function is able to send /// @dev Tests that the sendMessage function is able to send
/// the same message twice. /// the same message twice.
function test_sendMessage_twice_succeeds() external { function test_sendMessage_twice_succeeds() external {
uint256 nonce = L1Messenger.messageNonce(); uint256 nonce = l1CrossDomainMessenger.messageNonce();
L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); l1CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000));
L1Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); l1CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000));
// the nonce increments for each message sent // the nonce increments for each message sent
assertEq(nonce + 2, L1Messenger.messageNonce()); assertEq(nonce + 2, l1CrossDomainMessenger.messageNonce());
} }
/// @dev Tests that the xDomainMessageSender reverts when not set. /// @dev Tests that the xDomainMessageSender reverts when not set.
function test_xDomainSender_notSet_reverts() external { function test_xDomainSender_notSet_reverts() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); l1CrossDomainMessenger.xDomainMessageSender();
} }
/// @dev Tests that the relayMessage function reverts when /// @dev Tests that the relayMessage function reverts when
...@@ -92,14 +93,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -92,14 +93,14 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
// Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Expect a revert. // Expect a revert.
vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
// Try to relay a v2 message. // Try to relay a v2 message.
vm.prank(address(op)); vm.prank(address(optimismPortal));
L2Messenger.relayMessage( l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 2 }), // nonce
sender, sender,
target, target,
...@@ -118,8 +119,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -118,8 +119,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectCall(target, hex"1111"); vm.expectCall(target, hex"1111");
// set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(op)); vm.prank(address(optimismPortal));
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -129,7 +130,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -129,7 +130,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
emit RelayedMessage(hash); emit RelayedMessage(hash);
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce
sender, sender,
target, target,
...@@ -139,28 +140,28 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -139,28 +140,28 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// the message hash is in the successfulMessages mapping // the message hash is in the successfulMessages mapping
assert(L1Messenger.successfulMessages(hash)); assert(l1CrossDomainMessenger.successfulMessages(hash));
// it is not in the received messages mapping // it is not in the received messages mapping
assertEq(L1Messenger.failedMessages(hash), false); assertEq(l1CrossDomainMessenger.failedMessages(hash), false);
} }
/// @dev Tests that relayMessage reverts if attempting to relay a message /// @dev Tests that relayMessage reverts if attempting to relay a message
/// sent to an L1 system contract. /// sent to an L1 system contract.
function test_relayMessage_toSystemContract_reverts() external { function test_relayMessage_toSystemContract_reverts() external {
// set the target to be the OptimismPortal // set the target to be the OptimismPortal
address target = address(op); address target = address(optimismPortal);
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.prank(address(op)); vm.prank(address(optimismPortal));
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
); );
vm.store(address(op), 0, bytes32(abi.encode(sender))); vm.store(address(optimismPortal), 0, bytes32(abi.encode(sender)));
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
); );
} }
...@@ -173,7 +174,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -173,7 +174,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address"); vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address");
L1Messenger.relayMessage{ value: 100 }( l1CrossDomainMessenger.relayMessage{ value: 100 }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, message
); );
} }
...@@ -182,18 +183,18 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -182,18 +183,18 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
/// after a message is relayed. /// after a message is relayed.
function test_xDomainMessageSender_reset_succeeds() external { function test_xDomainMessageSender_reset_succeeds() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); l1CrossDomainMessenger.xDomainMessageSender();
address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER;
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex"" Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), address(0), address(0), 0, 0, hex""
); );
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L1Messenger.xDomainMessageSender(); l1CrossDomainMessenger.xDomainMessageSender();
} }
/// @dev Tests that relayMessage should successfully call the target contract after /// @dev Tests that relayMessage should successfully call the target contract after
...@@ -210,11 +211,11 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -210,11 +211,11 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111" Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, value, 0, hex"1111"
); );
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
vm.etch(target, address(new Reverter()).code); vm.etch(target, address(new Reverter()).code);
vm.deal(address(op), value); vm.deal(address(optimismPortal), value);
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage{ value: value }( l1CrossDomainMessenger.relayMessage{ value: value }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce
sender, sender,
target, target,
...@@ -223,10 +224,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -223,10 +224,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
hex"1111" hex"1111"
); );
assertEq(address(L1Messenger).balance, value); assertEq(address(l1CrossDomainMessenger).balance, value);
assertEq(address(target).balance, 0); assertEq(address(target).balance, 0);
assertEq(L1Messenger.successfulMessages(hash), false); assertEq(l1CrossDomainMessenger.successfulMessages(hash), false);
assertEq(L1Messenger.failedMessages(hash), true); assertEq(l1CrossDomainMessenger.failedMessages(hash), true);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -234,7 +235,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -234,7 +235,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.etch(target, address(0).code); vm.etch(target, address(0).code);
vm.prank(address(sender)); vm.prank(address(sender));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce
sender, sender,
target, target,
...@@ -243,10 +244,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -243,10 +244,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
hex"1111" hex"1111"
); );
assertEq(address(L1Messenger).balance, 0); assertEq(address(l1CrossDomainMessenger).balance, 0);
assertEq(address(target).balance, value); assertEq(address(target).balance, value);
assertEq(L1Messenger.successfulMessages(hash), true); assertEq(l1CrossDomainMessenger.successfulMessages(hash), true);
assertEq(L1Messenger.failedMessages(hash), true); assertEq(l1CrossDomainMessenger.failedMessages(hash), true);
} }
/// @dev Tests that relayMessage should successfully call the target contract after /// @dev Tests that relayMessage should successfully call the target contract after
...@@ -268,7 +269,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -268,7 +269,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Target should be called with expected data. // Target should be called with expected data.
vm.expectCall(target, hex"1111"); vm.expectCall(target, hex"1111");
...@@ -278,8 +279,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -278,8 +279,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
emit RelayedMessage(hash); emit RelayedMessage(hash);
// Relay the message. // Relay the message.
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -289,8 +290,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -289,8 +290,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message was successfully relayed. // Message was successfully relayed.
assertEq(L1Messenger.successfulMessages(hash), true); assertEq(l1CrossDomainMessenger.successfulMessages(hash), true);
assertEq(L1Messenger.failedMessages(hash), false); assertEq(l1CrossDomainMessenger.failedMessages(hash), false);
} }
/// @dev Tests that relayMessage should revert if the message is already replayed. /// @dev Tests that relayMessage should revert if the message is already replayed.
...@@ -310,20 +311,19 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -310,20 +311,19 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Mark legacy message as already relayed. // Mark legacy message as already relayed.
uint256 successfulMessagesSlot = 203; uint256 successfulMessagesSlot = 203;
bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex"1111", 0); bytes32 oldHash = Hashing.hashCrossDomainMessageV0(target, sender, hex"1111", 0);
bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot)); bytes32 slot = keccak256(abi.encode(oldHash, successfulMessagesSlot));
vm.store(address(L1Messenger), slot, bytes32(uint256(1))); vm.store(address(l1CrossDomainMessenger), slot, bytes32(uint256(1)));
// Expect revert. // Expect revert.
vm.expectRevert("CrossDomainMessenger: legacy withdrawal already relayed"); vm.expectRevert("CrossDomainMessenger: legacy withdrawal already relayed");
// Relay the message. // Relay the message.
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -333,8 +333,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -333,8 +333,8 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message was not relayed. // Message was not relayed.
assertEq(L1Messenger.successfulMessages(hash), false); assertEq(l1CrossDomainMessenger.successfulMessages(hash), false);
assertEq(L1Messenger.failedMessages(hash), false); assertEq(l1CrossDomainMessenger.failedMessages(hash), false);
} }
/// @dev Tests that relayMessage can be retried after a failure with a legacy message. /// @dev Tests that relayMessage can be retried after a failure with a legacy message.
...@@ -355,7 +355,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -355,7 +355,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Turn the target into a Reverter. // Turn the target into a Reverter.
vm.etch(target, address(new Reverter()).code); vm.etch(target, address(new Reverter()).code);
...@@ -368,9 +368,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -368,9 +368,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
emit FailedRelayedMessage(hash); emit FailedRelayedMessage(hash);
// Relay the message. // Relay the message.
vm.deal(address(op), value); vm.deal(address(optimismPortal), value);
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage{ value: value }( l1CrossDomainMessenger.relayMessage{ value: value }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -380,10 +380,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -380,10 +380,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message failed. // Message failed.
assertEq(address(L1Messenger).balance, value); assertEq(address(l1CrossDomainMessenger).balance, value);
assertEq(address(target).balance, 0); assertEq(address(target).balance, 0);
assertEq(L1Messenger.successfulMessages(hash), false); assertEq(l1CrossDomainMessenger.successfulMessages(hash), false);
assertEq(L1Messenger.failedMessages(hash), true); assertEq(l1CrossDomainMessenger.failedMessages(hash), true);
// Make the target not revert anymore. // Make the target not revert anymore.
vm.etch(target, address(0).code); vm.etch(target, address(0).code);
...@@ -397,7 +397,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -397,7 +397,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
// Retry the message. // Retry the message.
vm.prank(address(sender)); vm.prank(address(sender));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -407,10 +407,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -407,10 +407,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message was successfully relayed. // Message was successfully relayed.
assertEq(address(L1Messenger).balance, 0); assertEq(address(l1CrossDomainMessenger).balance, 0);
assertEq(address(target).balance, value); assertEq(address(target).balance, value);
assertEq(L1Messenger.successfulMessages(hash), true); assertEq(l1CrossDomainMessenger.successfulMessages(hash), true);
assertEq(L1Messenger.failedMessages(hash), true); assertEq(l1CrossDomainMessenger.failedMessages(hash), true);
} }
/// @dev Tests that relayMessage cannot be retried after success with a legacy message. /// @dev Tests that relayMessage cannot be retried after success with a legacy message.
...@@ -431,7 +431,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -431,7 +431,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Target should be called with expected data. // Target should be called with expected data.
vm.expectCall(target, hex"1111"); vm.expectCall(target, hex"1111");
...@@ -441,9 +441,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -441,9 +441,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
emit RelayedMessage(hash); emit RelayedMessage(hash);
// Relay the message. // Relay the message.
vm.deal(address(op), value); vm.deal(address(optimismPortal), value);
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage{ value: value }( l1CrossDomainMessenger.relayMessage{ value: value }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -453,17 +453,17 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -453,17 +453,17 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message was successfully relayed. // Message was successfully relayed.
assertEq(address(L1Messenger).balance, 0); assertEq(address(l1CrossDomainMessenger).balance, 0);
assertEq(address(target).balance, value); assertEq(address(target).balance, value);
assertEq(L1Messenger.successfulMessages(hash), true); assertEq(l1CrossDomainMessenger.successfulMessages(hash), true);
assertEq(L1Messenger.failedMessages(hash), false); assertEq(l1CrossDomainMessenger.failedMessages(hash), false);
// Expect a revert. // Expect a revert.
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
// Retry the message. // Retry the message.
vm.prank(address(sender)); vm.prank(address(sender));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -491,7 +491,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -491,7 +491,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Set the value of op.l2Sender() to be the L2 Cross Domain Messenger. // Set the value of op.l2Sender() to be the L2 Cross Domain Messenger.
vm.store(address(op), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); vm.store(address(optimismPortal), bytes32(senderSlotIndex), bytes32(abi.encode(sender)));
// Turn the target into a Reverter. // Turn the target into a Reverter.
vm.etch(target, address(new Reverter()).code); vm.etch(target, address(new Reverter()).code);
...@@ -500,9 +500,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -500,9 +500,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectCall(target, hex"1111"); vm.expectCall(target, hex"1111");
// Relay the message. // Relay the message.
vm.deal(address(op), value); vm.deal(address(optimismPortal), value);
vm.prank(address(op)); vm.prank(address(optimismPortal));
L1Messenger.relayMessage{ value: value }( l1CrossDomainMessenger.relayMessage{ value: value }(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -512,10 +512,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -512,10 +512,10 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message failed. // Message failed.
assertEq(address(L1Messenger).balance, value); assertEq(address(l1CrossDomainMessenger).balance, value);
assertEq(address(target).balance, 0); assertEq(address(target).balance, 0);
assertEq(L1Messenger.successfulMessages(hash), false); assertEq(l1CrossDomainMessenger.successfulMessages(hash), false);
assertEq(L1Messenger.failedMessages(hash), true); assertEq(l1CrossDomainMessenger.failedMessages(hash), true);
// Make the target not revert anymore. // Make the target not revert anymore.
vm.etch(target, address(0).code); vm.etch(target, address(0).code);
...@@ -529,7 +529,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -529,7 +529,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
// Retry the message // Retry the message
vm.prank(address(sender)); vm.prank(address(sender));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
...@@ -539,17 +539,17 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -539,17 +539,17 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
); );
// Message was successfully relayed. // Message was successfully relayed.
assertEq(address(L1Messenger).balance, 0); assertEq(address(l1CrossDomainMessenger).balance, 0);
assertEq(address(target).balance, value); assertEq(address(target).balance, value);
assertEq(L1Messenger.successfulMessages(hash), true); assertEq(l1CrossDomainMessenger.successfulMessages(hash), true);
assertEq(L1Messenger.failedMessages(hash), true); assertEq(l1CrossDomainMessenger.failedMessages(hash), true);
// Expect a revert. // Expect a revert.
vm.expectRevert("CrossDomainMessenger: message has already been relayed"); vm.expectRevert("CrossDomainMessenger: message has already been relayed");
// Retry the message again. // Retry the message again.
vm.prank(address(sender)); vm.prank(address(sender));
L1Messenger.relayMessage( l1CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce Encoding.encodeVersionedNonce({ _nonce: 0, _version: 0 }), // nonce
sender, sender,
target, target,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// Target contract dependencies // Target contract dependencies
...@@ -21,7 +21,7 @@ contract TestERC721 is ERC721 { ...@@ -21,7 +21,7 @@ contract TestERC721 is ERC721 {
} }
} }
contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { contract L1ERC721Bridge_Test is Bridge_Initializer {
TestERC721 internal localToken; TestERC721 internal localToken;
TestERC721 internal remoteToken; TestERC721 internal remoteToken;
uint256 internal constant tokenId = 1; uint256 internal constant tokenId = 1;
...@@ -56,26 +56,26 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -56,26 +56,26 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Approve the bridge to transfer the token. // Approve the bridge to transfer the token.
vm.prank(alice); vm.prank(alice);
localToken.approve(address(L1NFTBridge), tokenId); localToken.approve(address(l1ERC721Bridge), tokenId);
} }
/// @dev Tests that the constructor sets the correct values. /// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() public { function test_constructor_succeeds() public {
assertEq(address(L1NFTBridge.MESSENGER()), address(L1Messenger)); assertEq(address(l1ERC721Bridge.MESSENGER()), address(l1CrossDomainMessenger));
assertEq(address(L1NFTBridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE); assertEq(address(l1ERC721Bridge.OTHER_BRIDGE()), Predeploys.L2_ERC721_BRIDGE);
assertEq(address(L1NFTBridge.messenger()), address(L1Messenger)); assertEq(address(l1ERC721Bridge.messenger()), address(l1CrossDomainMessenger));
assertEq(address(L1NFTBridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE); assertEq(address(l1ERC721Bridge.otherBridge()), Predeploys.L2_ERC721_BRIDGE);
} }
/// @dev Tests that the ERC721 can be bridged successfully. /// @dev Tests that the ERC721 can be bridged successfully.
function test_bridgeERC721_succeeds() public { function test_bridgeERC721_succeeds() public {
// Expect a call to the messenger. // Expect a call to the messenger.
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeCall( abi.encodeCall(
L1Messenger.sendMessage, l1CrossDomainMessenger.sendMessage,
( (
address(L2NFTBridge), address(l2ERC721Bridge),
abi.encodeCall( abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721, L2ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
...@@ -91,11 +91,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -91,11 +91,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is locked in the bridge. // Token is locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge)); assertEq(localToken.ownerOf(tokenId), address(l1ERC721Bridge));
} }
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts. /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts.
...@@ -104,10 +104,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -104,10 +104,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.etch(alice, hex"01"); vm.etch(alice, hex"01");
vm.prank(alice); vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned"); vm.expectRevert("ERC721Bridge: account is not externally owned");
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -116,10 +116,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -116,10 +116,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert(); vm.expectRevert();
L1NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -128,10 +128,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -128,10 +128,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)");
L1NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -140,10 +140,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -140,10 +140,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner"); vm.expectRevert("ERC721: transfer from incorrect owner");
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -152,9 +152,9 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -152,9 +152,9 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_bridgeERC721To_succeeds() external { function test_bridgeERC721To_succeeds() external {
// Expect a call to the messenger. // Expect a call to the messenger.
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeCall( abi.encodeCall(
L1Messenger.sendMessage, l1CrossDomainMessenger.sendMessage,
( (
address(Predeploys.L2_ERC721_BRIDGE), address(Predeploys.L2_ERC721_BRIDGE),
abi.encodeCall( abi.encodeCall(
...@@ -172,11 +172,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -172,11 +172,11 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is locked in the bridge. // Token is locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), true); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), true);
assertEq(localToken.ownerOf(tokenId), address(L1NFTBridge)); assertEq(localToken.ownerOf(tokenId), address(l1ERC721Bridge));
} }
/// @dev Tests that the ERC721 bridge reverts for non externally owned accounts /// @dev Tests that the ERC721 bridge reverts for non externally owned accounts
...@@ -185,10 +185,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -185,10 +185,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert(); vm.expectRevert();
L1NFTBridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721To(address(0), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -198,10 +198,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -198,10 +198,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)"); vm.expectRevert("L1ERC721Bridge: remote token cannot be address(0)");
L1NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -211,10 +211,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -211,10 +211,10 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
vm.expectRevert("ERC721: transfer from incorrect owner"); vm.expectRevert("ERC721: transfer from incorrect owner");
L1NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -222,7 +222,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -222,7 +222,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_succeeds() external { function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L1NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l1ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -230,15 +230,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -230,15 +230,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(Predeploys.L2_ERC721_BRIDGE) abi.encode(Predeploys.L2_ERC721_BRIDGE)
); );
vm.prank(address(L1Messenger)); vm.prank(address(l1CrossDomainMessenger));
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(L1NFTBridge.deposits(address(localToken), address(remoteToken), tokenId), false); assertEq(l1ERC721Bridge.deposits(address(localToken), address(remoteToken), tokenId), false);
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
} }
...@@ -248,7 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -248,7 +248,7 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
} }
/// @dev Tests that the ERC721 bridge finalize reverts when not called /// @dev Tests that the ERC721 bridge finalize reverts when not called
...@@ -256,11 +256,13 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -256,11 +256,13 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L1Messenger), abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encode(alice) address(l1CrossDomainMessenger),
abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(alice)
); );
vm.prank(address(L1Messenger)); vm.prank(address(l1CrossDomainMessenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
} }
/// @dev Tests that the ERC721 bridge finalize reverts when the local token /// @dev Tests that the ERC721 bridge finalize reverts when the local token
...@@ -268,13 +270,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -268,13 +270,15 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_selfToken_reverts() external { function test_finalizeBridgeERC721_selfToken_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(Predeploys.L2_ERC721_BRIDGE) abi.encode(Predeploys.L2_ERC721_BRIDGE)
); );
vm.prank(address(L1Messenger)); vm.prank(address(l1CrossDomainMessenger));
vm.expectRevert("L1ERC721Bridge: local token cannot be self"); vm.expectRevert("L1ERC721Bridge: local token cannot be self");
L1NFTBridge.finalizeBridgeERC721(address(L1NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678"); l1ERC721Bridge.finalizeBridgeERC721(
address(l1ERC721Bridge), address(remoteToken), alice, alice, tokenId, hex"5678"
);
} }
/// @dev Tests that the ERC721 bridge finalize reverts when the remote token /// @dev Tests that the ERC721 bridge finalize reverts when the remote token
...@@ -282,12 +286,12 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -282,12 +286,12 @@ contract L1ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_notEscrowed_reverts() external { function test_finalizeBridgeERC721_notEscrowed_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector(L1Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l1CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(Predeploys.L2_ERC721_BRIDGE) abi.encode(Predeploys.L2_ERC721_BRIDGE)
); );
vm.prank(address(L1Messenger)); vm.prank(address(l1CrossDomainMessenger));
vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge"); vm.expectRevert("L1ERC721Bridge: Token ID is not escrowed in the L1 Bridge");
L1NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l1ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
} }
} }
...@@ -4,7 +4,7 @@ pragma solidity 0.8.15; ...@@ -4,7 +4,7 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { stdStorage, StdStorage } from "forge-std/Test.sol"; import { stdStorage, StdStorage } from "forge-std/Test.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
...@@ -22,20 +22,20 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol"; ...@@ -22,20 +22,20 @@ import { OptimismPortal } from "src/L1/OptimismPortal.sol";
contract L1StandardBridge_Getter_Test is Bridge_Initializer { contract L1StandardBridge_Getter_Test is Bridge_Initializer {
/// @dev Test that the accessors return the correct initialized values. /// @dev Test that the accessors return the correct initialized values.
function test_getters_succeeds() external view { function test_getters_succeeds() external view {
assert(L1Bridge.l2TokenBridge() == address(L2Bridge)); assert(l1StandardBridge.l2TokenBridge() == address(l2StandardBridge));
assert(L1Bridge.OTHER_BRIDGE() == L2Bridge); assert(l1StandardBridge.OTHER_BRIDGE() == l2StandardBridge);
assert(L1Bridge.messenger() == L1Messenger); assert(l1StandardBridge.messenger() == l1CrossDomainMessenger);
assert(L1Bridge.MESSENGER() == L1Messenger); assert(l1StandardBridge.MESSENGER() == l1CrossDomainMessenger);
} }
} }
contract L1StandardBridge_Initialize_Test is Bridge_Initializer { contract L1StandardBridge_Initialize_Test is Bridge_Initializer {
/// @dev Test that the initialize function sets the correct values. /// @dev Test that the initialize function sets the correct values.
function test_initialize_succeeds() external { function test_initialize_succeeds() external {
assertEq(address(L1Bridge.messenger()), address(L1Messenger)); assertEq(address(l1StandardBridge.messenger()), address(l1CrossDomainMessenger));
assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); assertEq(address(l1StandardBridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);
assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE); assertEq(address(l2StandardBridge), Predeploys.L2_STANDARD_BRIDGE);
bytes32 slot0 = vm.load(address(L1Bridge), bytes32(uint256(0))); bytes32 slot0 = vm.load(address(l1StandardBridge), bytes32(uint256(0)));
assertEq(slot0, bytes32(uint256(Constants.INITIALIZER))); assertEq(slot0, bytes32(uint256(Constants.INITIALIZER)));
} }
} }
...@@ -45,29 +45,29 @@ contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer { } ...@@ -45,29 +45,29 @@ contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer { }
contract L1StandardBridge_Receive_Test is Bridge_Initializer { contract L1StandardBridge_Receive_Test is Bridge_Initializer {
/// @dev Tests receive bridges ETH successfully. /// @dev Tests receive bridges ETH successfully.
function test_receive_succeeds() external { function test_receive_succeeds() external {
assertEq(address(op).balance, 0); assertEq(address(optimismPortal).balance, 0);
// The legacy event must be emitted for backwards compatibility // The legacy event must be emitted for backwards compatibility
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHDepositInitiated(alice, alice, 100, hex""); emit ETHDepositInitiated(alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHBridgeInitiated(alice, alice, 100, hex""); emit ETHBridgeInitiated(alice, alice, 100, hex"");
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector( abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector, CrossDomainMessenger.sendMessage.selector,
address(L2Bridge), address(l2StandardBridge),
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""), abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""),
200_000 200_000
) )
); );
vm.prank(alice, alice); vm.prank(alice, alice);
(bool success,) = address(L1Bridge).call{ value: 100 }(hex""); (bool success,) = address(l1StandardBridge).call{ value: 100 }(hex"");
assertEq(success, true); assertEq(success, true);
assertEq(address(op).balance, 100); assertEq(address(optimismPortal).balance, 100);
} }
} }
...@@ -77,59 +77,76 @@ contract PreBridgeETH is Bridge_Initializer { ...@@ -77,59 +77,76 @@ contract PreBridgeETH is Bridge_Initializer {
/// @dev Asserts the expected calls and events for bridging ETH depending /// @dev Asserts the expected calls and events for bridging ETH depending
/// on whether the bridge call is legacy or not. /// on whether the bridge call is legacy or not.
function _preBridgeETH(bool isLegacy) internal { function _preBridgeETH(bool isLegacy) internal {
assertEq(address(op).balance, 0); assertEq(address(optimismPortal).balance, 0);
uint256 nonce = L1Messenger.messageNonce(); uint256 nonce = l1CrossDomainMessenger.messageNonce();
uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
bytes memory message = bytes memory message =
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead"); abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 500, hex"dead");
if (isLegacy) { if (isLegacy) {
vm.expectCall( vm.expectCall(
address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.depositETH.selector, 50000, hex"dead") address(l1StandardBridge),
500,
abi.encodeWithSelector(l1StandardBridge.depositETH.selector, 50000, hex"dead")
); );
} else { } else {
vm.expectCall(address(L1Bridge), 500, abi.encodeWithSelector(L1Bridge.bridgeETH.selector, 50000, hex"dead")); vm.expectCall(
address(l1StandardBridge),
500,
abi.encodeWithSelector(l1StandardBridge.bridgeETH.selector, 50000, hex"dead")
);
} }
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
500, 500,
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 50000) abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 50000)
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 500, 50000, message CrossDomainMessenger.relayMessage.selector,
nonce,
address(l1StandardBridge),
address(l2StandardBridge),
500,
50000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 50000); uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 50000);
vm.expectCall( vm.expectCall(
address(op), address(optimismPortal),
500, 500,
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, address(L2Messenger), 500, baseGas, false, innerMessage OptimismPortal.depositTransaction.selector,
address(l2CrossDomainMessenger),
500,
baseGas,
false,
innerMessage
) )
); );
bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage); bytes memory opaqueData = abi.encodePacked(uint256(500), uint256(500), baseGas, false, innerMessage);
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHDepositInitiated(alice, alice, 500, hex"dead"); emit ETHDepositInitiated(alice, alice, 500, hex"dead");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHBridgeInitiated(alice, alice, 500, hex"dead"); emit ETHBridgeInitiated(alice, alice, 500, hex"dead");
// OptimismPortal emits a TransactionDeposited event on `depositTransaction` call // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call
vm.expectEmit(true, true, true, true, address(op)); vm.expectEmit(true, true, true, true, address(optimismPortal));
emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData);
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 50000); emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 50000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessageExtension1(address(L1Bridge), 500); emit SentMessageExtension1(address(l1StandardBridge), 500);
vm.prank(alice, alice); vm.prank(alice, alice);
} }
...@@ -143,8 +160,8 @@ contract L1StandardBridge_DepositETH_Test is PreBridgeETH { ...@@ -143,8 +160,8 @@ contract L1StandardBridge_DepositETH_Test is PreBridgeETH {
/// ETH ends up in the optimismPortal. /// ETH ends up in the optimismPortal.
function test_depositETH_succeeds() external { function test_depositETH_succeeds() external {
_preBridgeETH({ isLegacy: true }); _preBridgeETH({ isLegacy: true });
L1Bridge.depositETH{ value: 500 }(50000, hex"dead"); l1StandardBridge.depositETH{ value: 500 }(50000, hex"dead");
assertEq(address(op).balance, 500); assertEq(address(optimismPortal).balance, 500);
} }
} }
...@@ -156,8 +173,8 @@ contract L1StandardBridge_BridgeETH_Test is PreBridgeETH { ...@@ -156,8 +173,8 @@ contract L1StandardBridge_BridgeETH_Test is PreBridgeETH {
/// ETH ends up in the optimismPortal. /// ETH ends up in the optimismPortal.
function test_bridgeETH_succeeds() external { function test_bridgeETH_succeeds() external {
_preBridgeETH({ isLegacy: false }); _preBridgeETH({ isLegacy: false });
L1Bridge.bridgeETH{ value: 500 }(50000, hex"dead"); l1StandardBridge.bridgeETH{ value: 500 }(50000, hex"dead");
assertEq(address(op).balance, 500); assertEq(address(optimismPortal).balance, 500);
} }
} }
...@@ -167,7 +184,7 @@ contract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer { ...@@ -167,7 +184,7 @@ contract L1StandardBridge_DepositETH_TestFail is Bridge_Initializer {
vm.etch(alice, address(L1Token).code); vm.etch(alice, address(L1Token).code);
vm.expectRevert("StandardBridge: function can only be called from an EOA"); vm.expectRevert("StandardBridge: function can only be called from an EOA");
vm.prank(alice); vm.prank(alice);
L1Bridge.depositETH{ value: 1 }(300, hex""); l1StandardBridge.depositETH{ value: 1 }(300, hex"");
} }
} }
...@@ -175,18 +192,22 @@ contract PreBridgeETHTo is Bridge_Initializer { ...@@ -175,18 +192,22 @@ contract PreBridgeETHTo is Bridge_Initializer {
/// @dev Asserts the expected calls and events for bridging ETH to a different /// @dev Asserts the expected calls and events for bridging ETH to a different
/// address depending on whether the bridge call is legacy or not. /// address depending on whether the bridge call is legacy or not.
function _preBridgeETHTo(bool isLegacy) internal { function _preBridgeETHTo(bool isLegacy) internal {
assertEq(address(op).balance, 0); assertEq(address(optimismPortal).balance, 0);
uint256 nonce = L1Messenger.messageNonce(); uint256 nonce = l1CrossDomainMessenger.messageNonce();
uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
if (isLegacy) { if (isLegacy) {
vm.expectCall( vm.expectCall(
address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.depositETHTo.selector, bob, 60000, hex"dead") address(l1StandardBridge),
600,
abi.encodeWithSelector(l1StandardBridge.depositETHTo.selector, bob, 60000, hex"dead")
); );
} else { } else {
vm.expectCall( vm.expectCall(
address(L1Bridge), 600, abi.encodeWithSelector(L1Bridge.bridgeETHTo.selector, bob, 60000, hex"dead") address(l1StandardBridge),
600,
abi.encodeWithSelector(l1StandardBridge.bridgeETHTo.selector, bob, 60000, hex"dead")
); );
} }
...@@ -196,41 +217,52 @@ contract PreBridgeETHTo is Bridge_Initializer { ...@@ -196,41 +217,52 @@ contract PreBridgeETHTo is Bridge_Initializer {
// the L1 bridge should call // the L1 bridge should call
// L1CrossDomainMessenger.sendMessage // L1CrossDomainMessenger.sendMessage
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 60000) abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 60000)
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 600, 60000, message CrossDomainMessenger.relayMessage.selector,
nonce,
address(l1StandardBridge),
address(l2StandardBridge),
600,
60000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 60000); uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 60000);
vm.expectCall( vm.expectCall(
address(op), address(optimismPortal),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, address(L2Messenger), 600, baseGas, false, innerMessage OptimismPortal.depositTransaction.selector,
address(l2CrossDomainMessenger),
600,
baseGas,
false,
innerMessage
) )
); );
bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage); bytes memory opaqueData = abi.encodePacked(uint256(600), uint256(600), baseGas, false, innerMessage);
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHDepositInitiated(alice, bob, 600, hex"dead"); emit ETHDepositInitiated(alice, bob, 600, hex"dead");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHBridgeInitiated(alice, bob, 600, hex"dead"); emit ETHBridgeInitiated(alice, bob, 600, hex"dead");
// OptimismPortal emits a TransactionDeposited event on `depositTransaction` call // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call
vm.expectEmit(true, true, true, true, address(op)); vm.expectEmit(true, true, true, true, address(optimismPortal));
emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData);
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 60000); emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 60000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessageExtension1(address(L1Bridge), 600); emit SentMessageExtension1(address(l1StandardBridge), 600);
// deposit eth to bob // deposit eth to bob
vm.prank(alice, alice); vm.prank(alice, alice);
...@@ -245,8 +277,8 @@ contract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo { ...@@ -245,8 +277,8 @@ contract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo {
/// ETH ends up in the optimismPortal. /// ETH ends up in the optimismPortal.
function test_depositETHTo_succeeds() external { function test_depositETHTo_succeeds() external {
_preBridgeETHTo({ isLegacy: true }); _preBridgeETHTo({ isLegacy: true });
L1Bridge.depositETHTo{ value: 600 }(bob, 60000, hex"dead"); l1StandardBridge.depositETHTo{ value: 600 }(bob, 60000, hex"dead");
assertEq(address(op).balance, 600); assertEq(address(optimismPortal).balance, 600);
} }
} }
...@@ -258,8 +290,8 @@ contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { ...@@ -258,8 +290,8 @@ contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo {
/// ETH ends up in the optimismPortal. /// ETH ends up in the optimismPortal.
function test_bridgeETHTo_succeeds() external { function test_bridgeETHTo_succeeds() external {
_preBridgeETHTo({ isLegacy: false }); _preBridgeETHTo({ isLegacy: false });
L1Bridge.bridgeETHTo{ value: 600 }(bob, 60000, hex"dead"); l1StandardBridge.bridgeETHTo{ value: 600 }(bob, 60000, hex"dead");
assertEq(address(op).balance, 600); assertEq(address(optimismPortal).balance, 600);
} }
} }
...@@ -280,18 +312,18 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { ...@@ -280,18 +312,18 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {
/// Calls depositTransaction on the OptimismPortal. /// Calls depositTransaction on the OptimismPortal.
/// Only EOA can call depositERC20. /// Only EOA can call depositERC20.
function test_depositERC20_succeeds() external { function test_depositERC20_succeeds() external {
uint256 nonce = L1Messenger.messageNonce(); uint256 nonce = l1CrossDomainMessenger.messageNonce();
uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
// Deal Alice's ERC20 State // Deal Alice's ERC20 State
deal(address(L1Token), alice, 100000, true); deal(address(L1Token), alice, 100000, true);
vm.prank(alice); vm.prank(alice);
L1Token.approve(address(L1Bridge), type(uint256).max); L1Token.approve(address(l1StandardBridge), type(uint256).max);
// The L1Bridge should transfer alice's tokens to itself // The l1StandardBridge should transfer alice's tokens to itself
vm.expectCall( vm.expectCall(
address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 100) address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(l1StandardBridge), 100)
); );
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
...@@ -300,46 +332,57 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer { ...@@ -300,46 +332,57 @@ contract L1StandardBridge_DepositERC20_Test is Bridge_Initializer {
// the L1 bridge should call L1CrossDomainMessenger.sendMessage // the L1 bridge should call L1CrossDomainMessenger.sendMessage
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000) abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000)
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message CrossDomainMessenger.relayMessage.selector,
nonce,
address(l1StandardBridge),
address(l2StandardBridge),
0,
10000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 10000); uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 10000);
vm.expectCall( vm.expectCall(
address(op), address(optimismPortal),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage OptimismPortal.depositTransaction.selector,
address(l2CrossDomainMessenger),
0,
baseGas,
false,
innerMessage
) )
); );
bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage);
// Should emit both the bedrock and legacy events // Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, alice, 100, hex"");
// OptimismPortal emits a TransactionDeposited event on `depositTransaction` call // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call
vm.expectEmit(true, true, true, true, address(op)); vm.expectEmit(true, true, true, true, address(optimismPortal));
emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData);
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000); emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 10000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessageExtension1(address(L1Bridge), 0); emit SentMessageExtension1(address(l1StandardBridge), 0);
vm.prank(alice); vm.prank(alice);
L1Bridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex""); l1StandardBridge.depositERC20(address(L1Token), address(L2Token), 100, 10000, hex"");
assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100); assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 100);
} }
} }
...@@ -352,7 +395,7 @@ contract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer { ...@@ -352,7 +395,7 @@ contract L1StandardBridge_DepositERC20_TestFail is Bridge_Initializer {
vm.expectRevert("StandardBridge: function can only be called from an EOA"); vm.expectRevert("StandardBridge: function can only be called from an EOA");
vm.prank(alice, alice); vm.prank(alice, alice);
L1Bridge.depositERC20(address(0), address(0), 100, 100, hex""); l1StandardBridge.depositERC20(address(0), address(0), 100, 100, hex"");
} }
} }
...@@ -364,65 +407,77 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer { ...@@ -364,65 +407,77 @@ contract L1StandardBridge_DepositERC20To_Test is Bridge_Initializer {
/// Calls depositTransaction on the OptimismPortal. /// Calls depositTransaction on the OptimismPortal.
/// Contracts can call depositERC20. /// Contracts can call depositERC20.
function test_depositERC20To_succeeds() external { function test_depositERC20To_succeeds() external {
uint256 nonce = L1Messenger.messageNonce(); uint256 nonce = l1CrossDomainMessenger.messageNonce();
uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION uint256 version = 0; // Internal constant in the OptimismPortal: DEPOSIT_VERSION
address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address l1MessengerAliased = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex"" StandardBridge.finalizeBridgeERC20.selector, address(L2Token), address(L1Token), alice, bob, 1000, hex""
); );
bytes memory innerMessage = abi.encodeWithSelector( bytes memory innerMessage = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, nonce, address(L1Bridge), address(L2Bridge), 0, 10000, message CrossDomainMessenger.relayMessage.selector,
nonce,
address(l1StandardBridge),
address(l2StandardBridge),
0,
10000,
message
); );
uint64 baseGas = L1Messenger.baseGas(message, 10000); uint64 baseGas = l1CrossDomainMessenger.baseGas(message, 10000);
bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage); bytes memory opaqueData = abi.encodePacked(uint256(0), uint256(0), baseGas, false, innerMessage);
deal(address(L1Token), alice, 100000, true); deal(address(L1Token), alice, 100000, true);
vm.prank(alice); vm.prank(alice);
L1Token.approve(address(L1Bridge), type(uint256).max); L1Token.approve(address(l1StandardBridge), type(uint256).max);
// Should emit both the bedrock and legacy events // Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); emit ERC20DepositInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex"");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex""); emit ERC20BridgeInitiated(address(L1Token), address(L2Token), alice, bob, 1000, hex"");
// OptimismPortal emits a TransactionDeposited event on `depositTransaction` call // OptimismPortal emits a TransactionDeposited event on `depositTransaction` call
vm.expectEmit(true, true, true, true, address(op)); vm.expectEmit(true, true, true, true, address(optimismPortal));
emit TransactionDeposited(l1MessengerAliased, address(L2Messenger), version, opaqueData); emit TransactionDeposited(l1MessengerAliased, address(l2CrossDomainMessenger), version, opaqueData);
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessage(address(L2Bridge), address(L1Bridge), message, nonce, 10000); emit SentMessage(address(l2StandardBridge), address(l1StandardBridge), message, nonce, 10000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L1Messenger)); vm.expectEmit(true, true, true, true, address(l1CrossDomainMessenger));
emit SentMessageExtension1(address(L1Bridge), 0); emit SentMessageExtension1(address(l1StandardBridge), 0);
// the L1 bridge should call L1CrossDomainMessenger.sendMessage // the L1 bridge should call L1CrossDomainMessenger.sendMessage
vm.expectCall( vm.expectCall(
address(L1Messenger), address(l1CrossDomainMessenger),
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L2Bridge), message, 10000) abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l2StandardBridge), message, 10000)
); );
// The L1 XDM should call OptimismPortal.depositTransaction // The L1 XDM should call OptimismPortal.depositTransaction
vm.expectCall( vm.expectCall(
address(op), address(optimismPortal),
abi.encodeWithSelector( abi.encodeWithSelector(
OptimismPortal.depositTransaction.selector, address(L2Messenger), 0, baseGas, false, innerMessage OptimismPortal.depositTransaction.selector,
address(l2CrossDomainMessenger),
0,
baseGas,
false,
innerMessage
) )
); );
vm.expectCall( vm.expectCall(
address(L1Token), abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(L1Bridge), 1000) address(L1Token),
abi.encodeWithSelector(ERC20.transferFrom.selector, alice, address(l1StandardBridge), 1000)
); );
vm.prank(alice); vm.prank(alice);
L1Bridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex""); l1StandardBridge.depositERC20To(address(L1Token), address(L2Token), bob, 1000, 10000, hex"");
assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 1000); assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 1000);
} }
} }
...@@ -435,25 +490,25 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer { ...@@ -435,25 +490,25 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is Bridge_Initializer {
function test_finalizeETHWithdrawal_succeeds() external { function test_finalizeETHWithdrawal_succeeds() external {
uint256 aliceBalance = alice.balance; uint256 aliceBalance = alice.balance;
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHWithdrawalFinalized(alice, alice, 100, hex""); emit ETHWithdrawalFinalized(alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHBridgeFinalized(alice, alice, 100, hex""); emit ETHBridgeFinalized(alice, alice, 100, hex"");
vm.expectCall(alice, hex""); vm.expectCall(alice, hex"");
vm.mockCall( vm.mockCall(
address(L1Bridge.messenger()), address(l1StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
// ensure that the messenger has ETH to call with // ensure that the messenger has ETH to call with
vm.deal(address(L1Bridge.messenger()), 100); vm.deal(address(l1StandardBridge.messenger()), 100);
vm.prank(address(L1Bridge.messenger())); vm.prank(address(l1StandardBridge.messenger()));
L1Bridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex""); l1StandardBridge.finalizeETHWithdrawal{ value: 100 }(alice, alice, 100, hex"");
assertEq(address(L1Bridge.messenger()).balance, 0); assertEq(address(l1StandardBridge.messenger()).balance, 0);
assertEq(aliceBalance + 100, alice.balance); assertEq(aliceBalance + 100, alice.balance);
} }
} }
...@@ -468,32 +523,33 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer { ...@@ -468,32 +523,33 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_Test is Bridge_Initializer {
/// Emits ERC20WithdrawalFinalized event. /// Emits ERC20WithdrawalFinalized event.
/// Only callable by the L2 bridge. /// Only callable by the L2 bridge.
function test_finalizeERC20Withdrawal_succeeds() external { function test_finalizeERC20Withdrawal_succeeds() external {
deal(address(L1Token), address(L1Bridge), 100, true); deal(address(L1Token), address(l1StandardBridge), 100, true);
uint256 slot = stdstore.target(address(L1Bridge)).sig("deposits(address,address)").with_key(address(L1Token)) uint256 slot = stdstore.target(address(l1StandardBridge)).sig("deposits(address,address)").with_key(
.with_key(address(L2Token)).find(); address(L1Token)
).with_key(address(L2Token)).find();
// Give the L1 bridge some ERC20 tokens // Give the L1 bridge some ERC20 tokens
vm.store(address(L1Bridge), bytes32(slot), bytes32(uint256(100))); vm.store(address(l1StandardBridge), bytes32(slot), bytes32(uint256(100)));
assertEq(L1Bridge.deposits(address(L1Token), address(L2Token)), 100); assertEq(l1StandardBridge.deposits(address(L1Token), address(L2Token)), 100);
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit ERC20WithdrawalFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit ERC20BridgeFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100)); vm.expectCall(address(L1Token), abi.encodeWithSelector(ERC20.transfer.selector, alice, 100));
vm.mockCall( vm.mockCall(
address(L1Bridge.messenger()), address(l1StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.prank(address(L1Bridge.messenger())); vm.prank(address(l1StandardBridge.messenger()));
L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
assertEq(L1Token.balanceOf(address(L1Bridge)), 0); assertEq(L1Token.balanceOf(address(l1StandardBridge)), 0);
assertEq(L1Token.balanceOf(address(alice)), 100); assertEq(L1Token.balanceOf(address(alice)), 100);
} }
} }
...@@ -502,87 +558,87 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer ...@@ -502,87 +558,87 @@ contract L1StandardBridge_FinalizeERC20Withdrawal_TestFail is Bridge_Initializer
/// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge.
function test_finalizeERC20Withdrawal_notMessenger_reverts() external { function test_finalizeERC20Withdrawal_notMessenger_reverts() external {
vm.mockCall( vm.mockCall(
address(L1Bridge.messenger()), address(l1StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.prank(address(28)); vm.prank(address(28));
vm.expectRevert("StandardBridge: function can only be called from the other bridge"); vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
} }
/// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge. /// @dev Tests that finalizing an ERC20 withdrawal reverts if the caller is not the L2 bridge.
function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external { function test_finalizeERC20Withdrawal_notOtherBridge_reverts() external {
vm.mockCall( vm.mockCall(
address(L1Bridge.messenger()), address(l1StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(address(0))) abi.encode(address(address(0)))
); );
vm.prank(address(L1Bridge.messenger())); vm.prank(address(l1StandardBridge.messenger()));
vm.expectRevert("StandardBridge: function can only be called from the other bridge"); vm.expectRevert("StandardBridge: function can only be called from the other bridge");
L1Bridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex""); l1StandardBridge.finalizeERC20Withdrawal(address(L1Token), address(L2Token), alice, alice, 100, hex"");
} }
} }
contract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { contract L1StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {
/// @dev Tests that finalizing bridged ETH succeeds. /// @dev Tests that finalizing bridged ETH succeeds.
function test_finalizeBridgeETH_succeeds() external { function test_finalizeBridgeETH_succeeds() external {
address messenger = address(L1Bridge.messenger()); address messenger = address(l1StandardBridge.messenger());
vm.mockCall( vm.mockCall(
messenger, messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(messenger, 100); vm.deal(messenger, 100);
vm.prank(messenger); vm.prank(messenger);
vm.expectEmit(true, true, true, true, address(L1Bridge)); vm.expectEmit(true, true, true, true, address(l1StandardBridge));
emit ETHBridgeFinalized(alice, alice, 100, hex""); emit ETHBridgeFinalized(alice, alice, 100, hex"");
L1Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex"");
} }
} }
contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer { contract L1StandardBridge_FinalizeBridgeETH_TestFail is Bridge_Initializer {
/// @dev Tests that finalizing bridged ETH reverts if the amount is incorrect. /// @dev Tests that finalizing bridged ETH reverts if the amount is incorrect.
function test_finalizeBridgeETH_incorrectValue_reverts() external { function test_finalizeBridgeETH_incorrectValue_reverts() external {
address messenger = address(L1Bridge.messenger()); address messenger = address(l1StandardBridge.messenger());
vm.mockCall( vm.mockCall(
messenger, messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(messenger, 100); vm.deal(messenger, 100);
vm.prank(messenger); vm.prank(messenger);
vm.expectRevert("StandardBridge: amount sent does not match amount required"); vm.expectRevert("StandardBridge: amount sent does not match amount required");
L1Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); l1StandardBridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex"");
} }
/// @dev Tests that finalizing bridged ETH reverts if the destination is the L1 bridge. /// @dev Tests that finalizing bridged ETH reverts if the destination is the L1 bridge.
function test_finalizeBridgeETH_sendToSelf_reverts() external { function test_finalizeBridgeETH_sendToSelf_reverts() external {
address messenger = address(L1Bridge.messenger()); address messenger = address(l1StandardBridge.messenger());
vm.mockCall( vm.mockCall(
messenger, messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(messenger, 100); vm.deal(messenger, 100);
vm.prank(messenger); vm.prank(messenger);
vm.expectRevert("StandardBridge: cannot send to self"); vm.expectRevert("StandardBridge: cannot send to self");
L1Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L1Bridge), 100, hex""); l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l1StandardBridge), 100, hex"");
} }
/// @dev Tests that finalizing bridged ETH reverts if the destination is the messenger. /// @dev Tests that finalizing bridged ETH reverts if the destination is the messenger.
function test_finalizeBridgeETH_sendToMessenger_reverts() external { function test_finalizeBridgeETH_sendToMessenger_reverts() external {
address messenger = address(L1Bridge.messenger()); address messenger = address(l1StandardBridge.messenger());
vm.mockCall( vm.mockCall(
messenger, messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1Bridge.OTHER_BRIDGE())) abi.encode(address(l1StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(messenger, 100); vm.deal(messenger, 100);
vm.prank(messenger); vm.prank(messenger);
vm.expectRevert("StandardBridge: cannot send to messenger"); vm.expectRevert("StandardBridge: cannot send to messenger");
L1Bridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex""); l1StandardBridge.finalizeBridgeETH{ value: 100 }(alice, messenger, 100, hex"");
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { Messenger_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol"; import { Reverter, ConfigurableCaller } from "test/mocks/Callers.sol";
// Libraries // Libraries
...@@ -14,26 +14,26 @@ import { Types } from "src/libraries/Types.sol"; ...@@ -14,26 +14,26 @@ import { Types } from "src/libraries/Types.sol";
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
contract L2CrossDomainMessenger_Test is Messenger_Initializer { contract L2CrossDomainMessenger_Test is Bridge_Initializer {
/// @dev Receiver address for testing /// @dev Receiver address for testing
address recipient = address(0xabbaacdc); address recipient = address(0xabbaacdc);
/// @dev Tests that `messageNonce` can be decoded correctly. /// @dev Tests that `messageNonce` can be decoded correctly.
function test_messageVersion_succeeds() external { function test_messageVersion_succeeds() external {
(, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce()); (, uint16 version) = Encoding.decodeVersionedNonce(l2CrossDomainMessenger.messageNonce());
assertEq(version, L2Messenger.MESSAGE_VERSION()); assertEq(version, l2CrossDomainMessenger.MESSAGE_VERSION());
} }
/// @dev Tests that `sendMessage` executes successfully. /// @dev Tests that `sendMessage` executes successfully.
function test_sendMessage_succeeds() external { function test_sendMessage_succeeds() external {
bytes memory xDomainCallData = bytes memory xDomainCallData =
Encoding.encodeCrossDomainMessage(L2Messenger.messageNonce(), alice, recipient, 0, 100, hex"ff"); Encoding.encodeCrossDomainMessage(l2CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff");
vm.expectCall( vm.expectCall(
address(messagePasser), address(l2ToL1MessagePasser),
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, L2ToL1MessagePasser.initiateWithdrawal.selector,
address(L1Messenger), address(l1CrossDomainMessenger),
L2Messenger.baseGas(hex"ff", 100), l2CrossDomainMessenger.baseGas(hex"ff", 100),
xDomainCallData xDomainCallData
) )
); );
...@@ -41,56 +41,56 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -41,56 +41,56 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
// MessagePassed event // MessagePassed event
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit MessagePassed( emit MessagePassed(
messagePasser.messageNonce(), l2ToL1MessagePasser.messageNonce(),
address(L2Messenger), address(l2CrossDomainMessenger),
address(L1Messenger), address(l1CrossDomainMessenger),
0, 0,
L2Messenger.baseGas(hex"ff", 100), l2CrossDomainMessenger.baseGas(hex"ff", 100),
xDomainCallData, xDomainCallData,
Hashing.hashWithdrawal( Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
nonce: messagePasser.messageNonce(), nonce: l2ToL1MessagePasser.messageNonce(),
sender: address(L2Messenger), sender: address(l2CrossDomainMessenger),
target: address(L1Messenger), target: address(l1CrossDomainMessenger),
value: 0, value: 0,
gasLimit: L2Messenger.baseGas(hex"ff", 100), gasLimit: l2CrossDomainMessenger.baseGas(hex"ff", 100),
data: xDomainCallData data: xDomainCallData
}) })
) )
); );
vm.prank(alice); vm.prank(alice);
L2Messenger.sendMessage(recipient, hex"ff", uint32(100)); l2CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100));
} }
/// @dev Tests that `sendMessage` can be called twice and that /// @dev Tests that `sendMessage` can be called twice and that
/// the nonce increments correctly. /// the nonce increments correctly.
function test_sendMessage_twice_succeeds() external { function test_sendMessage_twice_succeeds() external {
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = l2CrossDomainMessenger.messageNonce();
L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); l2CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000));
L2Messenger.sendMessage(recipient, hex"aa", uint32(500_000)); l2CrossDomainMessenger.sendMessage(recipient, hex"aa", uint32(500_000));
// the nonce increments for each message sent // the nonce increments for each message sent
assertEq(nonce + 2, L2Messenger.messageNonce()); assertEq(nonce + 2, l2CrossDomainMessenger.messageNonce());
} }
/// @dev Tests that `sendMessage` reverts if the recipient is the zero address. /// @dev Tests that `sendMessage` reverts if the recipient is the zero address.
function test_xDomainSender_senderNotSet_reverts() external { function test_xDomainSender_senderNotSet_reverts() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); l2CrossDomainMessenger.xDomainMessageSender();
} }
/// @dev Tests that `sendMessage` reverts if the message version is not supported. /// @dev Tests that `sendMessage` reverts if the message version is not supported.
function test_relayMessage_v2_reverts() external { function test_relayMessage_v2_reverts() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = address(L1Messenger); address sender = address(l1CrossDomainMessenger);
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
// Expect a revert. // Expect a revert.
vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time"); vm.expectRevert("CrossDomainMessenger: only version 0 or 1 messages are supported at this time");
// Try to relay a v2 message. // Try to relay a v2 message.
vm.prank(caller); vm.prank(caller);
L2Messenger.relayMessage( l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(0, 2), // nonce Encoding.encodeVersionedNonce(0, 2), // nonce
sender, sender,
target, target,
...@@ -103,8 +103,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -103,8 +103,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
/// @dev Tests that `relayMessage` executes successfully. /// @dev Tests that `relayMessage` executes successfully.
function test_relayMessage_succeeds() external { function test_relayMessage_succeeds() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = address(L1Messenger); address sender = address(l1CrossDomainMessenger);
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
vm.expectCall(target, hex"1111"); vm.expectCall(target, hex"1111");
...@@ -117,7 +117,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -117,7 +117,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
emit RelayedMessage(hash); emit RelayedMessage(hash);
L2Messenger.relayMessage( l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(0, 1), // nonce Encoding.encodeVersionedNonce(0, 1), // nonce
sender, sender,
target, target,
...@@ -127,36 +127,36 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -127,36 +127,36 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
); );
// the message hash is in the successfulMessages mapping // the message hash is in the successfulMessages mapping
assert(L2Messenger.successfulMessages(hash)); assert(l2CrossDomainMessenger.successfulMessages(hash));
// it is not in the received messages mapping // it is not in the received messages mapping
assertEq(L2Messenger.failedMessages(hash), false); assertEq(l2CrossDomainMessenger.failedMessages(hash), false);
} }
/// @dev Tests that `relayMessage` reverts if attempting to relay /// @dev Tests that `relayMessage` reverts if attempting to relay
/// a message sent to an L1 system contract. /// a message sent to an L1 system contract.
function test_relayMessage_toSystemContract_reverts() external { function test_relayMessage_toSystemContract_reverts() external {
address target = address(messagePasser); address target = address(l2ToL1MessagePasser);
address sender = address(L1Messenger); address sender = address(l1CrossDomainMessenger);
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
bytes memory message = hex"1111"; bytes memory message = hex"1111";
vm.prank(caller); vm.prank(caller);
vm.expectRevert("CrossDomainMessenger: message cannot be replayed"); vm.expectRevert("CrossDomainMessenger: message cannot be replayed");
L1Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message); l1CrossDomainMessenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), sender, target, 0, 0, message);
} }
/// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender` /// @dev Tests that `relayMessage` correctly resets the `xDomainMessageSender`
/// to the original value after a message is relayed. /// to the original value after a message is relayed.
function test_xDomainMessageSender_reset_succeeds() external { function test_xDomainMessageSender_reset_succeeds() external {
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); l2CrossDomainMessenger.xDomainMessageSender();
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
vm.prank(caller); vm.prank(caller);
L2Messenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex""); l2CrossDomainMessenger.relayMessage(Encoding.encodeVersionedNonce(0, 1), address(0), address(0), 0, 0, hex"");
vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set");
L2Messenger.xDomainMessageSender(); l2CrossDomainMessenger.xDomainMessageSender();
} }
/// @dev Tests that `relayMessage` is able to send a successful call /// @dev Tests that `relayMessage` is able to send a successful call
...@@ -164,8 +164,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -164,8 +164,8 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
/// gets stuck, but the second message succeeds. /// gets stuck, but the second message succeeds.
function test_relayMessage_retry_succeeds() external { function test_relayMessage_retry_succeeds() external {
address target = address(0xabcd); address target = address(0xabcd);
address sender = address(L1Messenger); address sender = address(l1CrossDomainMessenger);
address caller = AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)); address caller = AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger));
uint256 value = 100; uint256 value = 100;
bytes32 hash = bytes32 hash =
...@@ -174,7 +174,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -174,7 +174,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.etch(target, address(new Reverter()).code); vm.etch(target, address(new Reverter()).code);
vm.deal(address(caller), value); vm.deal(address(caller), value);
vm.prank(caller); vm.prank(caller);
L2Messenger.relayMessage{ value: value }( l2CrossDomainMessenger.relayMessage{ value: value }(
Encoding.encodeVersionedNonce(0, 1), // nonce Encoding.encodeVersionedNonce(0, 1), // nonce
sender, sender,
target, target,
...@@ -183,10 +183,10 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -183,10 +183,10 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
hex"1111" hex"1111"
); );
assertEq(address(L2Messenger).balance, value); assertEq(address(l2CrossDomainMessenger).balance, value);
assertEq(address(target).balance, 0); assertEq(address(target).balance, 0);
assertEq(L2Messenger.successfulMessages(hash), false); assertEq(l2CrossDomainMessenger.successfulMessages(hash), false);
assertEq(L2Messenger.failedMessages(hash), true); assertEq(l2CrossDomainMessenger.failedMessages(hash), true);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -194,7 +194,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -194,7 +194,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.etch(target, address(0).code); vm.etch(target, address(0).code);
vm.prank(address(sender)); vm.prank(address(sender));
L2Messenger.relayMessage( l2CrossDomainMessenger.relayMessage(
Encoding.encodeVersionedNonce(0, 1), // nonce Encoding.encodeVersionedNonce(0, 1), // nonce
sender, sender,
target, target,
...@@ -203,9 +203,9 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer { ...@@ -203,9 +203,9 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
hex"1111" hex"1111"
); );
assertEq(address(L2Messenger).balance, 0); assertEq(address(l2CrossDomainMessenger).balance, 0);
assertEq(address(target).balance, value); assertEq(address(target).balance, value);
assertEq(L2Messenger.successfulMessages(hash), true); assertEq(l2CrossDomainMessenger.successfulMessages(hash), true);
assertEq(L2Messenger.failedMessages(hash), true); assertEq(l2CrossDomainMessenger.failedMessages(hash), true);
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Target contract dependencies // Target contract dependencies
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
...@@ -33,7 +33,7 @@ contract TestMintableERC721 is OptimismMintableERC721 { ...@@ -33,7 +33,7 @@ contract TestMintableERC721 is OptimismMintableERC721 {
} }
} }
contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { contract L2ERC721Bridge_Test is Bridge_Initializer {
TestMintableERC721 internal localToken; TestMintableERC721 internal localToken;
TestERC721 internal remoteToken; TestERC721 internal remoteToken;
uint256 internal constant tokenId = 1; uint256 internal constant tokenId = 1;
...@@ -61,22 +61,22 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -61,22 +61,22 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
super.setUp(); super.setUp();
remoteToken = new TestERC721(); remoteToken = new TestERC721();
localToken = new TestMintableERC721(address(L2NFTBridge), address(remoteToken)); localToken = new TestMintableERC721(address(l2ERC721Bridge), address(remoteToken));
// Mint alice a token. // Mint alice a token.
localToken.mint(alice, tokenId); localToken.mint(alice, tokenId);
// Approve the bridge to transfer the token. // Approve the bridge to transfer the token.
vm.prank(alice); vm.prank(alice);
localToken.approve(address(L2NFTBridge), tokenId); localToken.approve(address(l2ERC721Bridge), tokenId);
} }
/// @dev Tests that the constructor sets the correct variables. /// @dev Tests that the constructor sets the correct variables.
function test_constructor_succeeds() public { function test_constructor_succeeds() public {
assertEq(address(L2NFTBridge.MESSENGER()), address(L2Messenger)); assertEq(address(l2ERC721Bridge.MESSENGER()), address(l2CrossDomainMessenger));
assertEq(address(L2NFTBridge.OTHER_BRIDGE()), address(L1NFTBridge)); assertEq(address(l2ERC721Bridge.OTHER_BRIDGE()), address(l1ERC721Bridge));
assertEq(address(L2NFTBridge.messenger()), address(L2Messenger)); assertEq(address(l2ERC721Bridge.messenger()), address(l2CrossDomainMessenger));
assertEq(address(L2NFTBridge.otherBridge()), address(L1NFTBridge)); assertEq(address(l2ERC721Bridge.otherBridge()), address(l1ERC721Bridge));
} }
/// @dev Tests that `bridgeERC721` correctly bridges a token and /// @dev Tests that `bridgeERC721` correctly bridges a token and
...@@ -84,11 +84,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -84,11 +84,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_bridgeERC721_succeeds() public { function test_bridgeERC721_succeeds() public {
// Expect a call to the messenger. // Expect a call to the messenger.
vm.expectCall( vm.expectCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeCall( abi.encodeCall(
L2Messenger.sendMessage, l2CrossDomainMessenger.sendMessage,
( (
address(L1NFTBridge), address(l1ERC721Bridge),
abi.encodeCall( abi.encodeCall(
L2ERC721Bridge.finalizeBridgeERC721, L2ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678") (address(remoteToken), address(localToken), alice, alice, tokenId, hex"5678")
...@@ -104,7 +104,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -104,7 +104,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is burned. // Token is burned.
vm.expectRevert("ERC721: invalid token ID"); vm.expectRevert("ERC721: invalid token ID");
...@@ -117,7 +117,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -117,7 +117,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
vm.etch(alice, hex"01"); vm.etch(alice, hex"01");
vm.prank(alice); vm.prank(alice);
vm.expectRevert("ERC721Bridge: account is not externally owned"); vm.expectRevert("ERC721Bridge: account is not externally owned");
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -128,7 +128,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -128,7 +128,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert(); vm.expectRevert();
L2NFTBridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(0), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -139,7 +139,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -139,7 +139,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)");
L2NFTBridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(localToken), address(0), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -150,7 +150,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -150,7 +150,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -161,11 +161,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -161,11 +161,11 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_bridgeERC721To_succeeds() external { function test_bridgeERC721To_succeeds() external {
// Expect a call to the messenger. // Expect a call to the messenger.
vm.expectCall( vm.expectCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeCall( abi.encodeCall(
L2Messenger.sendMessage, l2CrossDomainMessenger.sendMessage,
( (
address(L1NFTBridge), address(l1ERC721Bridge),
abi.encodeCall( abi.encodeCall(
L1ERC721Bridge.finalizeBridgeERC721, L1ERC721Bridge.finalizeBridgeERC721,
(address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678") (address(remoteToken), address(localToken), alice, bob, tokenId, hex"5678")
...@@ -181,7 +181,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -181,7 +181,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is burned. // Token is burned.
vm.expectRevert("ERC721: invalid token ID"); vm.expectRevert("ERC721: invalid token ID");
...@@ -193,7 +193,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -193,7 +193,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert(); vm.expectRevert();
L2NFTBridge.bridgeERC721To(address(0), address(L1NFTBridge), bob, tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721To(address(0), address(l1ERC721Bridge), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -204,7 +204,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -204,7 +204,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)"); vm.expectRevert("L2ERC721Bridge: remote token cannot be address(0)");
L2NFTBridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721To(address(localToken), address(0), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -215,7 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -215,7 +215,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the token. // Bridge the token.
vm.prank(bob); vm.prank(bob);
vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner"); vm.expectRevert("L2ERC721Bridge: Withdrawal is not being initiated by NFT owner");
L2NFTBridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721To(address(localToken), address(remoteToken), bob, tokenId, 1234, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -225,7 +225,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -225,7 +225,7 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_succeeds() external { function test_finalizeBridgeERC721_succeeds() external {
// Bridge the token. // Bridge the token.
vm.prank(alice); vm.prank(alice);
L2NFTBridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(localToken), address(remoteToken), tokenId, 1234, hex"5678");
// Expect an event to be emitted. // Expect an event to be emitted.
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -233,12 +233,12 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -233,12 +233,12 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(L1NFTBridge) abi.encode(l1ERC721Bridge)
); );
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
// Token is not locked in the bridge. // Token is not locked in the bridge.
assertEq(localToken.ownerOf(tokenId), alice); assertEq(localToken.ownerOf(tokenId), alice);
...@@ -252,18 +252,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -252,18 +252,18 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Bridge the non-compliant token. // Bridge the non-compliant token.
vm.prank(alice); vm.prank(alice);
L2NFTBridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678"); l2ERC721Bridge.bridgeERC721(address(nonCompliantToken), address(0x01), tokenId, 1234, hex"5678");
// Attempt to finalize the withdrawal. Should revert because the token does not claim // Attempt to finalize the withdrawal. Should revert because the token does not claim
// to be compliant with the `IOptimismMintableERC721` interface. // to be compliant with the `IOptimismMintableERC721` interface.
vm.mockCall( vm.mockCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(L1NFTBridge) abi.encode(l1ERC721Bridge)
); );
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("L2ERC721Bridge: local token interface is not compliant"); vm.expectRevert("L2ERC721Bridge: local token interface is not compliant");
L2NFTBridge.finalizeBridgeERC721( l2ERC721Bridge.finalizeBridgeERC721(
address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678" address(address(nonCompliantToken)), address(address(0x01)), alice, alice, tokenId, hex"5678"
); );
} }
...@@ -273,18 +273,20 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -273,18 +273,20 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.prank(alice); vm.prank(alice);
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
} }
/// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge. /// @dev Tests that `finalizeBridgeERC721` reverts when not called by the remote bridge.
function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external { function test_finalizeBridgeERC721_notFromRemoteMessenger_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L2Messenger), abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encode(alice) address(l2CrossDomainMessenger),
abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(alice)
); );
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("ERC721Bridge: function can only be called from the other bridge"); vm.expectRevert("ERC721Bridge: function can only be called from the other bridge");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
} }
/// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the /// @dev Tests that `finalizeBridgeERC721` reverts when the local token is the
...@@ -292,26 +294,28 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer { ...@@ -292,26 +294,28 @@ contract L2ERC721Bridge_Test is ERC721Bridge_Initializer {
function test_finalizeBridgeERC721_selfToken_reverts() external { function test_finalizeBridgeERC721_selfToken_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1NFTBridge)) abi.encode(address(l1ERC721Bridge))
); );
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("L2ERC721Bridge: local token cannot be self"); vm.expectRevert("L2ERC721Bridge: local token cannot be self");
L2NFTBridge.finalizeBridgeERC721(address(L2NFTBridge), address(remoteToken), alice, alice, tokenId, hex"5678"); l2ERC721Bridge.finalizeBridgeERC721(
address(l2ERC721Bridge), address(remoteToken), alice, alice, tokenId, hex"5678"
);
} }
/// @dev Tests that `finalizeBridgeERC721` reverts when already finalized. /// @dev Tests that `finalizeBridgeERC721` reverts when already finalized.
function test_finalizeBridgeERC721_alreadyExists_reverts() external { function test_finalizeBridgeERC721_alreadyExists_reverts() external {
// Finalize a withdrawal. // Finalize a withdrawal.
vm.mockCall( vm.mockCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector(L2Messenger.xDomainMessageSender.selector), abi.encodeWithSelector(l2CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L1NFTBridge)) abi.encode(address(l1ERC721Bridge))
); );
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("ERC721: token already minted"); vm.expectRevert("ERC721: token already minted");
L2NFTBridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678"); l2ERC721Bridge.finalizeBridgeERC721(address(localToken), address(remoteToken), alice, alice, tokenId, hex"5678");
} }
} }
......
...@@ -3,7 +3,7 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,7 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { stdError } from "forge-std/Test.sol"; import { stdError } from "forge-std/Test.sol";
import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { NextImpl } from "test/mocks/NextImpl.sol"; import { NextImpl } from "test/mocks/NextImpl.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
...@@ -17,26 +17,35 @@ import { Proxy } from "src/universal/Proxy.sol"; ...@@ -17,26 +17,35 @@ import { Proxy } from "src/universal/Proxy.sol";
// Target contract // Target contract
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { contract L2OutputOracle_constructor_Test is CommonTest {
/// @dev Tests that constructor sets the initial values correctly. /// @dev Tests that constructor sets the initial values correctly.
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(oracle.PROPOSER(), proposer); address proposer = cfg.l2OutputOracleProposer();
assertEq(oracle.proposer(), proposer); address challenger = cfg.l2OutputOracleChallenger();
assertEq(oracle.CHALLENGER(), owner); uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
assertEq(oracle.challenger(), owner); uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp();
assertEq(oracle.submissionInterval(), submissionInterval); uint256 l2BlockTime = cfg.l2BlockTime();
assertEq(oracle.latestBlockNumber(), startingBlockNumber); uint256 finalizationPeriodSeconds = cfg.finalizationPeriodSeconds();
assertEq(oracle.startingBlockNumber(), startingBlockNumber);
assertEq(oracle.startingTimestamp(), startingTimestamp); assertEq(l2OutputOracle.PROPOSER(), proposer);
assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime); assertEq(l2OutputOracle.proposer(), proposer);
assertEq(oracle.l2BlockTime(), l2BlockTime); assertEq(l2OutputOracle.CHALLENGER(), challenger);
assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); assertEq(l2OutputOracle.challenger(), challenger);
assertEq(oracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds); assertEq(l2OutputOracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(l2OutputOracle.submissionInterval(), submissionInterval);
assertEq(l2OutputOracle.latestBlockNumber(), startingBlockNumber);
assertEq(l2OutputOracle.startingBlockNumber(), startingBlockNumber);
assertEq(l2OutputOracle.startingTimestamp(), startingTimestamp);
assertEq(l2OutputOracle.L2_BLOCK_TIME(), l2BlockTime);
assertEq(l2OutputOracle.l2BlockTime(), l2BlockTime);
assertEq(l2OutputOracle.finalizationPeriodSeconds(), finalizationPeriodSeconds);
assertEq(l2OutputOracle.FINALIZATION_PERIOD_SECONDS(), finalizationPeriodSeconds);
} }
/// @dev Tests that the constructor reverts if the l2BlockTime is invalid. /// @dev Tests that the constructor reverts if the l2BlockTime is invalid.
function test_constructor_l2BlockTimeZero_reverts() external { function test_constructor_l2BlockTimeZero_reverts() external {
uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0"); vm.expectRevert("L2OutputOracle: L2 block time must be greater than 0");
new L2OutputOracle({ new L2OutputOracle({
_submissionInterval: submissionInterval, _submissionInterval: submissionInterval,
...@@ -47,6 +56,7 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { ...@@ -47,6 +56,7 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer {
/// @dev Tests that the constructor reverts if the submissionInterval is zero. /// @dev Tests that the constructor reverts if the submissionInterval is zero.
function test_constructor_submissionInterval_reverts() external { function test_constructor_submissionInterval_reverts() external {
uint256 l2BlockTime = cfg.l2BlockTime();
vm.expectRevert("L2OutputOracle: submission interval must be greater than 0"); vm.expectRevert("L2OutputOracle: submission interval must be greater than 0");
new L2OutputOracle({ new L2OutputOracle({
_submissionInterval: 0, _submissionInterval: 0,
...@@ -59,9 +69,9 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { ...@@ -59,9 +69,9 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer {
function test_initialize_badTimestamp_reverts() external { function test_initialize_badTimestamp_reverts() external {
// Reset the initialized field in the 0th storage slot // Reset the initialized field in the 0th storage slot
// so that initialize can be called again. // so that initialize can be called again.
vm.store(address(oracle), bytes32(uint256(0)), bytes32(uint256(0))); vm.store(address(l2OutputOracle), bytes32(uint256(0)), bytes32(uint256(0)));
vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time"); vm.expectRevert("L2OutputOracle: starting L2 timestamp must be less than current time");
oracle.initialize({ l2OutputOracle.initialize({
_startingBlockNumber: 0, _startingBlockNumber: 0,
_startingTimestamp: block.timestamp + 1, _startingTimestamp: block.timestamp + 1,
_proposer: address(0), _proposer: address(0),
...@@ -70,48 +80,48 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer { ...@@ -70,48 +80,48 @@ contract L2OutputOracle_constructor_Test is L2OutputOracle_Initializer {
} }
} }
contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { contract L2OutputOracle_getter_Test is CommonTest {
bytes32 proposedOutput1 = keccak256(abi.encode(1)); bytes32 proposedOutput1 = keccak256(abi.encode(1));
/// @dev Tests that `latestBlockNumber` returns the correct value. /// @dev Tests that `latestBlockNumber` returns the correct value.
function test_latestBlockNumber_succeeds() external { function test_latestBlockNumber_succeeds() external {
uint256 proposedNumber = oracle.nextBlockNumber(); uint256 proposedNumber = l2OutputOracle.nextBlockNumber();
// Roll to after the block number we'll propose // Roll to after the block number we'll propose
warpToProposeTime(proposedNumber); warpToProposeTime(proposedNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0); l2OutputOracle.proposeL2Output(proposedOutput1, proposedNumber, 0, 0);
assertEq(oracle.latestBlockNumber(), proposedNumber); assertEq(l2OutputOracle.latestBlockNumber(), proposedNumber);
} }
/// @dev Tests that `getL2Output` returns the correct value. /// @dev Tests that `getL2Output` returns the correct value.
function test_getL2Output_succeeds() external { function test_getL2Output_succeeds() external {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
uint256 nextOutputIndex = oracle.nextOutputIndex(); uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(proposedOutput1, nextBlockNumber, 0, 0);
Types.OutputProposal memory proposal = oracle.getL2Output(nextOutputIndex); Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(nextOutputIndex);
assertEq(proposal.outputRoot, proposedOutput1); assertEq(proposal.outputRoot, proposedOutput1);
assertEq(proposal.timestamp, block.timestamp); assertEq(proposal.timestamp, block.timestamp);
// The block number is larger than the latest proposed output: // The block number is larger than the latest proposed output:
vm.expectRevert(stdError.indexOOBError); vm.expectRevert(stdError.indexOOBError);
oracle.getL2Output(nextOutputIndex + 1); l2OutputOracle.getL2Output(nextOutputIndex + 1);
} }
/// @dev Tests that `getL2OutputIndexAfter` returns the correct value /// @dev Tests that `getL2OutputIndexAfter` returns the correct value
/// when the input is the exact block number of the proposal. /// when the input is the exact block number of the proposal.
function test_getL2OutputIndexAfter_sameBlock_succeeds() external { function test_getL2OutputIndexAfter_sameBlock_succeeds() external {
bytes32 output1 = keccak256(abi.encode(1)); bytes32 output1 = keccak256(abi.encode(1));
uint256 nextBlockNumber1 = oracle.nextBlockNumber(); uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber1); warpToProposeTime(nextBlockNumber1);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);
// Querying with exact same block as proposed returns the proposal. // Querying with exact same block as proposed returns the proposal.
uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1); uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1);
assertEq(index1, 0); assertEq(index1, 0);
} }
...@@ -119,88 +129,94 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer { ...@@ -119,88 +129,94 @@ contract L2OutputOracle_getter_Test is L2OutputOracle_Initializer {
/// when the input is the previous block number of the proposal. /// when the input is the previous block number of the proposal.
function test_getL2OutputIndexAfter_previousBlock_succeeds() external { function test_getL2OutputIndexAfter_previousBlock_succeeds() external {
bytes32 output1 = keccak256(abi.encode(1)); bytes32 output1 = keccak256(abi.encode(1));
uint256 nextBlockNumber1 = oracle.nextBlockNumber(); uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber1); warpToProposeTime(nextBlockNumber1);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);
// Querying with previous block returns the proposal too. // Querying with previous block returns the proposal too.
uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 - 1); uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1 - 1);
assertEq(index1, 0); assertEq(index1, 0);
} }
/// @dev Tests that `getL2OutputIndexAfter` returns the correct value. /// @dev Tests that `getL2OutputIndexAfter` returns the correct value.
function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external { function test_getL2OutputIndexAfter_multipleOutputsExist_succeeds() external {
bytes32 output1 = keccak256(abi.encode(1)); bytes32 output1 = keccak256(abi.encode(1));
uint256 nextBlockNumber1 = oracle.nextBlockNumber(); uint256 nextBlockNumber1 = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber1); warpToProposeTime(nextBlockNumber1);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(output1, nextBlockNumber1, 0, 0); l2OutputOracle.proposeL2Output(output1, nextBlockNumber1, 0, 0);
bytes32 output2 = keccak256(abi.encode(2)); bytes32 output2 = keccak256(abi.encode(2));
uint256 nextBlockNumber2 = oracle.nextBlockNumber(); uint256 nextBlockNumber2 = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber2); warpToProposeTime(nextBlockNumber2);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(output2, nextBlockNumber2, 0, 0); l2OutputOracle.proposeL2Output(output2, nextBlockNumber2, 0, 0);
bytes32 output3 = keccak256(abi.encode(3)); bytes32 output3 = keccak256(abi.encode(3));
uint256 nextBlockNumber3 = oracle.nextBlockNumber(); uint256 nextBlockNumber3 = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber3); warpToProposeTime(nextBlockNumber3);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(output3, nextBlockNumber3, 0, 0); l2OutputOracle.proposeL2Output(output3, nextBlockNumber3, 0, 0);
bytes32 output4 = keccak256(abi.encode(4)); bytes32 output4 = keccak256(abi.encode(4));
uint256 nextBlockNumber4 = oracle.nextBlockNumber(); uint256 nextBlockNumber4 = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber4); warpToProposeTime(nextBlockNumber4);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(output4, nextBlockNumber4, 0, 0); l2OutputOracle.proposeL2Output(output4, nextBlockNumber4, 0, 0);
// Querying with a block number between the first and second proposal // Querying with a block number between the first and second proposal
uint256 index1 = oracle.getL2OutputIndexAfter(nextBlockNumber1 + 1); uint256 index1 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber1 + 1);
assertEq(index1, 1); assertEq(index1, 1);
// Querying with a block number between the second and third proposal // Querying with a block number between the second and third proposal
uint256 index2 = oracle.getL2OutputIndexAfter(nextBlockNumber2 + 1); uint256 index2 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber2 + 1);
assertEq(index2, 2); assertEq(index2, 2);
// Querying with a block number between the third and fourth proposal // Querying with a block number between the third and fourth proposal
uint256 index3 = oracle.getL2OutputIndexAfter(nextBlockNumber3 + 1); uint256 index3 = l2OutputOracle.getL2OutputIndexAfter(nextBlockNumber3 + 1);
assertEq(index3, 3); assertEq(index3, 3);
} }
/// @dev Tests that `getL2OutputIndexAfter` reverts when no output exists. /// @dev Tests that `getL2OutputIndexAfter` reverts when no output exists.
function test_getL2OutputIndexAfter_noOutputsExis_reverts() external { function test_getL2OutputIndexAfter_noOutputsExis_reverts() external {
vm.expectRevert("L2OutputOracle: cannot get output as no outputs have been proposed yet"); vm.expectRevert("L2OutputOracle: cannot get output as no outputs have been proposed yet");
oracle.getL2OutputIndexAfter(0); l2OutputOracle.getL2OutputIndexAfter(0);
} }
/// @dev Tests that `nextBlockNumber` returns the correct value. /// @dev Tests that `nextBlockNumber` returns the correct value.
function test_nextBlockNumber_succeeds() external { function test_nextBlockNumber_succeeds() external {
assertEq( assertEq(
oracle.nextBlockNumber(), l2OutputOracle.nextBlockNumber(),
// The return value should match this arithmetic // The return value should match this arithmetic
oracle.latestBlockNumber() + oracle.SUBMISSION_INTERVAL() l2OutputOracle.latestBlockNumber() + l2OutputOracle.SUBMISSION_INTERVAL()
); );
} }
/// @dev Tests that `computeL2Timestamp` returns the correct value. /// @dev Tests that `computeL2Timestamp` returns the correct value.
function test_computeL2Timestamp_succeeds() external { function test_computeL2Timestamp_succeeds() external {
uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp();
uint256 l2BlockTime = cfg.l2BlockTime();
// reverts if timestamp is too low // reverts if timestamp is too low
vm.expectRevert(stdError.arithmeticError); vm.expectRevert(stdError.arithmeticError);
oracle.computeL2Timestamp(startingBlockNumber - 1); l2OutputOracle.computeL2Timestamp(startingBlockNumber - 1);
// check timestamp for the very first block // check timestamp for the very first block
assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp); assertEq(l2OutputOracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);
// check timestamp for the first block after the starting block // check timestamp for the first block after the starting block
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime); assertEq(l2OutputOracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + l2BlockTime);
// check timestamp for some other block number // check timestamp for some other block number
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024); assertEq(
l2OutputOracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + l2BlockTime * 96024
);
} }
} }
contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { contract L2OutputOracle_proposeL2Output_Test is CommonTest {
/// @dev Test that `proposeL2Output` succeeds for a valid input /// @dev Test that `proposeL2Output` succeeds for a valid input
/// and when a block hash and number are not specified. /// and when a block hash and number are not specified.
function test_proposeL2Output_proposeAnotherOutput_succeeds() public { function test_proposeL2Output_proposeAnotherOutput_succeeds() public {
...@@ -214,62 +230,62 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { ...@@ -214,62 +230,62 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer {
uint256 prevL1BlockNumber = block.number - 1; uint256 prevL1BlockNumber = block.number - 1;
bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber); bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);
} }
/// @dev Tests that `proposeL2Output` reverts when called by a party /// @dev Tests that `proposeL2Output` reverts when called by a party
/// that is not the proposer. /// that is not the proposer.
function test_proposeL2Output_notProposer_reverts() external { function test_proposeL2Output_notProposer_reverts() external {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(address(128)); vm.prank(address(128));
vm.expectRevert("L2OutputOracle: only the proposer address can propose new outputs"); vm.expectRevert("L2OutputOracle: only the proposer address can propose new outputs");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
/// @dev Tests that `proposeL2Output` reverts when given a zero blockhash. /// @dev Tests that `proposeL2Output` reverts when given a zero blockhash.
function test_proposeL2Output_emptyOutput_reverts() external { function test_proposeL2Output_emptyOutput_reverts() external {
bytes32 outputToPropose = bytes32(0); bytes32 outputToPropose = bytes32(0);
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
vm.expectRevert("L2OutputOracle: L2 output proposal cannot be the zero hash"); vm.expectRevert("L2OutputOracle: L2 output proposal cannot be the zero hash");
oracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(outputToPropose, nextBlockNumber, 0, 0);
} }
/// @dev Tests that `proposeL2Output` reverts when given a block number /// @dev Tests that `proposeL2Output` reverts when given a block number
/// that does not match the next expected block number. /// that does not match the next expected block number.
function test_proposeL2Output_unexpectedBlockNumber_reverts() external { function test_proposeL2Output_unexpectedBlockNumber_reverts() external {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
vm.expectRevert("L2OutputOracle: block number must be equal to next expected block number"); vm.expectRevert("L2OutputOracle: block number must be equal to next expected block number");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);
} }
/// @dev Tests that `proposeL2Output` reverts when given a block number /// @dev Tests that `proposeL2Output` reverts when given a block number
/// that has a timestamp in the future. /// that has a timestamp in the future.
function test_proposeL2Output_futureTimetamp_reverts() external { function test_proposeL2Output_futureTimetamp_reverts() external {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
uint256 nextTimestamp = oracle.computeL2Timestamp(nextBlockNumber); uint256 nextTimestamp = l2OutputOracle.computeL2Timestamp(nextBlockNumber);
vm.warp(nextTimestamp); vm.warp(nextTimestamp);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
vm.expectRevert("L2OutputOracle: cannot propose L2 output in the future"); vm.expectRevert("L2OutputOracle: cannot propose L2 output in the future");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, 0, 0);
} }
/// @dev Tests that `proposeL2Output` reverts when given a block number /// @dev Tests that `proposeL2Output` reverts when given a block number
/// whose hash does not match the given block hash. /// whose hash does not match the given block hash.
function test_proposeL2Output_wrongFork_reverts() external { function test_proposeL2Output_wrongFork_reverts() external {
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number - 1); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, bytes32(uint256(0x01)), block.number);
} }
/// @dev Tests that `proposeL2Output` reverts when given a block number /// @dev Tests that `proposeL2Output` reverts when given a block number
...@@ -282,38 +298,39 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer { ...@@ -282,38 +298,39 @@ contract L2OutputOracle_proposeL2Output_Test is L2OutputOracle_Initializer {
uint256 l1BlockNumber = block.number - 1; uint256 l1BlockNumber = block.number - 1;
bytes32 l1BlockHash = blockhash(l1BlockNumber); bytes32 l1BlockHash = blockhash(l1BlockNumber);
uint256 nextBlockNumber = oracle.nextBlockNumber(); uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
warpToProposeTime(nextBlockNumber); warpToProposeTime(nextBlockNumber);
vm.prank(proposer); vm.prank(cfg.l2OutputOracleProposer());
// This will fail when foundry no longer returns zerod block hashes // This will fail when foundry no longer returns zerod block hashes
vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height"); vm.expectRevert("L2OutputOracle: block hash does not match the hash at the expected height");
oracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1); l2OutputOracle.proposeL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);
} }
} }
contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { contract L2OutputOracle_deleteOutputs_Test is CommonTest {
/// @dev Tests that `deleteL2Outputs` succeeds for a single output. /// @dev Tests that `deleteL2Outputs` succeeds for a single output.
function test_deleteOutputs_singleOutput_succeeds() external { function test_deleteOutputs_singleOutput_succeeds() external {
proposeAnotherOutput(); proposeAnotherOutput();
proposeAnotherOutput(); proposeAnotherOutput();
uint256 latestBlockNumber = oracle.latestBlockNumber(); uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber();
uint256 latestOutputIndex = oracle.latestOutputIndex(); uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex();
Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 1); Types.OutputProposal memory newLatestOutput = l2OutputOracle.getL2Output(latestOutputIndex - 1);
vm.prank(owner); vm.prank(l2OutputOracle.challenger());
vm.expectEmit(true, true, false, false); vm.expectEmit(true, true, false, false);
emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex); emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex);
oracle.deleteL2Outputs(latestOutputIndex); l2OutputOracle.deleteL2Outputs(latestOutputIndex);
// validate latestBlockNumber has been reduced // validate latestBlockNumber has been reduced
uint256 latestBlockNumberAfter = oracle.latestBlockNumber(); uint256 latestBlockNumberAfter = l2OutputOracle.latestBlockNumber();
uint256 latestOutputIndexAfter = oracle.latestOutputIndex(); uint256 latestOutputIndexAfter = l2OutputOracle.latestOutputIndex();
uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter); assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);
// validate that the new latest output is as expected. // validate that the new latest output is as expected.
Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter); Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(latestOutputIndexAfter);
assertEq(newLatestOutput.outputRoot, proposal.outputRoot); assertEq(newLatestOutput.outputRoot, proposal.outputRoot);
assertEq(newLatestOutput.timestamp, proposal.timestamp); assertEq(newLatestOutput.timestamp, proposal.timestamp);
} }
...@@ -325,43 +342,44 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { ...@@ -325,43 +342,44 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer {
proposeAnotherOutput(); proposeAnotherOutput();
proposeAnotherOutput(); proposeAnotherOutput();
uint256 latestBlockNumber = oracle.latestBlockNumber(); uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber();
uint256 latestOutputIndex = oracle.latestOutputIndex(); uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex();
Types.OutputProposal memory newLatestOutput = oracle.getL2Output(latestOutputIndex - 3); Types.OutputProposal memory newLatestOutput = l2OutputOracle.getL2Output(latestOutputIndex - 3);
vm.prank(owner); vm.prank(l2OutputOracle.challenger());
vm.expectEmit(true, true, false, false); vm.expectEmit(true, true, false, false);
emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2); emit OutputsDeleted(latestOutputIndex + 1, latestOutputIndex - 2);
oracle.deleteL2Outputs(latestOutputIndex - 2); l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2);
// validate latestBlockNumber has been reduced // validate latestBlockNumber has been reduced
uint256 latestBlockNumberAfter = oracle.latestBlockNumber(); uint256 latestBlockNumberAfter = l2OutputOracle.latestBlockNumber();
uint256 latestOutputIndexAfter = oracle.latestOutputIndex(); uint256 latestOutputIndexAfter = l2OutputOracle.latestOutputIndex();
uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter); assertEq(latestBlockNumber - submissionInterval * 3, latestBlockNumberAfter);
// validate that the new latest output is as expected. // validate that the new latest output is as expected.
Types.OutputProposal memory proposal = oracle.getL2Output(latestOutputIndexAfter); Types.OutputProposal memory proposal = l2OutputOracle.getL2Output(latestOutputIndexAfter);
assertEq(newLatestOutput.outputRoot, proposal.outputRoot); assertEq(newLatestOutput.outputRoot, proposal.outputRoot);
assertEq(newLatestOutput.timestamp, proposal.timestamp); assertEq(newLatestOutput.timestamp, proposal.timestamp);
} }
/// @dev Tests that `deleteL2Outputs` reverts when not called by the challenger. /// @dev Tests that `deleteL2Outputs` reverts when not called by the challenger.
function test_deleteL2Outputs_ifNotChallenger_reverts() external { function test_deleteL2Outputs_ifNotChallenger_reverts() external {
uint256 latestBlockNumber = oracle.latestBlockNumber(); uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber();
vm.expectRevert("L2OutputOracle: only the challenger address can delete outputs"); vm.expectRevert("L2OutputOracle: only the challenger address can delete outputs");
oracle.deleteL2Outputs(latestBlockNumber); l2OutputOracle.deleteL2Outputs(latestBlockNumber);
} }
/// @dev Tests that `deleteL2Outputs` reverts for a non-existant output index. /// @dev Tests that `deleteL2Outputs` reverts for a non-existant output index.
function test_deleteL2Outputs_nonExistent_reverts() external { function test_deleteL2Outputs_nonExistent_reverts() external {
proposeAnotherOutput(); proposeAnotherOutput();
uint256 latestBlockNumber = oracle.latestBlockNumber(); uint256 latestBlockNumber = l2OutputOracle.latestBlockNumber();
vm.prank(owner); vm.prank(l2OutputOracle.challenger());
vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index");
oracle.deleteL2Outputs(latestBlockNumber + 1); l2OutputOracle.deleteL2Outputs(latestBlockNumber + 1);
} }
/// @dev Tests that `deleteL2Outputs` reverts when trying to delete outputs /// @dev Tests that `deleteL2Outputs` reverts when trying to delete outputs
...@@ -372,14 +390,14 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { ...@@ -372,14 +390,14 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer {
proposeAnotherOutput(); proposeAnotherOutput();
// Delete the latest two outputs // Delete the latest two outputs
uint256 latestOutputIndex = oracle.latestOutputIndex(); uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex();
vm.prank(owner); vm.prank(l2OutputOracle.challenger());
oracle.deleteL2Outputs(latestOutputIndex - 2); l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2);
// Now try to delete the same output again // Now try to delete the same output again
vm.prank(owner); vm.prank(l2OutputOracle.challenger());
vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index"); vm.expectRevert("L2OutputOracle: cannot delete outputs after the latest output index");
oracle.deleteL2Outputs(latestOutputIndex - 2); l2OutputOracle.deleteL2Outputs(latestOutputIndex - 2);
} }
/// @dev Tests that `deleteL2Outputs` reverts for finalized outputs. /// @dev Tests that `deleteL2Outputs` reverts for finalized outputs.
...@@ -387,43 +405,48 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer { ...@@ -387,43 +405,48 @@ contract L2OutputOracle_deleteOutputs_Test is L2OutputOracle_Initializer {
proposeAnotherOutput(); proposeAnotherOutput();
// Warp past the finalization period + 1 second // Warp past the finalization period + 1 second
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
uint256 latestOutputIndex = oracle.latestOutputIndex(); uint256 latestOutputIndex = l2OutputOracle.latestOutputIndex();
// Try to delete a finalized output // Try to delete a finalized output
vm.prank(owner); vm.prank(l2OutputOracle.challenger());
vm.expectRevert("L2OutputOracle: cannot delete outputs that have already been finalized"); vm.expectRevert("L2OutputOracle: cannot delete outputs that have already been finalized");
oracle.deleteL2Outputs(latestOutputIndex); l2OutputOracle.deleteL2Outputs(latestOutputIndex);
} }
} }
contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { contract L2OutputOracleUpgradeable_Test is CommonTest {
Proxy internal proxy;
function setUp() public override {
super.setUp();
proxy = Proxy(payable(address(oracle)));
}
/// @dev Tests that the proxy is initialized with the correct values. /// @dev Tests that the proxy is initialized with the correct values.
function test_initValuesOnProxy_succeeds() external { function test_initValuesOnProxy_succeeds() external {
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval); address proposer = cfg.l2OutputOracleProposer();
assertEq(oracle.submissionInterval(), submissionInterval); address challenger = cfg.l2OutputOracleChallenger();
assertEq(oracle.L2_BLOCK_TIME(), l2BlockTime); uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
assertEq(oracle.l2BlockTime(), l2BlockTime); uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
assertEq(oracle.startingBlockNumber(), startingBlockNumber); uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp();
assertEq(oracle.startingTimestamp(), startingTimestamp); uint256 l2BlockTime = cfg.l2BlockTime();
assertEq(oracle.finalizationPeriodSeconds(), finalizationPeriodSeconds); uint256 finalizationPeriodSeconds = cfg.finalizationPeriodSeconds();
assertEq(oracle.PROPOSER(), proposer);
assertEq(oracle.proposer(), proposer); assertEq(l2OutputOracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(oracle.CHALLENGER(), owner); assertEq(l2OutputOracle.submissionInterval(), submissionInterval);
assertEq(oracle.challenger(), owner); assertEq(l2OutputOracle.L2_BLOCK_TIME(), l2BlockTime);
assertEq(l2OutputOracle.l2BlockTime(), l2BlockTime);
assertEq(l2OutputOracle.startingBlockNumber(), startingBlockNumber);
assertEq(l2OutputOracle.startingTimestamp(), startingTimestamp);
assertEq(l2OutputOracle.finalizationPeriodSeconds(), finalizationPeriodSeconds);
assertEq(l2OutputOracle.PROPOSER(), proposer);
assertEq(l2OutputOracle.proposer(), proposer);
assertEq(l2OutputOracle.CHALLENGER(), challenger);
assertEq(l2OutputOracle.challenger(), challenger);
} }
/// @dev Tests that the impl is created with the correct values. /// @dev Tests that the impl is created with the correct values.
function test_initValuesOnImpl_succeeds() external { function test_initValuesOnImpl_succeeds() external {
L2OutputOracle oracleImpl = L2OutputOracle(mustGetAddress("L2OutputOracle"));
uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL()); assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());
uint256 l2BlockTime = cfg.l2BlockTime();
assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME()); assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());
// The values that are set in the initialize function should be all // The values that are set in the initialize function should be all
...@@ -438,8 +461,10 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -438,8 +461,10 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
/// @dev Tests that the proxy cannot be initialized twice. /// @dev Tests that the proxy cannot be initialized twice.
function test_initializeProxy_alreadyInitialized_reverts() external { function test_initializeProxy_alreadyInitialized_reverts() external {
uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp();
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L2OutputOracle(payable(proxy)).initialize({ l2OutputOracle.initialize({
_startingBlockNumber: startingBlockNumber, _startingBlockNumber: startingBlockNumber,
_startingTimestamp: startingTimestamp, _startingTimestamp: startingTimestamp,
_proposer: address(1), _proposer: address(1),
...@@ -449,8 +474,11 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -449,8 +474,11 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
/// @dev Tests that the implementation contract cannot be initialized twice. /// @dev Tests that the implementation contract cannot be initialized twice.
function test_initializeImpl_alreadyInitialized_reverts() external { function test_initializeImpl_alreadyInitialized_reverts() external {
L2OutputOracle oracleImpl = L2OutputOracle(mustGetAddress("L2OutputOracle"));
uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
uint256 startingTimestamp = cfg.l2OutputOracleStartingTimestamp();
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
L2OutputOracle(oracleImpl).initialize({ oracleImpl.initialize({
_startingBlockNumber: startingBlockNumber, _startingBlockNumber: startingBlockNumber,
_startingTimestamp: startingTimestamp, _startingTimestamp: startingTimestamp,
_proposer: address(1), _proposer: address(1),
...@@ -460,8 +488,9 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -460,8 +488,9 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
/// @dev Tests that the proxy can be successfully upgraded. /// @dev Tests that the proxy can be successfully upgraded.
function test_upgrading_succeeds() external { function test_upgrading_succeeds() external {
Proxy proxy = Proxy(mustGetAddress("L2OutputOracleProxy"));
// Check an unused slot before upgrading. // Check an unused slot before upgrading.
bytes32 slot21Before = vm.load(address(oracle), bytes32(uint256(21))); bytes32 slot21Before = vm.load(address(l2OutputOracle), bytes32(uint256(21)));
assertEq(bytes32(0), slot21Before); assertEq(bytes32(0), slot21Before);
NextImpl nextImpl = new NextImpl(); NextImpl nextImpl = new NextImpl();
...@@ -472,8 +501,8 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer { ...@@ -472,8 +501,8 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
assertEq(proxy.implementation(), address(nextImpl)); assertEq(proxy.implementation(), address(nextImpl));
// Verify that the NextImpl contract initialized its values according as expected // Verify that the NextImpl contract initialized its values according as expected
bytes32 slot21After = vm.load(address(oracle), bytes32(uint256(21))); bytes32 slot21After = vm.load(address(l2OutputOracle), bytes32(uint256(21)));
bytes32 slot21Expected = NextImpl(address(oracle)).slot21Init(); bytes32 slot21Expected = NextImpl(address(l2OutputOracle)).slot21Init();
assertEq(slot21Expected, slot21After); assertEq(slot21Expected, slot21After);
} }
} }
...@@ -3,7 +3,7 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,7 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
// Target contract is imported by the `Bridge_Initializer` // Target contract is imported by the `Bridge_Initializer`
import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { stdStorage, StdStorage } from "forge-std/Test.sol"; import { stdStorage, StdStorage } from "forge-std/Test.sol";
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol"; import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
...@@ -23,24 +23,24 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -23,24 +23,24 @@ contract L2StandardBridge_Test is Bridge_Initializer {
/// @dev Tests that the bridge is initialized correctly. /// @dev Tests that the bridge is initialized correctly.
function test_initialize_succeeds() external { function test_initialize_succeeds() external {
assertEq(address(L2Bridge.messenger()), address(L2Messenger)); assertEq(address(l2StandardBridge.messenger()), address(l2CrossDomainMessenger));
assertEq(L1Bridge.l2TokenBridge(), address(L2Bridge)); assertEq(l1StandardBridge.l2TokenBridge(), address(l2StandardBridge));
assertEq(address(L2Bridge.OTHER_BRIDGE()), address(L1Bridge)); assertEq(address(l2StandardBridge.OTHER_BRIDGE()), address(l1StandardBridge));
} }
/// @dev Tests that the bridge receives ETH and successfully initiates a withdrawal. /// @dev Tests that the bridge receives ETH and successfully initiates a withdrawal.
function test_receive_succeeds() external { function test_receive_succeeds() external {
assertEq(address(messagePasser).balance, 0); assertEq(address(l2ToL1MessagePasser).balance, 0);
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = l2CrossDomainMessenger.messageNonce();
bytes memory message = bytes memory message =
abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex""); abi.encodeWithSelector(StandardBridge.finalizeBridgeETH.selector, alice, alice, 100, hex"");
uint64 baseGas = L2Messenger.baseGas(message, 200_000); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 200_000);
bytes memory withdrawalData = abi.encodeWithSelector( bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, CrossDomainMessenger.relayMessage.selector,
nonce, nonce,
address(L2Bridge), address(l2StandardBridge),
address(L1Bridge), address(l1StandardBridge),
100, 100,
200_000, 200_000,
message message
...@@ -48,8 +48,8 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -48,8 +48,8 @@ contract L2StandardBridge_Test is Bridge_Initializer {
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
nonce: nonce, nonce: nonce,
sender: address(L2Messenger), sender: address(l2CrossDomainMessenger),
target: address(L1Messenger), target: address(l1CrossDomainMessenger),
value: 100, value: 100,
gasLimit: baseGas, gasLimit: baseGas,
data: withdrawalData data: withdrawalData
...@@ -63,24 +63,30 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -63,24 +63,30 @@ contract L2StandardBridge_Test is Bridge_Initializer {
emit ETHBridgeInitiated(alice, alice, 100, hex""); emit ETHBridgeInitiated(alice, alice, 100, hex"");
// L2ToL1MessagePasser will emit a MessagePassed event // L2ToL1MessagePasser will emit a MessagePassed event
vm.expectEmit(true, true, true, true, address(messagePasser)); vm.expectEmit(true, true, true, true, address(l2ToL1MessagePasser));
emit MessagePassed( emit MessagePassed(
nonce, address(L2Messenger), address(L1Messenger), 100, baseGas, withdrawalData, withdrawalHash nonce,
address(l2CrossDomainMessenger),
address(l1CrossDomainMessenger),
100,
baseGas,
withdrawalData,
withdrawalHash
); );
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L2Messenger)); vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger));
emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 200_000); emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 200_000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L2Messenger)); vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger));
emit SentMessageExtension1(address(L2Bridge), 100); emit SentMessageExtension1(address(l2StandardBridge), 100);
vm.expectCall( vm.expectCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector( abi.encodeWithSelector(
CrossDomainMessenger.sendMessage.selector, CrossDomainMessenger.sendMessage.selector,
address(L1Bridge), address(l1StandardBridge),
message, message,
200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT 200_000 // StandardBridge's RECEIVE_DEFAULT_GAS_LIMIT
) )
...@@ -89,23 +95,26 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -89,23 +95,26 @@ contract L2StandardBridge_Test is Bridge_Initializer {
vm.expectCall( vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER, Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData L2ToL1MessagePasser.initiateWithdrawal.selector,
address(l1CrossDomainMessenger),
baseGas,
withdrawalData
) )
); );
vm.prank(alice, alice); vm.prank(alice, alice);
(bool success,) = address(L2Bridge).call{ value: 100 }(hex""); (bool success,) = address(l2StandardBridge).call{ value: 100 }(hex"");
assertEq(success, true); assertEq(success, true);
assertEq(address(messagePasser).balance, 100); assertEq(address(l2ToL1MessagePasser).balance, 100);
} }
/// @dev Tests that `withdraw` reverts if the amount is not equal to the value sent. /// @dev Tests that `withdraw` reverts if the amount is not equal to the value sent.
function test_withdraw_insufficientValue_reverts() external { function test_withdraw_insufficientValue_reverts() external {
assertEq(address(messagePasser).balance, 0); assertEq(address(l2ToL1MessagePasser).balance, 0);
vm.expectRevert("StandardBridge: bridging ETH must include sufficient ETH value"); vm.expectRevert("StandardBridge: bridging ETH must include sufficient ETH value");
vm.prank(alice, alice); vm.prank(alice, alice);
L2Bridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex""); l2StandardBridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 100, 1000, hex"");
} }
/// @dev Tests that the legacy `withdraw` interface on the L2StandardBridge /// @dev Tests that the legacy `withdraw` interface on the L2StandardBridge
...@@ -114,7 +123,7 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -114,7 +123,7 @@ contract L2StandardBridge_Test is Bridge_Initializer {
assertTrue(alice.balance >= 100); assertTrue(alice.balance >= 100);
assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0); assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, 0);
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit WithdrawalInitiated({ emit WithdrawalInitiated({
l1Token: address(0), l1Token: address(0),
l2Token: Predeploys.LEGACY_ERC20_ETH, l2Token: Predeploys.LEGACY_ERC20_ETH,
...@@ -124,11 +133,11 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -124,11 +133,11 @@ contract L2StandardBridge_Test is Bridge_Initializer {
data: hex"" data: hex""
}); });
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex"" }); emit ETHBridgeInitiated({ from: alice, to: alice, amount: 100, data: hex"" });
vm.prank(alice, alice); vm.prank(alice, alice);
L2Bridge.withdraw{ value: 100 }({ l2StandardBridge.withdraw{ value: 100 }({
_l2Token: Predeploys.LEGACY_ERC20_ETH, _l2Token: Predeploys.LEGACY_ERC20_ETH,
_amount: 100, _amount: 100,
_minGasLimit: 1000, _minGasLimit: 1000,
...@@ -145,19 +154,25 @@ contract PreBridgeERC20 is Bridge_Initializer { ...@@ -145,19 +154,25 @@ contract PreBridgeERC20 is Bridge_Initializer {
// Alice has 100 L2Token // Alice has 100 L2Token
deal(_l2Token, alice, 100, true); deal(_l2Token, alice, 100, true);
assertEq(ERC20(_l2Token).balanceOf(alice), 100); assertEq(ERC20(_l2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = l2CrossDomainMessenger.messageNonce();
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex"" StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, alice, 100, hex""
); );
uint64 baseGas = L2Messenger.baseGas(message, 1000); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000);
bytes memory withdrawalData = abi.encodeWithSelector( bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message CrossDomainMessenger.relayMessage.selector,
nonce,
address(l2StandardBridge),
address(l1StandardBridge),
0,
1000,
message
); );
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
nonce: nonce, nonce: nonce,
sender: address(L2Messenger), sender: address(l2CrossDomainMessenger),
target: address(L1Messenger), target: address(l1CrossDomainMessenger),
value: 0, value: 0,
gasLimit: baseGas, gasLimit: baseGas,
data: withdrawalData data: withdrawalData
...@@ -166,28 +181,34 @@ contract PreBridgeERC20 is Bridge_Initializer { ...@@ -166,28 +181,34 @@ contract PreBridgeERC20 is Bridge_Initializer {
if (_isLegacy) { if (_isLegacy) {
vm.expectCall( vm.expectCall(
address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdraw.selector, _l2Token, 100, 1000, hex"") address(l2StandardBridge),
abi.encodeWithSelector(l2StandardBridge.withdraw.selector, _l2Token, 100, 1000, hex"")
); );
} else { } else {
vm.expectCall( vm.expectCall(
address(L2Bridge), address(l2StandardBridge),
abi.encodeWithSelector(L2Bridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex"") abi.encodeWithSelector(
l2StandardBridge.bridgeERC20.selector, _l2Token, address(L1Token), 100, 1000, hex""
)
); );
} }
vm.expectCall( vm.expectCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000) abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000)
); );
vm.expectCall( vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER, Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData L2ToL1MessagePasser.initiateWithdrawal.selector,
address(l1CrossDomainMessenger),
baseGas,
withdrawalData
) )
); );
// The L2Bridge should burn the tokens // The l2StandardBridge should burn the tokens
vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); vm.expectCall(_l2Token, abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100));
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -198,16 +219,22 @@ contract PreBridgeERC20 is Bridge_Initializer { ...@@ -198,16 +219,22 @@ contract PreBridgeERC20 is Bridge_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit MessagePassed( emit MessagePassed(
nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash nonce,
address(l2CrossDomainMessenger),
address(l1CrossDomainMessenger),
0,
baseGas,
withdrawalData,
withdrawalHash
); );
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000); emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 1000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit SentMessageExtension1(address(L2Bridge), 0); emit SentMessageExtension1(address(l2StandardBridge), 0);
vm.prank(alice, alice); vm.prank(alice, alice);
} }
...@@ -220,7 +247,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { ...@@ -220,7 +247,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
// - calls Withdrawer.initiateWithdrawal // - calls Withdrawer.initiateWithdrawal
function test_withdraw_withdrawingERC20_succeeds() external { function test_withdraw_withdrawingERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) }); _preBridgeERC20({ _isLegacy: true, _l2Token: address(L2Token) });
L2Bridge.withdraw(address(L2Token), 100, 1000, hex""); l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
} }
...@@ -231,21 +258,21 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { ...@@ -231,21 +258,21 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
// - calls Withdrawer.initiateWithdrawal // - calls Withdrawer.initiateWithdrawal
function test_bridgeERC20_succeeds() external { function test_bridgeERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) }); _preBridgeERC20({ _isLegacy: false, _l2Token: address(L2Token) });
L2Bridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex""); l2StandardBridge.bridgeERC20(address(L2Token), address(L1Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
} }
function test_withdrawLegacyERC20_succeeds() external { function test_withdrawLegacyERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) }); _preBridgeERC20({ _isLegacy: true, _l2Token: address(LegacyL2Token) });
L2Bridge.withdraw(address(LegacyL2Token), 100, 1000, hex""); l2StandardBridge.withdraw(address(LegacyL2Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
} }
function test_bridgeLegacyERC20_succeeds() external { function test_bridgeLegacyERC20_succeeds() external {
_preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) }); _preBridgeERC20({ _isLegacy: false, _l2Token: address(LegacyL2Token) });
L2Bridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex""); l2StandardBridge.bridgeERC20(address(LegacyL2Token), address(L1Token), 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
} }
...@@ -255,7 +282,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 { ...@@ -255,7 +282,7 @@ contract L2StandardBridge_BridgeERC20_Test is PreBridgeERC20 {
deal(address(L2Token), address(this), 100, true); deal(address(L2Token), address(this), 100, true);
vm.expectRevert("StandardBridge: function can only be called from an EOA"); vm.expectRevert("StandardBridge: function can only be called from an EOA");
L2Bridge.withdraw(address(L2Token), 100, 1000, hex""); l2StandardBridge.withdraw(address(L2Token), 100, 1000, hex"");
} }
} }
...@@ -265,70 +292,86 @@ contract PreBridgeERC20To is Bridge_Initializer { ...@@ -265,70 +292,86 @@ contract PreBridgeERC20To is Bridge_Initializer {
function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal { function _preBridgeERC20To(bool _isLegacy, address _l2Token) internal {
deal(_l2Token, alice, 100, true); deal(_l2Token, alice, 100, true);
assertEq(ERC20(L2Token).balanceOf(alice), 100); assertEq(ERC20(L2Token).balanceOf(alice), 100);
uint256 nonce = L2Messenger.messageNonce(); uint256 nonce = l2CrossDomainMessenger.messageNonce();
bytes memory message = abi.encodeWithSelector( bytes memory message = abi.encodeWithSelector(
StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex"" StandardBridge.finalizeBridgeERC20.selector, address(L1Token), _l2Token, alice, bob, 100, hex""
); );
uint64 baseGas = L2Messenger.baseGas(message, 1000); uint64 baseGas = l2CrossDomainMessenger.baseGas(message, 1000);
bytes memory withdrawalData = abi.encodeWithSelector( bytes memory withdrawalData = abi.encodeWithSelector(
CrossDomainMessenger.relayMessage.selector, nonce, address(L2Bridge), address(L1Bridge), 0, 1000, message CrossDomainMessenger.relayMessage.selector,
nonce,
address(l2StandardBridge),
address(l1StandardBridge),
0,
1000,
message
); );
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
nonce: nonce, nonce: nonce,
sender: address(L2Messenger), sender: address(l2CrossDomainMessenger),
target: address(L1Messenger), target: address(l1CrossDomainMessenger),
value: 0, value: 0,
gasLimit: baseGas, gasLimit: baseGas,
data: withdrawalData data: withdrawalData
}) })
); );
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex""); emit WithdrawalInitiated(address(L1Token), _l2Token, alice, bob, 100, hex"");
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex""); emit ERC20BridgeInitiated(_l2Token, address(L1Token), alice, bob, 100, hex"");
vm.expectEmit(true, true, true, true, address(messagePasser)); vm.expectEmit(true, true, true, true, address(l2ToL1MessagePasser));
emit MessagePassed( emit MessagePassed(
nonce, address(L2Messenger), address(L1Messenger), 0, baseGas, withdrawalData, withdrawalHash nonce,
address(l2CrossDomainMessenger),
address(l1CrossDomainMessenger),
0,
baseGas,
withdrawalData,
withdrawalHash
); );
// SentMessage event emitted by the CrossDomainMessenger // SentMessage event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L2Messenger)); vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger));
emit SentMessage(address(L1Bridge), address(L2Bridge), message, nonce, 1000); emit SentMessage(address(l1StandardBridge), address(l2StandardBridge), message, nonce, 1000);
// SentMessageExtension1 event emitted by the CrossDomainMessenger // SentMessageExtension1 event emitted by the CrossDomainMessenger
vm.expectEmit(true, true, true, true, address(L2Messenger)); vm.expectEmit(true, true, true, true, address(l2CrossDomainMessenger));
emit SentMessageExtension1(address(L2Bridge), 0); emit SentMessageExtension1(address(l2StandardBridge), 0);
if (_isLegacy) { if (_isLegacy) {
vm.expectCall( vm.expectCall(
address(L2Bridge), abi.encodeWithSelector(L2Bridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"") address(l2StandardBridge),
abi.encodeWithSelector(l2StandardBridge.withdrawTo.selector, _l2Token, bob, 100, 1000, hex"")
); );
} else { } else {
vm.expectCall( vm.expectCall(
address(L2Bridge), address(l2StandardBridge),
abi.encodeWithSelector( abi.encodeWithSelector(
L2Bridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex"" l2StandardBridge.bridgeERC20To.selector, _l2Token, address(L1Token), bob, 100, 1000, hex""
) )
); );
} }
vm.expectCall( vm.expectCall(
address(L2Messenger), address(l2CrossDomainMessenger),
abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(L1Bridge), message, 1000) abi.encodeWithSelector(CrossDomainMessenger.sendMessage.selector, address(l1StandardBridge), message, 1000)
); );
vm.expectCall( vm.expectCall(
Predeploys.L2_TO_L1_MESSAGE_PASSER, Predeploys.L2_TO_L1_MESSAGE_PASSER,
abi.encodeWithSelector( abi.encodeWithSelector(
L2ToL1MessagePasser.initiateWithdrawal.selector, address(L1Messenger), baseGas, withdrawalData L2ToL1MessagePasser.initiateWithdrawal.selector,
address(l1CrossDomainMessenger),
baseGas,
withdrawalData
) )
); );
// The L2Bridge should burn the tokens // The l2StandardBridge should burn the tokens
vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100)); vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.burn.selector, alice, 100));
vm.prank(alice, alice); vm.prank(alice, alice);
...@@ -340,7 +383,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To { ...@@ -340,7 +383,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
/// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`.
function test_withdrawTo_withdrawingERC20_succeeds() external { function test_withdrawTo_withdrawingERC20_succeeds() external {
_preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) }); _preBridgeERC20To({ _isLegacy: true, _l2Token: address(L2Token) });
L2Bridge.withdrawTo(address(L2Token), bob, 100, 1000, hex""); l2StandardBridge.withdrawTo(address(L2Token), bob, 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
} }
...@@ -349,7 +392,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To { ...@@ -349,7 +392,7 @@ contract L2StandardBridge_BridgeERC20To_Test is PreBridgeERC20To {
/// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`. /// and initiates a withdrawal with `Withdrawer.initiateWithdrawal`.
function test_bridgeERC20To_succeeds() external { function test_bridgeERC20To_succeeds() external {
_preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) }); _preBridgeERC20To({ _isLegacy: false, _l2Token: address(L2Token) });
L2Bridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex""); l2StandardBridge.bridgeERC20To(address(L2Token), address(L1Token), bob, 100, 1000, hex"");
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
} }
} }
...@@ -361,37 +404,37 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { ...@@ -361,37 +404,37 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
/// - call `Withdrawer.initiateWithdrawal` if the token pair is not supported /// - call `Withdrawer.initiateWithdrawal` if the token pair is not supported
function test_finalizeDeposit_depositingERC20_succeeds() external { function test_finalizeDeposit_depositingERC20_succeeds() external {
vm.mockCall( vm.mockCall(
address(L2Bridge.messenger()), address(l2StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(l2StandardBridge.OTHER_BRIDGE()))
); );
vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100)); vm.expectCall(address(L2Token), abi.encodeWithSelector(OptimismMintableERC20.mint.selector, alice, 100));
// Should emit both the bedrock and legacy events // Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex""); emit ERC20BridgeFinalized(address(L2Token), address(L1Token), alice, alice, 100, hex"");
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); l2StandardBridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex"");
} }
/// @dev Tests that `finalizeDeposit` succeeds when depositing ETH. /// @dev Tests that `finalizeDeposit` succeeds when depositing ETH.
function test_finalizeDeposit_depositingETH_succeeds() external { function test_finalizeDeposit_depositingETH_succeeds() external {
vm.mockCall( vm.mockCall(
address(L2Bridge.messenger()), address(l2StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(l2StandardBridge.OTHER_BRIDGE()))
); );
// Should emit both the bedrock and legacy events // Should emit both the bedrock and legacy events
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex""); emit DepositFinalized(address(L1Token), address(L2Token), alice, alice, 100, hex"");
vm.expectEmit(true, true, true, true, address(L2Bridge)); vm.expectEmit(true, true, true, true, address(l2StandardBridge));
emit ERC20BridgeFinalized( emit ERC20BridgeFinalized(
address(L2Token), // localToken address(L2Token), // localToken
address(L1Token), // remoteToken address(L1Token), // remoteToken
...@@ -401,58 +444,58 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer { ...@@ -401,58 +444,58 @@ contract L2StandardBridge_Bridge_Test is Bridge_Initializer {
hex"" hex""
); );
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
L2Bridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex""); l2StandardBridge.finalizeDeposit(address(L1Token), address(L2Token), alice, alice, 100, hex"");
} }
/// @dev Tests that `finalizeDeposit` reverts if the amounts do not match. /// @dev Tests that `finalizeDeposit` reverts if the amounts do not match.
function test_finalizeBridgeETH_incorrectValue_reverts() external { function test_finalizeBridgeETH_incorrectValue_reverts() external {
vm.mockCall( vm.mockCall(
address(L2Bridge.messenger()), address(l2StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(l2StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(address(L2Messenger), 100); vm.deal(address(l2CrossDomainMessenger), 100);
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("StandardBridge: amount sent does not match amount required"); vm.expectRevert("StandardBridge: amount sent does not match amount required");
L2Bridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex""); l2StandardBridge.finalizeBridgeETH{ value: 50 }(alice, alice, 100, hex"");
} }
/// @dev Tests that `finalizeDeposit` reverts if the receipient is the other bridge. /// @dev Tests that `finalizeDeposit` reverts if the receipient is the other bridge.
function test_finalizeBridgeETH_sendToSelf_reverts() external { function test_finalizeBridgeETH_sendToSelf_reverts() external {
vm.mockCall( vm.mockCall(
address(L2Bridge.messenger()), address(l2StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(l2StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(address(L2Messenger), 100); vm.deal(address(l2CrossDomainMessenger), 100);
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("StandardBridge: cannot send to self"); vm.expectRevert("StandardBridge: cannot send to self");
L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Bridge), 100, hex""); l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l2StandardBridge), 100, hex"");
} }
/// @dev Tests that `finalizeDeposit` reverts if the receipient is the messenger. /// @dev Tests that `finalizeDeposit` reverts if the receipient is the messenger.
function test_finalizeBridgeETH_sendToMessenger_reverts() external { function test_finalizeBridgeETH_sendToMessenger_reverts() external {
vm.mockCall( vm.mockCall(
address(L2Bridge.messenger()), address(l2StandardBridge.messenger()),
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(l2StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(address(L2Messenger), 100); vm.deal(address(l2CrossDomainMessenger), 100);
vm.prank(address(L2Messenger)); vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("StandardBridge: cannot send to messenger"); vm.expectRevert("StandardBridge: cannot send to messenger");
L2Bridge.finalizeBridgeETH{ value: 100 }(alice, address(L2Messenger), 100, hex""); l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, address(l2CrossDomainMessenger), 100, hex"");
} }
} }
contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {
/// @dev Tests that `finalizeBridgeETH` succeeds. /// @dev Tests that `finalizeBridgeETH` succeeds.
function test_finalizeBridgeETH_succeeds() external { function test_finalizeBridgeETH_succeeds() external {
address messenger = address(L2Bridge.messenger()); address messenger = address(l2StandardBridge.messenger());
vm.mockCall( vm.mockCall(
messenger, messenger,
abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector), abi.encodeWithSelector(CrossDomainMessenger.xDomainMessageSender.selector),
abi.encode(address(L2Bridge.OTHER_BRIDGE())) abi.encode(address(l2StandardBridge.OTHER_BRIDGE()))
); );
vm.deal(messenger, 100); vm.deal(messenger, 100);
vm.prank(messenger); vm.prank(messenger);
...@@ -463,6 +506,6 @@ contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer { ...@@ -463,6 +506,6 @@ contract L2StandardBridge_FinalizeBridgeETH_Test is Bridge_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ETHBridgeFinalized(alice, alice, 100, hex""); emit ETHBridgeFinalized(alice, alice, 100, hex"");
L2Bridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex"");
} }
} }
...@@ -2,36 +2,13 @@ ...@@ -2,36 +2,13 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
// Target contract
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
contract L2ToL1MessagePasserTest is CommonTest { contract L2ToL1MessagePasserTest is CommonTest {
L2ToL1MessagePasser messagePasser;
event MessagePassed(
uint256 indexed nonce,
address indexed sender,
address indexed target,
uint256 value,
uint256 gasLimit,
bytes data,
bytes32 withdrawalHash
);
event WithdrawerBalanceBurnt(uint256 indexed amount);
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
messagePasser = new L2ToL1MessagePasser();
}
/// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state /// @dev Tests that `initiateWithdrawal` succeeds and correctly sets the state
/// of the message passer for the withdrawal hash. /// of the message passer for the withdrawal hash.
function testFuzz_initiateWithdrawal_succeeds( function testFuzz_initiateWithdrawal_succeeds(
...@@ -43,7 +20,7 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -43,7 +20,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
) )
external external
{ {
uint256 nonce = messagePasser.messageNonce(); uint256 nonce = l2ToL1MessagePasser.messageNonce();
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
...@@ -56,18 +33,18 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -56,18 +33,18 @@ contract L2ToL1MessagePasserTest is CommonTest {
}) })
); );
vm.expectEmit(true, true, true, true); vm.expectEmit(address(l2ToL1MessagePasser));
emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash); emit MessagePassed(nonce, _sender, _target, _value, _gasLimit, _data, withdrawalHash);
vm.deal(_sender, _value); vm.deal(_sender, _value);
vm.prank(_sender); vm.prank(_sender);
messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);
assertEq(messagePasser.sentMessages(withdrawalHash), true); assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true);
bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0))); bytes32 slot = keccak256(bytes.concat(withdrawalHash, bytes32(0)));
assertEq(vm.load(address(messagePasser), slot), bytes32(uint256(1))); assertEq(vm.load(address(l2ToL1MessagePasser), slot), bytes32(uint256(1)));
} }
/// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed
...@@ -82,7 +59,7 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -82,7 +59,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
{ {
bytes32 withdrawalHash = Hashing.hashWithdrawal( bytes32 withdrawalHash = Hashing.hashWithdrawal(
Types.WithdrawalTransaction({ Types.WithdrawalTransaction({
nonce: messagePasser.messageNonce(), nonce: l2ToL1MessagePasser.messageNonce(),
sender: address(this), sender: address(this),
target: _target, target: _target,
value: _value, value: _value,
...@@ -91,13 +68,13 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -91,13 +68,13 @@ contract L2ToL1MessagePasserTest is CommonTest {
}) })
); );
vm.expectEmit(address(messagePasser)); vm.expectEmit(address(l2ToL1MessagePasser));
emit MessagePassed( emit MessagePassed(
messagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash l2ToL1MessagePasser.messageNonce(), address(this), _target, _value, _gasLimit, _data, withdrawalHash
); );
vm.deal(address(this), _value); vm.deal(address(this), _value);
messagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data); l2ToL1MessagePasser.initiateWithdrawal{ value: _value }(_target, _gasLimit, _data);
} }
/// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed /// @dev Tests that `initiateWithdrawal` succeeds and emits the correct MessagePassed
...@@ -110,7 +87,7 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -110,7 +87,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
) )
external external
{ {
uint256 nonce = messagePasser.messageNonce(); uint256 nonce = l2ToL1MessagePasser.messageNonce();
// EOA emulation // EOA emulation
vm.prank(alice, alice); vm.prank(alice, alice);
...@@ -118,29 +95,28 @@ contract L2ToL1MessagePasserTest is CommonTest { ...@@ -118,29 +95,28 @@ contract L2ToL1MessagePasserTest is CommonTest {
bytes32 withdrawalHash = bytes32 withdrawalHash =
Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, _target, _value, _gasLimit, _data)); Hashing.hashWithdrawal(Types.WithdrawalTransaction(nonce, alice, _target, _value, _gasLimit, _data));
vm.expectEmit(address(messagePasser)); vm.expectEmit(address(l2ToL1MessagePasser));
emit MessagePassed(nonce, alice, _target, _value, _gasLimit, _data, withdrawalHash); emit MessagePassed(nonce, alice, _target, _value, _gasLimit, _data, withdrawalHash);
messagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data });
// the sent messages mapping is filled // the sent messages mapping is filled
assertEq(messagePasser.sentMessages(withdrawalHash), true); assertEq(l2ToL1MessagePasser.sentMessages(withdrawalHash), true);
// the nonce increments // the nonce increments
assertEq(nonce + 1, messagePasser.messageNonce()); assertEq(nonce + 1, l2ToL1MessagePasser.messageNonce());
} }
/// @dev Tests that `burn` succeeds and destroys the ETH held in the contract. /// @dev Tests that `burn` succeeds and destroys the ETH held in the contract.
function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external { function testFuzz_burn_succeeds(uint256 _value, address _target, uint256 _gasLimit, bytes memory _data) external {
vm.deal(address(this), _value); vm.deal(address(this), _value);
messagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data }); l2ToL1MessagePasser.initiateWithdrawal{ value: _value }({ _target: _target, _gasLimit: _gasLimit, _data: _data });
assertEq(address(messagePasser).balance, _value); assertEq(address(l2ToL1MessagePasser).balance, _value);
vm.expectEmit(true, false, false, false);
emit WithdrawerBalanceBurnt(_value); emit WithdrawerBalanceBurnt(_value);
messagePasser.burn(); l2ToL1MessagePasser.burn();
// The Withdrawer should have no balance // The Withdrawer should have no balance
assertEq(address(messagePasser).balance, 0); assertEq(address(l2ToL1MessagePasser).balance, 0);
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract dependencies // Target contract dependencies
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
......
...@@ -2,27 +2,13 @@ ...@@ -2,27 +2,13 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Testing contract dependencies
import { Predeploys } from "src/libraries/Predeploys.sol";
// Target contract
import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol";
contract LegacyMessagePasser_Test is CommonTest { contract LegacyMessagePasser_Test is CommonTest {
LegacyMessagePasser messagePasser;
/// @dev Sets up the test suite.
function setUp() public virtual override {
super.setUp();
messagePasser = new LegacyMessagePasser();
}
/// @dev Tests that `passMessageToL1` succeeds. /// @dev Tests that `passMessageToL1` succeeds.
function test_passMessageToL1_succeeds() external { function test_passMessageToL1_succeeds() external {
vm.prank(alice); vm.prank(alice);
messagePasser.passMessageToL1(hex"ff"); legacyMessagePasser.passMessageToL1(hex"ff");
assert(messagePasser.sentMessages(keccak256(abi.encodePacked(hex"ff", alice)))); assert(legacyMessagePasser.sentMessages(keccak256(abi.encodePacked(hex"ff", alice))));
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity ^0.8.15; pragma solidity ^0.8.15;
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { LibPosition } from "../src/dispute/lib/LibPosition.sol"; import { LibPosition } from "src/dispute/lib/LibPosition.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
/// @notice Tests for `LibPosition` /// @notice Tests for `LibPosition`
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { CommonTest } from "./CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { MIPS } from "src/cannon/MIPS.sol"; import { MIPS } from "src/cannon/MIPS.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import "src/libraries/DisputeTypes.sol"; import "src/libraries/DisputeTypes.sol";
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Target contract dependencies // Target contract dependencies
import { GovernanceToken } from "src/governance/GovernanceToken.sol"; import { GovernanceToken } from "src/governance/GovernanceToken.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol"; import { ILegacyMintableERC20, IOptimismMintableERC20 } from "src/universal/IOptimismMintableERC20.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
...@@ -14,7 +14,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { ...@@ -14,7 +14,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer {
} }
function test_bridge_succeeds() external { function test_bridge_succeeds() external {
assertEq(L2Token.bridge(), address(L2Bridge)); assertEq(L2Token.bridge(), address(l2StandardBridge));
} }
function test_l1Token_succeeds() external { function test_l1Token_succeeds() external {
...@@ -22,7 +22,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { ...@@ -22,7 +22,7 @@ contract OptimismMintableERC20_Test is Bridge_Initializer {
} }
function test_l2Bridge_succeeds() external { function test_l2Bridge_succeeds() external {
assertEq(L2Token.l2Bridge(), address(L2Bridge)); assertEq(L2Token.l2Bridge(), address(l2StandardBridge));
} }
function test_legacy_succeeds() external { function test_legacy_succeeds() external {
...@@ -31,16 +31,16 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { ...@@ -31,16 +31,16 @@ contract OptimismMintableERC20_Test is Bridge_Initializer {
assertEq(L2Token.remoteToken(), address(L1Token)); assertEq(L2Token.remoteToken(), address(L1Token));
assertEq(L2Token.l1Token(), address(L1Token)); assertEq(L2Token.l1Token(), address(L1Token));
// Getters for the bridge // Getters for the bridge
assertEq(L2Token.BRIDGE(), address(L2Bridge)); assertEq(L2Token.BRIDGE(), address(l2StandardBridge));
assertEq(L2Token.bridge(), address(L2Bridge)); assertEq(L2Token.bridge(), address(l2StandardBridge));
assertEq(L2Token.l2Bridge(), address(L2Bridge)); assertEq(L2Token.l2Bridge(), address(l2StandardBridge));
} }
function test_mint_succeeds() external { function test_mint_succeeds() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit Mint(alice, 100); emit Mint(alice, 100);
vm.prank(address(L2Bridge)); vm.prank(address(l2StandardBridge));
L2Token.mint(alice, 100); L2Token.mint(alice, 100);
assertEq(L2Token.balanceOf(alice), 100); assertEq(L2Token.balanceOf(alice), 100);
...@@ -54,13 +54,13 @@ contract OptimismMintableERC20_Test is Bridge_Initializer { ...@@ -54,13 +54,13 @@ contract OptimismMintableERC20_Test is Bridge_Initializer {
} }
function test_burn_succeeds() external { function test_burn_succeeds() external {
vm.prank(address(L2Bridge)); vm.prank(address(l2StandardBridge));
L2Token.mint(alice, 100); L2Token.mint(alice, 100);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit Burn(alice, 100); emit Burn(alice, 100);
vm.prank(address(L2Bridge)); vm.prank(address(l2StandardBridge));
L2Token.burn(alice, 100); L2Token.burn(alice, 100);
assertEq(L2Token.balanceOf(alice), 0); assertEq(L2Token.balanceOf(alice), 0);
......
...@@ -2,18 +2,14 @@ ...@@ -2,18 +2,14 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
contract OptimismMintableTokenFactory_Test is Bridge_Initializer { contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
function setUp() public override {
super.setUp();
}
function test_bridge_succeeds() external { function test_bridge_succeeds() external {
assertEq(address(L2TokenFactory.BRIDGE()), address(L2Bridge)); assertEq(address(l2OptimismMintableERC20Factory.BRIDGE()), address(l2StandardBridge));
} }
function test_createStandardL2Token_succeeds() external { function test_createStandardL2Token_succeeds() external {
...@@ -29,7 +25,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -29,7 +25,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
emit OptimismMintableERC20Created(local, remote, alice); emit OptimismMintableERC20Created(local, remote, alice);
vm.prank(alice); vm.prank(alice);
address addr = L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); address addr = l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP");
assertTrue(addr == local); assertTrue(addr == local);
assertTrue(OptimismMintableERC20(local).decimals() == 18); assertTrue(OptimismMintableERC20(local).decimals() == 18);
} }
...@@ -45,7 +41,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -45,7 +41,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
emit OptimismMintableERC20Created(local, remote, alice); emit OptimismMintableERC20Created(local, remote, alice);
vm.prank(alice); vm.prank(alice);
address addr = L2TokenFactory.createOptimismMintableERC20WithDecimals(remote, "Beep", "BOOP", 6); address addr = l2OptimismMintableERC20Factory.createOptimismMintableERC20WithDecimals(remote, "Beep", "BOOP", 6);
assertTrue(addr == local); assertTrue(addr == local);
assertTrue(OptimismMintableERC20(local).decimals() == 6); assertTrue(OptimismMintableERC20(local).decimals() == 6);
...@@ -55,18 +51,18 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -55,18 +51,18 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
address remote = address(4); address remote = address(4);
vm.prank(alice); vm.prank(alice);
L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP");
vm.expectRevert(); vm.expectRevert();
vm.prank(alice); vm.prank(alice);
L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP");
} }
function test_createStandardL2Token_remoteIsZero_reverts() external { function test_createStandardL2Token_remoteIsZero_reverts() external {
address remote = address(0); address remote = address(0);
vm.expectRevert("OptimismMintableERC20Factory: must provide remote token address"); vm.expectRevert("OptimismMintableERC20Factory: must provide remote token address");
L2TokenFactory.createStandardL2Token(remote, "Beep", "BOOP"); l2OptimismMintableERC20Factory.createStandardL2Token(remote, "Beep", "BOOP");
} }
function calculateTokenAddress( function calculateTokenAddress(
...@@ -79,10 +75,12 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -79,10 +75,12 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
view view
returns (address) returns (address)
{ {
bytes memory constructorArgs = abi.encode(address(L2Bridge), _remote, _name, _symbol, _decimals); bytes memory constructorArgs = abi.encode(address(l2StandardBridge), _remote, _name, _symbol, _decimals);
bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC20).creationCode, constructorArgs); bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC20).creationCode, constructorArgs);
bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol, _decimals)); bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol, _decimals));
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(L2TokenFactory), salt, keccak256(bytecode))); bytes32 hash = keccak256(
abi.encodePacked(bytes1(0xff), address(l2OptimismMintableERC20Factory), salt, keccak256(bytecode))
);
return address(uint160(uint256(hash))); return address(uint160(uint256(hash)));
} }
} }
...@@ -5,10 +5,10 @@ import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol ...@@ -5,10 +5,10 @@ import { ERC721, IERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol
import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { OptimismMintableERC721, IOptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721, IOptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol";
contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { contract OptimismMintableERC721_Test is Bridge_Initializer {
ERC721 internal L1NFT; ERC721 internal L1NFT;
OptimismMintableERC721 internal L2NFT; OptimismMintableERC721 internal L2NFT;
...@@ -24,7 +24,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -24,7 +24,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
// Set up the token pair. // Set up the token pair.
L1NFT = new ERC721("L1NFT", "L1T"); L1NFT = new ERC721("L1NFT", "L1T");
L2NFT = new OptimismMintableERC721( L2NFT = new OptimismMintableERC721(
address(L2NFTBridge), address(l2ERC721Bridge),
1, 1,
address(L1NFT), address(L1NFT),
"L2NFT", "L2NFT",
...@@ -40,10 +40,10 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -40,10 +40,10 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
assertEq(L2NFT.name(), "L2NFT"); assertEq(L2NFT.name(), "L2NFT");
assertEq(L2NFT.symbol(), "L2T"); assertEq(L2NFT.symbol(), "L2T");
assertEq(L2NFT.remoteToken(), address(L1NFT)); assertEq(L2NFT.remoteToken(), address(L1NFT));
assertEq(L2NFT.bridge(), address(L2NFTBridge)); assertEq(L2NFT.bridge(), address(l2ERC721Bridge));
assertEq(L2NFT.remoteChainId(), 1); assertEq(L2NFT.remoteChainId(), 1);
assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT)); assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT));
assertEq(L2NFT.BRIDGE(), address(L2NFTBridge)); assertEq(L2NFT.BRIDGE(), address(l2ERC721Bridge));
assertEq(L2NFT.REMOTE_CHAIN_ID(), 1); assertEq(L2NFT.REMOTE_CHAIN_ID(), 1);
} }
...@@ -69,7 +69,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -69,7 +69,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
emit Mint(alice, 1); emit Mint(alice, 1);
// Mint the token. // Mint the token.
vm.prank(address(L2NFTBridge)); vm.prank(address(l2ERC721Bridge));
L2NFT.safeMint(alice, 1); L2NFT.safeMint(alice, 1);
// Token should be owned by alice. // Token should be owned by alice.
...@@ -85,7 +85,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -85,7 +85,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
function test_burn_succeeds() external { function test_burn_succeeds() external {
// Mint the token first. // Mint the token first.
vm.prank(address(L2NFTBridge)); vm.prank(address(l2ERC721Bridge));
L2NFT.safeMint(alice, 1); L2NFT.safeMint(alice, 1);
// Expect a transfer event. // Expect a transfer event.
...@@ -97,7 +97,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -97,7 +97,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
emit Burn(alice, 1); emit Burn(alice, 1);
// Burn the token. // Burn the token.
vm.prank(address(L2NFTBridge)); vm.prank(address(l2ERC721Bridge));
L2NFT.burn(alice, 1); L2NFT.burn(alice, 1);
// Token should be owned by address(0). // Token should be owned by address(0).
...@@ -107,7 +107,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -107,7 +107,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
function test_burn_notBridge_reverts() external { function test_burn_notBridge_reverts() external {
// Mint the token first. // Mint the token first.
vm.prank(address(L2NFTBridge)); vm.prank(address(l2ERC721Bridge));
L2NFT.safeMint(alice, 1); L2NFT.safeMint(alice, 1);
// Try to burn the token. // Try to burn the token.
...@@ -118,7 +118,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer { ...@@ -118,7 +118,7 @@ contract OptimismMintableERC721_Test is ERC721Bridge_Initializer {
function test_tokenURI_succeeds() external { function test_tokenURI_succeeds() external {
// Mint the token first. // Mint the token first.
vm.prank(address(L2NFTBridge)); vm.prank(address(l2ERC721Bridge));
L2NFT.safeMint(alice, 1); L2NFT.safeMint(alice, 1);
// Token URI should be correct. // Token URI should be correct.
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { ERC721Bridge_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol";
import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol"; import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol";
contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { contract OptimismMintableERC721Factory_Test is Bridge_Initializer {
OptimismMintableERC721Factory internal factory; OptimismMintableERC721Factory internal factory;
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
...@@ -15,14 +15,14 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { ...@@ -15,14 +15,14 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
super.setUp(); super.setUp();
// Set up the token pair. // Set up the token pair.
factory = new OptimismMintableERC721Factory(address(L2NFTBridge), 1); factory = new OptimismMintableERC721Factory(address(l2ERC721Bridge), 1);
// Label the addresses for nice traces. // Label the addresses for nice traces.
vm.label(address(factory), "OptimismMintableERC721Factory"); vm.label(address(factory), "OptimismMintableERC721Factory");
} }
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(factory.BRIDGE(), address(L2NFTBridge)); assertEq(factory.BRIDGE(), address(l2ERC721Bridge));
assertEq(factory.REMOTE_CHAIN_ID(), 1); assertEq(factory.REMOTE_CHAIN_ID(), 1);
} }
...@@ -49,7 +49,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { ...@@ -49,7 +49,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
assertEq(created.name(), "L2Token"); assertEq(created.name(), "L2Token");
assertEq(created.symbol(), "L2T"); assertEq(created.symbol(), "L2T");
assertEq(created.REMOTE_TOKEN(), remote); assertEq(created.REMOTE_TOKEN(), remote);
assertEq(created.BRIDGE(), address(L2NFTBridge)); assertEq(created.BRIDGE(), address(l2ERC721Bridge));
assertEq(created.REMOTE_CHAIN_ID(), 1); assertEq(created.REMOTE_CHAIN_ID(), 1);
} }
...@@ -80,7 +80,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer { ...@@ -80,7 +80,7 @@ contract OptimismMintableERC721Factory_Test is ERC721Bridge_Initializer {
view view
returns (address) returns (address)
{ {
bytes memory constructorArgs = abi.encode(address(L2NFTBridge), 1, _remote, _name, _symbol); bytes memory constructorArgs = abi.encode(address(l2ERC721Bridge), 1, _remote, _name, _symbol);
bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC721).creationCode, constructorArgs); bytes memory bytecode = abi.encodePacked(type(OptimismMintableERC721).creationCode, constructorArgs);
bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol)); bytes32 salt = keccak256(abi.encode(_remote, _name, _symbol));
bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(factory), salt, keccak256(bytecode))); bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(factory), salt, keccak256(bytecode)));
......
...@@ -3,8 +3,10 @@ pragma solidity 0.8.15; ...@@ -3,8 +3,10 @@ pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { stdError } from "forge-std/Test.sol"; import { stdError } from "forge-std/Test.sol";
import { Portal_Initializer } from "test/CommonTest.t.sol";
import { CommonTest } from "test/setup/CommonTest.sol";
import { NextImpl } from "test/mocks/NextImpl.sol"; import { NextImpl } from "test/mocks/NextImpl.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Libraries // Libraries
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
...@@ -17,11 +19,9 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol"; ...@@ -17,11 +19,9 @@ import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol";
// Target contract
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
contract OptimismPortal_Test is Portal_Initializer { contract OptimismPortal_Test is CommonTest {
event Paused(address); event Paused(address);
event Unpaused(address); event Unpaused(address);
...@@ -34,87 +34,96 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -34,87 +34,96 @@ contract OptimismPortal_Test is Portal_Initializer {
/// @dev Tests that the constructor sets the correct values. /// @dev Tests that the constructor sets the correct values.
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(address(op.L2_ORACLE()), address(oracle)); address guardian = cfg.portalGuardian();
assertEq(address(op.l2Oracle()), address(oracle)); assertEq(address(optimismPortal.L2_ORACLE()), address(l2OutputOracle));
assertEq(op.GUARDIAN(), guardian); assertEq(address(optimismPortal.l2Oracle()), address(l2OutputOracle));
assertEq(op.guardian(), guardian); assertEq(optimismPortal.GUARDIAN(), guardian);
assertEq(op.l2Sender(), 0x000000000000000000000000000000000000dEaD); assertEq(optimismPortal.guardian(), guardian);
assertEq(op.paused(), false); assertEq(optimismPortal.l2Sender(), 0x000000000000000000000000000000000000dEaD);
assertEq(optimismPortal.paused(), false);
} }
/// @dev Tests that `pause` successfully pauses /// @dev Tests that `pause` successfully pauses
/// when called by the GUARDIAN. /// when called by the GUARDIAN.
function test_pause_succeeds() external { function test_pause_succeeds() external {
address guardian = op.GUARDIAN(); address guardian = optimismPortal.GUARDIAN();
assertEq(op.paused(), false); assertEq(optimismPortal.paused(), false);
vm.expectEmit(true, true, true, true, address(op)); vm.expectEmit(address(optimismPortal));
emit Paused(guardian); emit Paused(guardian);
vm.prank(guardian); vm.prank(guardian);
op.pause(); optimismPortal.pause();
assertEq(op.paused(), true); assertEq(optimismPortal.paused(), true);
} }
/// @dev Tests that `pause` reverts when called by a non-GUARDIAN. /// @dev Tests that `pause` reverts when called by a non-GUARDIAN.
function test_pause_onlyGuardian_reverts() external { function test_pause_onlyGuardian_reverts() external {
assertEq(op.paused(), false); assertEq(optimismPortal.paused(), false);
assertTrue(op.GUARDIAN() != alice); assertTrue(optimismPortal.GUARDIAN() != alice);
vm.expectRevert("OptimismPortal: only guardian can pause"); vm.expectRevert("OptimismPortal: only guardian can pause");
vm.prank(alice); vm.prank(alice);
op.pause(); optimismPortal.pause();
assertEq(op.paused(), false); assertEq(optimismPortal.paused(), false);
} }
/// @dev Tests that `unpause` successfully unpauses /// @dev Tests that `unpause` successfully unpauses
/// when called by the GUARDIAN. /// when called by the GUARDIAN.
function test_unpause_succeeds() external { function test_unpause_succeeds() external {
address guardian = op.GUARDIAN(); address guardian = optimismPortal.GUARDIAN();
vm.prank(guardian); vm.prank(guardian);
op.pause(); optimismPortal.pause();
assertEq(op.paused(), true); assertEq(optimismPortal.paused(), true);
vm.expectEmit(true, true, true, true, address(op)); vm.expectEmit(address(optimismPortal));
emit Unpaused(guardian); emit Unpaused(guardian);
vm.prank(guardian); vm.prank(guardian);
op.unpause(); optimismPortal.unpause();
assertEq(op.paused(), false); assertEq(optimismPortal.paused(), false);
} }
/// @dev Tests that `unpause` reverts when called by a non-GUARDIAN. /// @dev Tests that `unpause` reverts when called by a non-GUARDIAN.
function test_unpause_onlyGuardian_reverts() external { function test_unpause_onlyGuardian_reverts() external {
address guardian = op.GUARDIAN(); address guardian = optimismPortal.GUARDIAN();
vm.prank(guardian); vm.prank(guardian);
op.pause(); optimismPortal.pause();
assertEq(op.paused(), true); assertEq(optimismPortal.paused(), true);
assertTrue(op.GUARDIAN() != alice); assertTrue(optimismPortal.GUARDIAN() != alice);
vm.expectRevert("OptimismPortal: only guardian can unpause"); vm.expectRevert("OptimismPortal: only guardian can unpause");
vm.prank(alice); vm.prank(alice);
op.unpause(); optimismPortal.unpause();
assertEq(op.paused(), true); assertEq(optimismPortal.paused(), true);
} }
/// @dev Tests that `receive` successdully deposits ETH. /// @dev Tests that `receive` successdully deposits ETH.
function test_receive_succeeds() external { function testFuzz_receive_succeeds(uint256 _value) external {
vm.expectEmit(true, true, false, true); vm.expectEmit(address(optimismPortal));
emitTransactionDeposited(alice, alice, 100, 100, 100_000, false, hex""); emitTransactionDeposited({
_from: alice,
_to: alice,
_value: _value,
_mint: _value,
_gasLimit: 100_000,
_isCreation: false,
_data: hex""
});
// give alice money and send as an eoa // give alice money and send as an eoa
vm.deal(alice, 2 ** 64); vm.deal(alice, _value);
vm.prank(alice, alice); vm.prank(alice, alice);
(bool s,) = address(op).call{ value: 100 }(hex""); (bool s,) = address(optimismPortal).call{ value: _value }(hex"");
assert(s); assertTrue(s);
assertEq(address(op).balance, 100); assertEq(address(optimismPortal).balance, _value);
} }
/// @dev Tests that `depositTransaction` reverts when the destination address is non-zero /// @dev Tests that `depositTransaction` reverts when the destination address is non-zero
...@@ -122,16 +131,16 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -122,16 +131,16 @@ contract OptimismPortal_Test is Portal_Initializer {
function test_depositTransaction_contractCreation_reverts() external { function test_depositTransaction_contractCreation_reverts() external {
// contract creation must have a target of address(0) // contract creation must have a target of address(0)
vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract"); vm.expectRevert("OptimismPortal: must send to address(0) when creating a contract");
op.depositTransaction(address(1), 1, 0, true, hex""); optimismPortal.depositTransaction(address(1), 1, 0, true, hex"");
} }
/// @dev Tests that `depositTransaction` reverts when the data is too large. /// @dev Tests that `depositTransaction` reverts when the data is too large.
/// This places an upper bound on unsafe blocks sent over p2p. /// This places an upper bound on unsafe blocks sent over p2p.
function test_depositTransaction_largeData_reverts() external { function test_depositTransaction_largeData_reverts() external {
uint256 size = 120_001; uint256 size = 120_001;
uint64 gasLimit = op.minimumGasLimit(uint64(size)); uint64 gasLimit = optimismPortal.minimumGasLimit(uint64(size));
vm.expectRevert("OptimismPortal: data too large"); vm.expectRevert("OptimismPortal: data too large");
op.depositTransaction({ optimismPortal.depositTransaction({
_to: address(0), _to: address(0),
_value: 0, _value: 0,
_gasLimit: gasLimit, _gasLimit: gasLimit,
...@@ -143,30 +152,34 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -143,30 +152,34 @@ contract OptimismPortal_Test is Portal_Initializer {
/// @dev Tests that `depositTransaction` reverts when the gas limit is too small. /// @dev Tests that `depositTransaction` reverts when the gas limit is too small.
function test_depositTransaction_smallGasLimit_reverts() external { function test_depositTransaction_smallGasLimit_reverts() external {
vm.expectRevert("OptimismPortal: gas limit too small"); vm.expectRevert("OptimismPortal: gas limit too small");
op.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); optimismPortal.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" });
} }
/// @dev Tests that `depositTransaction` succeeds for small, /// @dev Tests that `depositTransaction` succeeds for small,
/// but sufficient, gas limits. /// but sufficient, gas limits.
function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external {
vm.assume(_data.length <= type(uint64).max); uint64 gasLimit = optimismPortal.minimumGasLimit(uint64(_data.length));
uint64 gasLimit = op.minimumGasLimit(uint64(_data.length));
if (_shouldFail) { if (_shouldFail) {
gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1)); gasLimit = uint64(bound(gasLimit, 0, gasLimit - 1));
vm.expectRevert("OptimismPortal: gas limit too small"); vm.expectRevert("OptimismPortal: gas limit too small");
} }
op.depositTransaction({ _to: address(0x40), _value: 0, _gasLimit: gasLimit, _isCreation: false, _data: _data }); optimismPortal.depositTransaction({
_to: address(0x40),
_value: 0,
_gasLimit: gasLimit,
_isCreation: false,
_data: _data
});
} }
/// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes. /// @dev Tests that `minimumGasLimit` succeeds for small calldata sizes.
/// The gas limit should be 21k for 0 calldata and increase linearly /// The gas limit should be 21k for 0 calldata and increase linearly
/// for larger calldata sizes. /// for larger calldata sizes.
function test_minimumGasLimit_succeeds() external { function test_minimumGasLimit_succeeds() external {
assertEq(op.minimumGasLimit(0), 21_000); assertEq(optimismPortal.minimumGasLimit(0), 21_000);
assertTrue(op.minimumGasLimit(2) > op.minimumGasLimit(1)); assertTrue(optimismPortal.minimumGasLimit(2) > optimismPortal.minimumGasLimit(1));
assertTrue(op.minimumGasLimit(3) > op.minimumGasLimit(2)); assertTrue(optimismPortal.minimumGasLimit(3) > optimismPortal.minimumGasLimit(2));
} }
/// @dev Tests that `depositTransaction` succeeds for an EOA. /// @dev Tests that `depositTransaction` succeeds for an EOA.
...@@ -181,12 +194,16 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -181,12 +194,16 @@ contract OptimismPortal_Test is Portal_Initializer {
external external
{ {
_gasLimit = uint64( _gasLimit = uint64(
bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) bound(
_gasLimit,
optimismPortal.minimumGasLimit(uint64(_data.length)),
systemConfig.resourceConfig().maxResourceLimit
)
); );
if (_isCreation) _to = address(0); if (_isCreation) _to = address(0);
// EOA emulation // EOA emulation
vm.expectEmit(address(op)); vm.expectEmit(address(optimismPortal));
emitTransactionDeposited({ emitTransactionDeposited({
_from: depositor, _from: depositor,
_to: _to, _to: _to,
...@@ -199,14 +216,14 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -199,14 +216,14 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.deal(depositor, _mint); vm.deal(depositor, _mint);
vm.prank(depositor, depositor); vm.prank(depositor, depositor);
op.depositTransaction{ value: _mint }({ optimismPortal.depositTransaction{ value: _mint }({
_to: _to, _to: _to,
_value: _value, _value: _value,
_gasLimit: _gasLimit, _gasLimit: _gasLimit,
_isCreation: _isCreation, _isCreation: _isCreation,
_data: _data _data: _data
}); });
assertEq(address(op).balance, _mint); assertEq(address(optimismPortal).balance, _mint);
} }
/// @dev Tests that `depositTransaction` succeeds for a contract. /// @dev Tests that `depositTransaction` succeeds for a contract.
...@@ -221,11 +238,15 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -221,11 +238,15 @@ contract OptimismPortal_Test is Portal_Initializer {
external external
{ {
_gasLimit = uint64( _gasLimit = uint64(
bound(_gasLimit, op.minimumGasLimit(uint64(_data.length)), systemConfig.resourceConfig().maxResourceLimit) bound(
_gasLimit,
optimismPortal.minimumGasLimit(uint64(_data.length)),
systemConfig.resourceConfig().maxResourceLimit
)
); );
if (_isCreation) _to = address(0); if (_isCreation) _to = address(0);
vm.expectEmit(address(op)); vm.expectEmit(address(optimismPortal));
emitTransactionDeposited({ emitTransactionDeposited({
_from: AddressAliasHelper.applyL1ToL2Alias(address(this)), _from: AddressAliasHelper.applyL1ToL2Alias(address(this)),
_to: _to, _to: _to,
...@@ -238,45 +259,64 @@ contract OptimismPortal_Test is Portal_Initializer { ...@@ -238,45 +259,64 @@ contract OptimismPortal_Test is Portal_Initializer {
vm.deal(address(this), _mint); vm.deal(address(this), _mint);
vm.prank(address(this)); vm.prank(address(this));
op.depositTransaction{ value: _mint }({ optimismPortal.depositTransaction{ value: _mint }({
_to: _to, _to: _to,
_value: _value, _value: _value,
_gasLimit: _gasLimit, _gasLimit: _gasLimit,
_isCreation: _isCreation, _isCreation: _isCreation,
_data: _data _data: _data
}); });
assertEq(address(op).balance, _mint); assertEq(address(optimismPortal).balance, _mint);
}
/// @dev Tests that `isOutputFinalized` succeeds for an EOA depositing a tx with ETH and data.
function test_simple_isOutputFinalized_succeeds() external {
uint256 startingBlockNumber = cfg.l2OutputOracleStartingBlockNumber();
uint256 ts = block.timestamp;
vm.mockCall(
address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(Types.OutputProposal(bytes32(uint256(1)), uint128(ts), uint128(startingBlockNumber)))
);
// warp to the finalization period
vm.warp(ts + l2OutputOracle.FINALIZATION_PERIOD_SECONDS());
assertEq(optimismPortal.isOutputFinalized(0), false);
// warp past the finalization period
vm.warp(ts + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
assertEq(optimismPortal.isOutputFinalized(0), true);
} }
/// @dev Tests `isOutputFinalized` for a finalized output. /// @dev Tests `isOutputFinalized` for a finalized output.
function test_isOutputFinalized_succeeds() external { function test_isOutputFinalized_succeeds() external {
uint256 checkpoint = oracle.nextBlockNumber(); uint256 checkpoint = l2OutputOracle.nextBlockNumber();
uint256 nextOutputIndex = oracle.nextOutputIndex(); uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex();
vm.roll(checkpoint); vm.roll(checkpoint);
vm.warp(oracle.computeL2Timestamp(checkpoint) + 1); vm.warp(l2OutputOracle.computeL2Timestamp(checkpoint) + 1);
vm.prank(oracle.PROPOSER()); vm.prank(l2OutputOracle.PROPOSER());
oracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0); l2OutputOracle.proposeL2Output(keccak256(abi.encode(2)), checkpoint, 0, 0);
// warp to the final second of the finalization period // warp to the final second of the finalization period
uint256 finalizationHorizon = block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS(); uint256 finalizationHorizon = block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS();
vm.warp(finalizationHorizon); vm.warp(finalizationHorizon);
// The checkpointed block should not be finalized until 1 second from now. // The checkpointed block should not be finalized until 1 second from now.
assertEq(op.isOutputFinalized(nextOutputIndex), false); assertEq(optimismPortal.isOutputFinalized(nextOutputIndex), false);
// Nor should a block after it // Nor should a block after it
vm.expectRevert(stdError.indexOOBError); vm.expectRevert(stdError.indexOOBError);
assertEq(op.isOutputFinalized(nextOutputIndex + 1), false); assertEq(optimismPortal.isOutputFinalized(nextOutputIndex + 1), false);
// warp past the finalization period // warp past the finalization period
vm.warp(finalizationHorizon + 1); vm.warp(finalizationHorizon + 1);
// It should now be finalized. // It should now be finalized.
assertEq(op.isOutputFinalized(nextOutputIndex), true); assertEq(optimismPortal.isOutputFinalized(nextOutputIndex), true);
// But not the block after it. // But not the block after it.
vm.expectRevert(stdError.indexOOBError); vm.expectRevert(stdError.indexOOBError);
assertEq(op.isOutputFinalized(nextOutputIndex + 1), false); assertEq(optimismPortal.isOutputFinalized(nextOutputIndex + 1), false);
} }
} }
contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { contract OptimismPortal_FinalizeWithdrawal_Test is CommonTest {
// Reusable default values for a test withdrawal // Reusable default values for a test withdrawal
Types.WithdrawalTransaction _defaultTx; Types.WithdrawalTransaction _defaultTx;
...@@ -311,21 +351,24 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -311,21 +351,24 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
messagePasserStorageRoot: _storageRoot, messagePasserStorageRoot: _storageRoot,
latestBlockhash: bytes32(uint256(0)) latestBlockhash: bytes32(uint256(0))
}); });
_proposedBlockNumber = oracle.nextBlockNumber(); _proposedBlockNumber = l2OutputOracle.nextBlockNumber();
_proposedOutputIndex = oracle.nextOutputIndex(); _proposedOutputIndex = l2OutputOracle.nextOutputIndex();
} }
/// @dev Setup the system for a ready-to-use state. /// @dev Setup the system for a ready-to-use state.
function setUp() public override { function setUp() public override {
// Configure the oracle to return the output root we've prepared. // Configure the oracle to return the output root we've prepared.
vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1);
vm.prank(oracle.PROPOSER()); vm.prank(l2OutputOracle.PROPOSER());
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(
l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS()
+ 1
);
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF); vm.deal(address(optimismPortal), 0xFFFFFFFF);
} }
/// @dev Asserts that the reentrant call will revert. /// @dev Asserts that the reentrant call will revert.
...@@ -333,18 +376,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -333,18 +376,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction"); vm.expectRevert("OptimismPortal: can only trigger one withdrawal per transaction");
// Arguments here don't matter, as the require check is the first thing that happens. // Arguments here don't matter, as the require check is the first thing that happens.
// We assume that this has already been proven. // We assume that this has already been proven.
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
// Assert that the withdrawal was not finalized. // Assert that the withdrawal was not finalized.
assertFalse(op.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx))); assertFalse(optimismPortal.finalizedWithdrawals(Hashing.hashWithdrawal(_defaultTx)));
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when paused. /// @dev Tests that `proveWithdrawalTransaction` reverts when paused.
function test_proveWithdrawalTransaction_paused_reverts() external { function test_proveWithdrawalTransaction_paused_reverts() external {
vm.prank(op.GUARDIAN()); vm.prank(optimismPortal.GUARDIAN());
op.pause(); optimismPortal.pause();
vm.expectRevert("OptimismPortal: paused"); vm.expectRevert("OptimismPortal: paused");
op.proveWithdrawalTransaction({ optimismPortal.proveWithdrawalTransaction({
_tx: _defaultTx, _tx: _defaultTx,
_l2OutputIndex: _proposedOutputIndex, _l2OutputIndex: _proposedOutputIndex,
_outputRootProof: _outputRootProof, _outputRootProof: _outputRootProof,
...@@ -354,9 +397,9 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -354,9 +397,9 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
/// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract. /// @dev Tests that `proveWithdrawalTransaction` reverts when the target is the portal contract.
function test_proveWithdrawalTransaction_onSelfCall_reverts() external { function test_proveWithdrawalTransaction_onSelfCall_reverts() external {
_defaultTx.target = address(op); _defaultTx.target = address(optimismPortal);
vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract"); vm.expectRevert("OptimismPortal: you cannot send messages to the portal contract");
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when /// @dev Tests that `proveWithdrawalTransaction` reverts when
...@@ -365,7 +408,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -365,7 +408,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Modify the version to invalidate the withdrawal proof. // Modify the version to invalidate the withdrawal proof.
_outputRootProof.version = bytes32(uint256(1)); _outputRootProof.version = bytes32(uint256(1));
vm.expectRevert("OptimismPortal: invalid output root proof"); vm.expectRevert("OptimismPortal: invalid output root proof");
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing. /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal is missing.
...@@ -373,7 +416,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -373,7 +416,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// modify the default test values to invalidate the proof. // modify the default test values to invalidate the proof.
_defaultTx.data = hex"abcd"; _defaultTx.data = hex"abcd";
vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key"); vm.expectRevert("MerkleTrie: path remainder must share all nibbles with key");
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
} }
/// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already /// @dev Tests that `proveWithdrawalTransaction` reverts when the withdrawal has already
...@@ -381,10 +424,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -381,10 +424,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProve_reverts() external { function test_proveWithdrawalTransaction_replayProve_reverts() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.expectRevert("OptimismPortal: withdrawal hash has already been proven"); vm.expectRevert("OptimismPortal: withdrawal hash has already been proven");
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
} }
/// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already /// @dev Tests that `proveWithdrawalTransaction` succeeds when the withdrawal has already
...@@ -392,7 +435,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -392,7 +435,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external { function test_proveWithdrawalTransaction_replayProveChangedOutputRoot_succeeds() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`
// inside of the `provenWithdrawal`s mapping. // inside of the `provenWithdrawal`s mapping.
...@@ -405,7 +448,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -405,7 +448,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Store a different output root within the `provenWithdrawals` mapping without // Store a different output root within the `provenWithdrawals` mapping without
// touching the l2BlockNumber or timestamp. // touching the l2BlockNumber or timestamp.
vm.store(address(op), slot, bytes32(0)); vm.store(address(optimismPortal), slot, bytes32(0));
// Warp ahead 1 second // Warp ahead 1 second
vm.warp(block.timestamp + 1); vm.warp(block.timestamp + 1);
...@@ -414,10 +457,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -414,10 +457,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// our proof with a changed outputRoot // our proof with a changed outputRoot
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Ensure that the withdrawal was updated within the mapping // Ensure that the withdrawal was updated within the mapping
(, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash); (, uint128 timestamp,) = optimismPortal.provenWithdrawals(_withdrawalHash);
assertEq(timestamp, block.timestamp); assertEq(timestamp, block.timestamp);
} }
...@@ -426,7 +469,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -426,7 +469,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external { function test_proveWithdrawalTransaction_replayProveChangedOutputRootAndOutputIndex_succeeds() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Compute the storage slot of the outputRoot corresponding to the `withdrawalHash` // Compute the storage slot of the outputRoot corresponding to the `withdrawalHash`
// inside of the `provenWithdrawal`s mapping. // inside of the `provenWithdrawal`s mapping.
...@@ -439,15 +482,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -439,15 +482,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Store a dummy output root within the `provenWithdrawals` mapping without touching the // Store a dummy output root within the `provenWithdrawals` mapping without touching the
// l2BlockNumber or timestamp. // l2BlockNumber or timestamp.
vm.store(address(op), slot, bytes32(0)); vm.store(address(optimismPortal), slot, bytes32(0));
// Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle // Fetch the output proposal at `_proposedOutputIndex` from the L2OutputOracle
Types.OutputProposal memory proposal = op.L2_ORACLE().getL2Output(_proposedOutputIndex); Types.OutputProposal memory proposal = optimismPortal.L2_ORACLE().getL2Output(_proposedOutputIndex);
// Propose the same output root again, creating the same output at a different index + l2BlockNumber. // Propose the same output root again, creating the same output at a different index + l2BlockNumber.
vm.startPrank(op.L2_ORACLE().PROPOSER()); vm.startPrank(optimismPortal.L2_ORACLE().PROPOSER());
op.L2_ORACLE().proposeL2Output( optimismPortal.L2_ORACLE().proposeL2Output(
proposal.outputRoot, op.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number proposal.outputRoot, optimismPortal.L2_ORACLE().nextBlockNumber(), blockhash(block.number), block.number
); );
vm.stopPrank(); vm.stopPrank();
...@@ -458,10 +501,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -458,10 +501,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// our proof with a changed outputRoot + a different output index // our proof with a changed outputRoot + a different output index
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(
_defaultTx, _proposedOutputIndex + 1, _outputRootProof, _withdrawalProof
);
// Ensure that the withdrawal was updated within the mapping // Ensure that the withdrawal was updated within the mapping
(, uint128 timestamp,) = op.provenWithdrawals(_withdrawalHash); (, uint128 timestamp,) = optimismPortal.provenWithdrawals(_withdrawalHash);
assertEq(timestamp, block.timestamp); assertEq(timestamp, block.timestamp);
} }
...@@ -469,7 +514,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -469,7 +514,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external { function test_proveWithdrawalTransaction_validWithdrawalProof_succeeds() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` succeeds. /// @dev Tests that `finalizeWithdrawalTransaction` succeeds.
...@@ -478,23 +523,23 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -478,23 +523,23 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, false, true); vm.expectEmit(true, true, false, true);
emit WithdrawalFinalized(_withdrawalHash, true); emit WithdrawalFinalized(_withdrawalHash, true);
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
assert(address(bob).balance == bobBalanceBefore + 100); assert(address(bob).balance == bobBalanceBefore + 100);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused.
function test_finalizeWithdrawalTransaction_paused_reverts() external { function test_finalizeWithdrawalTransaction_paused_reverts() external {
vm.prank(op.GUARDIAN()); vm.prank(optimismPortal.GUARDIAN());
op.pause(); optimismPortal.pause();
vm.expectRevert("OptimismPortal: paused"); vm.expectRevert("OptimismPortal: paused");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has not been
...@@ -502,7 +547,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -502,7 +547,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
uint256 bobBalanceBefore = address(bob).balance; uint256 bobBalanceBefore = address(bob).balance;
vm.expectRevert("OptimismPortal: withdrawal has not been proven yet"); vm.expectRevert("OptimismPortal: withdrawal has not been proven yet");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
assert(address(bob).balance == bobBalanceBefore); assert(address(bob).balance == bobBalanceBefore);
} }
...@@ -514,18 +559,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -514,18 +559,18 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Mock a call where the resulting output root is anything but the original output root. In // Mock a call where the resulting output root is anything but the original output root. In
// this case we just use bytes32(uint256(1)). // this case we just use bytes32(uint256(1)).
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(bytes32(uint256(1)), _proposedBlockNumber) abi.encode(bytes32(uint256(1)), _proposedBlockNumber)
); );
vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
assert(address(bob).balance == bobBalanceBefore); assert(address(bob).balance == bobBalanceBefore);
} }
...@@ -538,19 +583,21 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -538,19 +583,21 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal // Prove our withdrawal
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a startingTimestamp change on the L2 Oracle // Mock a startingTimestamp change on the L2 Oracle
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), abi.encodeWithSignature("startingTimestamp()"), abi.encode(block.timestamp + 1) address(optimismPortal.L2_ORACLE()),
abi.encodeWithSignature("startingTimestamp()"),
abi.encode(block.timestamp + 1)
); );
// Attempt to finalize the withdrawal // Attempt to finalize the withdrawal
vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"); vm.expectRevert("OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same // Ensure that bob's balance has remained the same
assertEq(bobBalanceBefore, address(bob).balance); assertEq(bobBalanceBefore, address(bob).balance);
...@@ -564,15 +611,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -564,15 +611,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal // Prove our withdrawal
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock an outputRoot change on the output proposal before attempting // Mock an outputRoot change on the output proposal before attempting
// to finalize the withdrawal. // to finalize the withdrawal.
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(
Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber)) Types.OutputProposal(bytes32(uint256(0)), uint128(block.timestamp), uint128(_proposedBlockNumber))
...@@ -581,7 +628,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -581,7 +628,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Attempt to finalize the withdrawal // Attempt to finalize the withdrawal
vm.expectRevert("OptimismPortal: output root proven is not the same as current output root"); vm.expectRevert("OptimismPortal: output root proven is not the same as current output root");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same // Ensure that bob's balance has remained the same
assertEq(bobBalanceBefore, address(bob).balance); assertEq(bobBalanceBefore, address(bob).balance);
...@@ -595,22 +642,22 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -595,22 +642,22 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Prove our withdrawal // Prove our withdrawal
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp to after the finalization period // Warp to after the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a timestamp change on the output proposal that has not passed the // Mock a timestamp change on the output proposal that has not passed the
// finalization period. // finalization period.
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber))) abi.encode(Types.OutputProposal(_outputRoot, uint128(block.timestamp + 1), uint128(_proposedBlockNumber)))
); );
// Attempt to finalize the withdrawal // Attempt to finalize the withdrawal
vm.expectRevert("OptimismPortal: output proposal finalization period has not elapsed"); vm.expectRevert("OptimismPortal: output proposal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
// Ensure that bob's balance has remained the same // Ensure that bob's balance has remained the same
assertEq(bobBalanceBefore, address(bob).balance); assertEq(bobBalanceBefore, address(bob).balance);
...@@ -623,12 +670,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -623,12 +670,12 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalFinalized(_withdrawalHash, false); emit WithdrawalFinalized(_withdrawalHash, false);
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
assert(address(bob).balance == bobBalanceBefore); assert(address(bob).balance == bobBalanceBefore);
} }
...@@ -637,17 +684,17 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -637,17 +684,17 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
/// has not yet passed. /// has not yet passed.
function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external { function test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() external {
// Setup the Oracle to return an output with a recent timestamp // Setup the Oracle to return an output with a recent timestamp
uint256 recentTimestamp = block.timestamp - 1000; uint256 recentTimestamp = block.timestamp - 1;
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber))) abi.encode(Types.OutputProposal(_outputRoot, uint128(recentTimestamp), uint128(_proposedBlockNumber)))
); );
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal has already been
...@@ -655,15 +702,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -655,15 +702,15 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
function test_finalizeWithdrawalTransaction_onReplay_reverts() external { function test_finalizeWithdrawalTransaction_onReplay_reverts() external {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(_withdrawalHash, alice, bob); emit WithdrawalProven(_withdrawalHash, alice, bob);
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalFinalized(_withdrawalHash, true); emit WithdrawalFinalized(_withdrawalHash, true);
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); vm.expectRevert("OptimismPortal: withdrawal has already been finalized");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the withdrawal transaction
...@@ -691,7 +738,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -691,7 +738,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
}); });
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode( abi.encode(
Types.OutputProposal( Types.OutputProposal(
...@@ -702,11 +749,13 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -702,11 +749,13 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
) )
); );
op.proveWithdrawalTransaction(insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof); optimismPortal.proveWithdrawalTransaction(
insufficientGasTx, _proposedOutputIndex, outputRootProof, withdrawalProof
);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectRevert("SafeCall: Not enough gas"); vm.expectRevert("SafeCall: Not enough gas");
op.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx); optimismPortal.finalizeWithdrawalTransaction{ gas: gasLimit }(insufficientGasTx);
} }
/// @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize /// @dev Tests that `finalizeWithdrawalTransaction` reverts if a sub-call attempts to finalize
...@@ -736,22 +785,22 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -736,22 +785,22 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
}); });
// Setup the Oracle to return the outputRoot we want as well as a finalized timestamp. // Setup the Oracle to return the outputRoot we want as well as a finalized timestamp.
uint256 finalizedTimestamp = block.timestamp - oracle.FINALIZATION_PERIOD_SECONDS() - 1; uint256 finalizedTimestamp = block.timestamp - l2OutputOracle.FINALIZATION_PERIOD_SECONDS() - 1;
vm.mockCall( vm.mockCall(
address(op.L2_ORACLE()), address(optimismPortal.L2_ORACLE()),
abi.encodeWithSelector(L2OutputOracle.getL2Output.selector), abi.encodeWithSelector(L2OutputOracle.getL2Output.selector),
abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber))) abi.encode(Types.OutputProposal(outputRoot, uint128(finalizedTimestamp), uint128(_proposedBlockNumber)))
); );
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalProven(withdrawalHash, alice, address(this)); emit WithdrawalProven(withdrawalHash, alice, address(this));
op.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof); optimismPortal.proveWithdrawalTransaction(_testTx, _proposedBlockNumber, outputRootProof, withdrawalProof);
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
vm.expectCall(address(this), _testTx.data); vm.expectCall(address(this), _testTx.data);
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit WithdrawalFinalized(withdrawalHash, true); emit WithdrawalFinalized(withdrawalHash, true);
op.finalizeWithdrawalTransaction(_testTx); optimismPortal.finalizeWithdrawalTransaction(_testTx);
// Ensure that bob's balance was not changed by the reentrant call. // Ensure that bob's balance was not changed by the reentrant call.
assert(address(bob).balance == bobBalanceBefore); assert(address(bob).balance == bobBalanceBefore);
...@@ -768,7 +817,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -768,7 +817,7 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
external external
{ {
vm.assume( vm.assume(
_target != address(op) // Cannot call the optimism portal or a contract _target != address(optimismPortal) // Cannot call the optimism portal or a contract
&& _target.code.length == 0 // No accounts with code && _target.code.length == 0 // No accounts with code
&& _target != CONSOLE // The console has no code but behaves like a contract && _target != CONSOLE // The console has no code but behaves like a contract
&& uint160(_target) > 9 // No precompiles (or zero address) && uint160(_target) > 9 // No precompiles (or zero address)
...@@ -776,10 +825,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -776,10 +825,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Total ETH supply is currently about 120M ETH. // Total ETH supply is currently about 120M ETH.
uint256 value = bound(_value, 0, 200_000_000 ether); uint256 value = bound(_value, 0, 200_000_000 ether);
vm.deal(address(op), value); vm.deal(address(optimismPortal), value);
uint256 gasLimit = bound(_gasLimit, 0, 50_000_000); uint256 gasLimit = bound(_gasLimit, 0, 50_000_000);
uint256 nonce = messagePasser.messageNonce(); uint256 nonce = l2ToL1MessagePasser.messageNonce();
// Get a withdrawal transaction and mock proof from the differential testing script. // Get a withdrawal transaction and mock proof from the differential testing script.
Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({ Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({
...@@ -812,58 +861,46 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer { ...@@ -812,58 +861,46 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Setup the Oracle to return the outputRoot // Setup the Oracle to return the outputRoot
vm.mockCall( vm.mockCall(
address(oracle), address(l2OutputOracle),
abi.encodeWithSelector(oracle.getL2Output.selector), abi.encodeWithSelector(l2OutputOracle.getL2Output.selector),
abi.encode(outputRoot, block.timestamp, 100) abi.encode(outputRoot, block.timestamp, 100)
); );
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction( optimismPortal.proveWithdrawalTransaction(
_tx, _tx,
100, // l2BlockNumber 100, // l2BlockNumber
proof, proof,
withdrawalProof withdrawalProof
); );
(bytes32 _root,,) = op.provenWithdrawals(withdrawalHash); (bytes32 _root,,) = optimismPortal.provenWithdrawals(withdrawalHash);
assertTrue(_root != bytes32(0)); assertTrue(_root != bytes32(0));
// Warp past the finalization period // Warp past the finalization period
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Finalize the withdrawal transaction // Finalize the withdrawal transaction
vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data); vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data);
op.finalizeWithdrawalTransaction(_tx); optimismPortal.finalizeWithdrawalTransaction(_tx);
assertTrue(op.finalizedWithdrawals(withdrawalHash)); assertTrue(optimismPortal.finalizedWithdrawals(withdrawalHash));
} }
} }
contract OptimismPortalUpgradeable_Test is Portal_Initializer { contract OptimismPortalUpgradeable_Test is CommonTest {
Proxy internal proxy;
uint64 initialBlockNum;
/// @dev Sets up the test.
function setUp() public override {
super.setUp();
initialBlockNum = uint64(block.number);
proxy = Proxy(payable(address(op)));
}
/// @dev Tests that the proxy is initialized correctly. /// @dev Tests that the proxy is initialized correctly.
function test_params_initValuesOnProxy_succeeds() external { function test_params_initValuesOnProxy_succeeds() external {
OptimismPortal p = OptimismPortal(payable(address(proxy))); (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params();
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = p.params();
ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); ResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();
assertEq(prevBaseFee, rcfg.minimumBaseFee); assertEq(prevBaseFee, rcfg.minimumBaseFee);
assertEq(prevBoughtGas, 0); assertEq(prevBoughtGas, 0);
assertEq(prevBlockNum, initialBlockNum); assertEq(prevBlockNum, block.number);
} }
/// @dev Tests that the proxy cannot be initialized twice. /// @dev Tests that the proxy cannot be initialized twice.
function test_initialize_cannotInitProxy_reverts() external { function test_initialize_cannotInitProxy_reverts() external {
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
OptimismPortal(payable(proxy)).initialize({ optimismPortal.initialize({
_l2Oracle: L2OutputOracle(address(0)), _l2Oracle: L2OutputOracle(address(0)),
_systemConfig: SystemConfig(address(0)), _systemConfig: SystemConfig(address(0)),
_guardian: address(0), _guardian: address(0),
...@@ -873,8 +910,9 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { ...@@ -873,8 +910,9 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
/// @dev Tests that the implementation cannot be initialized twice. /// @dev Tests that the implementation cannot be initialized twice.
function test_initialize_cannotInitImpl_reverts() external { function test_initialize_cannotInitImpl_reverts() external {
address opImpl = mustGetAddress("OptimismPortal");
vm.expectRevert("Initializable: contract is already initialized"); vm.expectRevert("Initializable: contract is already initialized");
OptimismPortal(opImpl).initialize({ OptimismPortal(payable(opImpl)).initialize({
_l2Oracle: L2OutputOracle(address(0)), _l2Oracle: L2OutputOracle(address(0)),
_systemConfig: SystemConfig(address(0)), _systemConfig: SystemConfig(address(0)),
_guardian: address(0), _guardian: address(0),
...@@ -885,21 +923,22 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { ...@@ -885,21 +923,22 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
/// @dev Tests that the proxy can be upgraded. /// @dev Tests that the proxy can be upgraded.
function test_upgradeToAndCall_upgrading_succeeds() external { function test_upgradeToAndCall_upgrading_succeeds() external {
// Check an unused slot before upgrading. // Check an unused slot before upgrading.
bytes32 slot21Before = vm.load(address(op), bytes32(uint256(21))); bytes32 slot21Before = vm.load(address(optimismPortal), bytes32(uint256(21)));
assertEq(bytes32(0), slot21Before); assertEq(bytes32(0), slot21Before);
NextImpl nextImpl = new NextImpl(); NextImpl nextImpl = new NextImpl();
vm.startPrank(multisig);
vm.startPrank(EIP1967Helper.getAdmin(address(optimismPortal)));
// The value passed to the initialize must be larger than the last value // The value passed to the initialize must be larger than the last value
// that initialize was called with. // that initialize was called with.
proxy.upgradeToAndCall( Proxy(payable(address(optimismPortal))).upgradeToAndCall(
address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, Constants.INITIALIZER + 1) address(nextImpl), abi.encodeWithSelector(NextImpl.initialize.selector, Constants.INITIALIZER + 1)
); );
assertEq(proxy.implementation(), address(nextImpl)); assertEq(Proxy(payable(address(optimismPortal))).implementation(), address(nextImpl));
// Verify that the NextImpl contract initialized its values according as expected // Verify that the NextImpl contract initialized its values according as expected
bytes32 slot21After = vm.load(address(op), bytes32(uint256(21))); bytes32 slot21After = vm.load(address(optimismPortal), bytes32(uint256(21)));
bytes32 slot21Expected = NextImpl(address(op)).slot21Init(); bytes32 slot21Expected = NextImpl(address(optimismPortal)).slot21Init();
assertEq(slot21Expected, slot21After); assertEq(slot21Expected, slot21After);
} }
} }
...@@ -907,7 +946,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer { ...@@ -907,7 +946,7 @@ contract OptimismPortalUpgradeable_Test is Portal_Initializer {
/// @title OptimismPortalResourceFuzz_Test /// @title OptimismPortalResourceFuzz_Test
/// @dev Test various values of the resource metering config to ensure that deposits cannot be /// @dev Test various values of the resource metering config to ensure that deposits cannot be
/// broken by changing the config. /// broken by changing the config.
contract OptimismPortalResourceFuzz_Test is Portal_Initializer { contract OptimismPortalResourceFuzz_Test is CommonTest {
/// @dev The max gas limit observed throughout this test. Setting this too high can cause /// @dev The max gas limit observed throughout this test. Setting this too high can cause
/// the test to take too long to run. /// the test to take too long to run.
uint256 constant MAX_GAS_LIMIT = 30_000_000; uint256 constant MAX_GAS_LIMIT = 30_000_000;
...@@ -961,18 +1000,18 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer { ...@@ -961,18 +1000,18 @@ contract OptimismPortalResourceFuzz_Test is Portal_Initializer {
// Set the resource params // Set the resource params
uint256 _prevBlockNum = block.number - _blockDiff; uint256 _prevBlockNum = block.number - _blockDiff;
vm.store( vm.store(
address(op), address(optimismPortal),
bytes32(uint256(1)), bytes32(uint256(1)),
bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee) bytes32((_prevBlockNum << 192) | (uint256(_prevBoughtGas) << 128) | _prevBaseFee)
); );
// Ensure that the storage setting is correct // Ensure that the storage setting is correct
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = op.params(); (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params();
assertEq(prevBaseFee, _prevBaseFee); assertEq(prevBaseFee, _prevBaseFee);
assertEq(prevBoughtGas, _prevBoughtGas); assertEq(prevBoughtGas, _prevBoughtGas);
assertEq(prevBlockNum, _prevBlockNum); assertEq(prevBlockNum, _prevBlockNum);
// Do a deposit, should not revert // Do a deposit, should not revert
op.depositTransaction{ gas: MAX_GAS_LIMIT }({ optimismPortal.depositTransaction{ gas: MAX_GAS_LIMIT }({
_to: address(0x20), _to: address(0x20),
_value: 0x40, _value: 0x40,
_gasLimit: _gasLimit, _gasLimit: _gasLimit,
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Libraries // Libraries
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
...@@ -14,44 +15,27 @@ import { Proxy } from "src/universal/Proxy.sol"; ...@@ -14,44 +15,27 @@ import { Proxy } from "src/universal/Proxy.sol";
import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol"; import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol";
contract ProtocolVersions_Init is CommonTest { contract ProtocolVersions_Init is CommonTest {
ProtocolVersions protocolVersions;
ProtocolVersions protocolVersionsImpl;
event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data); event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data);
// Dummy values used to test getters ProtocolVersion required;
ProtocolVersion constant required = ProtocolVersion.wrap(0xabcd); ProtocolVersion recommended;
ProtocolVersion constant recommended = ProtocolVersion.wrap(0x1234);
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
required = ProtocolVersion.wrap(cfg.requiredProtocolVersion());
Proxy proxy = new Proxy(multisig); recommended = ProtocolVersion.wrap(cfg.recommendedProtocolVersion());
protocolVersionsImpl = new ProtocolVersions();
vm.prank(multisig);
proxy.upgradeToAndCall(
address(protocolVersionsImpl),
abi.encodeCall(
ProtocolVersions.initialize,
(
alice, // _owner,
required,
recommended
)
)
);
protocolVersions = ProtocolVersions(address(proxy));
} }
} }
contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init {
/// @dev Tests that initialization sets the correct values. /// @dev Tests that initialization sets the correct values.
function test_initialize_values_succeeds() external { function test_initialize_values_succeeds() external {
ProtocolVersions protocolVersionsImpl = ProtocolVersions(mustGetAddress("ProtocolVersions"));
address owner = cfg.finalSystemOwner();
assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required)); assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required));
assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), ProtocolVersion.unwrap(recommended)); assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), ProtocolVersion.unwrap(recommended));
assertEq(protocolVersions.owner(), alice); assertEq(protocolVersions.owner(), owner);
assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.required()), 0); assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.required()), 0);
assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.recommended()), 0); assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.recommended()), 0);
...@@ -60,6 +44,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { ...@@ -60,6 +44,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init {
/// @dev Ensures that the events are emitted during initialization. /// @dev Ensures that the events are emitted during initialization.
function test_initialize_events_succeeds() external { function test_initialize_events_succeeds() external {
ProtocolVersions protocolVersionsImpl = ProtocolVersions(mustGetAddress("ProtocolVersions"));
assertEq(protocolVersionsImpl.owner(), address(0xdEad)); assertEq(protocolVersionsImpl.owner(), address(0xdEad));
// Wipe out the initialized slot so the proxy can be initialized again // Wipe out the initialized slot so the proxy can be initialized again
...@@ -71,7 +56,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init { ...@@ -71,7 +56,7 @@ contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init {
vm.expectEmit(true, true, true, true, address(protocolVersions)); vm.expectEmit(true, true, true, true, address(protocolVersions));
emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended)); emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended));
vm.prank(multisig); vm.prank(EIP1967Helper.getAdmin(address(protocolVersions)));
Proxy(payable(address(protocolVersions))).upgradeToAndCall( Proxy(payable(address(protocolVersions))).upgradeToAndCall(
address(protocolVersionsImpl), address(protocolVersionsImpl),
abi.encodeCall( abi.encodeCall(
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { FeeVault_Initializer } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { Reverter } from "test/mocks/Callers.sol"; import { Reverter } from "test/mocks/Callers.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol";
...@@ -15,127 +15,143 @@ import { FeeVault } from "src/universal/FeeVault.sol"; ...@@ -15,127 +15,143 @@ import { FeeVault } from "src/universal/FeeVault.sol";
// Target contract // Target contract
import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol"; import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol";
contract SequencerFeeVault_Test is FeeVault_Initializer { contract SequencerFeeVault_Test is CommonTest {
address recipient;
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
vm.etch( recipient = cfg.sequencerFeeVaultRecipient();
Predeploys.SEQUENCER_FEE_WALLET,
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L1)).code
);
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
} }
/// @dev Tests that the minimum withdrawal amount is correct. /// @dev Tests that the minimum withdrawal amount is correct.
function test_minWithdrawalAmount_succeeds() external { function test_minWithdrawalAmount_succeeds() external {
assertEq(vault.MIN_WITHDRAWAL_AMOUNT(), NON_ZERO_VALUE); assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), cfg.sequencerFeeVaultMinimumWithdrawalAmount());
} }
/// @dev Tests that the l1 fee wallet is correct. /// @dev Tests that the l1 fee wallet is correct.
function test_constructor_succeeds() external { function test_constructor_succeeds() external {
assertEq(vault.l1FeeWallet(), recipient); assertEq(sequencerFeeVault.l1FeeWallet(), recipient);
} }
/// @dev Tests that the fee vault is able to receive ETH. /// @dev Tests that the fee vault is able to receive ETH.
function test_receive_succeeds() external { function test_receive_succeeds() external {
uint256 balance = address(vault).balance; uint256 balance = address(sequencerFeeVault).balance;
vm.prank(alice); vm.prank(alice);
(bool success,) = address(vault).call{ value: 100 }(hex""); (bool success,) = address(sequencerFeeVault).call{ value: 100 }(hex"");
assertEq(success, true); assertEq(success, true);
assertEq(address(vault).balance, balance + 100); assertEq(address(sequencerFeeVault).balance, balance + 100);
} }
/// @dev Tests that `withdraw` reverts if the balance is less than the minimum /// @dev Tests that `withdraw` reverts if the balance is less than the minimum
/// withdrawal amount. /// withdrawal amount.
function test_withdraw_notEnough_reverts() external { function test_withdraw_notEnough_reverts() external {
assert(address(vault).balance < vault.MIN_WITHDRAWAL_AMOUNT()); assert(address(sequencerFeeVault).balance < sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT());
vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount"); vm.expectRevert("FeeVault: withdrawal amount must be greater than minimum withdrawal amount");
vault.withdraw(); sequencerFeeVault.withdraw();
} }
/// @dev Tests that `withdraw` successfully initiates a withdrawal to L1. /// @dev Tests that `withdraw` successfully initiates a withdrawal to L1.
function test_withdraw_toL1_succeeds() external { function test_withdraw_toL1_succeeds() external {
uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1; // Set the code with the withdrawal network set to L1
vm.deal(address(vault), amount); vm.etch(
Predeploys.SEQUENCER_FEE_WALLET,
address(
new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1)
).code
);
uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1;
vm.deal(address(sequencerFeeVault), amount);
// No ether has been withdrawn yet // No ether has been withdrawn yet
assertEq(vault.totalProcessed(), 0); assertEq(sequencerFeeVault.totalProcessed(), 0);
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); emit Withdrawal(address(sequencerFeeVault).balance, sequencerFeeVault.RECIPIENT(), address(this));
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L1); emit Withdrawal(
address(sequencerFeeVault).balance,
sequencerFeeVault.RECIPIENT(),
address(this),
FeeVault.WithdrawalNetwork.L1
);
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall( vm.expectCall(
Predeploys.L2_STANDARD_BRIDGE, Predeploys.L2_STANDARD_BRIDGE,
address(vault).balance, address(sequencerFeeVault).balance,
abi.encodeWithSelector(StandardBridge.bridgeETHTo.selector, vault.l1FeeWallet(), 35_000, bytes("")) abi.encodeWithSelector(
StandardBridge.bridgeETHTo.selector, sequencerFeeVault.l1FeeWallet(), 35_000, bytes("")
)
); );
vault.withdraw(); sequencerFeeVault.withdraw();
// The withdrawal was successful // The withdrawal was successful
assertEq(vault.totalProcessed(), amount); assertEq(sequencerFeeVault.totalProcessed(), amount);
assertEq(address(vault).balance, ZERO_VALUE); assertEq(address(sequencerFeeVault).balance, 0);
assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, amount); assertEq(Predeploys.L2_TO_L1_MESSAGE_PASSER.balance, amount);
} }
} }
contract SequencerFeeVault_L2Withdrawal_Test is FeeVault_Initializer { contract SequencerFeeVault_L2Withdrawal_Test is CommonTest {
address recipient;
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
vm.etch( recipient = cfg.sequencerFeeVaultRecipient();
Predeploys.SEQUENCER_FEE_WALLET,
address(new SequencerFeeVault(recipient, NON_ZERO_VALUE, FeeVault.WithdrawalNetwork.L2)).code
);
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
} }
/// @dev Tests that `withdraw` successfully initiates a withdrawal to L2. /// @dev Tests that `withdraw` successfully initiates a withdrawal to L2.
function test_withdraw_toL2_succeeds() external { function test_withdraw_toL2_succeeds() external {
uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT() + 1; uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT() + 1;
vm.deal(address(vault), amount); vm.deal(address(sequencerFeeVault), amount);
// No ether has been withdrawn yet // No ether has been withdrawn yet
assertEq(vault.totalProcessed(), 0); assertEq(sequencerFeeVault.totalProcessed(), 0);
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this)); emit Withdrawal(address(sequencerFeeVault).balance, sequencerFeeVault.RECIPIENT(), address(this));
vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(true, true, true, true, address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(vault).balance, vault.RECIPIENT(), address(this), FeeVault.WithdrawalNetwork.L2); emit Withdrawal(
address(sequencerFeeVault).balance,
sequencerFeeVault.RECIPIENT(),
address(this),
FeeVault.WithdrawalNetwork.L2
);
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall(recipient, address(vault).balance, bytes("")); vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes(""));
vault.withdraw(); sequencerFeeVault.withdraw();
// The withdrawal was successful // The withdrawal was successful
assertEq(vault.totalProcessed(), amount); assertEq(sequencerFeeVault.totalProcessed(), amount);
assertEq(address(vault).balance, ZERO_VALUE); assertEq(address(sequencerFeeVault).balance, 0);
assertEq(recipient.balance, amount); assertEq(recipient.balance, amount);
} }
/// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate /// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate
/// a situation where insufficient gas is provided to the RECIPIENT. /// a situation where insufficient gas is provided to the RECIPIENT.
function test_withdraw_toL2recipientReverts_fails() external { function test_withdraw_toL2recipientReverts_fails() external {
uint256 amount = vault.MIN_WITHDRAWAL_AMOUNT(); uint256 amount = sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT();
vm.deal(address(vault), amount); vm.deal(address(sequencerFeeVault), amount);
// No ether has been withdrawn yet // No ether has been withdrawn yet
assertEq(vault.totalProcessed(), 0); assertEq(sequencerFeeVault.totalProcessed(), 0);
// Ensure the RECIPIENT reverts // Ensure the RECIPIENT reverts
vm.etch(vault.RECIPIENT(), type(Reverter).runtimeCode); vm.etch(sequencerFeeVault.RECIPIENT(), type(Reverter).runtimeCode);
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall(recipient, address(vault).balance, bytes("")); vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes(""));
vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient"); vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient");
vault.withdraw(); sequencerFeeVault.withdraw();
assertEq(vault.totalProcessed(), 0); assertEq(sequencerFeeVault.totalProcessed(), 0);
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { StandardBridge } from "src/universal/StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol";
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Testing utilities // Testing utilities
import { CommonTest } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Target contract dependencies // Target contract dependencies
import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol";
...@@ -15,89 +16,59 @@ import { Proxy } from "src/universal/Proxy.sol"; ...@@ -15,89 +16,59 @@ import { Proxy } from "src/universal/Proxy.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol";
contract SystemConfig_Init is CommonTest { contract SystemConfig_Init is CommonTest {
SystemConfig sysConf;
SystemConfig systemConfigImpl;
event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data); event ConfigUpdate(uint256 indexed version, SystemConfig.UpdateType indexed updateType, bytes data);
}
// Dummy addresses used to test getters contract SystemConfig_Initialize_Test is SystemConfig_Init {
address constant batchInbox = address(0x18); address batchInbox;
address constant l1CrossDomainMessenger = address(0x20); address owner;
address constant l1ERC721Bridge = address(0x21); uint256 overhead;
address constant l1StandardBridge = address(0x22); uint256 scalar;
address constant l2OutputOracle = address(0x23); bytes32 batcherHash;
address constant optimismPortal = address(0x24); uint64 gasLimit;
address constant optimismMintableERC20Factory = address(0x25); address unsafeBlockSigner;
uint256 constant overhead = 2100; address systemConfigImpl;
uint256 constant scalar = 1000000; address optimismMintableERC20Factory;
bytes32 constant batcherHash = bytes32(hex"abcd");
uint64 constant gasLimit = 30_000_000;
address constant unsafeBlockSigner = address(1);
function setUp() public virtual override { function setUp() public virtual override {
super.setUp(); super.setUp();
batchInbox = cfg.batchInboxAddress();
Proxy proxy = new Proxy(multisig); owner = cfg.finalSystemOwner();
systemConfigImpl = new SystemConfig(); overhead = cfg.gasPriceOracleOverhead();
scalar = cfg.gasPriceOracleScalar();
vm.prank(multisig); batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress())));
proxy.upgradeToAndCall( gasLimit = uint64(cfg.l2GenesisBlockGasLimit());
address(systemConfigImpl), unsafeBlockSigner = cfg.p2pSequencerAddress();
abi.encodeCall( systemConfigImpl = mustGetAddress("SystemConfig");
SystemConfig.initialize, optimismMintableERC20Factory = mustGetAddress("OptimismMintableERC20FactoryProxy");
(
alice, // _owner,
overhead, // _overhead,
scalar, // _scalar,
batcherHash, // _batcherHash
gasLimit, // _gasLimit,
unsafeBlockSigner, // _unsafeBlockSigner,
Constants.DEFAULT_RESOURCE_CONFIG(), // _config,
0, // _startBlock
batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger,
l1ERC721Bridge: l1ERC721Bridge,
l1StandardBridge: l1StandardBridge,
l2OutputOracle: l2OutputOracle,
optimismPortal: optimismPortal,
optimismMintableERC20Factory: optimismMintableERC20Factory
})
)
)
);
sysConf = SystemConfig(address(proxy));
} }
}
contract SystemConfig_Initialize_Test is SystemConfig_Init {
/// @dev Tests that initailization sets the correct values. /// @dev Tests that initailization sets the correct values.
function test_initialize_values_succeeds() external { function test_initialize_values_succeeds() external {
assertEq(sysConf.l1CrossDomainMessenger(), l1CrossDomainMessenger); assertEq(systemConfig.l1CrossDomainMessenger(), address(l1CrossDomainMessenger));
assertEq(sysConf.l1ERC721Bridge(), l1ERC721Bridge); assertEq(systemConfig.l1ERC721Bridge(), address(l1ERC721Bridge));
assertEq(sysConf.l1StandardBridge(), l1StandardBridge); assertEq(systemConfig.l1StandardBridge(), address(l1StandardBridge));
assertEq(sysConf.l2OutputOracle(), l2OutputOracle); assertEq(systemConfig.l2OutputOracle(), address(l2OutputOracle));
assertEq(sysConf.optimismPortal(), optimismPortal); assertEq(systemConfig.optimismPortal(), address(optimismPortal));
assertEq(sysConf.optimismMintableERC20Factory(), optimismMintableERC20Factory); assertEq(systemConfig.optimismMintableERC20Factory(), optimismMintableERC20Factory);
assertEq(sysConf.batchInbox(), batchInbox); assertEq(systemConfig.batchInbox(), batchInbox);
assertEq(sysConf.owner(), alice); assertEq(systemConfig.owner(), owner);
assertEq(sysConf.overhead(), overhead); assertEq(systemConfig.overhead(), overhead);
assertEq(sysConf.scalar(), scalar); assertEq(systemConfig.scalar(), scalar);
assertEq(sysConf.batcherHash(), batcherHash); assertEq(systemConfig.batcherHash(), batcherHash);
assertEq(sysConf.gasLimit(), gasLimit); assertEq(systemConfig.gasLimit(), gasLimit);
assertEq(sysConf.unsafeBlockSigner(), unsafeBlockSigner); assertEq(systemConfig.unsafeBlockSigner(), unsafeBlockSigner);
// Depends on start block being set to 0 in `initialize` // Depends on start block being set to 0 in `initialize`
assertEq(sysConf.startBlock(), block.number); assertEq(systemConfig.startBlock(), block.number);
// Depends on `initialize` being called with defaults // Depends on `initialize` being called with defaults
ResourceMetering.ResourceConfig memory cfg = Constants.DEFAULT_RESOURCE_CONFIG(); ResourceMetering.ResourceConfig memory rcfg = Constants.DEFAULT_RESOURCE_CONFIG();
ResourceMetering.ResourceConfig memory actual = sysConf.resourceConfig(); ResourceMetering.ResourceConfig memory actual = systemConfig.resourceConfig();
assertEq(actual.maxResourceLimit, cfg.maxResourceLimit); assertEq(actual.maxResourceLimit, rcfg.maxResourceLimit);
assertEq(actual.elasticityMultiplier, cfg.elasticityMultiplier); assertEq(actual.elasticityMultiplier, rcfg.elasticityMultiplier);
assertEq(actual.baseFeeMaxChangeDenominator, cfg.baseFeeMaxChangeDenominator); assertEq(actual.baseFeeMaxChangeDenominator, rcfg.baseFeeMaxChangeDenominator);
assertEq(actual.minimumBaseFee, cfg.minimumBaseFee); assertEq(actual.minimumBaseFee, rcfg.minimumBaseFee);
assertEq(actual.systemTxMaxGas, cfg.systemTxMaxGas); assertEq(actual.systemTxMaxGas, rcfg.systemTxMaxGas);
assertEq(actual.maximumBaseFee, cfg.maximumBaseFee); assertEq(actual.maximumBaseFee, rcfg.maximumBaseFee);
} }
/// @dev Ensures that the start block override can be used to set the start block. /// @dev Ensures that the start block override can be used to set the start block.
...@@ -105,15 +76,17 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -105,15 +76,17 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
uint256 startBlock = 100; uint256 startBlock = 100;
// Wipe out the initialized slot so the proxy can be initialized again // Wipe out the initialized slot so the proxy can be initialized again
vm.store(address(sysConf), bytes32(0), bytes32(0)); vm.store(address(systemConfig), bytes32(0), bytes32(0));
assertEq(sysConf.startBlock(), block.number); assertEq(systemConfig.startBlock(), block.number);
// the startBlock slot is 106, wipe it out // the startBlock slot is 106, wipe it out
vm.store(address(sysConf), bytes32(uint256(106)), bytes32(0)); vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(0));
assertEq(sysConf.startBlock(), 0); assertEq(systemConfig.startBlock(), 0);
address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS))));
vm.prank(admin);
vm.prank(multisig); Proxy(payable(address(systemConfig))).upgradeToAndCall(
Proxy(payable(address(sysConf))).upgradeToAndCall(
address(systemConfigImpl), address(systemConfigImpl),
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
...@@ -128,31 +101,31 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -128,31 +101,31 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
startBlock, // _startBlock startBlock, // _startBlock
batchInbox, // _batchInbox batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger, l1CrossDomainMessenger: address(l1CrossDomainMessenger),
l1ERC721Bridge: l1ERC721Bridge, l1ERC721Bridge: address(l1ERC721Bridge),
l1StandardBridge: l1StandardBridge, l1StandardBridge: address(l1StandardBridge),
l2OutputOracle: l2OutputOracle, l2OutputOracle: address(l2OutputOracle),
optimismPortal: optimismPortal, optimismPortal: address(optimismPortal),
optimismMintableERC20Factory: optimismMintableERC20Factory optimismMintableERC20Factory: optimismMintableERC20Factory
}) })
) )
) )
); );
assertEq(sysConf.startBlock(), startBlock); assertEq(systemConfig.startBlock(), startBlock);
} }
/// @dev Tests that initialization with start block already set is a noop. /// @dev Tests that initialization with start block already set is a noop.
function test_initialize_startBlockNoop_reverts() external { function test_initialize_startBlockNoop_reverts() external {
// wipe out initialized slot so we can initialize again // wipe out initialized slot so we can initialize again
vm.store(address(sysConf), bytes32(0), bytes32(0)); vm.store(address(systemConfig), bytes32(0), bytes32(0));
// the startBlock slot is 106, set it to something non zero // the startBlock slot is 106, set it to something non zero
vm.store(address(sysConf), bytes32(uint256(106)), bytes32(uint256(0xff))); vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(uint256(0xff)));
// Initialize with a non zero start block, should see a revert // Initialize with a non zero start block, should see a revert
vm.prank(multisig); vm.prank(EIP1967Helper.getAdmin(address(systemConfig)));
// The call to initialize reverts due to: "SystemConfig: cannot override an already set start block" // The call to initialize reverts due to: "SystemConfig: cannot override an already set start block"
// but the proxy revert message bubbles up. // but the proxy revert message bubbles up.
Proxy(payable(address(sysConf))).upgradeToAndCall( Proxy(payable(address(systemConfig))).upgradeToAndCall(
address(systemConfigImpl), address(systemConfigImpl),
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
...@@ -167,11 +140,11 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -167,11 +140,11 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
1, // _startBlock 1, // _startBlock
batchInbox, // _batchInbox batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger, l1CrossDomainMessenger: address(l1CrossDomainMessenger),
l1ERC721Bridge: l1ERC721Bridge, l1ERC721Bridge: address(l1ERC721Bridge),
l1StandardBridge: l1StandardBridge, l1StandardBridge: address(l1StandardBridge),
l2OutputOracle: l2OutputOracle, l2OutputOracle: address(l2OutputOracle),
optimismPortal: optimismPortal, optimismPortal: address(optimismPortal),
optimismMintableERC20Factory: optimismMintableERC20Factory optimismMintableERC20Factory: optimismMintableERC20Factory
}) })
) )
...@@ -180,29 +153,31 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -180,29 +153,31 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
// It was initialized with 1 but it was already set so the override // It was initialized with 1 but it was already set so the override
// should be ignored. // should be ignored.
uint256 startBlock = sysConf.startBlock(); uint256 startBlock = systemConfig.startBlock();
assertEq(startBlock, 0xff); assertEq(startBlock, 0xff);
} }
/// @dev Ensures that the events are emitted during initialization. /// @dev Ensures that the events are emitted during initialization.
function test_initialize_events_succeeds() external { function test_initialize_events_succeeds() external {
// Wipe out the initialized slot so the proxy can be initialized again // Wipe out the initialized slot so the proxy can be initialized again
vm.store(address(sysConf), bytes32(0), bytes32(0)); vm.store(address(systemConfig), bytes32(0), bytes32(0));
vm.store(address(sysConf), bytes32(uint256(106)), bytes32(0)); vm.store(address(systemConfig), bytes32(uint256(106)), bytes32(0));
assertEq(sysConf.startBlock(), 0); assertEq(systemConfig.startBlock(), 0);
// The order depends here // The order depends here
vm.expectEmit(true, true, true, true, address(sysConf)); vm.expectEmit(true, true, true, true, address(systemConfig));
emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(batcherHash)); emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(batcherHash));
vm.expectEmit(true, true, true, true, address(sysConf)); vm.expectEmit(true, true, true, true, address(systemConfig));
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(overhead, scalar)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(overhead, scalar));
vm.expectEmit(true, true, true, true, address(sysConf)); vm.expectEmit(true, true, true, true, address(systemConfig));
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(gasLimit)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(gasLimit));
vm.expectEmit(true, true, true, true, address(sysConf)); vm.expectEmit(true, true, true, true, address(systemConfig));
emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(unsafeBlockSigner)); emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(unsafeBlockSigner));
vm.prank(multisig); address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS))));
Proxy(payable(address(sysConf))).upgradeToAndCall( vm.prank(admin);
Proxy(payable(address(systemConfig))).upgradeToAndCall(
address(systemConfigImpl), address(systemConfigImpl),
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
...@@ -217,11 +192,11 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -217,11 +192,11 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
0, // _startBlock 0, // _startBlock
batchInbox, // _batchInbox batchInbox, // _batchInbox
SystemConfig.Addresses({ // _addresses SystemConfig.Addresses({ // _addresses
l1CrossDomainMessenger: l1CrossDomainMessenger, l1CrossDomainMessenger: address(l1CrossDomainMessenger),
l1ERC721Bridge: l1ERC721Bridge, l1ERC721Bridge: address(l1ERC721Bridge),
l1StandardBridge: l1StandardBridge, l1StandardBridge: address(l1StandardBridge),
l2OutputOracle: l2OutputOracle, l2OutputOracle: address(l2OutputOracle),
optimismPortal: optimismPortal, optimismPortal: address(optimismPortal),
optimismMintableERC20Factory: optimismMintableERC20Factory optimismMintableERC20Factory: optimismMintableERC20Factory
}) })
) )
...@@ -233,15 +208,19 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -233,15 +208,19 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
contract SystemConfig_Initialize_TestFail is SystemConfig_Init { contract SystemConfig_Initialize_TestFail is SystemConfig_Init {
/// @dev Tests that initialization reverts if the gas limit is too low. /// @dev Tests that initialization reverts if the gas limit is too low.
function test_initialize_lowGasLimit_reverts() external { function test_initialize_lowGasLimit_reverts() external {
uint64 minimumGasLimit = sysConf.minimumGasLimit(); address systemConfigImpl = mustGetAddress("SystemConfig");
uint64 minimumGasLimit = systemConfig.minimumGasLimit();
// Wipe out the initialized slot so the proxy can be initialized again // Wipe out the initialized slot so the proxy can be initialized again
vm.store(address(sysConf), bytes32(0), bytes32(0)); vm.store(address(systemConfig), bytes32(0), bytes32(0));
vm.prank(multisig);
address admin = address(uint160(uint256(vm.load(address(systemConfig), Constants.PROXY_OWNER_ADDRESS))));
vm.prank(admin);
// The call to initialize reverts due to: "SystemConfig: gas limit too low" // The call to initialize reverts due to: "SystemConfig: gas limit too low"
// but the proxy revert message bubbles up. // but the proxy revert message bubbles up.
vm.expectRevert("Proxy: delegatecall to new implementation contract failed"); vm.expectRevert("Proxy: delegatecall to new implementation contract failed");
Proxy(payable(address(sysConf))).upgradeToAndCall( Proxy(payable(address(systemConfig))).upgradeToAndCall(
address(systemConfigImpl), address(systemConfigImpl),
abi.encodeCall( abi.encodeCall(
SystemConfig.initialize, SystemConfig.initialize,
...@@ -273,32 +252,32 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -273,32 +252,32 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
/// @dev Tests that `setBatcherHash` reverts if the caller is not the owner. /// @dev Tests that `setBatcherHash` reverts if the caller is not the owner.
function test_setBatcherHash_notOwner_reverts() external { function test_setBatcherHash_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
sysConf.setBatcherHash(bytes32(hex"")); systemConfig.setBatcherHash(bytes32(hex""));
} }
/// @dev Tests that `setGasConfig` reverts if the caller is not the owner. /// @dev Tests that `setGasConfig` reverts if the caller is not the owner.
function test_setGasConfig_notOwner_reverts() external { function test_setGasConfig_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
sysConf.setGasConfig(0, 0); systemConfig.setGasConfig(0, 0);
} }
/// @dev Tests that `setGasLimit` reverts if the caller is not the owner. /// @dev Tests that `setGasLimit` reverts if the caller is not the owner.
function test_setGasLimit_notOwner_reverts() external { function test_setGasLimit_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
sysConf.setGasLimit(0); systemConfig.setGasLimit(0);
} }
/// @dev Tests that `setUnsafeBlockSigner` reverts if the caller is not the owner. /// @dev Tests that `setUnsafeBlockSigner` reverts if the caller is not the owner.
function test_setUnsafeBlockSigner_notOwner_reverts() external { function test_setUnsafeBlockSigner_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
sysConf.setUnsafeBlockSigner(address(0x20)); systemConfig.setUnsafeBlockSigner(address(0x20));
} }
/// @dev Tests that `setResourceConfig` reverts if the caller is not the owner. /// @dev Tests that `setResourceConfig` reverts if the caller is not the owner.
function test_setResourceConfig_notOwner_reverts() external { function test_setResourceConfig_notOwner_reverts() external {
ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG(); ResourceMetering.ResourceConfig memory config = Constants.DEFAULT_RESOURCE_CONFIG();
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
sysConf.setResourceConfig(config); systemConfig.setResourceConfig(config);
} }
/// @dev Tests that `setResourceConfig` reverts if the min base fee /// @dev Tests that `setResourceConfig` reverts if the min base fee
...@@ -312,9 +291,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -312,9 +291,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
minimumBaseFee: 2 gwei, minimumBaseFee: 2 gwei,
maximumBaseFee: 1 gwei maximumBaseFee: 1 gwei
}); });
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
vm.expectRevert("SystemConfig: min base fee must be less than max base"); vm.expectRevert("SystemConfig: min base fee must be less than max base");
sysConf.setResourceConfig(config); systemConfig.setResourceConfig(config);
} }
/// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator /// @dev Tests that `setResourceConfig` reverts if the baseFeeMaxChangeDenominator
...@@ -328,14 +307,14 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -328,14 +307,14 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
minimumBaseFee: 1 gwei, minimumBaseFee: 1 gwei,
maximumBaseFee: 2 gwei maximumBaseFee: 2 gwei
}); });
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
vm.expectRevert("SystemConfig: denominator must be larger than 1"); vm.expectRevert("SystemConfig: denominator must be larger than 1");
sysConf.setResourceConfig(config); systemConfig.setResourceConfig(config);
} }
/// @dev Tests that `setResourceConfig` reverts if the gas limit is too low. /// @dev Tests that `setResourceConfig` reverts if the gas limit is too low.
function test_setResourceConfig_lowGasLimit_reverts() external { function test_setResourceConfig_lowGasLimit_reverts() external {
uint64 gasLimit = sysConf.gasLimit(); uint64 gasLimit = systemConfig.gasLimit();
ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({ ResourceMetering.ResourceConfig memory config = ResourceMetering.ResourceConfig({
maxResourceLimit: uint32(gasLimit), maxResourceLimit: uint32(gasLimit),
...@@ -345,9 +324,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -345,9 +324,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
minimumBaseFee: 1 gwei, minimumBaseFee: 1 gwei,
maximumBaseFee: 2 gwei maximumBaseFee: 2 gwei
}); });
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
vm.expectRevert("SystemConfig: gas limit too low"); vm.expectRevert("SystemConfig: gas limit too low");
sysConf.setResourceConfig(config); systemConfig.setResourceConfig(config);
} }
/// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier /// @dev Tests that `setResourceConfig` reverts if the elasticity multiplier
...@@ -361,9 +340,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -361,9 +340,9 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
minimumBaseFee: 1 gwei, minimumBaseFee: 1 gwei,
maximumBaseFee: 2 gwei maximumBaseFee: 2 gwei
}); });
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
vm.expectRevert("SystemConfig: precision loss with target resource limit"); vm.expectRevert("SystemConfig: precision loss with target resource limit");
sysConf.setResourceConfig(config); systemConfig.setResourceConfig(config);
} }
} }
...@@ -373,9 +352,9 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -373,9 +352,9 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash)); emit ConfigUpdate(0, SystemConfig.UpdateType.BATCHER, abi.encode(newBatcherHash));
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
sysConf.setBatcherHash(newBatcherHash); systemConfig.setBatcherHash(newBatcherHash);
assertEq(sysConf.batcherHash(), newBatcherHash); assertEq(systemConfig.batcherHash(), newBatcherHash);
} }
/// @dev Tests that `setGasConfig` updates the overhead and scalar successfully. /// @dev Tests that `setGasConfig` updates the overhead and scalar successfully.
...@@ -383,23 +362,23 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -383,23 +362,23 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_CONFIG, abi.encode(newOverhead, newScalar));
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
sysConf.setGasConfig(newOverhead, newScalar); systemConfig.setGasConfig(newOverhead, newScalar);
assertEq(sysConf.overhead(), newOverhead); assertEq(systemConfig.overhead(), newOverhead);
assertEq(sysConf.scalar(), newScalar); assertEq(systemConfig.scalar(), newScalar);
} }
/// @dev Tests that `setGasLimit` updates the gas limit successfully. /// @dev Tests that `setGasLimit` updates the gas limit successfully.
function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external { function testFuzz_setGasLimit_succeeds(uint64 newGasLimit) external {
uint64 minimumGasLimit = sysConf.minimumGasLimit(); uint64 minimumGasLimit = systemConfig.minimumGasLimit();
newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max))); newGasLimit = uint64(bound(uint256(newGasLimit), uint256(minimumGasLimit), uint256(type(uint64).max)));
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit)); emit ConfigUpdate(0, SystemConfig.UpdateType.GAS_LIMIT, abi.encode(newGasLimit));
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
sysConf.setGasLimit(newGasLimit); systemConfig.setGasLimit(newGasLimit);
assertEq(sysConf.gasLimit(), newGasLimit); assertEq(systemConfig.gasLimit(), newGasLimit);
} }
/// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully. /// @dev Tests that `setUnsafeBlockSigner` updates the block signer successfully.
...@@ -407,8 +386,8 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -407,8 +386,8 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner)); emit ConfigUpdate(0, SystemConfig.UpdateType.UNSAFE_BLOCK_SIGNER, abi.encode(newUnsafeSigner));
vm.prank(sysConf.owner()); vm.prank(systemConfig.owner());
sysConf.setUnsafeBlockSigner(newUnsafeSigner); systemConfig.setUnsafeBlockSigner(newUnsafeSigner);
assertEq(sysConf.unsafeBlockSigner(), newUnsafeSigner); assertEq(systemConfig.unsafeBlockSigner(), newUnsafeSigner);
} }
} }
...@@ -5,12 +5,13 @@ import { StdUtils } from "forge-std/StdUtils.sol"; ...@@ -5,12 +5,13 @@ import { StdUtils } from "forge-std/StdUtils.sol";
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { Messenger_Initializer } from "test/CommonTest.t.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Encoding } from "src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
contract RelayActor is StdUtils { contract RelayActor is StdUtils {
// Storage slot of the l2Sender // Storage slot of the l2Sender
...@@ -88,7 +89,7 @@ contract RelayActor is StdUtils { ...@@ -88,7 +89,7 @@ contract RelayActor is StdUtils {
} }
} }
contract XDM_MinGasLimits is Messenger_Initializer { contract XDM_MinGasLimits is Bridge_Initializer {
RelayActor actor; RelayActor actor;
function init(bool doFail) public virtual { function init(bool doFail) public virtual {
...@@ -96,10 +97,10 @@ contract XDM_MinGasLimits is Messenger_Initializer { ...@@ -96,10 +97,10 @@ contract XDM_MinGasLimits is Messenger_Initializer {
super.setUp(); super.setUp();
// Deploy a relay actor // Deploy a relay actor
actor = new RelayActor(op, L1Messenger, vm, doFail); actor = new RelayActor(optimismPortal, l1CrossDomainMessenger, vm, doFail);
// Give the portal some ether to send to `relayMessage` // Give the portal some ether to send to `relayMessage`
vm.deal(address(op), type(uint128).max); vm.deal(address(optimismPortal), type(uint128).max);
// Target the `RelayActor` contract // Target the `RelayActor` contract
targetContract(address(actor)); targetContract(address(actor));
...@@ -138,9 +139,9 @@ contract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits { ...@@ -138,9 +139,9 @@ contract XDM_MinGasLimits_Succeeds is XDM_MinGasLimits {
for (uint256 i = 0; i < length; ++i) { for (uint256 i = 0; i < length; ++i) {
bytes32 hash = actor.hashes(i); bytes32 hash = actor.hashes(i);
// The message hash is set in the successfulMessages mapping // The message hash is set in the successfulMessages mapping
assertTrue(L1Messenger.successfulMessages(hash)); assertTrue(l1CrossDomainMessenger.successfulMessages(hash));
// The message hash is not set in the failedMessages mapping // The message hash is not set in the failedMessages mapping
assertFalse(L1Messenger.failedMessages(hash)); assertFalse(l1CrossDomainMessenger.failedMessages(hash));
} }
assertFalse(actor.reverted()); assertFalse(actor.reverted());
} }
...@@ -171,9 +172,9 @@ contract XDM_MinGasLimits_Reverts is XDM_MinGasLimits { ...@@ -171,9 +172,9 @@ contract XDM_MinGasLimits_Reverts is XDM_MinGasLimits {
for (uint256 i = 0; i < length; ++i) { for (uint256 i = 0; i < length; ++i) {
bytes32 hash = actor.hashes(i); bytes32 hash = actor.hashes(i);
// The message hash is not set in the successfulMessages mapping // The message hash is not set in the successfulMessages mapping
assertFalse(L1Messenger.successfulMessages(hash)); assertFalse(l1CrossDomainMessenger.successfulMessages(hash));
// The message hash is set in the failedMessages mapping // The message hash is set in the failedMessages mapping
assertTrue(L1Messenger.failedMessages(hash)); assertTrue(l1CrossDomainMessenger.failedMessages(hash));
} }
assertFalse(actor.reverted()); assertFalse(actor.reverted());
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { L2OutputOracle_Initializer } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
...@@ -29,14 +29,14 @@ contract L2OutputOracle_Proposer { ...@@ -29,14 +29,14 @@ contract L2OutputOracle_Proposer {
} }
} }
contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_Initializer { contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is CommonTest {
L2OutputOracle_Proposer internal actor; L2OutputOracle_Proposer internal actor;
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
// Create a proposer actor. // Create a proposer actor.
actor = new L2OutputOracle_Proposer(oracle, vm); actor = new L2OutputOracle_Proposer(l2OutputOracle, vm);
// Set the target contract to the proposer actor. // Set the target contract to the proposer actor.
targetContract(address(actor)); targetContract(address(actor));
...@@ -57,6 +57,6 @@ contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_In ...@@ -57,6 +57,6 @@ contract L2OutputOracle_MonotonicBlockNumIncrease_Invariant is L2OutputOracle_In
/// correspond to a block number that is less than the current output. /// correspond to a block number that is less than the current output.
function invariant_monotonicBlockNumIncrease() external { function invariant_monotonicBlockNumIncrease() external {
// Assert that the block number of proposals must monotonically increase. // Assert that the block number of proposals must monotonically increase.
assertTrue(oracle.nextBlockNumber() >= oracle.latestBlockNumber()); assertTrue(l2OutputOracle.nextBlockNumber() >= l2OutputOracle.latestBlockNumber());
} }
} }
...@@ -11,7 +11,7 @@ import { SystemConfig } from "src/L1/SystemConfig.sol"; ...@@ -11,7 +11,7 @@ import { SystemConfig } from "src/L1/SystemConfig.sol";
import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Portal_Initializer } from "test/CommonTest.t.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
...@@ -74,7 +74,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering { ...@@ -74,7 +74,7 @@ contract OptimismPortal_Depositor is StdUtils, ResourceMetering {
} }
} }
contract OptimismPortal_Invariant_Harness is Portal_Initializer { contract OptimismPortal_Invariant_Harness is CommonTest {
// Reusable default values for a test withdrawal // Reusable default values for a test withdrawal
Types.WithdrawalTransaction _defaultTx; Types.WithdrawalTransaction _defaultTx;
...@@ -109,28 +109,31 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer { ...@@ -109,28 +109,31 @@ contract OptimismPortal_Invariant_Harness is Portal_Initializer {
messagePasserStorageRoot: _storageRoot, messagePasserStorageRoot: _storageRoot,
latestBlockhash: bytes32(uint256(0)) latestBlockhash: bytes32(uint256(0))
}); });
_proposedBlockNumber = oracle.nextBlockNumber(); _proposedBlockNumber = l2OutputOracle.nextBlockNumber();
_proposedOutputIndex = oracle.nextOutputIndex(); _proposedOutputIndex = l2OutputOracle.nextOutputIndex();
// Configure the oracle to return the output root we've prepared. // Configure the oracle to return the output root we've prepared.
vm.warp(oracle.computeL2Timestamp(_proposedBlockNumber) + 1); vm.warp(l2OutputOracle.computeL2Timestamp(_proposedBlockNumber) + 1);
vm.prank(oracle.PROPOSER()); vm.prank(l2OutputOracle.PROPOSER());
oracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0); l2OutputOracle.proposeL2Output(_outputRoot, _proposedBlockNumber, 0, 0);
// Warp beyond the finalization period for the block we've proposed. // Warp beyond the finalization period for the block we've proposed.
vm.warp(oracle.getL2Output(_proposedOutputIndex).timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(
l2OutputOracle.getL2Output(_proposedOutputIndex).timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS()
+ 1
);
// Fund the portal so that we can withdraw ETH. // Fund the portal so that we can withdraw ETH.
vm.deal(address(op), 0xFFFFFFFF); vm.deal(address(optimismPortal), 0xFFFFFFFF);
} }
} }
contract OptimismPortal_Deposit_Invariant is Portal_Initializer { contract OptimismPortal_Deposit_Invariant is CommonTest {
OptimismPortal_Depositor internal actor; OptimismPortal_Depositor internal actor;
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
// Create a deposit actor. // Create a deposit actor.
actor = new OptimismPortal_Depositor(vm, op); actor = new OptimismPortal_Depositor(vm, optimismPortal);
targetContract(address(actor)); targetContract(address(actor));
...@@ -155,12 +158,12 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { ...@@ -155,12 +158,12 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {
super.setUp(); super.setUp();
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Set the target contract to the portal proxy // Set the target contract to the portal proxy
targetContract(address(op)); targetContract(address(optimismPortal));
// Exclude the proxy admin from the senders so that the proxy cannot be upgraded // Exclude the proxy admin from the senders so that the proxy cannot be upgraded
excludeSender(EIP1967Helper.getAdmin(address(op))); excludeSender(EIP1967Helper.getAdmin(address(optimismPortal)));
} }
/// @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the finalization
...@@ -170,7 +173,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness { ...@@ -170,7 +173,7 @@ contract OptimismPortal_CannotTimeTravel is OptimismPortal_Invariant_Harness {
/// until after the finalization period has elapsed. /// until after the finalization period has elapsed.
function invariant_cannotFinalizeBeforePeriodHasPassed() external { function invariant_cannotFinalizeBeforePeriodHasPassed() external {
vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed"); vm.expectRevert("OptimismPortal: proven withdrawal finalization period has not elapsed");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
} }
} }
...@@ -179,18 +182,18 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness ...@@ -179,18 +182,18 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness
super.setUp(); super.setUp();
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp past the finalization period. // Warp past the finalization period.
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Finalize the withdrawal transaction. // Finalize the withdrawal transaction.
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
// Set the target contract to the portal proxy // Set the target contract to the portal proxy
targetContract(address(op)); targetContract(address(optimismPortal));
// Exclude the proxy admin from the senders so that the proxy cannot be upgraded // Exclude the proxy admin from the senders so that the proxy cannot be upgraded
excludeSender(EIP1967Helper.getAdmin(address(op))); excludeSender(EIP1967Helper.getAdmin(address(optimismPortal)));
} }
/// @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal /// @custom:invariant `finalizeWithdrawalTransaction` should revert if the withdrawal
...@@ -200,7 +203,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness ...@@ -200,7 +203,7 @@ contract OptimismPortal_CannotFinalizeTwice is OptimismPortal_Invariant_Harness
/// allows a withdrawal to be finalized twice. /// allows a withdrawal to be finalized twice.
function invariant_cannotFinalizeTwice() external { function invariant_cannotFinalizeTwice() external {
vm.expectRevert("OptimismPortal: withdrawal has already been finalized"); vm.expectRevert("OptimismPortal: withdrawal has already been finalized");
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
} }
} }
...@@ -209,15 +212,15 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant ...@@ -209,15 +212,15 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant
super.setUp(); super.setUp();
// Prove the withdrawal transaction // Prove the withdrawal transaction
op.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof); optimismPortal.proveWithdrawalTransaction(_defaultTx, _proposedOutputIndex, _outputRootProof, _withdrawalProof);
// Warp past the finalization period. // Warp past the finalization period.
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS() + 1); vm.warp(block.timestamp + l2OutputOracle.FINALIZATION_PERIOD_SECONDS() + 1);
// Set the target contract to the portal proxy // Set the target contract to the portal proxy
targetContract(address(op)); targetContract(address(optimismPortal));
// Exclude the proxy admin from the senders so that the proxy cannot be upgraded // Exclude the proxy admin from the senders so that the proxy cannot be upgraded
excludeSender(EIP1967Helper.getAdmin(address(op))); excludeSender(EIP1967Helper.getAdmin(address(optimismPortal)));
} }
/// @custom:invariant A withdrawal should **always** be able to be finalized /// @custom:invariant A withdrawal should **always** be able to be finalized
...@@ -230,7 +233,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant ...@@ -230,7 +233,7 @@ contract OptimismPortal_CanAlwaysFinalizeAfterWindow is OptimismPortal_Invariant
function invariant_canAlwaysFinalize() external { function invariant_canAlwaysFinalize() external {
uint256 bobBalanceBefore = address(bob).balance; uint256 bobBalanceBefore = address(bob).balance;
op.finalizeWithdrawalTransaction(_defaultTx); optimismPortal.finalizeWithdrawalTransaction(_defaultTx);
assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value); assertEq(address(bob).balance, bobBalanceBefore + _defaultTx.value);
} }
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { CommonTest } from "test/setup/CommonTest.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol";
/// @title Bridge_Initializer
/// @dev This contract extends the CommonTest contract with token deployments
/// meant to be used with the bridge contracts.
contract Bridge_Initializer is CommonTest {
ERC20 L1Token;
ERC20 BadL1Token;
OptimismMintableERC20 L2Token;
LegacyMintableERC20 LegacyL2Token;
ERC20 NativeL2Token;
ERC20 BadL2Token;
OptimismMintableERC20 RemoteL1Token;
function setUp() public virtual override {
super.setUp();
L1Token = new ERC20("Native L1 Token", "L1T");
LegacyL2Token = new LegacyMintableERC20({
_l2Bridge: address(l2StandardBridge),
_l1Token: address(L1Token),
_name: string.concat("LegacyL2-", L1Token.name()),
_symbol: string.concat("LegacyL2-", L1Token.symbol())
});
vm.label(address(LegacyL2Token), "LegacyMintableERC20");
// Deploy the L2 ERC20 now
L2Token = OptimismMintableERC20(
l2OptimismMintableERC20Factory.createStandardL2Token(
address(L1Token),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
)
);
BadL2Token = OptimismMintableERC20(
l2OptimismMintableERC20Factory.createStandardL2Token(
address(1),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
)
);
NativeL2Token = new ERC20("Native L2 Token", "L2T");
RemoteL1Token = OptimismMintableERC20(
l1OptimismMintableERC20Factory.createStandardL2Token(
address(NativeL2Token),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
)
);
BadL1Token = OptimismMintableERC20(
l1OptimismMintableERC20Factory.createStandardL2Token(
address(1),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
)
);
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { Setup } from "test/setup/Setup.sol";
import { Events } from "test/setup/Events.sol";
import { FFIInterface } from "test/setup/FFIInterface.sol";
/// @title CommonTest
/// @dev An extenstion to `Test` that sets up the optimism smart contracts.
contract CommonTest is Setup, Test, Events {
address alice = address(128);
address bob = address(256);
bytes32 constant nonZeroHash = keccak256(abi.encode("NON_ZERO"));
FFIInterface ffi;
function setUp() public virtual override {
vm.deal(alice, type(uint64).max);
vm.deal(bob, type(uint64).max);
vm.label(alice, "alice");
vm.label(bob, "bob");
Setup.setUp();
ffi = new FFIInterface();
// Make sure the base fee is non zero
vm.fee(1 gwei);
// Set sane initialize block numbers
vm.warp(cfg.l2OutputOracleStartingTimestamp() + 1);
vm.roll(cfg.l2OutputOracleStartingBlockNumber() + 1);
// Deploy L1
Setup.L1();
// Deploy L2
Setup.L2({ cfg: cfg });
}
/// @dev Helper function that wraps `TransactionDeposited` event.
/// The magic `0` is the version.
function emitTransactionDeposited(
address _from,
address _to,
uint256 _mint,
uint256 _value,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
)
internal
{
emit TransactionDeposited(_from, _to, 0, abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data));
}
// @dev Advance the evm's time to meet the L2OutputOracle's requirements for proposeL2Output
function warpToProposeTime(uint256 _nextBlockNumber) public {
vm.warp(l2OutputOracle.computeL2Timestamp(_nextBlockNumber) + 1);
}
/// @dev Helper function to propose an output.
function proposeAnotherOutput() public {
bytes32 proposedOutput2 = keccak256(abi.encode());
uint256 nextBlockNumber = l2OutputOracle.nextBlockNumber();
uint256 nextOutputIndex = l2OutputOracle.nextOutputIndex();
warpToProposeTime(nextBlockNumber);
uint256 proposedNumber = l2OutputOracle.latestBlockNumber();
uint256 submissionInterval = cfg.l2OutputOracleSubmissionInterval();
// Ensure the submissionInterval is enforced
assertEq(nextBlockNumber, proposedNumber + submissionInterval);
vm.roll(nextBlockNumber + 1);
vm.expectEmit(true, true, true, true);
emit OutputProposed(proposedOutput2, nextOutputIndex, nextBlockNumber, block.timestamp);
address proposer = cfg.l2OutputOracleProposer();
vm.prank(proposer);
l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { FeeVault } from "src/universal/FeeVault.sol";
/// @title Events
/// @dev Contains various events that are tested against. This contract needs to
/// exist until we either modularize the implementations or use a newer version of
/// solc that allows for referencing events from other contracts.
contract Events {
/// @dev OpenZeppelin Ownable.sol transferOwnership event
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
event WithdrawalFinalized(bytes32 indexed withdrawalHash, bool success);
event WithdrawalProven(bytes32 indexed withdrawalHash, address indexed from, address indexed to);
event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
event SentMessageExtension1(address indexed sender, uint256 value);
event MessagePassed(
uint256 indexed nonce,
address indexed sender,
address indexed target,
uint256 value,
uint256 gasLimit,
bytes data,
bytes32 withdrawalHash
);
event WithdrawerBalanceBurnt(uint256 indexed amount);
event RelayedMessage(bytes32 indexed msgHash);
event FailedRelayedMessage(bytes32 indexed msgHash);
event TransactionDeposited(
address indexed from,
address indexed to,
uint256 mint,
uint256 value,
uint64 gasLimit,
bool isCreation,
bytes data
);
event WhatHappened(bool success, bytes returndata);
event OutputProposed(
bytes32 indexed outputRoot, uint256 indexed l2OutputIndex, uint256 indexed l2BlockNumber, uint256 l1Timestamp
);
event OutputsDeleted(uint256 indexed prevNextOutputIndex, uint256 indexed newNextOutputIndex);
event Withdrawal(uint256 value, address to, address from);
event Withdrawal(uint256 value, address to, address from, FeeVault.WithdrawalNetwork withdrawalNetwork);
event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes data);
event ERC20DepositInitiated(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event ERC20WithdrawalFinalized(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event WithdrawalInitiated(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event DepositFinalized(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event DepositFailed(
address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes data
);
event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes data);
event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes data);
event ERC20BridgeInitiated(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 amount,
bytes data
);
event ERC20BridgeFinalized(
address indexed localToken,
address indexed remoteToken,
address indexed from,
address to,
uint256 amount,
bytes data
);
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Predeploys } from "src/libraries/Predeploys.sol";
import { L2CrossDomainMessenger } from "src/L2/L2CrossDomainMessenger.sol";
import { L2StandardBridge } from "src/L2/L2StandardBridge.sol";
import { L2ToL1MessagePasser } from "src/L2/L2ToL1MessagePasser.sol";
import { L2ERC721Bridge } from "src/L2/L2ERC721Bridge.sol";
import { BaseFeeVault } from "src/L2/BaseFeeVault.sol";
import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol";
import { L1FeeVault } from "src/L2/L1FeeVault.sol";
import { GasPriceOracle } from "src/L2/GasPriceOracle.sol";
import { L1Block } from "src/L2/L1Block.sol";
import { LegacyMessagePasser } from "src/legacy/LegacyMessagePasser.sol";
import { GovernanceToken } from "src/governance/GovernanceToken.sol";
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";
import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol";
import { FeeVault } from "src/universal/FeeVault.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { DeployConfig } from "scripts/DeployConfig.s.sol";
import { Deploy } from "scripts/Deploy.s.sol";
import { L2OutputOracle } from "src/L1/L2OutputOracle.sol";
import { ProtocolVersions } from "src/L1/ProtocolVersions.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { AddressManager } from "src/legacy/AddressManager.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
/// @title Setup
/// @dev This contact is responsible for setting up the contracts in state. It currently
/// sets the L2 contracts directly at the predeploy addresses instead of setting them
/// up behind proxies. In the future we will migrate to importing the genesis JSON
/// file that is created to set up the L2 contracts instead of setting them up manually.
contract Setup is Deploy {
OptimismPortal optimismPortal;
L2OutputOracle l2OutputOracle;
SystemConfig systemConfig;
L1StandardBridge l1StandardBridge;
L1CrossDomainMessenger l1CrossDomainMessenger;
AddressManager addressManager;
L1ERC721Bridge l1ERC721Bridge;
OptimismMintableERC20Factory l1OptimismMintableERC20Factory;
ProtocolVersions protocolVersions;
L2CrossDomainMessenger l2CrossDomainMessenger =
L2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER));
L2StandardBridge l2StandardBridge = L2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));
L2ToL1MessagePasser l2ToL1MessagePasser = L2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
OptimismMintableERC20Factory l2OptimismMintableERC20Factory =
OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);
L2ERC721Bridge l2ERC721Bridge = L2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
BaseFeeVault baseFeeVault = BaseFeeVault(payable(Predeploys.BASE_FEE_VAULT));
SequencerFeeVault sequencerFeeVault = SequencerFeeVault(payable(Predeploys.SEQUENCER_FEE_WALLET));
L1FeeVault l1FeeVault = L1FeeVault(payable(Predeploys.L1_FEE_VAULT));
GasPriceOracle gasPriceOracle = GasPriceOracle(Predeploys.GAS_PRICE_ORACLE);
L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES);
LegacyMessagePasser legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER);
GovernanceToken governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN);
LegacyERC20ETH legacyERC20ETH = LegacyERC20ETH(Predeploys.LEGACY_ERC20_ETH);
function setUp() public virtual override {
Deploy.setUp();
}
/// @dev Sets up the L1 contracts.
function L1() public {
// Set the deterministic deployer in state to ensure that it is there
vm.etch(
0x4e59b44847b379578588920cA78FbF26c0B4956C,
hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"
);
Deploy.run();
optimismPortal = OptimismPortal(mustGetAddress("OptimismPortalProxy"));
l2OutputOracle = L2OutputOracle(mustGetAddress("L2OutputOracleProxy"));
systemConfig = SystemConfig(mustGetAddress("SystemConfigProxy"));
l1StandardBridge = L1StandardBridge(mustGetAddress("L1StandardBridgeProxy"));
l1CrossDomainMessenger = L1CrossDomainMessenger(mustGetAddress("L1CrossDomainMessengerProxy"));
addressManager = AddressManager(mustGetAddress("AddressManager"));
l1ERC721Bridge = L1ERC721Bridge(mustGetAddress("L1ERC721BridgeProxy"));
l1OptimismMintableERC20Factory =
OptimismMintableERC20Factory(mustGetAddress("OptimismMintableERC20FactoryProxy"));
protocolVersions = ProtocolVersions(mustGetAddress("ProtocolVersionsProxy"));
vm.label(address(l2OutputOracle), "L2OutputOracle");
vm.label(mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
vm.label(address(optimismPortal), "OptimismPortal");
vm.label(mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy");
vm.label(address(systemConfig), "SystemConfig");
vm.label(mustGetAddress("SystemConfigProxy"), "SystemConfigProxy");
vm.label(address(l1StandardBridge), "L1StandardBridge");
vm.label(mustGetAddress("L1StandardBridgeProxy"), "L1StandardBridgeProxy");
vm.label(address(l1CrossDomainMessenger), "L1CrossDomainMessenger");
vm.label(mustGetAddress("L1CrossDomainMessengerProxy"), "L1CrossDomainMessengerProxy");
vm.label(address(addressManager), "AddressManager");
vm.label(address(l1ERC721Bridge), "L1ERC721Bridge");
vm.label(mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy");
vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory");
vm.label(mustGetAddress("OptimismMintableERC20FactoryProxy"), "OptimismMintableERC20FactoryProxy");
vm.label(address(protocolVersions), "ProtocolVersions");
vm.label(mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy");
vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased");
}
/// @dev Sets up the L2 contracts. Depends on `L1()` being called first.
function L2(DeployConfig cfg) public {
// Set up L2. There are currently no proxies set in the L2 initialization.
vm.etch(
address(l2CrossDomainMessenger), address(new L2CrossDomainMessenger(address(l1CrossDomainMessenger))).code
);
l2CrossDomainMessenger.initialize();
vm.etch(address(l2ToL1MessagePasser), address(new L2ToL1MessagePasser()).code);
vm.etch(
address(l2StandardBridge), address(new L2StandardBridge(StandardBridge(payable(l1StandardBridge)))).code
);
l2StandardBridge.initialize();
vm.etch(address(l2OptimismMintableERC20Factory), address(new OptimismMintableERC20Factory()).code);
l2OptimismMintableERC20Factory.initialize(address(l2StandardBridge));
vm.etch(address(legacyERC20ETH), address(new LegacyERC20ETH()).code);
vm.etch(address(l2ERC721Bridge), address(new L2ERC721Bridge(address(l1ERC721Bridge))).code);
l2ERC721Bridge.initialize();
vm.etch(
address(sequencerFeeVault),
address(
new SequencerFeeVault(cfg.sequencerFeeVaultRecipient(), cfg.sequencerFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2)
).code
);
vm.etch(
address(baseFeeVault),
address(
new BaseFeeVault(cfg.baseFeeVaultRecipient(), cfg.baseFeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L1)
).code
);
vm.etch(
address(l1FeeVault),
address(
new L1FeeVault(cfg.l1FeeVaultRecipient(), cfg.l1FeeVaultMinimumWithdrawalAmount(), FeeVault.WithdrawalNetwork.L2)
).code
);
vm.etch(address(l1Block), address(new L1Block()).code);
vm.etch(address(gasPriceOracle), address(new GasPriceOracle()).code);
vm.etch(address(legacyMessagePasser), address(new LegacyMessagePasser()).code);
vm.etch(address(governanceToken), address(new GovernanceToken()).code);
// Set the ERC20 token name and symbol
vm.store(
address(governanceToken),
bytes32(uint256(3)),
bytes32(0x4f7074696d69736d000000000000000000000000000000000000000000000010)
);
vm.store(
address(governanceToken),
bytes32(uint256(4)),
bytes32(0x4f50000000000000000000000000000000000000000000000000000000000004)
);
// Set the governance token's owner to be the final system owner
address finalSystemOwner = cfg.finalSystemOwner();
vm.prank(governanceToken.owner());
governanceToken.transferOwnership(finalSystemOwner);
vm.label(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY, "OptimismMintableERC20Factory");
vm.label(Predeploys.LEGACY_ERC20_ETH, "LegacyERC20ETH");
vm.label(Predeploys.L2_STANDARD_BRIDGE, "L2StandardBridge");
vm.label(Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger");
vm.label(Predeploys.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser");
vm.label(Predeploys.SEQUENCER_FEE_WALLET, "SequencerFeeVault");
vm.label(Predeploys.L2_ERC721_BRIDGE, "L2ERC721Bridge");
vm.label(Predeploys.BASE_FEE_VAULT, "BaseFeeVault");
vm.label(Predeploys.L1_FEE_VAULT, "L1FeeVault");
vm.label(Predeploys.L1_BLOCK_ATTRIBUTES, "L1Block");
vm.label(Predeploys.GAS_PRICE_ORACLE, "GasPriceOracle");
vm.label(Predeploys.LEGACY_MESSAGE_PASSER, "LegacyMessagePasser");
vm.label(Predeploys.GOVERNANCE_TOKEN, "GovernanceToken");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment