Repository: gakonst/ethers-rs
Pull request #614 (2021-11-23 19:18:39)

feat: verify checksum before project compilation
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.

Bug fixes and new features should include tests.

Contributors guide: https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md

The contributors guide includes instructions for running rustfmt and building the
documentation.
-->

## Motivation

We have noticed scenarios where an ongoing operation was terminated, leading to a corrupted `solc` binary. If this binary (with the appropriate name) is considered OK and used to compile contracts, we end up with errors that are hard to debug.

<!--
Explain the context and why you're making that change. What is the problem
you're trying to solve? In some cases there is not a problem and this can be
thought of as being the motivation for your change.
-->

## Solution

<!--
Summarize the solution and provide any necessary context needed to understand
the code change.
-->

The proposed solution by @odyslam and @gakonst was to:
- [x] Verify the SHA256 checksum of the `solc` binary against the checksum [found remotely](https://binaries.soliditylang.org/macosx-amd64/list.json). In case of mismatch, re-install that version of `solc` before proceeding.

## PR Checklist

- [ ] Added Tests
- [ ] Added Documentation
- [ ] Updated the changelog



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 93f01e62..471af9cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 ## ethers-core
 
+- Change types mapping for solidity `bytes` to rust `ethers::core::Bytes` and solidity `uint8[]` to rust `Vec<u8>`.
+  [613](https://github.com/gakonst/ethers-rs/pull/613)
+- Fix `format_units` to return a `String` of representing a decimal point float
+  such that the decimal places don't get truncated.
+  [597](https://github.com/gakonst/ethers-rs/pull/597)
+
 ### Unreleased
 
 ### 0.6.0
diff --git a/Cargo.lock b/Cargo.lock
index 28e9b475..07a1e048 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -14,9 +14,9 @@ dependencies = [
 
 [[package]]
 name = "addr2line"
-version = "0.16.0"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
+checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
 dependencies = [
  "gimli",
 ]
@@ -78,9 +78,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.44"
+version = "1.0.48"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
+checksum = "62e1f47f7dc0422027a4e370dd4548d4d66b26782e513e98dca1e689e058a80e"
 
 [[package]]
 name = "arrayref"
@@ -113,13 +113,13 @@ dependencies = [
 
 [[package]]
 name = "async_io_stream"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "541b3487bf601cf3a63dfba621d6d0252611f120aaf27b198f018c0e1714f0df"
+checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c"
 dependencies = [
  "futures",
  "pharos",
- "rustc_version 0.3.3",
+ "rustc_version",
 ]
 
 [[package]]
@@ -153,9 +153,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
 [[package]]
 name = "backtrace"
-version = "0.3.61"
+version = "0.3.63"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01"
+checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6"
 dependencies = [
  "addr2line",
  "cc",
@@ -196,9 +196,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
 
 [[package]]
 name = "base64ct"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40a96587c05c810ddbb79e2674d519cff1379517e7b91d166dff7a7cc0e9af6e"
+checksum = "392c772b012d685a640cdad68a5a21f4a45e696f85a2c2c907aab2fe49a91e19"
 
 [[package]]
 name = "bech32"
@@ -320,15 +320,15 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
 
 [[package]]
 name = "bumpalo"
-version = "3.7.1"
+version = "3.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
+checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
 
 [[package]]
 name = "byte-slice-cast"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca0796d76a983651b4a0ddda16203032759f2fd9103d9181f7c65c06ee8872e6"
+checksum = "1d30c751592b77c499e7bce34d99d67c2c11bdc0574e9a488ddade14150a4698"
 
 [[package]]
 name = "byte-tools"
@@ -377,16 +377,16 @@ checksum = "ba2ae6de944143141f6155a473a6b02f66c7c3f9f47316f802f80204ebfe6e12"
 dependencies = [
  "camino",
  "cargo-platform",
- "semver 1.0.4",
+ "semver",
  "serde",
  "serde_json",
 ]
 
 [[package]]
 name = "cc"
-version = "1.0.71"
+version = "1.0.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
+checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
 
 [[package]]
 name = "ccm"
@@ -577,9 +577,9 @@ dependencies = [
 
 [[package]]
 name = "const-oid"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df"
+checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
 
 [[package]]
 name = "const-oid"
@@ -601,9 +601,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
 
 [[package]]
 name = "core-foundation"
-version = "0.9.1"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
+checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -611,9 +611,9 @@ dependencies = [
 
 [[package]]
 name = "core-foundation-sys"
-version = "0.8.2"
+version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
 [[package]]
 name = "cpufeatures"
@@ -626,9 +626,9 @@ dependencies = [
 
 [[package]]
 name = "crc32fast"
-version = "1.2.1"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+checksum = "3825b1e8580894917dc4468cb634a1b4e9745fddc854edad72d9c04644c0319f"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -641,9 +641,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
 
 [[package]]
 name = "crypto-bigint"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d12477e115c0d570c12a2dfd859f80b55b60ddb5075df210d3af06d133a69f45"
+checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03"
 dependencies = [
  "generic-array 0.14.4",
  "rand_core 0.6.3",
@@ -730,7 +730,7 @@ version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2"
 dependencies = [
- "const-oid 0.6.1",
+ "const-oid 0.6.2",
 ]
 
 [[package]]
@@ -807,9 +807,9 @@ dependencies = [
 
 [[package]]
 name = "ed25519"
-version = "1.2.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc"
+checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816"
 dependencies = [
  "signature",
 ]
@@ -840,7 +840,7 @@ version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b"
 dependencies = [
- "crypto-bigint 0.2.10",
+ "crypto-bigint 0.2.11",
  "ff",
  "generic-array 0.14.4",
  "group",
@@ -872,9 +872,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.28"
+version = "0.8.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
+checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
 dependencies = [
  "cfg-if 1.0.0",
 ]
@@ -1156,7 +1156,7 @@ dependencies = [
  "rand 0.8.4",
  "rusoto_core",
  "rusoto_kms",
- "semver 1.0.4",
+ "semver",
  "serde_json",
  "sha2 0.9.8",
  "spki",
@@ -1182,9 +1182,10 @@ dependencies = [
  "md-5",
  "once_cell",
  "regex",
- "semver 1.0.4",
+ "semver",
  "serde",
  "serde_json",
+ "sha2 0.9.8",
  "svm-rs",
  "tempdir",
  "thiserror",
@@ -1265,9 +1266,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
 
 [[package]]
 name = "futures"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
+checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1296,9 +1297,9 @@ checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
+checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -1403,9 +1404,9 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.25.0"
+version = "0.26.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
+checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
 
 [[package]]
 name = "glob"
@@ -1426,9 +1427,9 @@ dependencies = [
 
 [[package]]
 name = "h2"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c06815895acec637cd6ed6e9662c935b866d20a106f8361892893a7d9234964"
+checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55"
 dependencies = [
  "bytes",
  "fnv",
@@ -1487,9 +1488,9 @@ checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0"
 
 [[package]]
 name = "hidapi"
-version = "1.2.6"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81e07da7e8614133e88b3a93b7352eb3729e3ccd82d5ab661adf23bef1761bf8"
+checksum = "8d6f5e247bc66f3255d755e96d9d43f6b191f4e182072b811d55584ff58c510f"
 dependencies = [
  "cc",
  "libc",
@@ -1528,9 +1529,9 @@ dependencies = [
 
 [[package]]
 name = "http-body"
-version = "0.4.3"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5"
+checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
 dependencies = [
  "bytes",
  "http",
@@ -1545,15 +1546,15 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
 
 [[package]]
 name = "httpdate"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 
 [[package]]
 name = "hyper"
-version = "0.14.13"
+version = "0.14.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593"
+checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -1741,9 +1742,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.103"
+version = "0.2.108"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
+checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
 
 [[package]]
 name = "libusb1-sys"
@@ -1816,9 +1817,9 @@ dependencies = [
 
 [[package]]
 name = "mio"
-version = "0.7.13"
+version = "0.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16"
+checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
 dependencies = [
  "libc",
  "log",
@@ -1913,9 +1914,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
 
 [[package]]
 name = "object"
-version = "0.26.2"
+version = "0.27.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
+checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
 dependencies = [
  "memchr",
 ]
@@ -1940,9 +1941,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.36"
+version = "0.10.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a"
+checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
 dependencies = [
  "bitflags",
  "cfg-if 1.0.0",
@@ -1960,9 +1961,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.67"
+version = "0.9.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058"
+checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
 dependencies = [
  "autocfg",
  "cc",
@@ -2073,23 +2074,14 @@ version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 
-[[package]]
-name = "pest"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
-dependencies = [
- "ucd-trie",
-]
-
 [[package]]
 name = "pharos"
-version = "0.5.2"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "235c4b2ebc9552f5eba94ec982acb6c12f224980878e5b74a7d61806bb9c3591"
+checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414"
 dependencies = [
  "futures",
- "rustc_version 0.4.0",
+ "rustc_version",
 ]
 
 [[package]]
@@ -2136,15 +2128,15 @@ dependencies = [
 
 [[package]]
 name = "pkg-config"
-version = "0.3.20"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
+checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.10"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
 
 [[package]]
 name = "primitive-types"
@@ -2500,7 +2492,7 @@ dependencies = [
  "log",
  "rusoto_credential",
  "rusoto_signature",
- "rustc_version 0.4.0",
+ "rustc_version",
  "serde",
  "serde_json",
  "tokio",
@@ -2559,7 +2551,7 @@ dependencies = [
  "percent-encoding",
  "pin-project-lite",
  "rusoto_credential",
- "rustc_version 0.4.0",
+ "rustc_version",
  "serde",
  "sha2 0.9.8",
  "tokio",
@@ -2577,22 +2569,13 @@ version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
 
-[[package]]
-name = "rustc_version"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
-dependencies = [
- "semver 0.11.0",
-]
-
 [[package]]
 name = "rustc_version"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
 dependencies = [
- "semver 1.0.4",
+ "semver",
 ]
 
 [[package]]
@@ -2707,15 +2690,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "semver"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
-dependencies = [
- "semver-parser",
-]
-
 [[package]]
 name = "semver"
 version = "1.0.4"
@@ -2725,15 +2699,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "semver-parser"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
-dependencies = [
- "pest",
-]
-
 [[package]]
 name = "send_wrapper"
 version = "0.5.0"
@@ -2772,9 +2737,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.68"
+version = "1.0.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
+checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
 dependencies = [
  "itoa",
  "ryu",
@@ -2869,9 +2834,9 @@ dependencies = [
 
 [[package]]
 name = "signature"
-version = "1.3.1"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
+checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4"
 dependencies = [
  "digest 0.9.0",
  "rand_core 0.6.3",
@@ -2892,9 +2857,9 @@ dependencies = [
 
 [[package]]
 name = "slab"
-version = "0.4.4"
+version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
+checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
 
 [[package]]
 name = "smallvec"
@@ -2965,23 +2930,25 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
 
 [[package]]
 name = "svm-rs"
-version = "0.1.2"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389ff0db3eea702209e1127ec16e007552f3ccbae84610db6d2f66c7bda0650f"
+checksum = "3a5e16a3a87cca053bcab26e5de589ccb5779f84dda466f96eead79a98d7de7c"
 dependencies = [
  "anyhow",
  "cfg-if 1.0.0",
  "console 0.14.1",
  "dialoguer",
+ "hex",
  "home",
  "indicatif",
  "itertools",
  "once_cell",
  "rand 0.8.4",
  "reqwest",
- "semver 1.0.4",
+ "semver",
  "serde",
  "serde_json",
+ "sha2 0.9.8",
  "structopt",
  "tempfile",
  "thiserror",
@@ -2991,9 +2958,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "1.0.81"
+version = "1.0.82"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
+checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3111,9 +3078,9 @@ dependencies = [
 
 [[package]]
 name = "tinyvec"
-version = "1.5.0"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7"
+checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
 dependencies = [
  "tinyvec_macros",
 ]
@@ -3126,9 +3093,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 
 [[package]]
 name = "tokio"
-version = "1.12.0"
+version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc"
+checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
 dependencies = [
  "autocfg",
  "bytes",
@@ -3146,9 +3113,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-macros"
-version = "1.4.1"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "154794c8f499c2619acd19e839294703e9e32e7630ef5f46ea80d4ef0fbee5eb"
+checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3326,12 +3293,6 @@ version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
 
-[[package]]
-name = "ucd-trie"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
-
 [[package]]
 name = "uint"
 version = "0.9.1"
@@ -3622,7 +3583,7 @@ dependencies = [
  "futures",
  "js-sys",
  "pharos",
- "rustc_version 0.4.0",
+ "rustc_version",
  "send_wrapper",
  "thiserror",
  "wasm-bindgen",
@@ -3680,18 +3641,18 @@ dependencies = [
 
 [[package]]
 name = "zeroize"
-version = "1.4.2"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970"
+checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
 dependencies = [
  "zeroize_derive",
 ]
 
 [[package]]
 name = "zeroize_derive"
-version = "1.2.0"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7"
+checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/ethers-contract/ethers-contract-abigen/src/contract/types.rs b/ethers-contract/ethers-contract-abigen/src/contract/types.rs
index e44def58..4100c35f 100644
--- a/ethers-contract/ethers-contract-abigen/src/contract/types.rs
+++ b/ethers-contract/ethers-contract-abigen/src/contract/types.rs
@@ -8,7 +8,7 @@ pub(crate) fn expand(kind: &ParamType) -> Result<TokenStream> {
 
     match kind {
         ParamType::Address => Ok(quote! { #ethers_core::types::Address }),
-        ParamType::Bytes => Ok(quote! { Vec<u8> }),
+        ParamType::Bytes => Ok(quote! { #ethers_core::types::Bytes }),
         ParamType::Int(n) => match n / 8 {
             1 => Ok(quote! { i8 }),
             2 => Ok(quote! { i16 }),
diff --git a/ethers-contract/src/multicall/mod.rs b/ethers-contract/src/multicall/mod.rs
index 86affacc..096969d6 100644
--- a/ethers-contract/src/multicall/mod.rs
+++ b/ethers-contract/src/multicall/mod.rs
@@ -297,7 +297,7 @@ impl<M: Middleware> Multicall<M> {
             .iter()
             .zip(&return_data)
             .map(|(call, bytes)| {
-                let mut tokens: Vec<Token> = call.function.decode_output(bytes)?;
+                let mut tokens: Vec<Token> = call.function.decode_output(bytes.as_ref())?;
 
                 Ok(match tokens.len() {
                     0 => Token::Tuple(vec![]),
@@ -343,10 +343,10 @@ impl<M: Middleware> Multicall<M> {
         Ok(tx_hash)
     }
 
-    fn as_contract_call(&self) -> ContractCall<M, (U256, Vec<Vec<u8>>)> {
+    fn as_contract_call(&self) -> ContractCall<M, (U256, Vec<Bytes>)> {
         // Map the Multicall struct into appropriate types for `aggregate` function
-        let calls: Vec<(Address, Vec<u8>)> =
-            self.calls.iter().map(|call| (call.target, call.data.to_vec())).collect();
+        let calls: Vec<(Address, Bytes)> =
+            self.calls.iter().map(|call| (call.target, call.data.clone())).collect();
 
         // Construct the ContractCall for `aggregate` function to broadcast the transaction
         let mut contract_call = self.contract.aggregate(calls);
diff --git a/ethers-contract/src/multicall/multicall_contract.rs b/ethers-contract/src/multicall/multicall_contract.rs
index 87c22faa..5706736f 100644
--- a/ethers-contract/src/multicall/multicall_contract.rs
+++ b/ethers-contract/src/multicall/multicall_contract.rs
@@ -41,8 +41,8 @@ mod multicallcontract_mod {
         #[doc = "Calls the contract's `aggregate` (0x252dba42) function"]
         pub fn aggregate(
             &self,
-            calls: Vec<(Address, Vec<u8>)>,
-        ) -> ContractCall<M, (U256, Vec<Vec<u8>>)> {
+            calls: Vec<(Address, Bytes)>,
+        ) -> ContractCall<M, (U256, Vec<Bytes>)> {
             self.0
                 .method_hash([37, 45, 186, 66], calls)
                 .expect("method not found (this should never happen)")
diff --git a/ethers-core/Cargo.toml b/ethers-core/Cargo.toml
index 098bb42a..8edaf24d 100644
--- a/ethers-core/Cargo.toml
+++ b/ethers-core/Cargo.toml
@@ -36,7 +36,7 @@ cargo_metadata = { version = "0.14.1", optional = true }
 
 # eip712 feature enabled dependencies
 convert_case = { version = "0.4.0", optional = true }
-syn = { version = "1.0.81", optional = true }
+syn = { version = "1.0.82", optional = true }
 quote = { version = "1.0.9", optional = true }
 proc-macro2 = { version = "1.0.32", optional = true }
 
diff --git a/ethers-core/ethers-derive-eip712/Cargo.toml b/ethers-core/ethers-derive-eip712/Cargo.toml
index 912b9b21..ee6a1209 100644
--- a/ethers-core/ethers-derive-eip712/Cargo.toml
+++ b/ethers-core/ethers-derive-eip712/Cargo.toml
@@ -18,6 +18,6 @@ serde_json = "1.0.68"
 proc-macro2 = "1.0.29"
 
 [dev-dependencies]
-ethers-contract = { version = "^0.6.0", path = "../../ethers-contract"}
+ethers-contract = { version = "^0.6.0", path = "../../ethers-contract", features = ["abigen"]}
 ethers-contract-derive = { version = "^0.6.0", path = "../../ethers-contract/ethers-contract-derive" }
 ethers-signers = { version = "^0.6.0", path = "../../ethers-signers" }
diff --git a/ethers-core/ethers-derive-eip712/src/lib.rs b/ethers-core/ethers-derive-eip712/src/lib.rs
index 5fe9594e..f42a6cbe 100644
--- a/ethers-core/ethers-derive-eip712/src/lib.rs
+++ b/ethers-core/ethers-derive-eip712/src/lib.rs
@@ -18,7 +18,7 @@
 //!
 //! # Example Usage
 //!
-//! ```rust
+//! ```ignore
 //! use ethers_contract::EthAbiType;
 //! use ethers_derive_eip712::*;
 //! use ethers_core::types::{transaction::eip712::Eip712, H160};
@@ -50,7 +50,7 @@
 //!     project: "radicle-reward".to_string(),
 //! };
 //!
-//! let hash = puzzle.encode_eip712()?;
+//! let hash = puzzle.encode_eip712().unwrap();
 //! ```
 //!
 //! # Limitations
diff --git a/ethers-core/src/abi/mod.rs b/ethers-core/src/abi/mod.rs
index 29f60512..cc169e40 100644
--- a/ethers-core/src/abi/mod.rs
+++ b/ethers-core/src/abi/mod.rs
@@ -1,6 +1,9 @@
 //! This module implements extensions to the [`ethabi`](https://docs.rs/ethabi) API.
 // Adapted from [Gnosis' ethcontract](https://github.com/gnosis/ethcontract-rs/blob/master/common/src/abiext.rs)
-use crate::{types::Selector, utils::id};
+use crate::{
+    types::{Bytes, Selector},
+    utils::id,
+};
 
 pub use ethabi::{Contract as Abi, *};
 
@@ -117,7 +120,8 @@ macro_rules! impl_abi_type {
 }
 
 impl_abi_type!(
-    Vec<u8> => Bytes,
+    Bytes => Bytes,
+    Vec<u8> =>  Array(Box::new(ParamType::Uint(8))),
     Address => Address,
     bool => Bool,
     String => String,
@@ -231,10 +235,17 @@ mod tests {
 
     #[test]
     fn abi_type_works() {
-        assert_eq!(ParamType::Bytes, Vec::<u8>::param_type());
-        assert_eq!(ParamType::Array(Box::new(ParamType::Bytes)), Vec::<Vec<u8>>::param_type());
+        assert_eq!(ParamType::Bytes, Bytes::param_type());
+        assert_eq!(ParamType::Array(Box::new(ParamType::Uint(8))), Vec::<u8>::param_type());
+        assert_eq!(ParamType::Array(Box::new(ParamType::Bytes)), Vec::<Bytes>::param_type());
         assert_eq!(
-            ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Bytes)))),
+            ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Uint(8))))),
+            Vec::<Vec<u8>>::param_type()
+        );
+        assert_eq!(
+            ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Array(Box::new(
+                ParamType::Uint(8)
+            )))))),
             Vec::<Vec<Vec<u8>>>::param_type()
         );
 
@@ -242,7 +253,7 @@ mod tests {
 
         assert_eq!(
             ParamType::Tuple(vec![ParamType::Bytes, ParamType::Address]),
-            <(Vec<u8>, Address)>::param_type()
+            <(Bytes, Address)>::param_type()
         );
 
         assert_eq!(ParamType::FixedBytes(32), <[u8; 32]>::param_type());
diff --git a/ethers-core/src/abi/tokens.rs b/ethers-core/src/abi/tokens.rs
index b32ea32f..ca567078 100644
--- a/ethers-core/src/abi/tokens.rs
+++ b/ethers-core/src/abi/tokens.rs
@@ -287,7 +287,7 @@ macro_rules! tokenizable_item {
 
 tokenizable_item! {
     Token, String, Address, H256, U256, I256, U128, bool, Vec<u8>,
-    i8, i16, i32, i64, i128, u16, u32, u64, u128,
+    i8, i16, i32, i64, i128, u16, u32, u64, u128, Bytes,
 }
 
 macro_rules! impl_tokenizable_item_tuple {
@@ -321,12 +321,13 @@ impl Tokenizable for Vec<u8> {
     fn from_token(token: Token) -> Result<Self, InvalidOutputType> {
         match token {
             Token::Bytes(data) => Ok(data),
+            Token::Array(data) => data.into_iter().map(u8::from_token).collect(),
             Token::FixedBytes(data) => Ok(data),
             other => Err(InvalidOutputType(format!("Expected `bytes`, got {:?}", other))),
         }
     }
     fn into_token(self) -> Token {
-        Token::Bytes(self)
+        Token::Array(self.into_iter().map(Tokenizable::into_token).collect())
     }
 }
 
diff --git a/ethers-core/src/types/bytes.rs b/ethers-core/src/types/bytes.rs
index 485052d8..f2179711 100644
--- a/ethers-core/src/types/bytes.rs
+++ b/ethers-core/src/types/bytes.rs
@@ -34,6 +34,18 @@ impl From<Vec<u8>> for Bytes {
     }
 }
 
+impl<const N: usize> From<[u8; N]> for Bytes {
+    fn from(src: [u8; N]) -> Self {
+        src.to_vec().into()
+    }
+}
+
+impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
+    fn from(src: &'a [u8; N]) -> Self {
+        src.to_vec().into()
+    }
+}
+
 pub fn serialize_bytes<S, T>(x: T, s: S) -> Result<S::Ok, S::Error>
 where
     S: Serializer,
diff --git a/ethers-core/src/utils/mod.rs b/ethers-core/src/utils/mod.rs
index 0099e2e4..7b16f1a5 100644
--- a/ethers-core/src/utils/mod.rs
+++ b/ethers-core/src/utils/mod.rs
@@ -58,10 +58,25 @@ pub fn format_ether<T: Into<U256>>(amount: T) -> U256 {
 }
 
 /// Divides the provided amount with 10^{units} provided.
-pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> U256 {
+///
+/// ```
+/// use ethers_core::{types::U256, utils::format_units};
+///
+/// let eth = format_units(1395633240123456000_u128, "ether");
+/// assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
+///
+/// let eth = format_units(U256::from_dec_str("1395633240123456000").unwrap(), "ether");
+/// assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
+///
+/// let eth = format_units(U256::from_dec_str("1395633240123456789").unwrap(), "ether");
+/// assert_eq!(eth, "1.395633240123456789");
+/// ```
+pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> String {
     let units = units.into();
     let amount = amount.into();
-    amount / 10u64.pow(units.as_num())
+    let amount_decimals = amount % U256::from(10_u128.pow(units.as_num()));
+    let amount_integer = amount / U256::from(10_u128.pow(units.as_num()));
+    amount_integer.to_string() + "." + &amount_decimals.to_string()
 }
 
 /// Converts the input to a U256 and converts from Ether to Wei.
@@ -367,10 +382,19 @@ mod tests {
     #[test]
     fn test_format_units() {
         let gwei_in_ether = format_units(WEI_IN_ETHER, 9);
-        assert_eq!(gwei_in_ether.as_u64(), 1e9 as u64);
+        assert_eq!(gwei_in_ether.parse::<f64>().unwrap() as u64, 1e9 as u64);
 
         let eth = format_units(WEI_IN_ETHER, "ether");
-        assert_eq!(eth.as_u64(), 1);
+        assert_eq!(eth.parse::<f64>().unwrap() as u64, 1);
+
+        let eth = format_units(1395633240123456000_u128, "ether");
+        assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
+
+        let eth = format_units(U256::from_dec_str("1395633240123456000").unwrap(), "ether");
+        assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
+
+        let eth = format_units(U256::from_dec_str("1395633240123456789").unwrap(), "ether");
+        assert_eq!(eth, "1.395633240123456789");
     }
 
     #[test]
diff --git a/ethers-signers/Cargo.toml b/ethers-signers/Cargo.toml
index f52b7b66..0df07065 100644
--- a/ethers-signers/Cargo.toml
+++ b/ethers-signers/Cargo.toml
@@ -26,7 +26,7 @@ sha2 = { version = "0.9.8", default-features = false }
 rand = { version = "0.8.4", default-features = false }
 yubihsm = { version = "0.39.0", features = ["secp256k1", "http", "usb"], optional = true }
 futures-util = "0.3.18"
-futures-executor = "0.3.17"
+futures-executor = "0.3.18"
 semver = "1.0.4"
 
 # aws
diff --git a/ethers-solc/Cargo.toml b/ethers-solc/Cargo.toml
index 478861fa..828c0c2a 100644
--- a/ethers-solc/Cargo.toml
+++ b/ethers-solc/Cargo.toml
@@ -24,10 +24,11 @@ futures-util = { version = "0.3.18", optional = true }
 once_cell = "1.8.0"
 regex = "1.5.4"
 md-5 = "0.9.1"
+sha2 = "0.9.8"
 thiserror = "1.0.30"
 hex = "0.4.3"
 colored = "2.0.0"
-svm = { package = "svm-rs", version = "0.1.2", optional = true }
+svm = { package = "svm-rs", version = "0.2.0", optional = true }
 glob = "0.3.0"
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
diff --git a/ethers-solc/src/compile.rs b/ethers-solc/src/compile.rs
index 4a2bc2f5..5b652acd 100644
--- a/ethers-solc/src/compile.rs
+++ b/ethers-solc/src/compile.rs
@@ -46,16 +46,20 @@ static LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
 #[cfg(all(feature = "svm", feature = "async"))]
 /// A list of upstream Solc releases, used to check which version
 /// we should download.
-pub static RELEASES: Lazy<Vec<Version>> = Lazy::new(|| {
+pub static RELEASES: Lazy<(svm::Releases, Vec<Version>)> = Lazy::new(|| {
     // Try to download the releases, if it fails default to empty
     match tokio::runtime::Runtime::new()
         .expect("could not create tokio rt to get remote releases")
         // TODO: Can we make this future timeout at a small time amount so that
         // we do not degrade startup performance if the consumer has a weak network?
-        .block_on(svm::all_versions())
+        .block_on(svm::all_releases(svm::platform()))
     {
-        Ok(inner) => inner,
-        Err(_) => Vec::new(),
+        Ok(releases) => {
+            let mut sorted_releases = releases.releases.keys().cloned().collect::<Vec<Version>>();
+            sorted_releases.sort();
+            (releases, sorted_releases)
+        }
+        Err(_) => (svm::Releases::default(), Vec::new()),
     }
 });
 
@@ -162,7 +166,7 @@ impl Solc {
         // load the local / remote versions
         let versions = svm::installed_versions().unwrap_or_default();
         let local_versions = Self::find_matching_installation(&versions, &sol_version);
-        let remote_versions = Self::find_matching_installation(&RELEASES, &sol_version);
+        let remote_versions = Self::find_matching_installation(&RELEASES.1, &sol_version);
 
         // if there's a better upstream version than the one we have, install it
         Ok(match (local_versions, remote_versions) {
@@ -225,6 +229,29 @@ impl Solc {
         Ok(())
     }
 
+    /// Verify that the checksum for this version of solc is correct. We check against the SHA256
+    /// checksum from the build information published by binaries.soliditylang
+    #[cfg(all(feature = "svm", feature = "async"))]
+    pub fn verify_checksum(&self) -> Result<()> {
+        let version = self.version_short()?;
+        let mut version_path = svm::version_path(version.to_string().as_str());
+        version_path.push(format!("solc-{}", version.to_string().as_str()));
+        let content = std::fs::read(version_path)?;
+
+        use sha2::Digest;
+        let mut hasher = sha2::Sha256::new();
+        hasher.update(&content);
+        let checksum_calc = &hasher.finalize()[..];
+
+        let checksum_found = &RELEASES.0.get_checksum(&version).expect("checksum not found");
+
+        if checksum_calc == checksum_found {
+            Ok(())
+        } else {
+            Err(SolcError::ChecksumMismatch)
+        }
+    }
+
     /// Convenience function for compiling all sources under the given path
     pub fn compile_source(&self, path: impl AsRef<Path>) -> Result<CompilerOutput> {
         self.compile(&CompilerInput::new(path)?)
@@ -271,6 +298,11 @@ impl Solc {
         compile_output(child.wait_with_output()?)
     }
 
+    pub fn version_short(&self) -> Result<Version> {
+        let version = self.version()?;
+        Ok(Version::new(version.major, version.minor, version.patch))
+    }
+
     /// Returns the version from the configured `solc`
     pub fn version(&self) -> Result<Version> {
         version_from_output(
diff --git a/ethers-solc/src/error.rs b/ethers-solc/src/error.rs
index 509839c8..86094921 100644
--- a/ethers-solc/src/error.rs
+++ b/ethers-solc/src/error.rs
@@ -12,6 +12,8 @@ pub enum SolcError {
     PragmaNotFound,
     #[error("could not find solc version locally or upstream")]
     VersionNotFound,
+    #[error("checksum mismatch")]
+    ChecksumMismatch,
     #[error(transparent)]
     SemverError(#[from] semver::Error),
     /// Deserialization error
diff --git a/ethers-solc/src/lib.rs b/ethers-solc/src/lib.rs
index a2b7033a..d678521b 100644
--- a/ethers-solc/src/lib.rs
+++ b/ethers-solc/src/lib.rs
@@ -183,6 +183,9 @@ impl<Artifacts: ArtifactOutput> Project<Artifacts> {
     fn svm_compile(&self, sources: Sources) -> Result<ProjectCompileOutput<Artifacts>> {
         // split them by version
         let mut sources_by_version = BTreeMap::new();
+        // we store the solc versions by path, in case there exists a corrupt solc binary
+        let mut solc_versions = HashMap::new();
+
         for (path, source) in sources.into_iter() {
             // will detect and install the solc version
             let version = Solc::detect_version(&source)?;
@@ -194,8 +197,9 @@ impl<Artifacts: ArtifactOutput> Project<Artifacts> {
             if !self.allowed_lib_paths.0.is_empty() {
                 solc = solc.arg("--allow-paths").arg(self.allowed_lib_paths.to_string());
             }
+            solc_versions.insert(solc.solc.clone(), version);
             let entry = sources_by_version.entry(solc).or_insert_with(BTreeMap::new);
-            entry.insert(path, source);
+            entry.insert(path.clone(), source);
         }
 
         let mut compiled =
@@ -203,6 +207,13 @@ impl<Artifacts: ArtifactOutput> Project<Artifacts> {
 
         // run the compilation step for each version
         for (solc, sources) in sources_by_version {
+            // verify that this solc version's checksum matches the checksum found remotely. If
+            // not, re-install the same version.
+            let version = solc_versions.get(&solc.solc).unwrap();
+            if let Err(_e) = solc.verify_checksum() {
+                Solc::blocking_install(version)?;
+            }
+            // once matched, proceed to compile with it
             compiled.extend(self.compile_with_version(&solc, sources)?);
         }
         if !compiled.has_compiled_contracts() &&


Test patch:
diff --git a/ethers-contract/tests/contract.rs b/ethers-contract/tests/contract.rs
index 606a5f34..8748af2b 100644
--- a/ethers-contract/tests/contract.rs
+++ b/ethers-contract/tests/contract.rs
@@ -9,7 +9,7 @@ mod eth_tests {
     use super::*;
     use ethers_contract::{LogMeta, Multicall};
     use ethers_core::{
-        types::{transaction::eip712::Eip712, Address, BlockId, I256, U256},
+        types::{transaction::eip712::Eip712, Address, BlockId, Bytes, I256, U256},
         utils::{keccak256, Ganache},
     };
     use ethers_derive_eip712::*;
@@ -525,7 +525,7 @@ mod eth_tests {
         struct FooBar {
             foo: I256,
             bar: U256,
-            fizz: Vec<u8>,
+            fizz: Bytes,
             buzz: [u8; 32],
             far: String,
             out: Address,
@@ -563,7 +563,7 @@ mod eth_tests {
         let foo_bar = FooBar {
             foo: I256::from(10),
             bar: U256::from(20),
-            fizz: b"fizz".to_vec(),
+            fizz: b"fizz".into(),
             buzz: keccak256("buzz"),
             far: String::from("space"),
             out: Address::from([0; 20]),