├── .cargo └── config ├── .github └── workflows │ ├── benchmark.yml │ └── rust.yml ├── .gitignore ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── benchmark ├── erc1155_benchmark │ ├── .gas-snapshot │ ├── Cargo.lock │ ├── Cargo.toml │ ├── snapshot.py │ └── src │ │ └── lib.rs ├── erc20_benchmark │ ├── .gas-snapshot │ ├── Cargo.lock │ ├── Cargo.toml │ ├── snapshot.py │ └── src │ │ └── lib.rs ├── erc6909_benchmark │ ├── .gas-snapshot │ ├── Cargo.lock │ ├── Cargo.toml │ ├── snapshot.py │ └── src │ │ └── lib.rs └── erc721_benchmark │ ├── .gas-snapshot │ ├── Cargo.lock │ ├── Cargo.toml │ ├── snapshot.py │ └── src │ └── lib.rs ├── rustfmt.toml └── src ├── auth ├── auth.rs ├── mod.rs └── owned.rs ├── lib.rs ├── mixins ├── erc4626.rs └── mod.rs ├── tokens ├── erc1155.rs ├── erc20.rs ├── erc6909.rs ├── erc721.rs ├── mod.rs └── weth.rs └── utils ├── bytes32address.rs ├── create3.rs └── mod.rs /.cargo/config: -------------------------------------------------------------------------------- 1 | [target.wasm32-unknown-unknown] 2 | rustflags = [ 3 | "-C", "link-arg=-zstack-size=32768", 4 | ] 5 | 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | 12 | [target.x86_64-apple-darwin] 13 | rustflags = [ 14 | "-C", "link-arg=-undefined", 15 | "-C", "link-arg=dynamic_lookup", 16 | ] 17 | 18 | [profile.release] 19 | codegen-units = 1 # prefer efficiency to compile time 20 | panic = "abort" # use simple panics 21 | opt-level = "z" # optimize for size 22 | strip = true # remove debug info 23 | lto = true # link time optimization 24 | debug = false # no debug data 25 | rpath = false # no run-time search path 26 | debug-assertions = false # prune debug assertions 27 | incremental = false # no incremental builds -------------------------------------------------------------------------------- /.github/workflows/benchmark.yml: -------------------------------------------------------------------------------- 1 | name: benchmark 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | check: 11 | strategy: 12 | fail-fast: true 13 | 14 | name: Run benchmarks 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout repository content 18 | uses: actions/checkout@v4 19 | id: repo 20 | 21 | - name: Install Rust 22 | uses: actions-rs/toolchain@v1 23 | with: 24 | profile: minimal 25 | toolchain: nightly 26 | override: true 27 | components: rust-src 28 | target: wasm32-unknown-unknown 29 | id: rust 30 | 31 | - name: Set up cargo cache 32 | uses: actions/cache@v3 33 | continue-on-error: false 34 | with: 35 | path: | 36 | ~/.cargo/bin/ 37 | ~/.cargo/registry/index/ 38 | ~/.cargo/registry/cache/ 39 | ~/.cargo/git/db/ 40 | target/ 41 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 42 | restore-keys: ${{ runner.os }}-cargo- 43 | 44 | - name: Install Stylus CLI 45 | run: | 46 | cargo install --locked cargo-stylus || true 47 | id: stylus 48 | 49 | - name: Install Foundry 50 | uses: foundry-rs/foundry-toolchain@v1 51 | id: foundry 52 | 53 | - name: Clone test node 54 | uses: actions/checkout@v4 55 | with: 56 | repository: OffchainLabs/nitro-testnode 57 | path: nitro-testnode 58 | ref: stylus 59 | submodules: recursive 60 | token: ${{ github.token }} 61 | id: get-node 62 | 63 | - name: Install docker-compose 64 | run: | 65 | sudo curl -L https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 66 | sudo chmod +x /usr/local/bin/docker-compose 67 | id: docker-compose 68 | 69 | - name: Run node 70 | working-directory: ./nitro-testnode 71 | run: | 72 | ./test-node.bash --init --detach 73 | id: run-node 74 | 75 | - name: Fund deployer 76 | working-directory: ./nitro-testnode 77 | run: | 78 | ./test-node.bash script send-l2 --to address_0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 --ethamount 100 79 | id: fund-deployer 80 | 81 | - name: Setup Python 82 | uses: deadsnakes/action@v2.1.1 83 | with: 84 | python-version: "3.10" 85 | id: python 86 | 87 | - name: Run ERC20 benchmark 88 | working-directory: ./benchmark/erc20_benchmark 89 | run: python snapshot.py 90 | id: erc20 91 | 92 | - name: Run ERC721 benchmark 93 | working-directory: ./benchmark/erc721_benchmark 94 | run: python snapshot.py 95 | id: erc721 96 | 97 | - name: Run ERC1155 benchmark 98 | working-directory: ./benchmark/erc1155_benchmark 99 | run: python snapshot.py 100 | id: erc1155 101 | 102 | - name: Run ERC6909 benchmark 103 | working-directory: ./benchmark/erc6909_benchmark 104 | run: python snapshot.py 105 | id: erc6909 -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: rust 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Build 19 | run: cargo build --verbose 20 | - name: Run tests 21 | run: cargo test --verbose --all-features 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | target/ 5 | 6 | # Ignores development broadcast logs 7 | !/broadcast 8 | /broadcast/*/31337/ 9 | /broadcast/**/dry-run/ 10 | 11 | # Docs 12 | docs/ 13 | 14 | # Dotenv file 15 | .env 16 | 17 | # Other 18 | .DS_Store -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 🫡 Contributing 2 | 3 | 🙏 Thank you so much for your interest in the project! There are many ways to get involved at every level. 4 | 5 | **No contribution is too small and all contributions are highly appreciated.** 6 | 7 | We particularly welcome support in the following areas: 8 | 9 | - [Reporting issues](https://github.com/cairoeth/rustmate/issues/new). 10 | - Fixing and responding to [existing issues](https://github.com/cairoeth/rustmate/issues). 11 | - Proposing changes and/or [new features](https://github.com/cairoeth/rustmate/issues). We are mainly working on gas optimizations and implementation/ERC support. 12 | - Implementing changes and/or new features. 13 | - Improving documentation and fixing typos. 14 | 15 | ## 🙋‍♀️ Opening an Issue 16 | 17 | If you encounter a bug or want to suggest a feature, you are welcome to [open an issue](https://github.com/cairoeth/rustmate/issues/new). Before opening an issue, please review the existing open and closed issues. 18 | 19 | When you propose a new feature, you should provide as much detail as possible, especially on the use cases that motivate it. Features are prioritised by their potential impact on the ecosystem, so we value information that shows the impact could be high. 20 | 21 | ## 🛠 Submitting a Pull Request (PR) 22 | 23 | As a contributor, you are expected to fork the `main` branch of this repository, work on your own fork, and then submit pull requests. The pull requests are reviewed and eventually merged into the `main` repository. See ["Fork-a-Repo"](https://help.github.com/articles/fork-a-repo) for how this works. 24 | 25 | ## 🤝 How to get started 26 | 27 | Follow [these steps in the README](https://github.com/cairoeth/rustmate#-how-to-replicate) to get started locally. -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "alloy-primitives" 16 | version = "0.3.3" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" 19 | dependencies = [ 20 | "alloy-rlp", 21 | "bytes", 22 | "cfg-if 1.0.0", 23 | "const-hex", 24 | "derive_more", 25 | "hex-literal", 26 | "itoa", 27 | "proptest", 28 | "ruint", 29 | "serde", 30 | "tiny-keccak", 31 | ] 32 | 33 | [[package]] 34 | name = "alloy-rlp" 35 | version = "0.3.3" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" 38 | dependencies = [ 39 | "arrayvec", 40 | "bytes", 41 | "smol_str", 42 | ] 43 | 44 | [[package]] 45 | name = "alloy-sol-macro" 46 | version = "0.3.1" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "a74ceeffdacf9dd0910404d743d07273776fd17b85f9cb17b49a97e5c6055ce9" 49 | dependencies = [ 50 | "dunce", 51 | "heck", 52 | "proc-macro2", 53 | "quote", 54 | "syn 2.0.38", 55 | "syn-solidity", 56 | "tiny-keccak", 57 | ] 58 | 59 | [[package]] 60 | name = "alloy-sol-types" 61 | version = "0.3.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "d5f347cb6bb307b3802ec455ef43ce00f5e590e0ceca3d2f3b070f5ee367e235" 64 | dependencies = [ 65 | "alloy-primitives", 66 | "alloy-sol-macro", 67 | "const-hex", 68 | "serde", 69 | ] 70 | 71 | [[package]] 72 | name = "arrayvec" 73 | version = "0.7.4" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 76 | 77 | [[package]] 78 | name = "autocfg" 79 | version = "1.1.0" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 82 | 83 | [[package]] 84 | name = "bit-set" 85 | version = "0.5.3" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 88 | dependencies = [ 89 | "bit-vec", 90 | ] 91 | 92 | [[package]] 93 | name = "bit-vec" 94 | version = "0.6.3" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 97 | 98 | [[package]] 99 | name = "bitflags" 100 | version = "1.3.2" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 103 | 104 | [[package]] 105 | name = "bitflags" 106 | version = "2.4.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" 109 | 110 | [[package]] 111 | name = "block-buffer" 112 | version = "0.10.4" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 115 | dependencies = [ 116 | "generic-array", 117 | ] 118 | 119 | [[package]] 120 | name = "bytes" 121 | version = "1.5.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 124 | 125 | [[package]] 126 | name = "cfg-if" 127 | version = "0.1.10" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 130 | 131 | [[package]] 132 | name = "cfg-if" 133 | version = "1.0.0" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 136 | 137 | [[package]] 138 | name = "const-hex" 139 | version = "1.9.1" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "c37be52ef5e3b394db27a2341010685ad5103c72ac15ce2e9420a7e8f93f342c" 142 | dependencies = [ 143 | "cfg-if 1.0.0", 144 | "cpufeatures", 145 | "hex", 146 | "serde", 147 | ] 148 | 149 | [[package]] 150 | name = "convert_case" 151 | version = "0.4.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 154 | 155 | [[package]] 156 | name = "convert_case" 157 | version = "0.6.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 160 | dependencies = [ 161 | "unicode-segmentation", 162 | ] 163 | 164 | [[package]] 165 | name = "cpufeatures" 166 | version = "0.2.9" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 169 | dependencies = [ 170 | "libc", 171 | ] 172 | 173 | [[package]] 174 | name = "crunchy" 175 | version = "0.2.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 178 | 179 | [[package]] 180 | name = "crypto-common" 181 | version = "0.1.6" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 184 | dependencies = [ 185 | "generic-array", 186 | "typenum", 187 | ] 188 | 189 | [[package]] 190 | name = "derivative" 191 | version = "2.2.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 194 | dependencies = [ 195 | "proc-macro2", 196 | "quote", 197 | "syn 1.0.109", 198 | ] 199 | 200 | [[package]] 201 | name = "derive_more" 202 | version = "0.99.17" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 205 | dependencies = [ 206 | "convert_case 0.4.0", 207 | "proc-macro2", 208 | "quote", 209 | "rustc_version", 210 | "syn 1.0.109", 211 | ] 212 | 213 | [[package]] 214 | name = "digest" 215 | version = "0.10.7" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 218 | dependencies = [ 219 | "block-buffer", 220 | "crypto-common", 221 | ] 222 | 223 | [[package]] 224 | name = "dunce" 225 | version = "1.0.4" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 228 | 229 | [[package]] 230 | name = "errno" 231 | version = "0.3.5" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" 234 | dependencies = [ 235 | "libc", 236 | "windows-sys", 237 | ] 238 | 239 | [[package]] 240 | name = "fastrand" 241 | version = "2.0.1" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 244 | 245 | [[package]] 246 | name = "fnv" 247 | version = "1.0.7" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 250 | 251 | [[package]] 252 | name = "generic-array" 253 | version = "0.14.7" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 256 | dependencies = [ 257 | "typenum", 258 | "version_check", 259 | ] 260 | 261 | [[package]] 262 | name = "getrandom" 263 | version = "0.2.10" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 266 | dependencies = [ 267 | "cfg-if 1.0.0", 268 | "libc", 269 | "wasi", 270 | ] 271 | 272 | [[package]] 273 | name = "heck" 274 | version = "0.4.1" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 277 | 278 | [[package]] 279 | name = "hex" 280 | version = "0.4.3" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 283 | 284 | [[package]] 285 | name = "hex-literal" 286 | version = "0.4.1" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 289 | 290 | [[package]] 291 | name = "itoa" 292 | version = "1.0.9" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 295 | 296 | [[package]] 297 | name = "keccak" 298 | version = "0.1.4" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" 301 | dependencies = [ 302 | "cpufeatures", 303 | ] 304 | 305 | [[package]] 306 | name = "keccak-const" 307 | version = "0.2.0" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "57d8d8ce877200136358e0bbff3a77965875db3af755a11e1fa6b1b3e2df13ea" 310 | 311 | [[package]] 312 | name = "lazy_static" 313 | version = "1.4.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 316 | 317 | [[package]] 318 | name = "libc" 319 | version = "0.2.149" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" 322 | 323 | [[package]] 324 | name = "libm" 325 | version = "0.2.8" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 328 | 329 | [[package]] 330 | name = "linux-raw-sys" 331 | version = "0.4.10" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" 334 | 335 | [[package]] 336 | name = "memchr" 337 | version = "2.6.4" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" 340 | 341 | [[package]] 342 | name = "memory_units" 343 | version = "0.4.0" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" 346 | 347 | [[package]] 348 | name = "num-traits" 349 | version = "0.2.17" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 352 | dependencies = [ 353 | "autocfg", 354 | "libm", 355 | ] 356 | 357 | [[package]] 358 | name = "ppv-lite86" 359 | version = "0.2.17" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 362 | 363 | [[package]] 364 | name = "proc-macro2" 365 | version = "1.0.69" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" 368 | dependencies = [ 369 | "unicode-ident", 370 | ] 371 | 372 | [[package]] 373 | name = "proptest" 374 | version = "1.3.1" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" 377 | dependencies = [ 378 | "bit-set", 379 | "bit-vec", 380 | "bitflags 2.4.0", 381 | "lazy_static", 382 | "num-traits", 383 | "rand", 384 | "rand_chacha", 385 | "rand_xorshift", 386 | "regex-syntax", 387 | "rusty-fork", 388 | "tempfile", 389 | "unarray", 390 | ] 391 | 392 | [[package]] 393 | name = "quick-error" 394 | version = "1.2.3" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 397 | 398 | [[package]] 399 | name = "quote" 400 | version = "1.0.33" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 403 | dependencies = [ 404 | "proc-macro2", 405 | ] 406 | 407 | [[package]] 408 | name = "rand" 409 | version = "0.8.5" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 412 | dependencies = [ 413 | "libc", 414 | "rand_chacha", 415 | "rand_core", 416 | ] 417 | 418 | [[package]] 419 | name = "rand_chacha" 420 | version = "0.3.1" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 423 | dependencies = [ 424 | "ppv-lite86", 425 | "rand_core", 426 | ] 427 | 428 | [[package]] 429 | name = "rand_core" 430 | version = "0.6.4" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 433 | dependencies = [ 434 | "getrandom", 435 | ] 436 | 437 | [[package]] 438 | name = "rand_xorshift" 439 | version = "0.3.0" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" 442 | dependencies = [ 443 | "rand_core", 444 | ] 445 | 446 | [[package]] 447 | name = "redox_syscall" 448 | version = "0.3.5" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 451 | dependencies = [ 452 | "bitflags 1.3.2", 453 | ] 454 | 455 | [[package]] 456 | name = "regex" 457 | version = "1.9.6" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" 460 | dependencies = [ 461 | "aho-corasick", 462 | "memchr", 463 | "regex-automata", 464 | "regex-syntax", 465 | ] 466 | 467 | [[package]] 468 | name = "regex-automata" 469 | version = "0.3.9" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" 472 | dependencies = [ 473 | "aho-corasick", 474 | "memchr", 475 | "regex-syntax", 476 | ] 477 | 478 | [[package]] 479 | name = "regex-syntax" 480 | version = "0.7.5" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" 483 | 484 | [[package]] 485 | name = "ruint" 486 | version = "1.10.1" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "95294d6e3a6192f3aabf91c38f56505a625aa495533442744185a36d75a790c4" 489 | dependencies = [ 490 | "proptest", 491 | "rand", 492 | "ruint-macro", 493 | "serde", 494 | "valuable", 495 | "zeroize", 496 | ] 497 | 498 | [[package]] 499 | name = "ruint-macro" 500 | version = "1.1.0" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" 503 | 504 | [[package]] 505 | name = "rustc_version" 506 | version = "0.4.0" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 509 | dependencies = [ 510 | "semver", 511 | ] 512 | 513 | [[package]] 514 | name = "rustix" 515 | version = "0.38.17" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "f25469e9ae0f3d0047ca8b93fc56843f38e6774f0914a107ff8b41be8be8e0b7" 518 | dependencies = [ 519 | "bitflags 2.4.0", 520 | "errno", 521 | "libc", 522 | "linux-raw-sys", 523 | "windows-sys", 524 | ] 525 | 526 | [[package]] 527 | name = "rustmate" 528 | version = "0.1.0" 529 | dependencies = [ 530 | "alloy-primitives", 531 | "alloy-sol-types", 532 | "stylus-sdk", 533 | "wee_alloc", 534 | ] 535 | 536 | [[package]] 537 | name = "rusty-fork" 538 | version = "0.3.0" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" 541 | dependencies = [ 542 | "fnv", 543 | "quick-error", 544 | "tempfile", 545 | "wait-timeout", 546 | ] 547 | 548 | [[package]] 549 | name = "semver" 550 | version = "1.0.19" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" 553 | 554 | [[package]] 555 | name = "serde" 556 | version = "1.0.188" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 559 | dependencies = [ 560 | "serde_derive", 561 | ] 562 | 563 | [[package]] 564 | name = "serde_derive" 565 | version = "1.0.188" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 568 | dependencies = [ 569 | "proc-macro2", 570 | "quote", 571 | "syn 2.0.38", 572 | ] 573 | 574 | [[package]] 575 | name = "sha3" 576 | version = "0.10.8" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 579 | dependencies = [ 580 | "digest", 581 | "keccak", 582 | ] 583 | 584 | [[package]] 585 | name = "smol_str" 586 | version = "0.2.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" 589 | dependencies = [ 590 | "serde", 591 | ] 592 | 593 | [[package]] 594 | name = "stylus-proc" 595 | version = "0.4.1" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "87a941ef748a746cd7b7075975073962d561934ffe91c056e22e20c8e89b64af" 598 | dependencies = [ 599 | "alloy-primitives", 600 | "alloy-sol-types", 601 | "cfg-if 1.0.0", 602 | "convert_case 0.6.0", 603 | "lazy_static", 604 | "proc-macro2", 605 | "quote", 606 | "regex", 607 | "sha3", 608 | "syn 1.0.109", 609 | "syn-solidity", 610 | ] 611 | 612 | [[package]] 613 | name = "stylus-sdk" 614 | version = "0.4.2" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "12c2d6fedbd0393e2b9f0259ca239c7ede9f87a89933627119b9dc038902d7e9" 617 | dependencies = [ 618 | "alloy-primitives", 619 | "alloy-sol-types", 620 | "cfg-if 1.0.0", 621 | "derivative", 622 | "fnv", 623 | "hex", 624 | "keccak-const", 625 | "lazy_static", 626 | "regex", 627 | "stylus-proc", 628 | ] 629 | 630 | [[package]] 631 | name = "syn" 632 | version = "1.0.109" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 635 | dependencies = [ 636 | "proc-macro2", 637 | "quote", 638 | "unicode-ident", 639 | ] 640 | 641 | [[package]] 642 | name = "syn" 643 | version = "2.0.38" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" 646 | dependencies = [ 647 | "proc-macro2", 648 | "quote", 649 | "unicode-ident", 650 | ] 651 | 652 | [[package]] 653 | name = "syn-solidity" 654 | version = "0.3.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "e5f995d2140b0f751dbe94365be2591edbf3d1b75dcfaeac14183abbd2ff07bd" 657 | dependencies = [ 658 | "proc-macro2", 659 | "quote", 660 | "syn 2.0.38", 661 | ] 662 | 663 | [[package]] 664 | name = "tempfile" 665 | version = "3.8.0" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" 668 | dependencies = [ 669 | "cfg-if 1.0.0", 670 | "fastrand", 671 | "redox_syscall", 672 | "rustix", 673 | "windows-sys", 674 | ] 675 | 676 | [[package]] 677 | name = "tiny-keccak" 678 | version = "2.0.2" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 681 | dependencies = [ 682 | "crunchy", 683 | ] 684 | 685 | [[package]] 686 | name = "typenum" 687 | version = "1.17.0" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 690 | 691 | [[package]] 692 | name = "unarray" 693 | version = "0.1.4" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" 696 | 697 | [[package]] 698 | name = "unicode-ident" 699 | version = "1.0.12" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 702 | 703 | [[package]] 704 | name = "unicode-segmentation" 705 | version = "1.10.1" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 708 | 709 | [[package]] 710 | name = "valuable" 711 | version = "0.1.0" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 714 | 715 | [[package]] 716 | name = "version_check" 717 | version = "0.9.4" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 720 | 721 | [[package]] 722 | name = "wait-timeout" 723 | version = "0.2.0" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 726 | dependencies = [ 727 | "libc", 728 | ] 729 | 730 | [[package]] 731 | name = "wasi" 732 | version = "0.11.0+wasi-snapshot-preview1" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 735 | 736 | [[package]] 737 | name = "wee_alloc" 738 | version = "0.4.5" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" 741 | dependencies = [ 742 | "cfg-if 0.1.10", 743 | "libc", 744 | "memory_units", 745 | "winapi", 746 | ] 747 | 748 | [[package]] 749 | name = "winapi" 750 | version = "0.3.9" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 753 | dependencies = [ 754 | "winapi-i686-pc-windows-gnu", 755 | "winapi-x86_64-pc-windows-gnu", 756 | ] 757 | 758 | [[package]] 759 | name = "winapi-i686-pc-windows-gnu" 760 | version = "0.4.0" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 763 | 764 | [[package]] 765 | name = "winapi-x86_64-pc-windows-gnu" 766 | version = "0.4.0" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 769 | 770 | [[package]] 771 | name = "windows-sys" 772 | version = "0.48.0" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 775 | dependencies = [ 776 | "windows-targets", 777 | ] 778 | 779 | [[package]] 780 | name = "windows-targets" 781 | version = "0.48.5" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 784 | dependencies = [ 785 | "windows_aarch64_gnullvm", 786 | "windows_aarch64_msvc", 787 | "windows_i686_gnu", 788 | "windows_i686_msvc", 789 | "windows_x86_64_gnu", 790 | "windows_x86_64_gnullvm", 791 | "windows_x86_64_msvc", 792 | ] 793 | 794 | [[package]] 795 | name = "windows_aarch64_gnullvm" 796 | version = "0.48.5" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 799 | 800 | [[package]] 801 | name = "windows_aarch64_msvc" 802 | version = "0.48.5" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 805 | 806 | [[package]] 807 | name = "windows_i686_gnu" 808 | version = "0.48.5" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 811 | 812 | [[package]] 813 | name = "windows_i686_msvc" 814 | version = "0.48.5" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 817 | 818 | [[package]] 819 | name = "windows_x86_64_gnu" 820 | version = "0.48.5" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 823 | 824 | [[package]] 825 | name = "windows_x86_64_gnullvm" 826 | version = "0.48.5" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 829 | 830 | [[package]] 831 | name = "windows_x86_64_msvc" 832 | version = "0.48.5" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 835 | 836 | [[package]] 837 | name = "zeroize" 838 | version = "1.6.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" 841 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustmate" 3 | version = "0.1.0" 4 | edition = "2021" 5 | license = "AGPL-3.0" 6 | homepage = "https://github.com/cairoeth/rustmate" 7 | repository = "https://github.com/cairoeth/rustmate" 8 | keywords = ["arbitrum", "ethereum", "stylus", "alloy", "rust"] 9 | description = "Blazing fast, modern, and optimized Rust building blocks for smart contract development using Stylus." 10 | readme = "README.md" 11 | 12 | [dependencies] 13 | alloy-primitives = "0.3.1" 14 | alloy-sol-types = "0.3.1" 15 | stylus-sdk = "0.4.2" 16 | wee_alloc = "0.4.5" 17 | 18 | [features] 19 | export-abi = ["stylus-sdk/export-abi"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🦀 rustmate 2 | 3 | [![Run benchmarks](https://github.com/cairoeth/rustmate/actions/workflows/benchmark.yml/badge.svg)](https://github.com/cairoeth/rustmate/actions/workflows/benchmark.yml) 4 | [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) 5 | 6 | **Blazing fast**, **modern**, and **optimized** Rust building blocks for smart contract development using Stylus. 7 | 8 | > This is **experimental software** and is provided on an "as is" and "as available" basis. We **do not give any warranties** and **will not be liable for any losses** incurred through any use of this code base. 9 | 10 | ## 📜 Contracts 11 | 12 | ```ml 13 | auth 14 | ├─ Owned — "Simple single owner authorization" 15 | ├─ Auth — "Flexible and updatable auth pattern" 16 | mixins 17 | ├─ ERC4626 — "Minimal ERC4626 tokenized Vault implementation" 18 | tokens 19 | ├─ WETH — "Minimalist and modern Wrapped Ether implementation" 20 | ├─ ERC20 — "Modern and gas efficient ERC20 + EIP-2612 implementation" 21 | ├─ ERC721 — "Modern, minimalist, and gas efficient ERC721 implementation" 22 | ├─ ERC1155 — "Minimalist and gas efficient standard ERC1155 implementation" 23 | ├─ ERC6909 — "Minimalist and gas efficient standard ERC6909 implementation" 24 | utils 25 | ├─ CREATE3 — "Deploy to deterministic addresses without an initcode factor" 26 | ├─ Bytes32Address — "Library for converting between addresses and bytes32 values" 27 | ``` 28 | 29 | ## 🔧 How to use 30 | 31 | First, install the [Stylus SDK for Rust](https://docs.arbitrum.io/stylus/stylus-quickstart) and create a new project: 32 | 33 | ```bash 34 | cargo stylus new my-project --minimal 35 | ``` 36 | 37 | Then, install `rustmate`: 38 | 39 | ```bash 40 | cargo add rustmate 41 | ``` 42 | 43 | Import the contracts you want to use: 44 | 45 | ```rust 46 | use rustmate::tokens::erc20::{ERC20, ERC20Params}; 47 | ``` 48 | 49 | ## ✅ Gas benchmarks 50 | 51 | ### 🧪 Results 52 | 53 |
ERC20 54 | 55 | | Function | Rustmate | Solmate | OpenZeppelin Contracts 5.0 | 56 | |:--------------:|:--------:|:-------:|:--------------------------:| 57 | | name() | 23043 | 24504 | 24514 | 58 | | symbol() | 22974 | 24571 | 24535 | 59 | | decimals() | 22726 | 21512 | 21520 | 60 | | totalSupply() | 25617 | 23562 | 23570 | 61 | | balanceOf() | 26851 | 24292 | 24296 | 62 | | allowance() | 28263 | 25011 | 25066 | 63 | | nonces() | 26835 | 24302 | N/A | 64 | | approve() | 50557 | 46683 | 46902 | 65 | | transfer() | 74234 | 47133 | 27454 | 66 | | transferFrom() | 60116 | 28993 | 29202 | 67 | 68 |
69 | 70 |
ERC721 71 | 72 | | Function | Rustmate | Solmate | OpenZeppelin Contracts 5.0 | 73 | |:-------------------:|:--------:|:-------:|:--------------------------:| 74 | | name() | 23286 | 24548 | 24556 | 75 | | symbol() | 23225 | 24548 | 24556 | 76 | | ownerOf() | 24212 | 24212 | 24308 | 77 | | balanceOf() | 27094 | 24352 | 24352 | 78 | | getApproved() | 26749 | 24132 | 26545 | 79 | | isApprovedForAll() | 28447 | 25046 | 25104 | 80 | | tokenURI() | 24293 | 23420 | 23420 | 81 | | approve() | 48639 | 48693 | 49043 | 82 | | setApprovalForAll() | 51279 | 46561 | 46669 | 83 | | transferFrom() | 32777 | 32437 | 32947 | 84 | | safeTransferFrom() | 32781 | 32643 | 31264 | 85 | | safeTransferFrom() | 33146 | 33140 | 34139 | 86 | | supportsInterface() | 21983 | 21983 | 21960 | 87 | 88 |
89 | 90 |
ERC1155 91 | 92 | | Function | Rustmate | Solmate | OpenZeppelin Contracts 5.0 | 93 | |:-----------------------:|:--------:|:-------:|:--------------------------:| 94 | | balanceOf() | 28390 | 24631 | 24675 | 95 | | isApprovedForAll() | 28474 | 25022 | 25081 | 96 | | uri() | 24346 | 22291 | 24984 | 97 | | setApprovalForAll() | 51321 | 46581 | 46690 | 98 | | safeTransferFrom() | 30167 | 29793 | 31672 | 99 | | safeBatchTransferFrom() | 33192 | 32054 | 33363 | 100 | | balanceOfBatch() | 25094 | 22961 | 23735 | 101 | | supportsInterface() | 22006 | 22006 | 22058 | 102 | 103 |
104 | 105 |
ERC6909 106 | 107 | | Function | Rustmate | Solmate | OpenZeppelin Contracts 5.0 | 108 | |:-------------------:|:--------:|:-------:|:--------------------------:| 109 | | transfer() | 77615 | 28656 | N/A | 110 | | transferFrom() | 68799 | 29356 | N/A | 111 | | approve() | 52110 | 47430 | N/A | 112 | | setOperator() | 51152 | 46750 | N/A | 113 | | supportsInterface() | 22376 | 21962 | N/A | 114 | 115 |
116 | 117 | ### 👷 How to replicate 118 | 119 | Install [Python](https://www.python.org/downloads/) and [Rust](https://www.rust-lang.org/tools/install), and then install the Stylus CLI tool with Cargo: 120 | 121 | ```bash 122 | RUSTFLAGS="-C link-args=-rdynamic" cargo install --force cargo-stylus 123 | ``` 124 | 125 | Add the `wasm32-unknown-unknown` build target to your Rust compiler: 126 | 127 | ```bash 128 | rustup target add wasm32-unknown-unknown 129 | ``` 130 | 131 | Then, clone the repository: 132 | 133 | ```bash 134 | git clone https://github.com/cairoeth/rustmate && cd rustmate 135 | ``` 136 | 137 | Clone Arbitrum Nitro node that supports Stylus: 138 | 139 | ```bash 140 | git clone -b stylus --recurse-submodules https://github.com/OffchainLabs/nitro-testnode.git && cd nitro-testnode 141 | ``` 142 | 143 | Run the node and wait for it to start up: 144 | 145 | ```bash 146 | ./test-node.bash --init --detach 147 | ``` 148 | 149 | Open another terminal window and fund the deployer address: 150 | 151 | ```bash 152 | ./test-node.bash script send-l2 --to address_0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 --ethamount 100 153 | ``` 154 | 155 | Navigate back to `rustmate` and select a benchmark to run. For example, ERC20: 156 | 157 | ```bash 158 | cd ../benchmark/erc20_benchmark && python snapshot.py 159 | ``` 160 | 161 | Check the results in the terminal or in the `.gas-snapshot` file. 162 | 163 | ## 🙏🏼 Acknowledgements 164 | 165 | This repository is inspired by or directly modified from many sources, primarily: 166 | 167 | - [solmate](https://github.com/transmissions11/solmate) 168 | - [OpenZeppelin Contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) 169 | - [snekmate](https://github.com/pcaversaccio/snekmate) 170 | - [stylus-sdk-rs](https://github.com/OffchainLabs/stylus-sdk-rs) 171 | 172 | ## 🫡 Contributing 173 | 174 | Check out the [Contribution Guidelines](./CONTRIBUTING.md)! 175 | -------------------------------------------------------------------------------- /benchmark/erc1155_benchmark/.gas-snapshot: -------------------------------------------------------------------------------- 1 | ERC1155:balanceOf(address,uint256) (gas: 24631) 2 | ERC1155:isApprovedForAll(address,address) (gas: 25022) 3 | ERC1155:uri(uint256) (gas: 22291) 4 | ERC1155:setApprovalForAll(address,bool) (gas: 46581) 5 | ERC1155:safeTransferFrom(address,address,uint256,uint256,bytes) (gas: ) 6 | ERC1155:safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) (gas: ) 7 | ERC1155:balanceOfBatch(address[],uint256[]) (gas: 22961) 8 | ERC1155:supportsInterface(bytes4) (gas: 22006) 9 | -------------------------------------------------------------------------------- /benchmark/erc1155_benchmark/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "alloy-primitives" 16 | version = "0.3.3" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" 19 | dependencies = [ 20 | "alloy-rlp", 21 | "bytes", 22 | "cfg-if 1.0.0", 23 | "const-hex", 24 | "derive_more", 25 | "hex-literal", 26 | "itoa", 27 | "proptest", 28 | "ruint", 29 | "serde", 30 | "tiny-keccak", 31 | ] 32 | 33 | [[package]] 34 | name = "alloy-rlp" 35 | version = "0.3.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" 38 | dependencies = [ 39 | "arrayvec", 40 | "bytes", 41 | ] 42 | 43 | [[package]] 44 | name = "alloy-sol-macro" 45 | version = "0.3.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "a74ceeffdacf9dd0910404d743d07273776fd17b85f9cb17b49a97e5c6055ce9" 48 | dependencies = [ 49 | "dunce", 50 | "heck", 51 | "proc-macro2", 52 | "quote", 53 | "syn 2.0.48", 54 | "syn-solidity", 55 | "tiny-keccak", 56 | ] 57 | 58 | [[package]] 59 | name = "alloy-sol-types" 60 | version = "0.3.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "d5f347cb6bb307b3802ec455ef43ce00f5e590e0ceca3d2f3b070f5ee367e235" 63 | dependencies = [ 64 | "alloy-primitives", 65 | "alloy-sol-macro", 66 | "const-hex", 67 | "serde", 68 | ] 69 | 70 | [[package]] 71 | name = "arrayvec" 72 | version = "0.7.4" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 75 | 76 | [[package]] 77 | name = "autocfg" 78 | version = "1.1.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 81 | 82 | [[package]] 83 | name = "bit-set" 84 | version = "0.5.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 87 | dependencies = [ 88 | "bit-vec", 89 | ] 90 | 91 | [[package]] 92 | name = "bit-vec" 93 | version = "0.6.3" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 96 | 97 | [[package]] 98 | name = "bitflags" 99 | version = "1.3.2" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 102 | 103 | [[package]] 104 | name = "bitflags" 105 | version = "2.4.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 108 | 109 | [[package]] 110 | name = "block-buffer" 111 | version = "0.10.4" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 114 | dependencies = [ 115 | "generic-array", 116 | ] 117 | 118 | [[package]] 119 | name = "bytes" 120 | version = "1.5.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 123 | 124 | [[package]] 125 | name = "cfg-if" 126 | version = "0.1.10" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 129 | 130 | [[package]] 131 | name = "cfg-if" 132 | version = "1.0.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 135 | 136 | [[package]] 137 | name = "const-hex" 138 | version = "1.10.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" 141 | dependencies = [ 142 | "cfg-if 1.0.0", 143 | "cpufeatures", 144 | "hex", 145 | "proptest", 146 | "serde", 147 | ] 148 | 149 | [[package]] 150 | name = "convert_case" 151 | version = "0.4.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 154 | 155 | [[package]] 156 | name = "convert_case" 157 | version = "0.6.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 160 | dependencies = [ 161 | "unicode-segmentation", 162 | ] 163 | 164 | [[package]] 165 | name = "cpufeatures" 166 | version = "0.2.12" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 169 | dependencies = [ 170 | "libc", 171 | ] 172 | 173 | [[package]] 174 | name = "crunchy" 175 | version = "0.2.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 178 | 179 | [[package]] 180 | name = "crypto-common" 181 | version = "0.1.6" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 184 | dependencies = [ 185 | "generic-array", 186 | "typenum", 187 | ] 188 | 189 | [[package]] 190 | name = "derivative" 191 | version = "2.2.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 194 | dependencies = [ 195 | "proc-macro2", 196 | "quote", 197 | "syn 1.0.109", 198 | ] 199 | 200 | [[package]] 201 | name = "derive_more" 202 | version = "0.99.17" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 205 | dependencies = [ 206 | "convert_case 0.4.0", 207 | "proc-macro2", 208 | "quote", 209 | "rustc_version", 210 | "syn 1.0.109", 211 | ] 212 | 213 | [[package]] 214 | name = "digest" 215 | version = "0.10.7" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 218 | dependencies = [ 219 | "block-buffer", 220 | "crypto-common", 221 | ] 222 | 223 | [[package]] 224 | name = "dunce" 225 | version = "1.0.4" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 228 | 229 | [[package]] 230 | name = "erc1155_benchmark" 231 | version = "0.1.0" 232 | dependencies = [ 233 | "alloy-primitives", 234 | "alloy-sol-types", 235 | "rustmate", 236 | "stylus-sdk", 237 | ] 238 | 239 | [[package]] 240 | name = "errno" 241 | version = "0.3.8" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 244 | dependencies = [ 245 | "libc", 246 | "windows-sys", 247 | ] 248 | 249 | [[package]] 250 | name = "fastrand" 251 | version = "2.0.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 254 | 255 | [[package]] 256 | name = "fnv" 257 | version = "1.0.7" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 260 | 261 | [[package]] 262 | name = "generic-array" 263 | version = "0.14.7" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 266 | dependencies = [ 267 | "typenum", 268 | "version_check", 269 | ] 270 | 271 | [[package]] 272 | name = "getrandom" 273 | version = "0.2.11" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" 276 | dependencies = [ 277 | "cfg-if 1.0.0", 278 | "libc", 279 | "wasi", 280 | ] 281 | 282 | [[package]] 283 | name = "heck" 284 | version = "0.4.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 287 | 288 | [[package]] 289 | name = "hex" 290 | version = "0.4.3" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 293 | 294 | [[package]] 295 | name = "hex-literal" 296 | version = "0.4.1" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 299 | 300 | [[package]] 301 | name = "itoa" 302 | version = "1.0.10" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 305 | 306 | [[package]] 307 | name = "keccak" 308 | version = "0.1.4" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" 311 | dependencies = [ 312 | "cpufeatures", 313 | ] 314 | 315 | [[package]] 316 | name = "keccak-const" 317 | version = "0.2.0" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "57d8d8ce877200136358e0bbff3a77965875db3af755a11e1fa6b1b3e2df13ea" 320 | 321 | [[package]] 322 | name = "lazy_static" 323 | version = "1.4.0" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 326 | 327 | [[package]] 328 | name = "libc" 329 | version = "0.2.151" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" 332 | 333 | [[package]] 334 | name = "libm" 335 | version = "0.2.8" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 338 | 339 | [[package]] 340 | name = "linux-raw-sys" 341 | version = "0.4.12" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" 344 | 345 | [[package]] 346 | name = "memchr" 347 | version = "2.7.1" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 350 | 351 | [[package]] 352 | name = "memory_units" 353 | version = "0.4.0" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" 356 | 357 | [[package]] 358 | name = "num-traits" 359 | version = "0.2.17" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 362 | dependencies = [ 363 | "autocfg", 364 | "libm", 365 | ] 366 | 367 | [[package]] 368 | name = "ppv-lite86" 369 | version = "0.2.17" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 372 | 373 | [[package]] 374 | name = "proc-macro2" 375 | version = "1.0.76" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" 378 | dependencies = [ 379 | "unicode-ident", 380 | ] 381 | 382 | [[package]] 383 | name = "proptest" 384 | version = "1.4.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" 387 | dependencies = [ 388 | "bit-set", 389 | "bit-vec", 390 | "bitflags 2.4.1", 391 | "lazy_static", 392 | "num-traits", 393 | "rand", 394 | "rand_chacha", 395 | "rand_xorshift", 396 | "regex-syntax", 397 | "rusty-fork", 398 | "tempfile", 399 | "unarray", 400 | ] 401 | 402 | [[package]] 403 | name = "quick-error" 404 | version = "1.2.3" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 407 | 408 | [[package]] 409 | name = "quote" 410 | version = "1.0.35" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 413 | dependencies = [ 414 | "proc-macro2", 415 | ] 416 | 417 | [[package]] 418 | name = "rand" 419 | version = "0.8.5" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 422 | dependencies = [ 423 | "libc", 424 | "rand_chacha", 425 | "rand_core", 426 | ] 427 | 428 | [[package]] 429 | name = "rand_chacha" 430 | version = "0.3.1" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 433 | dependencies = [ 434 | "ppv-lite86", 435 | "rand_core", 436 | ] 437 | 438 | [[package]] 439 | name = "rand_core" 440 | version = "0.6.4" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 443 | dependencies = [ 444 | "getrandom", 445 | ] 446 | 447 | [[package]] 448 | name = "rand_xorshift" 449 | version = "0.3.0" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" 452 | dependencies = [ 453 | "rand_core", 454 | ] 455 | 456 | [[package]] 457 | name = "redox_syscall" 458 | version = "0.4.1" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 461 | dependencies = [ 462 | "bitflags 1.3.2", 463 | ] 464 | 465 | [[package]] 466 | name = "regex" 467 | version = "1.10.2" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 470 | dependencies = [ 471 | "aho-corasick", 472 | "memchr", 473 | "regex-automata", 474 | "regex-syntax", 475 | ] 476 | 477 | [[package]] 478 | name = "regex-automata" 479 | version = "0.4.3" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 482 | dependencies = [ 483 | "aho-corasick", 484 | "memchr", 485 | "regex-syntax", 486 | ] 487 | 488 | [[package]] 489 | name = "regex-syntax" 490 | version = "0.8.2" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 493 | 494 | [[package]] 495 | name = "ruint" 496 | version = "1.11.1" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" 499 | dependencies = [ 500 | "proptest", 501 | "rand", 502 | "ruint-macro", 503 | "serde", 504 | "valuable", 505 | "zeroize", 506 | ] 507 | 508 | [[package]] 509 | name = "ruint-macro" 510 | version = "1.1.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" 513 | 514 | [[package]] 515 | name = "rustc_version" 516 | version = "0.4.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 519 | dependencies = [ 520 | "semver", 521 | ] 522 | 523 | [[package]] 524 | name = "rustix" 525 | version = "0.38.28" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" 528 | dependencies = [ 529 | "bitflags 2.4.1", 530 | "errno", 531 | "libc", 532 | "linux-raw-sys", 533 | "windows-sys", 534 | ] 535 | 536 | [[package]] 537 | name = "rustmate" 538 | version = "0.1.0" 539 | dependencies = [ 540 | "alloy-primitives", 541 | "alloy-sol-types", 542 | "stylus-sdk", 543 | "wee_alloc", 544 | ] 545 | 546 | [[package]] 547 | name = "rusty-fork" 548 | version = "0.3.0" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" 551 | dependencies = [ 552 | "fnv", 553 | "quick-error", 554 | "tempfile", 555 | "wait-timeout", 556 | ] 557 | 558 | [[package]] 559 | name = "semver" 560 | version = "1.0.21" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" 563 | 564 | [[package]] 565 | name = "serde" 566 | version = "1.0.195" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" 569 | dependencies = [ 570 | "serde_derive", 571 | ] 572 | 573 | [[package]] 574 | name = "serde_derive" 575 | version = "1.0.195" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" 578 | dependencies = [ 579 | "proc-macro2", 580 | "quote", 581 | "syn 2.0.48", 582 | ] 583 | 584 | [[package]] 585 | name = "sha3" 586 | version = "0.10.8" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 589 | dependencies = [ 590 | "digest", 591 | "keccak", 592 | ] 593 | 594 | [[package]] 595 | name = "stylus-proc" 596 | version = "0.4.1" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "87a941ef748a746cd7b7075975073962d561934ffe91c056e22e20c8e89b64af" 599 | dependencies = [ 600 | "alloy-primitives", 601 | "alloy-sol-types", 602 | "cfg-if 1.0.0", 603 | "convert_case 0.6.0", 604 | "lazy_static", 605 | "proc-macro2", 606 | "quote", 607 | "regex", 608 | "sha3", 609 | "syn 1.0.109", 610 | "syn-solidity", 611 | ] 612 | 613 | [[package]] 614 | name = "stylus-sdk" 615 | version = "0.4.2" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "12c2d6fedbd0393e2b9f0259ca239c7ede9f87a89933627119b9dc038902d7e9" 618 | dependencies = [ 619 | "alloy-primitives", 620 | "alloy-sol-types", 621 | "cfg-if 1.0.0", 622 | "derivative", 623 | "fnv", 624 | "hex", 625 | "keccak-const", 626 | "lazy_static", 627 | "regex", 628 | "stylus-proc", 629 | ] 630 | 631 | [[package]] 632 | name = "syn" 633 | version = "1.0.109" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 636 | dependencies = [ 637 | "proc-macro2", 638 | "quote", 639 | "unicode-ident", 640 | ] 641 | 642 | [[package]] 643 | name = "syn" 644 | version = "2.0.48" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" 647 | dependencies = [ 648 | "proc-macro2", 649 | "quote", 650 | "unicode-ident", 651 | ] 652 | 653 | [[package]] 654 | name = "syn-solidity" 655 | version = "0.3.1" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "e5f995d2140b0f751dbe94365be2591edbf3d1b75dcfaeac14183abbd2ff07bd" 658 | dependencies = [ 659 | "proc-macro2", 660 | "quote", 661 | "syn 2.0.48", 662 | ] 663 | 664 | [[package]] 665 | name = "tempfile" 666 | version = "3.9.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" 669 | dependencies = [ 670 | "cfg-if 1.0.0", 671 | "fastrand", 672 | "redox_syscall", 673 | "rustix", 674 | "windows-sys", 675 | ] 676 | 677 | [[package]] 678 | name = "tiny-keccak" 679 | version = "2.0.2" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 682 | dependencies = [ 683 | "crunchy", 684 | ] 685 | 686 | [[package]] 687 | name = "typenum" 688 | version = "1.17.0" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 691 | 692 | [[package]] 693 | name = "unarray" 694 | version = "0.1.4" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" 697 | 698 | [[package]] 699 | name = "unicode-ident" 700 | version = "1.0.12" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 703 | 704 | [[package]] 705 | name = "unicode-segmentation" 706 | version = "1.10.1" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 709 | 710 | [[package]] 711 | name = "valuable" 712 | version = "0.1.0" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 715 | 716 | [[package]] 717 | name = "version_check" 718 | version = "0.9.4" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 721 | 722 | [[package]] 723 | name = "wait-timeout" 724 | version = "0.2.0" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 727 | dependencies = [ 728 | "libc", 729 | ] 730 | 731 | [[package]] 732 | name = "wasi" 733 | version = "0.11.0+wasi-snapshot-preview1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 736 | 737 | [[package]] 738 | name = "wee_alloc" 739 | version = "0.4.5" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" 742 | dependencies = [ 743 | "cfg-if 0.1.10", 744 | "libc", 745 | "memory_units", 746 | "winapi", 747 | ] 748 | 749 | [[package]] 750 | name = "winapi" 751 | version = "0.3.9" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 754 | dependencies = [ 755 | "winapi-i686-pc-windows-gnu", 756 | "winapi-x86_64-pc-windows-gnu", 757 | ] 758 | 759 | [[package]] 760 | name = "winapi-i686-pc-windows-gnu" 761 | version = "0.4.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 764 | 765 | [[package]] 766 | name = "winapi-x86_64-pc-windows-gnu" 767 | version = "0.4.0" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 770 | 771 | [[package]] 772 | name = "windows-sys" 773 | version = "0.52.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 776 | dependencies = [ 777 | "windows-targets", 778 | ] 779 | 780 | [[package]] 781 | name = "windows-targets" 782 | version = "0.52.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 785 | dependencies = [ 786 | "windows_aarch64_gnullvm", 787 | "windows_aarch64_msvc", 788 | "windows_i686_gnu", 789 | "windows_i686_msvc", 790 | "windows_x86_64_gnu", 791 | "windows_x86_64_gnullvm", 792 | "windows_x86_64_msvc", 793 | ] 794 | 795 | [[package]] 796 | name = "windows_aarch64_gnullvm" 797 | version = "0.52.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 800 | 801 | [[package]] 802 | name = "windows_aarch64_msvc" 803 | version = "0.52.0" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 806 | 807 | [[package]] 808 | name = "windows_i686_gnu" 809 | version = "0.52.0" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 812 | 813 | [[package]] 814 | name = "windows_i686_msvc" 815 | version = "0.52.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 818 | 819 | [[package]] 820 | name = "windows_x86_64_gnu" 821 | version = "0.52.0" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 824 | 825 | [[package]] 826 | name = "windows_x86_64_gnullvm" 827 | version = "0.52.0" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 830 | 831 | [[package]] 832 | name = "windows_x86_64_msvc" 833 | version = "0.52.0" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 836 | 837 | [[package]] 838 | name = "zeroize" 839 | version = "1.7.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" 842 | -------------------------------------------------------------------------------- /benchmark/erc1155_benchmark/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "erc1155_benchmark" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | alloy-primitives = "0.3.1" 8 | alloy-sol-types = "0.3.1" 9 | stylus-sdk = "0.4.2" 10 | rustmate = { path = "../../" } 11 | 12 | [features] 13 | export-abi = ["stylus-sdk/export-abi"] 14 | 15 | [lib] 16 | crate-type = ["lib", "cdylib"] -------------------------------------------------------------------------------- /benchmark/erc1155_benchmark/snapshot.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import argparse 3 | 4 | # Initialize parser 5 | parser = argparse.ArgumentParser( 6 | prog='ERC1155 Benchmark', 7 | description='Run gas benchmark on ERC1155 implementations') 8 | 9 | # Adding optional argument 10 | parser.add_argument("-addr", "--address", help = "Use a specific contract address") 11 | 12 | # Read arguments from command line 13 | args = parser.parse_args() 14 | 15 | def run_benchmark(address): 16 | functions = { 17 | 'balanceOf(address,uint256)': ['(uint256)', address, '1'], 18 | 'isApprovedForAll(address,address)': ['(bool)', address, address], 19 | 'uri(uint256)': ['(string)', '1'], 20 | 'setApprovalForAll(address,bool)': ['(bool)', address, 'true'], 21 | 'safeTransferFrom(address,address,uint256,uint256,bytes)': ['(bool)', address, address, '1', '1', '0x'], 22 | 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)': ['(bool)', address, address, '[]', '[]', '0x'], 23 | 'balanceOfBatch(address[],uint256[])': ['(uint256[])', '[]', '[]'], 24 | 'supportsInterface(bytes4)': ['(bool)', '0x80ac58cd'] 25 | } 26 | 27 | # Run estimates and write to snapshot file 28 | with open('.gas-snapshot', 'w') as snapshot: 29 | for function, args in functions.items(): 30 | gas = subprocess.run(['cast', 'estimate', address, function + args[0]] + args[1:] + ['--rpc-url', 'http://localhost:8547'], stdout=subprocess.PIPE).stdout.decode("utf-8")[:-1] 31 | snapshot.write(f'ERC1155:{function} (gas: {gas})\n') 32 | 33 | print(subprocess.run(['cat', '.gas-snapshot'], stdout=subprocess.PIPE).stdout.decode("utf-8")) 34 | 35 | if args.address: 36 | print(f"Using {args.address}...") 37 | address = args.address 38 | else: 39 | contract = subprocess.run(['cargo', 'stylus', 'deploy', '-e', 'http://localhost:8547', '--private-key', '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'], stdout=subprocess.PIPE).stdout.decode("utf-8") 40 | location = contract.find('Base') 41 | address = contract[location-49:location-7] 42 | 43 | run_benchmark(address) -------------------------------------------------------------------------------- /benchmark/erc1155_benchmark/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Only run this as a WASM if the export-abi feature is not set. 2 | #![cfg_attr(not(feature = "export-abi"), no_main)] 3 | extern crate alloc; 4 | 5 | use rustmate::tokens::erc1155::{ERC1155Params, ERC1155}; 6 | use stylus_sdk::{alloy_primitives::U256, prelude::*}; 7 | 8 | pub struct SampleParams; 9 | 10 | /// Immutable definitions 11 | impl ERC1155Params for SampleParams { 12 | fn uri(id: U256) -> String { 13 | format!("ipfs://hash/{}", id) 14 | } 15 | } 16 | 17 | // The contract 18 | sol_storage! { 19 | #[entrypoint] // Makes SampleNFT the entrypoint 20 | pub struct SampleNFT { 21 | #[borrow] // Allows erc1155 to access SampleNFT's storage and make calls 22 | ERC1155 erc1155; 23 | } 24 | } 25 | 26 | #[external] 27 | #[inherit(ERC1155)] 28 | impl SampleNFT {} 29 | -------------------------------------------------------------------------------- /benchmark/erc20_benchmark/.gas-snapshot: -------------------------------------------------------------------------------- 1 | ERC20:name() (gas: 23043) 2 | ERC20:symbol() (gas: 22974) 3 | ERC20:decimals() (gas: 22726) 4 | ERC20:totalSupply() (gas: 25617) 5 | ERC20:balanceOf(address) (gas: 26851) 6 | ERC20:allowance(address,address) (gas: 28263) 7 | ERC20:nonces(address) (gas: 26835) 8 | ERC20:approve(address,uint256) (gas: 50557) 9 | ERC20:transfer(address,uint256) (gas: 74234) 10 | ERC20:transferFrom(address,address,uint256) (gas: 60116) 11 | -------------------------------------------------------------------------------- /benchmark/erc20_benchmark/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "alloy-primitives" 16 | version = "0.3.3" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" 19 | dependencies = [ 20 | "alloy-rlp", 21 | "bytes", 22 | "cfg-if 1.0.0", 23 | "const-hex", 24 | "derive_more", 25 | "hex-literal", 26 | "itoa", 27 | "proptest", 28 | "ruint", 29 | "serde", 30 | "tiny-keccak", 31 | ] 32 | 33 | [[package]] 34 | name = "alloy-rlp" 35 | version = "0.3.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" 38 | dependencies = [ 39 | "arrayvec", 40 | "bytes", 41 | ] 42 | 43 | [[package]] 44 | name = "alloy-sol-macro" 45 | version = "0.3.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "a74ceeffdacf9dd0910404d743d07273776fd17b85f9cb17b49a97e5c6055ce9" 48 | dependencies = [ 49 | "dunce", 50 | "heck", 51 | "proc-macro2", 52 | "quote", 53 | "syn 2.0.48", 54 | "syn-solidity", 55 | "tiny-keccak", 56 | ] 57 | 58 | [[package]] 59 | name = "alloy-sol-types" 60 | version = "0.3.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "d5f347cb6bb307b3802ec455ef43ce00f5e590e0ceca3d2f3b070f5ee367e235" 63 | dependencies = [ 64 | "alloy-primitives", 65 | "alloy-sol-macro", 66 | "const-hex", 67 | "serde", 68 | ] 69 | 70 | [[package]] 71 | name = "arrayvec" 72 | version = "0.7.4" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 75 | 76 | [[package]] 77 | name = "autocfg" 78 | version = "1.1.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 81 | 82 | [[package]] 83 | name = "bit-set" 84 | version = "0.5.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 87 | dependencies = [ 88 | "bit-vec", 89 | ] 90 | 91 | [[package]] 92 | name = "bit-vec" 93 | version = "0.6.3" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 96 | 97 | [[package]] 98 | name = "bitflags" 99 | version = "1.3.2" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 102 | 103 | [[package]] 104 | name = "bitflags" 105 | version = "2.4.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 108 | 109 | [[package]] 110 | name = "block-buffer" 111 | version = "0.10.4" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 114 | dependencies = [ 115 | "generic-array", 116 | ] 117 | 118 | [[package]] 119 | name = "bytes" 120 | version = "1.5.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 123 | 124 | [[package]] 125 | name = "cfg-if" 126 | version = "0.1.10" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 129 | 130 | [[package]] 131 | name = "cfg-if" 132 | version = "1.0.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 135 | 136 | [[package]] 137 | name = "const-hex" 138 | version = "1.10.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" 141 | dependencies = [ 142 | "cfg-if 1.0.0", 143 | "cpufeatures", 144 | "hex", 145 | "proptest", 146 | "serde", 147 | ] 148 | 149 | [[package]] 150 | name = "convert_case" 151 | version = "0.4.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 154 | 155 | [[package]] 156 | name = "convert_case" 157 | version = "0.6.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 160 | dependencies = [ 161 | "unicode-segmentation", 162 | ] 163 | 164 | [[package]] 165 | name = "cpufeatures" 166 | version = "0.2.12" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 169 | dependencies = [ 170 | "libc", 171 | ] 172 | 173 | [[package]] 174 | name = "crunchy" 175 | version = "0.2.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 178 | 179 | [[package]] 180 | name = "crypto-common" 181 | version = "0.1.6" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 184 | dependencies = [ 185 | "generic-array", 186 | "typenum", 187 | ] 188 | 189 | [[package]] 190 | name = "derivative" 191 | version = "2.2.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 194 | dependencies = [ 195 | "proc-macro2", 196 | "quote", 197 | "syn 1.0.109", 198 | ] 199 | 200 | [[package]] 201 | name = "derive_more" 202 | version = "0.99.17" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 205 | dependencies = [ 206 | "convert_case 0.4.0", 207 | "proc-macro2", 208 | "quote", 209 | "rustc_version", 210 | "syn 1.0.109", 211 | ] 212 | 213 | [[package]] 214 | name = "digest" 215 | version = "0.10.7" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 218 | dependencies = [ 219 | "block-buffer", 220 | "crypto-common", 221 | ] 222 | 223 | [[package]] 224 | name = "dunce" 225 | version = "1.0.4" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 228 | 229 | [[package]] 230 | name = "erc20_benchmark" 231 | version = "0.1.0" 232 | dependencies = [ 233 | "alloy-primitives", 234 | "alloy-sol-types", 235 | "rustmate", 236 | "stylus-sdk", 237 | ] 238 | 239 | [[package]] 240 | name = "errno" 241 | version = "0.3.8" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 244 | dependencies = [ 245 | "libc", 246 | "windows-sys", 247 | ] 248 | 249 | [[package]] 250 | name = "fastrand" 251 | version = "2.0.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 254 | 255 | [[package]] 256 | name = "fnv" 257 | version = "1.0.7" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 260 | 261 | [[package]] 262 | name = "generic-array" 263 | version = "0.14.7" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 266 | dependencies = [ 267 | "typenum", 268 | "version_check", 269 | ] 270 | 271 | [[package]] 272 | name = "getrandom" 273 | version = "0.2.11" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" 276 | dependencies = [ 277 | "cfg-if 1.0.0", 278 | "libc", 279 | "wasi", 280 | ] 281 | 282 | [[package]] 283 | name = "heck" 284 | version = "0.4.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 287 | 288 | [[package]] 289 | name = "hex" 290 | version = "0.4.3" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 293 | 294 | [[package]] 295 | name = "hex-literal" 296 | version = "0.4.1" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 299 | 300 | [[package]] 301 | name = "itoa" 302 | version = "1.0.10" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 305 | 306 | [[package]] 307 | name = "keccak" 308 | version = "0.1.4" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" 311 | dependencies = [ 312 | "cpufeatures", 313 | ] 314 | 315 | [[package]] 316 | name = "keccak-const" 317 | version = "0.2.0" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "57d8d8ce877200136358e0bbff3a77965875db3af755a11e1fa6b1b3e2df13ea" 320 | 321 | [[package]] 322 | name = "lazy_static" 323 | version = "1.4.0" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 326 | 327 | [[package]] 328 | name = "libc" 329 | version = "0.2.151" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" 332 | 333 | [[package]] 334 | name = "libm" 335 | version = "0.2.8" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 338 | 339 | [[package]] 340 | name = "linux-raw-sys" 341 | version = "0.4.12" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" 344 | 345 | [[package]] 346 | name = "memchr" 347 | version = "2.7.1" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 350 | 351 | [[package]] 352 | name = "memory_units" 353 | version = "0.4.0" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" 356 | 357 | [[package]] 358 | name = "num-traits" 359 | version = "0.2.17" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 362 | dependencies = [ 363 | "autocfg", 364 | "libm", 365 | ] 366 | 367 | [[package]] 368 | name = "ppv-lite86" 369 | version = "0.2.17" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 372 | 373 | [[package]] 374 | name = "proc-macro2" 375 | version = "1.0.76" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" 378 | dependencies = [ 379 | "unicode-ident", 380 | ] 381 | 382 | [[package]] 383 | name = "proptest" 384 | version = "1.4.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" 387 | dependencies = [ 388 | "bit-set", 389 | "bit-vec", 390 | "bitflags 2.4.1", 391 | "lazy_static", 392 | "num-traits", 393 | "rand", 394 | "rand_chacha", 395 | "rand_xorshift", 396 | "regex-syntax", 397 | "rusty-fork", 398 | "tempfile", 399 | "unarray", 400 | ] 401 | 402 | [[package]] 403 | name = "quick-error" 404 | version = "1.2.3" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 407 | 408 | [[package]] 409 | name = "quote" 410 | version = "1.0.35" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 413 | dependencies = [ 414 | "proc-macro2", 415 | ] 416 | 417 | [[package]] 418 | name = "rand" 419 | version = "0.8.5" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 422 | dependencies = [ 423 | "libc", 424 | "rand_chacha", 425 | "rand_core", 426 | ] 427 | 428 | [[package]] 429 | name = "rand_chacha" 430 | version = "0.3.1" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 433 | dependencies = [ 434 | "ppv-lite86", 435 | "rand_core", 436 | ] 437 | 438 | [[package]] 439 | name = "rand_core" 440 | version = "0.6.4" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 443 | dependencies = [ 444 | "getrandom", 445 | ] 446 | 447 | [[package]] 448 | name = "rand_xorshift" 449 | version = "0.3.0" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" 452 | dependencies = [ 453 | "rand_core", 454 | ] 455 | 456 | [[package]] 457 | name = "redox_syscall" 458 | version = "0.4.1" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 461 | dependencies = [ 462 | "bitflags 1.3.2", 463 | ] 464 | 465 | [[package]] 466 | name = "regex" 467 | version = "1.10.2" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 470 | dependencies = [ 471 | "aho-corasick", 472 | "memchr", 473 | "regex-automata", 474 | "regex-syntax", 475 | ] 476 | 477 | [[package]] 478 | name = "regex-automata" 479 | version = "0.4.3" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 482 | dependencies = [ 483 | "aho-corasick", 484 | "memchr", 485 | "regex-syntax", 486 | ] 487 | 488 | [[package]] 489 | name = "regex-syntax" 490 | version = "0.8.2" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 493 | 494 | [[package]] 495 | name = "ruint" 496 | version = "1.11.1" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" 499 | dependencies = [ 500 | "proptest", 501 | "rand", 502 | "ruint-macro", 503 | "serde", 504 | "valuable", 505 | "zeroize", 506 | ] 507 | 508 | [[package]] 509 | name = "ruint-macro" 510 | version = "1.1.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" 513 | 514 | [[package]] 515 | name = "rustc_version" 516 | version = "0.4.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 519 | dependencies = [ 520 | "semver", 521 | ] 522 | 523 | [[package]] 524 | name = "rustix" 525 | version = "0.38.28" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" 528 | dependencies = [ 529 | "bitflags 2.4.1", 530 | "errno", 531 | "libc", 532 | "linux-raw-sys", 533 | "windows-sys", 534 | ] 535 | 536 | [[package]] 537 | name = "rustmate" 538 | version = "0.1.0" 539 | dependencies = [ 540 | "alloy-primitives", 541 | "alloy-sol-types", 542 | "stylus-sdk", 543 | "wee_alloc", 544 | ] 545 | 546 | [[package]] 547 | name = "rusty-fork" 548 | version = "0.3.0" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" 551 | dependencies = [ 552 | "fnv", 553 | "quick-error", 554 | "tempfile", 555 | "wait-timeout", 556 | ] 557 | 558 | [[package]] 559 | name = "semver" 560 | version = "1.0.21" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" 563 | 564 | [[package]] 565 | name = "serde" 566 | version = "1.0.195" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" 569 | dependencies = [ 570 | "serde_derive", 571 | ] 572 | 573 | [[package]] 574 | name = "serde_derive" 575 | version = "1.0.195" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" 578 | dependencies = [ 579 | "proc-macro2", 580 | "quote", 581 | "syn 2.0.48", 582 | ] 583 | 584 | [[package]] 585 | name = "sha3" 586 | version = "0.10.8" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 589 | dependencies = [ 590 | "digest", 591 | "keccak", 592 | ] 593 | 594 | [[package]] 595 | name = "stylus-proc" 596 | version = "0.4.1" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "87a941ef748a746cd7b7075975073962d561934ffe91c056e22e20c8e89b64af" 599 | dependencies = [ 600 | "alloy-primitives", 601 | "alloy-sol-types", 602 | "cfg-if 1.0.0", 603 | "convert_case 0.6.0", 604 | "lazy_static", 605 | "proc-macro2", 606 | "quote", 607 | "regex", 608 | "sha3", 609 | "syn 1.0.109", 610 | "syn-solidity", 611 | ] 612 | 613 | [[package]] 614 | name = "stylus-sdk" 615 | version = "0.4.2" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "12c2d6fedbd0393e2b9f0259ca239c7ede9f87a89933627119b9dc038902d7e9" 618 | dependencies = [ 619 | "alloy-primitives", 620 | "alloy-sol-types", 621 | "cfg-if 1.0.0", 622 | "derivative", 623 | "fnv", 624 | "hex", 625 | "keccak-const", 626 | "lazy_static", 627 | "regex", 628 | "stylus-proc", 629 | ] 630 | 631 | [[package]] 632 | name = "syn" 633 | version = "1.0.109" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 636 | dependencies = [ 637 | "proc-macro2", 638 | "quote", 639 | "unicode-ident", 640 | ] 641 | 642 | [[package]] 643 | name = "syn" 644 | version = "2.0.48" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" 647 | dependencies = [ 648 | "proc-macro2", 649 | "quote", 650 | "unicode-ident", 651 | ] 652 | 653 | [[package]] 654 | name = "syn-solidity" 655 | version = "0.3.1" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "e5f995d2140b0f751dbe94365be2591edbf3d1b75dcfaeac14183abbd2ff07bd" 658 | dependencies = [ 659 | "proc-macro2", 660 | "quote", 661 | "syn 2.0.48", 662 | ] 663 | 664 | [[package]] 665 | name = "tempfile" 666 | version = "3.9.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" 669 | dependencies = [ 670 | "cfg-if 1.0.0", 671 | "fastrand", 672 | "redox_syscall", 673 | "rustix", 674 | "windows-sys", 675 | ] 676 | 677 | [[package]] 678 | name = "tiny-keccak" 679 | version = "2.0.2" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 682 | dependencies = [ 683 | "crunchy", 684 | ] 685 | 686 | [[package]] 687 | name = "typenum" 688 | version = "1.17.0" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 691 | 692 | [[package]] 693 | name = "unarray" 694 | version = "0.1.4" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" 697 | 698 | [[package]] 699 | name = "unicode-ident" 700 | version = "1.0.12" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 703 | 704 | [[package]] 705 | name = "unicode-segmentation" 706 | version = "1.10.1" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 709 | 710 | [[package]] 711 | name = "valuable" 712 | version = "0.1.0" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 715 | 716 | [[package]] 717 | name = "version_check" 718 | version = "0.9.4" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 721 | 722 | [[package]] 723 | name = "wait-timeout" 724 | version = "0.2.0" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 727 | dependencies = [ 728 | "libc", 729 | ] 730 | 731 | [[package]] 732 | name = "wasi" 733 | version = "0.11.0+wasi-snapshot-preview1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 736 | 737 | [[package]] 738 | name = "wee_alloc" 739 | version = "0.4.5" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" 742 | dependencies = [ 743 | "cfg-if 0.1.10", 744 | "libc", 745 | "memory_units", 746 | "winapi", 747 | ] 748 | 749 | [[package]] 750 | name = "winapi" 751 | version = "0.3.9" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 754 | dependencies = [ 755 | "winapi-i686-pc-windows-gnu", 756 | "winapi-x86_64-pc-windows-gnu", 757 | ] 758 | 759 | [[package]] 760 | name = "winapi-i686-pc-windows-gnu" 761 | version = "0.4.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 764 | 765 | [[package]] 766 | name = "winapi-x86_64-pc-windows-gnu" 767 | version = "0.4.0" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 770 | 771 | [[package]] 772 | name = "windows-sys" 773 | version = "0.52.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 776 | dependencies = [ 777 | "windows-targets", 778 | ] 779 | 780 | [[package]] 781 | name = "windows-targets" 782 | version = "0.52.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 785 | dependencies = [ 786 | "windows_aarch64_gnullvm", 787 | "windows_aarch64_msvc", 788 | "windows_i686_gnu", 789 | "windows_i686_msvc", 790 | "windows_x86_64_gnu", 791 | "windows_x86_64_gnullvm", 792 | "windows_x86_64_msvc", 793 | ] 794 | 795 | [[package]] 796 | name = "windows_aarch64_gnullvm" 797 | version = "0.52.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 800 | 801 | [[package]] 802 | name = "windows_aarch64_msvc" 803 | version = "0.52.0" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 806 | 807 | [[package]] 808 | name = "windows_i686_gnu" 809 | version = "0.52.0" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 812 | 813 | [[package]] 814 | name = "windows_i686_msvc" 815 | version = "0.52.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 818 | 819 | [[package]] 820 | name = "windows_x86_64_gnu" 821 | version = "0.52.0" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 824 | 825 | [[package]] 826 | name = "windows_x86_64_gnullvm" 827 | version = "0.52.0" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 830 | 831 | [[package]] 832 | name = "windows_x86_64_msvc" 833 | version = "0.52.0" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 836 | 837 | [[package]] 838 | name = "zeroize" 839 | version = "1.7.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" 842 | -------------------------------------------------------------------------------- /benchmark/erc20_benchmark/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "erc20_benchmark" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | alloy-primitives = "0.3.1" 8 | alloy-sol-types = "0.3.1" 9 | stylus-sdk = "0.4.2" 10 | rustmate = { path = "../../" } 11 | 12 | [features] 13 | export-abi = ["stylus-sdk/export-abi"] 14 | 15 | [lib] 16 | crate-type = ["lib", "cdylib"] -------------------------------------------------------------------------------- /benchmark/erc20_benchmark/snapshot.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import argparse 3 | 4 | # Initialize parser 5 | parser = argparse.ArgumentParser( 6 | prog='ERC20 Benchmark', 7 | description='Run gas benchmark on ERC20 implementations') 8 | 9 | # Adding optional argument 10 | parser.add_argument("-addr", "--address", help = "Use a specific contract address") 11 | 12 | # Read arguments from command line 13 | args = parser.parse_args() 14 | 15 | def run_benchmark(address): 16 | functions = { 17 | 'name()': ['(string)'], 18 | 'symbol()': ['(string)'], 19 | 'decimals()': ['(uint8)'], 20 | 'totalSupply()': ['(uint256)'], 21 | 'balanceOf(address)': ['(uint256)', address], 22 | 'allowance(address,address)': ['(uint256)', address, address], 23 | 'nonces(address)': ['(uint256)', address], 24 | 'approve(address,uint256)': ['(bool)', address, '100'], 25 | 'transfer(address,uint256)': ['(bool)', address, '100'], 26 | 'transferFrom(address,address,uint256)': ['(bool)', address, address, '100'], 27 | # 'permit(address,address,uint256,uint256,uint8,uint256,uint256)': ['(bool)', address, address, '100', '999', '0', '0', '0'], 28 | # 'domainSeparator()': ['(bytes32)'], 29 | } 30 | 31 | # Run estimates and write to snapshot file 32 | with open('.gas-snapshot', 'w') as snapshot: 33 | for function, args in functions.items(): 34 | gas = subprocess.run(['cast', 'estimate', address, function + args[0]] + args[1:] + ['--rpc-url', 'http://localhost:8547'], stdout=subprocess.PIPE).stdout.decode("utf-8")[:-1] 35 | snapshot.write(f'ERC20:{function} (gas: {gas})\n') 36 | 37 | print(subprocess.run(['cat', '.gas-snapshot'], stdout=subprocess.PIPE).stdout.decode("utf-8")) 38 | 39 | if args.address: 40 | print(f"Using {args.address}...") 41 | address = args.address 42 | else: 43 | contract = subprocess.run(['cargo', 'stylus', 'deploy', '-e', 'http://localhost:8547', '--private-key', '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'], stdout=subprocess.PIPE).stdout.decode("utf-8") 44 | location = contract.find('Base') 45 | address = contract[location-49:location-7] 46 | 47 | run_benchmark(address) -------------------------------------------------------------------------------- /benchmark/erc20_benchmark/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Only run this as a WASM if the export-abi feature is not set. 2 | #![cfg_attr(not(feature = "export-abi"), no_main)] 3 | extern crate alloc; 4 | 5 | use alloc::vec::Vec; 6 | use alloy_primitives::B256; 7 | use rustmate::tokens::erc20::{ERC20Params, ERC20}; 8 | use stylus_sdk::{alloy_primitives::U256, msg, prelude::*}; 9 | 10 | pub struct SampleParams; 11 | 12 | /// Immutable definitions 13 | impl ERC20Params for SampleParams { 14 | const NAME: &'static str = "MyToken"; 15 | const SYMBOL: &'static str = "MTK"; 16 | const DECIMALS: u8 = 18; 17 | const INITIAL_CHAIN_ID: u64 = 1; 18 | const INITIAL_DOMAIN_SEPARATOR: B256 = B256::ZERO; 19 | } 20 | 21 | // The contract 22 | sol_storage! { 23 | #[entrypoint] // Makes MyToken the entrypoint 24 | pub struct MyToken { 25 | #[borrow] // Allows erc20 to access MyToken's storage and make calls 26 | ERC20 erc20; 27 | } 28 | } 29 | 30 | #[external] 31 | #[inherit(ERC20)] 32 | impl MyToken { 33 | pub fn mint(&mut self, amount: U256) -> Result<(), Vec> { 34 | self.erc20.mint(msg::sender(), amount); 35 | 36 | Ok(()) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /benchmark/erc6909_benchmark/.gas-snapshot: -------------------------------------------------------------------------------- 1 | ERC6909:transfer(address,uint256,uint256) (gas: ) 2 | ERC6909:transferFrom(address,address,uint256,uint256) (gas: ) 3 | ERC6909:approve(address,uint256,uint256) (gas: 47430) 4 | ERC6909:setOperator(address,bool) (gas: 46750) 5 | ERC6909:supportsInterface(bytes4) (gas: 21962) 6 | -------------------------------------------------------------------------------- /benchmark/erc6909_benchmark/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "alloy-primitives" 16 | version = "0.3.3" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" 19 | dependencies = [ 20 | "alloy-rlp", 21 | "bytes", 22 | "cfg-if 1.0.0", 23 | "const-hex", 24 | "derive_more", 25 | "hex-literal", 26 | "itoa", 27 | "proptest", 28 | "ruint", 29 | "serde", 30 | "tiny-keccak", 31 | ] 32 | 33 | [[package]] 34 | name = "alloy-rlp" 35 | version = "0.3.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" 38 | dependencies = [ 39 | "arrayvec", 40 | "bytes", 41 | ] 42 | 43 | [[package]] 44 | name = "alloy-sol-macro" 45 | version = "0.3.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "a74ceeffdacf9dd0910404d743d07273776fd17b85f9cb17b49a97e5c6055ce9" 48 | dependencies = [ 49 | "dunce", 50 | "heck", 51 | "proc-macro2", 52 | "quote", 53 | "syn 2.0.48", 54 | "syn-solidity", 55 | "tiny-keccak", 56 | ] 57 | 58 | [[package]] 59 | name = "alloy-sol-types" 60 | version = "0.3.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "d5f347cb6bb307b3802ec455ef43ce00f5e590e0ceca3d2f3b070f5ee367e235" 63 | dependencies = [ 64 | "alloy-primitives", 65 | "alloy-sol-macro", 66 | "const-hex", 67 | "serde", 68 | ] 69 | 70 | [[package]] 71 | name = "arrayvec" 72 | version = "0.7.4" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 75 | 76 | [[package]] 77 | name = "autocfg" 78 | version = "1.1.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 81 | 82 | [[package]] 83 | name = "bit-set" 84 | version = "0.5.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 87 | dependencies = [ 88 | "bit-vec", 89 | ] 90 | 91 | [[package]] 92 | name = "bit-vec" 93 | version = "0.6.3" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 96 | 97 | [[package]] 98 | name = "bitflags" 99 | version = "1.3.2" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 102 | 103 | [[package]] 104 | name = "bitflags" 105 | version = "2.4.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 108 | 109 | [[package]] 110 | name = "block-buffer" 111 | version = "0.10.4" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 114 | dependencies = [ 115 | "generic-array", 116 | ] 117 | 118 | [[package]] 119 | name = "bytes" 120 | version = "1.5.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 123 | 124 | [[package]] 125 | name = "cfg-if" 126 | version = "0.1.10" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 129 | 130 | [[package]] 131 | name = "cfg-if" 132 | version = "1.0.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 135 | 136 | [[package]] 137 | name = "const-hex" 138 | version = "1.10.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" 141 | dependencies = [ 142 | "cfg-if 1.0.0", 143 | "cpufeatures", 144 | "hex", 145 | "proptest", 146 | "serde", 147 | ] 148 | 149 | [[package]] 150 | name = "convert_case" 151 | version = "0.4.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 154 | 155 | [[package]] 156 | name = "convert_case" 157 | version = "0.6.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 160 | dependencies = [ 161 | "unicode-segmentation", 162 | ] 163 | 164 | [[package]] 165 | name = "cpufeatures" 166 | version = "0.2.12" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 169 | dependencies = [ 170 | "libc", 171 | ] 172 | 173 | [[package]] 174 | name = "crunchy" 175 | version = "0.2.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 178 | 179 | [[package]] 180 | name = "crypto-common" 181 | version = "0.1.6" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 184 | dependencies = [ 185 | "generic-array", 186 | "typenum", 187 | ] 188 | 189 | [[package]] 190 | name = "derivative" 191 | version = "2.2.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 194 | dependencies = [ 195 | "proc-macro2", 196 | "quote", 197 | "syn 1.0.109", 198 | ] 199 | 200 | [[package]] 201 | name = "derive_more" 202 | version = "0.99.17" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 205 | dependencies = [ 206 | "convert_case 0.4.0", 207 | "proc-macro2", 208 | "quote", 209 | "rustc_version", 210 | "syn 1.0.109", 211 | ] 212 | 213 | [[package]] 214 | name = "digest" 215 | version = "0.10.7" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 218 | dependencies = [ 219 | "block-buffer", 220 | "crypto-common", 221 | ] 222 | 223 | [[package]] 224 | name = "dunce" 225 | version = "1.0.4" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 228 | 229 | [[package]] 230 | name = "erc6909_benchmark" 231 | version = "0.1.0" 232 | dependencies = [ 233 | "alloy-primitives", 234 | "alloy-sol-types", 235 | "rustmate", 236 | "stylus-sdk", 237 | ] 238 | 239 | [[package]] 240 | name = "errno" 241 | version = "0.3.8" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 244 | dependencies = [ 245 | "libc", 246 | "windows-sys", 247 | ] 248 | 249 | [[package]] 250 | name = "fastrand" 251 | version = "2.0.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 254 | 255 | [[package]] 256 | name = "fnv" 257 | version = "1.0.7" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 260 | 261 | [[package]] 262 | name = "generic-array" 263 | version = "0.14.7" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 266 | dependencies = [ 267 | "typenum", 268 | "version_check", 269 | ] 270 | 271 | [[package]] 272 | name = "getrandom" 273 | version = "0.2.11" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" 276 | dependencies = [ 277 | "cfg-if 1.0.0", 278 | "libc", 279 | "wasi", 280 | ] 281 | 282 | [[package]] 283 | name = "heck" 284 | version = "0.4.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 287 | 288 | [[package]] 289 | name = "hex" 290 | version = "0.4.3" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 293 | 294 | [[package]] 295 | name = "hex-literal" 296 | version = "0.4.1" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 299 | 300 | [[package]] 301 | name = "itoa" 302 | version = "1.0.10" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 305 | 306 | [[package]] 307 | name = "keccak" 308 | version = "0.1.4" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" 311 | dependencies = [ 312 | "cpufeatures", 313 | ] 314 | 315 | [[package]] 316 | name = "keccak-const" 317 | version = "0.2.0" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "57d8d8ce877200136358e0bbff3a77965875db3af755a11e1fa6b1b3e2df13ea" 320 | 321 | [[package]] 322 | name = "lazy_static" 323 | version = "1.4.0" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 326 | 327 | [[package]] 328 | name = "libc" 329 | version = "0.2.151" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" 332 | 333 | [[package]] 334 | name = "libm" 335 | version = "0.2.8" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 338 | 339 | [[package]] 340 | name = "linux-raw-sys" 341 | version = "0.4.12" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" 344 | 345 | [[package]] 346 | name = "memchr" 347 | version = "2.7.1" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 350 | 351 | [[package]] 352 | name = "memory_units" 353 | version = "0.4.0" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" 356 | 357 | [[package]] 358 | name = "num-traits" 359 | version = "0.2.17" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 362 | dependencies = [ 363 | "autocfg", 364 | "libm", 365 | ] 366 | 367 | [[package]] 368 | name = "ppv-lite86" 369 | version = "0.2.17" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 372 | 373 | [[package]] 374 | name = "proc-macro2" 375 | version = "1.0.76" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" 378 | dependencies = [ 379 | "unicode-ident", 380 | ] 381 | 382 | [[package]] 383 | name = "proptest" 384 | version = "1.4.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" 387 | dependencies = [ 388 | "bit-set", 389 | "bit-vec", 390 | "bitflags 2.4.1", 391 | "lazy_static", 392 | "num-traits", 393 | "rand", 394 | "rand_chacha", 395 | "rand_xorshift", 396 | "regex-syntax", 397 | "rusty-fork", 398 | "tempfile", 399 | "unarray", 400 | ] 401 | 402 | [[package]] 403 | name = "quick-error" 404 | version = "1.2.3" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 407 | 408 | [[package]] 409 | name = "quote" 410 | version = "1.0.35" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 413 | dependencies = [ 414 | "proc-macro2", 415 | ] 416 | 417 | [[package]] 418 | name = "rand" 419 | version = "0.8.5" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 422 | dependencies = [ 423 | "libc", 424 | "rand_chacha", 425 | "rand_core", 426 | ] 427 | 428 | [[package]] 429 | name = "rand_chacha" 430 | version = "0.3.1" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 433 | dependencies = [ 434 | "ppv-lite86", 435 | "rand_core", 436 | ] 437 | 438 | [[package]] 439 | name = "rand_core" 440 | version = "0.6.4" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 443 | dependencies = [ 444 | "getrandom", 445 | ] 446 | 447 | [[package]] 448 | name = "rand_xorshift" 449 | version = "0.3.0" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" 452 | dependencies = [ 453 | "rand_core", 454 | ] 455 | 456 | [[package]] 457 | name = "redox_syscall" 458 | version = "0.4.1" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 461 | dependencies = [ 462 | "bitflags 1.3.2", 463 | ] 464 | 465 | [[package]] 466 | name = "regex" 467 | version = "1.10.2" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 470 | dependencies = [ 471 | "aho-corasick", 472 | "memchr", 473 | "regex-automata", 474 | "regex-syntax", 475 | ] 476 | 477 | [[package]] 478 | name = "regex-automata" 479 | version = "0.4.3" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 482 | dependencies = [ 483 | "aho-corasick", 484 | "memchr", 485 | "regex-syntax", 486 | ] 487 | 488 | [[package]] 489 | name = "regex-syntax" 490 | version = "0.8.2" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 493 | 494 | [[package]] 495 | name = "ruint" 496 | version = "1.11.1" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" 499 | dependencies = [ 500 | "proptest", 501 | "rand", 502 | "ruint-macro", 503 | "serde", 504 | "valuable", 505 | "zeroize", 506 | ] 507 | 508 | [[package]] 509 | name = "ruint-macro" 510 | version = "1.1.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" 513 | 514 | [[package]] 515 | name = "rustc_version" 516 | version = "0.4.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 519 | dependencies = [ 520 | "semver", 521 | ] 522 | 523 | [[package]] 524 | name = "rustix" 525 | version = "0.38.28" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" 528 | dependencies = [ 529 | "bitflags 2.4.1", 530 | "errno", 531 | "libc", 532 | "linux-raw-sys", 533 | "windows-sys", 534 | ] 535 | 536 | [[package]] 537 | name = "rustmate" 538 | version = "0.1.0" 539 | dependencies = [ 540 | "alloy-primitives", 541 | "alloy-sol-types", 542 | "stylus-sdk", 543 | "wee_alloc", 544 | ] 545 | 546 | [[package]] 547 | name = "rusty-fork" 548 | version = "0.3.0" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" 551 | dependencies = [ 552 | "fnv", 553 | "quick-error", 554 | "tempfile", 555 | "wait-timeout", 556 | ] 557 | 558 | [[package]] 559 | name = "semver" 560 | version = "1.0.21" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" 563 | 564 | [[package]] 565 | name = "serde" 566 | version = "1.0.195" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" 569 | dependencies = [ 570 | "serde_derive", 571 | ] 572 | 573 | [[package]] 574 | name = "serde_derive" 575 | version = "1.0.195" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" 578 | dependencies = [ 579 | "proc-macro2", 580 | "quote", 581 | "syn 2.0.48", 582 | ] 583 | 584 | [[package]] 585 | name = "sha3" 586 | version = "0.10.8" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 589 | dependencies = [ 590 | "digest", 591 | "keccak", 592 | ] 593 | 594 | [[package]] 595 | name = "stylus-proc" 596 | version = "0.4.1" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "87a941ef748a746cd7b7075975073962d561934ffe91c056e22e20c8e89b64af" 599 | dependencies = [ 600 | "alloy-primitives", 601 | "alloy-sol-types", 602 | "cfg-if 1.0.0", 603 | "convert_case 0.6.0", 604 | "lazy_static", 605 | "proc-macro2", 606 | "quote", 607 | "regex", 608 | "sha3", 609 | "syn 1.0.109", 610 | "syn-solidity", 611 | ] 612 | 613 | [[package]] 614 | name = "stylus-sdk" 615 | version = "0.4.2" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "12c2d6fedbd0393e2b9f0259ca239c7ede9f87a89933627119b9dc038902d7e9" 618 | dependencies = [ 619 | "alloy-primitives", 620 | "alloy-sol-types", 621 | "cfg-if 1.0.0", 622 | "derivative", 623 | "fnv", 624 | "hex", 625 | "keccak-const", 626 | "lazy_static", 627 | "regex", 628 | "stylus-proc", 629 | ] 630 | 631 | [[package]] 632 | name = "syn" 633 | version = "1.0.109" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 636 | dependencies = [ 637 | "proc-macro2", 638 | "quote", 639 | "unicode-ident", 640 | ] 641 | 642 | [[package]] 643 | name = "syn" 644 | version = "2.0.48" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" 647 | dependencies = [ 648 | "proc-macro2", 649 | "quote", 650 | "unicode-ident", 651 | ] 652 | 653 | [[package]] 654 | name = "syn-solidity" 655 | version = "0.3.1" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "e5f995d2140b0f751dbe94365be2591edbf3d1b75dcfaeac14183abbd2ff07bd" 658 | dependencies = [ 659 | "proc-macro2", 660 | "quote", 661 | "syn 2.0.48", 662 | ] 663 | 664 | [[package]] 665 | name = "tempfile" 666 | version = "3.9.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" 669 | dependencies = [ 670 | "cfg-if 1.0.0", 671 | "fastrand", 672 | "redox_syscall", 673 | "rustix", 674 | "windows-sys", 675 | ] 676 | 677 | [[package]] 678 | name = "tiny-keccak" 679 | version = "2.0.2" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 682 | dependencies = [ 683 | "crunchy", 684 | ] 685 | 686 | [[package]] 687 | name = "typenum" 688 | version = "1.17.0" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 691 | 692 | [[package]] 693 | name = "unarray" 694 | version = "0.1.4" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" 697 | 698 | [[package]] 699 | name = "unicode-ident" 700 | version = "1.0.12" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 703 | 704 | [[package]] 705 | name = "unicode-segmentation" 706 | version = "1.10.1" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 709 | 710 | [[package]] 711 | name = "valuable" 712 | version = "0.1.0" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 715 | 716 | [[package]] 717 | name = "version_check" 718 | version = "0.9.4" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 721 | 722 | [[package]] 723 | name = "wait-timeout" 724 | version = "0.2.0" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 727 | dependencies = [ 728 | "libc", 729 | ] 730 | 731 | [[package]] 732 | name = "wasi" 733 | version = "0.11.0+wasi-snapshot-preview1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 736 | 737 | [[package]] 738 | name = "wee_alloc" 739 | version = "0.4.5" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" 742 | dependencies = [ 743 | "cfg-if 0.1.10", 744 | "libc", 745 | "memory_units", 746 | "winapi", 747 | ] 748 | 749 | [[package]] 750 | name = "winapi" 751 | version = "0.3.9" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 754 | dependencies = [ 755 | "winapi-i686-pc-windows-gnu", 756 | "winapi-x86_64-pc-windows-gnu", 757 | ] 758 | 759 | [[package]] 760 | name = "winapi-i686-pc-windows-gnu" 761 | version = "0.4.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 764 | 765 | [[package]] 766 | name = "winapi-x86_64-pc-windows-gnu" 767 | version = "0.4.0" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 770 | 771 | [[package]] 772 | name = "windows-sys" 773 | version = "0.52.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 776 | dependencies = [ 777 | "windows-targets", 778 | ] 779 | 780 | [[package]] 781 | name = "windows-targets" 782 | version = "0.52.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 785 | dependencies = [ 786 | "windows_aarch64_gnullvm", 787 | "windows_aarch64_msvc", 788 | "windows_i686_gnu", 789 | "windows_i686_msvc", 790 | "windows_x86_64_gnu", 791 | "windows_x86_64_gnullvm", 792 | "windows_x86_64_msvc", 793 | ] 794 | 795 | [[package]] 796 | name = "windows_aarch64_gnullvm" 797 | version = "0.52.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 800 | 801 | [[package]] 802 | name = "windows_aarch64_msvc" 803 | version = "0.52.0" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 806 | 807 | [[package]] 808 | name = "windows_i686_gnu" 809 | version = "0.52.0" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 812 | 813 | [[package]] 814 | name = "windows_i686_msvc" 815 | version = "0.52.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 818 | 819 | [[package]] 820 | name = "windows_x86_64_gnu" 821 | version = "0.52.0" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 824 | 825 | [[package]] 826 | name = "windows_x86_64_gnullvm" 827 | version = "0.52.0" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 830 | 831 | [[package]] 832 | name = "windows_x86_64_msvc" 833 | version = "0.52.0" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 836 | 837 | [[package]] 838 | name = "zeroize" 839 | version = "1.7.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" 842 | -------------------------------------------------------------------------------- /benchmark/erc6909_benchmark/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "erc6909_benchmark" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | alloy-primitives = "0.3.1" 8 | alloy-sol-types = "0.3.1" 9 | stylus-sdk = "0.4.2" 10 | rustmate = { path = "../../" } 11 | 12 | [features] 13 | export-abi = ["stylus-sdk/export-abi"] 14 | 15 | [lib] 16 | crate-type = ["lib", "cdylib"] -------------------------------------------------------------------------------- /benchmark/erc6909_benchmark/snapshot.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import argparse 3 | 4 | # Initialize parser 5 | parser = argparse.ArgumentParser( 6 | prog='ERC6909 Benchmark', 7 | description='Run gas benchmark on ERC6909 implementations') 8 | 9 | # Adding optional argument 10 | parser.add_argument("-addr", "--address", help = "Use a specific contract address") 11 | 12 | # Read arguments from command line 13 | args = parser.parse_args() 14 | 15 | def run_benchmark(address): 16 | functions = { 17 | 'transfer(address,uint256,uint256)': ['(bool)', address, '1', '1'], 18 | 'transferFrom(address,address,uint256,uint256)': ['(bool)', address, address, '1', '1'], 19 | 'approve(address,uint256,uint256)': ['(bool)', address, '1', '1'], 20 | 'setOperator(address,bool)': ['(bool)', address, 'true'], 21 | 'supportsInterface(bytes4)': ['(bool)', '0x80ac58cd'] 22 | } 23 | 24 | # Run estimates and write to snapshot file 25 | with open('.gas-snapshot', 'w') as snapshot: 26 | for function, args in functions.items(): 27 | gas = subprocess.run(['cast', 'estimate', address, function + args[0]] + args[1:] + ['--rpc-url', 'http://localhost:8547'], stdout=subprocess.PIPE).stdout.decode("utf-8")[:-1] 28 | snapshot.write(f'ERC6909:{function} (gas: {gas})\n') 29 | 30 | print(subprocess.run(['cat', '.gas-snapshot'], stdout=subprocess.PIPE).stdout.decode("utf-8")) 31 | 32 | if args.address: 33 | print(f"Using {args.address}...") 34 | address = args.address 35 | else: 36 | contract = subprocess.run(['cargo', 'stylus', 'deploy', '-e', 'http://localhost:8547', '--private-key', '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'], stdout=subprocess.PIPE).stdout.decode("utf-8") 37 | location = contract.find('Base') 38 | address = contract[location-49:location-7] 39 | 40 | run_benchmark(address) -------------------------------------------------------------------------------- /benchmark/erc6909_benchmark/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Only run this as a WASM if the export-abi feature is not set. 2 | #![cfg_attr(not(feature = "export-abi"), no_main)] 3 | extern crate alloc; 4 | 5 | use rustmate::tokens::erc6909::{ERC6909Params, ERC6909}; 6 | use stylus_sdk::prelude::*; 7 | 8 | pub struct SampleParams; 9 | 10 | /// Immutable definitions 11 | impl ERC6909Params for SampleParams {} 12 | 13 | // The contract 14 | sol_storage! { 15 | #[entrypoint] // Makes MyToken the entrypoint 16 | pub struct MyToken { 17 | #[borrow] // Allows ERC6909 to access MyToken's storage and make calls 18 | ERC6909 erc6909; 19 | } 20 | } 21 | 22 | #[external] 23 | #[inherit(ERC6909)] 24 | impl MyToken {} 25 | -------------------------------------------------------------------------------- /benchmark/erc721_benchmark/.gas-snapshot: -------------------------------------------------------------------------------- 1 | ERC721:name() (gas: 23286) 2 | ERC721:symbol() (gas: 23225) 3 | ERC721:ownerOf(uint256) (gas: ) 4 | ERC721:balanceOf(address) (gas: 27094) 5 | ERC721:getApproved(uint256) (gas: 26749) 6 | ERC721:isApprovedForAll(address,address) (gas: 28447) 7 | ERC721:tokenURI(uint256) (gas: 24293) 8 | ERC721:approve(address,uint256) (gas: 48693) 9 | ERC721:setApprovalForAll(address,bool) (gas: 51279) 10 | ERC721:transferFrom(address,address,uint256) (gas: ) 11 | ERC721:safeTransferFrom(address,address,uint256) (gas: ) 12 | ERC721:safeTransferFrom(address,address,uint256,bytes) (gas: ) 13 | ERC721:supportsInterface(bytes4) (gas: 21983) -------------------------------------------------------------------------------- /benchmark/erc721_benchmark/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "alloy-primitives" 16 | version = "0.3.3" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" 19 | dependencies = [ 20 | "alloy-rlp", 21 | "bytes", 22 | "cfg-if 1.0.0", 23 | "const-hex", 24 | "derive_more", 25 | "hex-literal", 26 | "itoa", 27 | "proptest", 28 | "ruint", 29 | "serde", 30 | "tiny-keccak", 31 | ] 32 | 33 | [[package]] 34 | name = "alloy-rlp" 35 | version = "0.3.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" 38 | dependencies = [ 39 | "arrayvec", 40 | "bytes", 41 | ] 42 | 43 | [[package]] 44 | name = "alloy-sol-macro" 45 | version = "0.3.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "a74ceeffdacf9dd0910404d743d07273776fd17b85f9cb17b49a97e5c6055ce9" 48 | dependencies = [ 49 | "dunce", 50 | "heck", 51 | "proc-macro2", 52 | "quote", 53 | "syn 2.0.48", 54 | "syn-solidity", 55 | "tiny-keccak", 56 | ] 57 | 58 | [[package]] 59 | name = "alloy-sol-types" 60 | version = "0.3.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "d5f347cb6bb307b3802ec455ef43ce00f5e590e0ceca3d2f3b070f5ee367e235" 63 | dependencies = [ 64 | "alloy-primitives", 65 | "alloy-sol-macro", 66 | "const-hex", 67 | "serde", 68 | ] 69 | 70 | [[package]] 71 | name = "arrayvec" 72 | version = "0.7.4" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 75 | 76 | [[package]] 77 | name = "autocfg" 78 | version = "1.1.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 81 | 82 | [[package]] 83 | name = "bit-set" 84 | version = "0.5.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 87 | dependencies = [ 88 | "bit-vec", 89 | ] 90 | 91 | [[package]] 92 | name = "bit-vec" 93 | version = "0.6.3" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 96 | 97 | [[package]] 98 | name = "bitflags" 99 | version = "1.3.2" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 102 | 103 | [[package]] 104 | name = "bitflags" 105 | version = "2.4.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 108 | 109 | [[package]] 110 | name = "block-buffer" 111 | version = "0.10.4" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 114 | dependencies = [ 115 | "generic-array", 116 | ] 117 | 118 | [[package]] 119 | name = "bytes" 120 | version = "1.5.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 123 | 124 | [[package]] 125 | name = "cfg-if" 126 | version = "0.1.10" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 129 | 130 | [[package]] 131 | name = "cfg-if" 132 | version = "1.0.0" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 135 | 136 | [[package]] 137 | name = "const-hex" 138 | version = "1.10.0" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" 141 | dependencies = [ 142 | "cfg-if 1.0.0", 143 | "cpufeatures", 144 | "hex", 145 | "proptest", 146 | "serde", 147 | ] 148 | 149 | [[package]] 150 | name = "convert_case" 151 | version = "0.4.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 154 | 155 | [[package]] 156 | name = "convert_case" 157 | version = "0.6.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 160 | dependencies = [ 161 | "unicode-segmentation", 162 | ] 163 | 164 | [[package]] 165 | name = "cpufeatures" 166 | version = "0.2.12" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 169 | dependencies = [ 170 | "libc", 171 | ] 172 | 173 | [[package]] 174 | name = "crunchy" 175 | version = "0.2.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 178 | 179 | [[package]] 180 | name = "crypto-common" 181 | version = "0.1.6" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 184 | dependencies = [ 185 | "generic-array", 186 | "typenum", 187 | ] 188 | 189 | [[package]] 190 | name = "derivative" 191 | version = "2.2.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 194 | dependencies = [ 195 | "proc-macro2", 196 | "quote", 197 | "syn 1.0.109", 198 | ] 199 | 200 | [[package]] 201 | name = "derive_more" 202 | version = "0.99.17" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 205 | dependencies = [ 206 | "convert_case 0.4.0", 207 | "proc-macro2", 208 | "quote", 209 | "rustc_version", 210 | "syn 1.0.109", 211 | ] 212 | 213 | [[package]] 214 | name = "digest" 215 | version = "0.10.7" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 218 | dependencies = [ 219 | "block-buffer", 220 | "crypto-common", 221 | ] 222 | 223 | [[package]] 224 | name = "dunce" 225 | version = "1.0.4" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 228 | 229 | [[package]] 230 | name = "erc721_benchmark" 231 | version = "0.1.0" 232 | dependencies = [ 233 | "alloy-primitives", 234 | "alloy-sol-types", 235 | "rustmate", 236 | "stylus-sdk", 237 | ] 238 | 239 | [[package]] 240 | name = "errno" 241 | version = "0.3.8" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 244 | dependencies = [ 245 | "libc", 246 | "windows-sys", 247 | ] 248 | 249 | [[package]] 250 | name = "fastrand" 251 | version = "2.0.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 254 | 255 | [[package]] 256 | name = "fnv" 257 | version = "1.0.7" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 260 | 261 | [[package]] 262 | name = "generic-array" 263 | version = "0.14.7" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 266 | dependencies = [ 267 | "typenum", 268 | "version_check", 269 | ] 270 | 271 | [[package]] 272 | name = "getrandom" 273 | version = "0.2.11" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" 276 | dependencies = [ 277 | "cfg-if 1.0.0", 278 | "libc", 279 | "wasi", 280 | ] 281 | 282 | [[package]] 283 | name = "heck" 284 | version = "0.4.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 287 | 288 | [[package]] 289 | name = "hex" 290 | version = "0.4.3" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 293 | 294 | [[package]] 295 | name = "hex-literal" 296 | version = "0.4.1" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 299 | 300 | [[package]] 301 | name = "itoa" 302 | version = "1.0.10" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 305 | 306 | [[package]] 307 | name = "keccak" 308 | version = "0.1.4" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" 311 | dependencies = [ 312 | "cpufeatures", 313 | ] 314 | 315 | [[package]] 316 | name = "keccak-const" 317 | version = "0.2.0" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "57d8d8ce877200136358e0bbff3a77965875db3af755a11e1fa6b1b3e2df13ea" 320 | 321 | [[package]] 322 | name = "lazy_static" 323 | version = "1.4.0" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 326 | 327 | [[package]] 328 | name = "libc" 329 | version = "0.2.151" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" 332 | 333 | [[package]] 334 | name = "libm" 335 | version = "0.2.8" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 338 | 339 | [[package]] 340 | name = "linux-raw-sys" 341 | version = "0.4.12" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" 344 | 345 | [[package]] 346 | name = "memchr" 347 | version = "2.7.1" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 350 | 351 | [[package]] 352 | name = "memory_units" 353 | version = "0.4.0" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" 356 | 357 | [[package]] 358 | name = "num-traits" 359 | version = "0.2.17" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 362 | dependencies = [ 363 | "autocfg", 364 | "libm", 365 | ] 366 | 367 | [[package]] 368 | name = "ppv-lite86" 369 | version = "0.2.17" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 372 | 373 | [[package]] 374 | name = "proc-macro2" 375 | version = "1.0.76" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" 378 | dependencies = [ 379 | "unicode-ident", 380 | ] 381 | 382 | [[package]] 383 | name = "proptest" 384 | version = "1.4.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" 387 | dependencies = [ 388 | "bit-set", 389 | "bit-vec", 390 | "bitflags 2.4.1", 391 | "lazy_static", 392 | "num-traits", 393 | "rand", 394 | "rand_chacha", 395 | "rand_xorshift", 396 | "regex-syntax", 397 | "rusty-fork", 398 | "tempfile", 399 | "unarray", 400 | ] 401 | 402 | [[package]] 403 | name = "quick-error" 404 | version = "1.2.3" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 407 | 408 | [[package]] 409 | name = "quote" 410 | version = "1.0.35" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 413 | dependencies = [ 414 | "proc-macro2", 415 | ] 416 | 417 | [[package]] 418 | name = "rand" 419 | version = "0.8.5" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 422 | dependencies = [ 423 | "libc", 424 | "rand_chacha", 425 | "rand_core", 426 | ] 427 | 428 | [[package]] 429 | name = "rand_chacha" 430 | version = "0.3.1" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 433 | dependencies = [ 434 | "ppv-lite86", 435 | "rand_core", 436 | ] 437 | 438 | [[package]] 439 | name = "rand_core" 440 | version = "0.6.4" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 443 | dependencies = [ 444 | "getrandom", 445 | ] 446 | 447 | [[package]] 448 | name = "rand_xorshift" 449 | version = "0.3.0" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" 452 | dependencies = [ 453 | "rand_core", 454 | ] 455 | 456 | [[package]] 457 | name = "redox_syscall" 458 | version = "0.4.1" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 461 | dependencies = [ 462 | "bitflags 1.3.2", 463 | ] 464 | 465 | [[package]] 466 | name = "regex" 467 | version = "1.10.2" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 470 | dependencies = [ 471 | "aho-corasick", 472 | "memchr", 473 | "regex-automata", 474 | "regex-syntax", 475 | ] 476 | 477 | [[package]] 478 | name = "regex-automata" 479 | version = "0.4.3" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 482 | dependencies = [ 483 | "aho-corasick", 484 | "memchr", 485 | "regex-syntax", 486 | ] 487 | 488 | [[package]] 489 | name = "regex-syntax" 490 | version = "0.8.2" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 493 | 494 | [[package]] 495 | name = "ruint" 496 | version = "1.11.1" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" 499 | dependencies = [ 500 | "proptest", 501 | "rand", 502 | "ruint-macro", 503 | "serde", 504 | "valuable", 505 | "zeroize", 506 | ] 507 | 508 | [[package]] 509 | name = "ruint-macro" 510 | version = "1.1.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" 513 | 514 | [[package]] 515 | name = "rustc_version" 516 | version = "0.4.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 519 | dependencies = [ 520 | "semver", 521 | ] 522 | 523 | [[package]] 524 | name = "rustix" 525 | version = "0.38.28" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" 528 | dependencies = [ 529 | "bitflags 2.4.1", 530 | "errno", 531 | "libc", 532 | "linux-raw-sys", 533 | "windows-sys", 534 | ] 535 | 536 | [[package]] 537 | name = "rustmate" 538 | version = "0.1.0" 539 | dependencies = [ 540 | "alloy-primitives", 541 | "alloy-sol-types", 542 | "stylus-sdk", 543 | "wee_alloc", 544 | ] 545 | 546 | [[package]] 547 | name = "rusty-fork" 548 | version = "0.3.0" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" 551 | dependencies = [ 552 | "fnv", 553 | "quick-error", 554 | "tempfile", 555 | "wait-timeout", 556 | ] 557 | 558 | [[package]] 559 | name = "semver" 560 | version = "1.0.21" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" 563 | 564 | [[package]] 565 | name = "serde" 566 | version = "1.0.195" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" 569 | dependencies = [ 570 | "serde_derive", 571 | ] 572 | 573 | [[package]] 574 | name = "serde_derive" 575 | version = "1.0.195" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" 578 | dependencies = [ 579 | "proc-macro2", 580 | "quote", 581 | "syn 2.0.48", 582 | ] 583 | 584 | [[package]] 585 | name = "sha3" 586 | version = "0.10.8" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 589 | dependencies = [ 590 | "digest", 591 | "keccak", 592 | ] 593 | 594 | [[package]] 595 | name = "stylus-proc" 596 | version = "0.4.1" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "87a941ef748a746cd7b7075975073962d561934ffe91c056e22e20c8e89b64af" 599 | dependencies = [ 600 | "alloy-primitives", 601 | "alloy-sol-types", 602 | "cfg-if 1.0.0", 603 | "convert_case 0.6.0", 604 | "lazy_static", 605 | "proc-macro2", 606 | "quote", 607 | "regex", 608 | "sha3", 609 | "syn 1.0.109", 610 | "syn-solidity", 611 | ] 612 | 613 | [[package]] 614 | name = "stylus-sdk" 615 | version = "0.4.2" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "12c2d6fedbd0393e2b9f0259ca239c7ede9f87a89933627119b9dc038902d7e9" 618 | dependencies = [ 619 | "alloy-primitives", 620 | "alloy-sol-types", 621 | "cfg-if 1.0.0", 622 | "derivative", 623 | "fnv", 624 | "hex", 625 | "keccak-const", 626 | "lazy_static", 627 | "regex", 628 | "stylus-proc", 629 | ] 630 | 631 | [[package]] 632 | name = "syn" 633 | version = "1.0.109" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 636 | dependencies = [ 637 | "proc-macro2", 638 | "quote", 639 | "unicode-ident", 640 | ] 641 | 642 | [[package]] 643 | name = "syn" 644 | version = "2.0.48" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" 647 | dependencies = [ 648 | "proc-macro2", 649 | "quote", 650 | "unicode-ident", 651 | ] 652 | 653 | [[package]] 654 | name = "syn-solidity" 655 | version = "0.3.1" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "e5f995d2140b0f751dbe94365be2591edbf3d1b75dcfaeac14183abbd2ff07bd" 658 | dependencies = [ 659 | "proc-macro2", 660 | "quote", 661 | "syn 2.0.48", 662 | ] 663 | 664 | [[package]] 665 | name = "tempfile" 666 | version = "3.9.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" 669 | dependencies = [ 670 | "cfg-if 1.0.0", 671 | "fastrand", 672 | "redox_syscall", 673 | "rustix", 674 | "windows-sys", 675 | ] 676 | 677 | [[package]] 678 | name = "tiny-keccak" 679 | version = "2.0.2" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 682 | dependencies = [ 683 | "crunchy", 684 | ] 685 | 686 | [[package]] 687 | name = "typenum" 688 | version = "1.17.0" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 691 | 692 | [[package]] 693 | name = "unarray" 694 | version = "0.1.4" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" 697 | 698 | [[package]] 699 | name = "unicode-ident" 700 | version = "1.0.12" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 703 | 704 | [[package]] 705 | name = "unicode-segmentation" 706 | version = "1.10.1" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 709 | 710 | [[package]] 711 | name = "valuable" 712 | version = "0.1.0" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 715 | 716 | [[package]] 717 | name = "version_check" 718 | version = "0.9.4" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 721 | 722 | [[package]] 723 | name = "wait-timeout" 724 | version = "0.2.0" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 727 | dependencies = [ 728 | "libc", 729 | ] 730 | 731 | [[package]] 732 | name = "wasi" 733 | version = "0.11.0+wasi-snapshot-preview1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 736 | 737 | [[package]] 738 | name = "wee_alloc" 739 | version = "0.4.5" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" 742 | dependencies = [ 743 | "cfg-if 0.1.10", 744 | "libc", 745 | "memory_units", 746 | "winapi", 747 | ] 748 | 749 | [[package]] 750 | name = "winapi" 751 | version = "0.3.9" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 754 | dependencies = [ 755 | "winapi-i686-pc-windows-gnu", 756 | "winapi-x86_64-pc-windows-gnu", 757 | ] 758 | 759 | [[package]] 760 | name = "winapi-i686-pc-windows-gnu" 761 | version = "0.4.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 764 | 765 | [[package]] 766 | name = "winapi-x86_64-pc-windows-gnu" 767 | version = "0.4.0" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 770 | 771 | [[package]] 772 | name = "windows-sys" 773 | version = "0.52.0" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 776 | dependencies = [ 777 | "windows-targets", 778 | ] 779 | 780 | [[package]] 781 | name = "windows-targets" 782 | version = "0.52.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 785 | dependencies = [ 786 | "windows_aarch64_gnullvm", 787 | "windows_aarch64_msvc", 788 | "windows_i686_gnu", 789 | "windows_i686_msvc", 790 | "windows_x86_64_gnu", 791 | "windows_x86_64_gnullvm", 792 | "windows_x86_64_msvc", 793 | ] 794 | 795 | [[package]] 796 | name = "windows_aarch64_gnullvm" 797 | version = "0.52.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 800 | 801 | [[package]] 802 | name = "windows_aarch64_msvc" 803 | version = "0.52.0" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 806 | 807 | [[package]] 808 | name = "windows_i686_gnu" 809 | version = "0.52.0" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 812 | 813 | [[package]] 814 | name = "windows_i686_msvc" 815 | version = "0.52.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 818 | 819 | [[package]] 820 | name = "windows_x86_64_gnu" 821 | version = "0.52.0" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 824 | 825 | [[package]] 826 | name = "windows_x86_64_gnullvm" 827 | version = "0.52.0" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 830 | 831 | [[package]] 832 | name = "windows_x86_64_msvc" 833 | version = "0.52.0" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 836 | 837 | [[package]] 838 | name = "zeroize" 839 | version = "1.7.0" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" 842 | -------------------------------------------------------------------------------- /benchmark/erc721_benchmark/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "erc721_benchmark" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | alloy-primitives = "0.3.1" 8 | alloy-sol-types = "0.3.1" 9 | stylus-sdk = "0.4.2" 10 | rustmate = { path = "../../" } 11 | 12 | [features] 13 | export-abi = ["stylus-sdk/export-abi"] 14 | 15 | [lib] 16 | crate-type = ["lib", "cdylib"] -------------------------------------------------------------------------------- /benchmark/erc721_benchmark/snapshot.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import argparse 3 | 4 | # Initialize parser 5 | parser = argparse.ArgumentParser( 6 | prog='ERC721 Benchmark', 7 | description='Run gas benchmark on ERC721 implementations') 8 | 9 | # Adding optional argument 10 | parser.add_argument("-addr", "--address", help = "Use a specific contract address") 11 | 12 | # Read arguments from command line 13 | args = parser.parse_args() 14 | 15 | def run_benchmark(address): 16 | functions = { 17 | 'name()': ['(string)'], 18 | 'symbol()': ['(string)'], 19 | 'ownerOf(uint256)': ['(address)', '1'], 20 | 'balanceOf(address)': ['(uint256)', address], 21 | 'getApproved(uint256)': ['(address)', '1'], 22 | 'isApprovedForAll(address,address)': ['(bool)', address, address], 23 | 'tokenURI(uint256)': ['(string)', '1'], 24 | 'approve(address,uint256)': ['(bool)', address, '1'], 25 | 'setApprovalForAll(address,bool)': ['(bool)', address, 'true'], 26 | 'transferFrom(address,address,uint256)': ['()', address, address, '1'], 27 | 'safeTransferFrom(address,address,uint256)': ['()', address, address, '1'], 28 | 'safeTransferFrom(address,address,uint256,bytes)': ['()', address, address, '1', '0x'], 29 | 'supportsInterface(bytes4)': ['(bool)', '0x80ac58cd'] 30 | } 31 | 32 | # Run estimates and write to snapshot file 33 | with open('.gas-snapshot', 'w') as snapshot: 34 | for function, args in functions.items(): 35 | gas = subprocess.run(['cast', 'estimate', address, function + args[0]] + args[1:] + ['--rpc-url', 'http://localhost:8547'], stdout=subprocess.PIPE).stdout.decode("utf-8")[:-1] 36 | snapshot.write(f'ERC721:{function} (gas: {gas})\n') 37 | 38 | print(subprocess.run(['cat', '.gas-snapshot'], stdout=subprocess.PIPE).stdout.decode("utf-8")) 39 | 40 | if args.address: 41 | print(f"Using {args.address}...") 42 | address = args.address 43 | else: 44 | contract = subprocess.run(['cargo', 'stylus', 'deploy', '-e', 'http://localhost:8547', '--private-key', '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'], stdout=subprocess.PIPE).stdout.decode("utf-8") 45 | location = contract.find('Base') 46 | address = contract[location-49:location-7] 47 | 48 | run_benchmark(address) -------------------------------------------------------------------------------- /benchmark/erc721_benchmark/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Only run this as a WASM if the export-abi feature is not set. 2 | #![cfg_attr(not(feature = "export-abi"), no_main)] 3 | extern crate alloc; 4 | 5 | use rustmate::tokens::erc721::{ERC721Params, ERC721}; 6 | use stylus_sdk::{alloy_primitives::U256, prelude::*}; 7 | 8 | pub struct SampleParams; 9 | 10 | /// Immutable definitions 11 | impl ERC721Params for SampleParams { 12 | const NAME: &'static str = "MyNFT"; 13 | const SYMBOL: &'static str = "NFT"; 14 | 15 | fn token_uri(id: U256) -> String { 16 | format!("ipfs://hash/{}", id) 17 | } 18 | } 19 | 20 | // The contract 21 | sol_storage! { 22 | #[entrypoint] // Makes SampleNFT the entrypoint 23 | pub struct SampleNFT { 24 | #[borrow] // Allows erc721 to access SampleNFT's storage and make calls 25 | ERC721 erc721; 26 | } 27 | } 28 | 29 | #[external] 30 | #[inherit(ERC721)] 31 | impl SampleNFT {} 32 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | force_multiline_blocks=true 2 | imports_indent="Block" 3 | imports_layout="Vertical" 4 | -------------------------------------------------------------------------------- /src/auth/auth.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the Auth library. 2 | //! 3 | //! The eponymous [`Auth`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! Note that this code is unaudited and not fit for production use. 7 | 8 | use alloy_primitives::{ 9 | Address, 10 | FixedBytes, 11 | }; 12 | use alloy_sol_types::{ 13 | sol, 14 | SolError, 15 | }; 16 | use core::{ 17 | borrow::BorrowMut, 18 | marker::PhantomData, 19 | }; 20 | use stylus_sdk::{ 21 | contract, 22 | evm, 23 | msg, 24 | prelude::*, 25 | }; 26 | 27 | pub trait AuthParams {} 28 | 29 | sol_storage! { 30 | pub struct Auth { 31 | address owner; 32 | address authority; 33 | bool initialized; 34 | PhantomData phantom; 35 | } 36 | } 37 | 38 | // Declare events 39 | sol! { 40 | event OwnershipTransferred(address indexed user, address indexed newOwner); 41 | event AuthorityUpdated(address indexed user, address indexed newAuthority); 42 | 43 | error Unauthorized(); 44 | error AlreadyInitialized(); 45 | error InvalidInitialize(); 46 | } 47 | 48 | /// Represents the ways methods may fail. 49 | pub enum AuthError { 50 | Unauthorized(Unauthorized), 51 | CallFailed(stylus_sdk::call::Error), 52 | AlreadyInitialized(AlreadyInitialized), 53 | InvalidInitialize(InvalidInitialize), 54 | } 55 | 56 | impl From for AuthError { 57 | fn from(err: stylus_sdk::call::Error) -> Self { 58 | Self::CallFailed(err) 59 | } 60 | } 61 | 62 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 63 | impl From for Vec { 64 | fn from(val: AuthError) -> Self { 65 | match val { 66 | AuthError::Unauthorized(err) => err.encode(), 67 | AuthError::CallFailed(err) => err.into(), 68 | AuthError::AlreadyInitialized(err) => err.encode(), 69 | AuthError::InvalidInitialize(err) => err.encode(), 70 | } 71 | } 72 | } 73 | 74 | /// Simplifies the result type for the contract's methods. 75 | type Result = core::result::Result; 76 | 77 | impl Auth { 78 | fn can_call( 79 | storage: &mut S, 80 | authority: Address, 81 | user: Address, 82 | target: Address, 83 | sig: FixedBytes<4>, 84 | ) -> Result { 85 | let authority_given = Authority::new(authority); 86 | let status = authority_given.can_call(&mut *storage, user, target, sig)?; 87 | 88 | Ok(status) 89 | } 90 | 91 | fn is_authorized>( 92 | storage: &mut S, 93 | user: Address, 94 | function_sig: FixedBytes<4>, 95 | ) -> Result { 96 | let authority = storage.borrow_mut().authority.get(); 97 | 98 | return Ok(authority != Address::ZERO 99 | && Self::can_call(storage, authority, user, contract::address(), function_sig)? 100 | || user == storage.borrow_mut().owner.get()); 101 | } 102 | } 103 | 104 | #[external] 105 | impl Auth { 106 | pub fn owner(&self) -> Result
{ 107 | Ok(self.owner.get()) 108 | } 109 | 110 | pub fn authority(&self) -> Result { 111 | Ok(Authority::new(self.authority.get())) 112 | } 113 | 114 | pub fn set_authority>( 115 | storage: &mut S, 116 | new_authority: Address, 117 | ) -> Result<()> { 118 | let authority = storage.borrow_mut().authority.get(); 119 | 120 | if msg::sender() != storage.borrow_mut().owner.get() 121 | || !(Self::can_call( 122 | storage, 123 | authority, 124 | msg::sender(), 125 | contract::address(), 126 | FixedBytes(contract::args(4).try_into().unwrap()), 127 | )?) 128 | { 129 | return Err(AuthError::Unauthorized(Unauthorized {})); 130 | } 131 | 132 | storage.borrow_mut().authority.set(new_authority); 133 | 134 | evm::log(AuthorityUpdated { 135 | user: msg::sender(), 136 | newAuthority: new_authority, 137 | }); 138 | 139 | Ok(()) 140 | } 141 | 142 | pub fn transfer_ownership>( 143 | storage: &mut S, 144 | new_owner: Address, 145 | ) -> Result<()> { 146 | if !Self::is_authorized( 147 | storage, 148 | msg::sender(), 149 | FixedBytes(contract::args(4).try_into().unwrap()), 150 | )? { 151 | return Err(AuthError::Unauthorized(Unauthorized {})); 152 | } 153 | 154 | storage.borrow_mut().owner.set(new_owner); 155 | 156 | evm::log(OwnershipTransferred { 157 | user: msg::sender(), 158 | newOwner: new_owner, 159 | }); 160 | 161 | Ok(()) 162 | } 163 | 164 | pub fn initialize(&mut self, _owner: Address, _authority: Address) -> Result<()> { 165 | if self.initialized.get() { 166 | return Err(AuthError::AlreadyInitialized(AlreadyInitialized {})); 167 | } 168 | 169 | if _owner.is_zero() || _authority.is_zero() { 170 | return Err(AuthError::InvalidInitialize(InvalidInitialize {})); 171 | } 172 | 173 | self.owner.set(_owner); 174 | self.authority.set(_authority); 175 | 176 | Ok(()) 177 | } 178 | } 179 | 180 | sol_interface! { 181 | interface Authority { 182 | function canCall( 183 | address, 184 | address, 185 | bytes4 186 | ) external returns (bool); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/auth/mod.rs: -------------------------------------------------------------------------------- 1 | #[allow(clippy::module_inception)] 2 | pub mod auth; 3 | pub mod owned; -------------------------------------------------------------------------------- /src/auth/owned.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of an Owned contract. 2 | //! 3 | //! The eponymous [`Owned`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! Note that this code is unaudited and not fit for production use. 7 | 8 | use alloc::vec::Vec; 9 | use alloy_primitives::Address; 10 | use alloy_sol_types::{ 11 | sol, 12 | SolError, 13 | }; 14 | use core::marker::PhantomData; 15 | use stylus_sdk::{ 16 | evm, 17 | msg, 18 | prelude::*, 19 | }; 20 | 21 | pub trait OwnedParams {} 22 | 23 | sol_storage! { 24 | pub struct Owned { 25 | address owner; 26 | bool initialized; 27 | PhantomData phantom; 28 | } 29 | } 30 | 31 | // Declare events and Solidity error types 32 | sol! { 33 | event OwnershipTransferred(address indexed user, address indexed newOwner); 34 | 35 | error Unauthorized(); 36 | error AlreadyInitialized(); 37 | error InvalidInitialize(); 38 | } 39 | 40 | /// Represents the ways methods may fail. 41 | pub enum OwnedError { 42 | Unauthorized(Unauthorized), 43 | AlreadyInitialized(AlreadyInitialized), 44 | InvalidInitialize(InvalidInitialize), 45 | } 46 | 47 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 48 | impl From for Vec { 49 | fn from(val: OwnedError) -> Self { 50 | match val { 51 | OwnedError::Unauthorized(err) => err.encode(), 52 | OwnedError::AlreadyInitialized(err) => err.encode(), 53 | OwnedError::InvalidInitialize(err) => err.encode(), 54 | } 55 | } 56 | } 57 | 58 | /// Simplifies the result type for the contract's methods. 59 | type Result = core::result::Result; 60 | 61 | impl Owned { 62 | pub fn only_owner(&mut self) -> Result<()> { 63 | if msg::sender() != self.owner.get() { 64 | return Err(OwnedError::Unauthorized(Unauthorized {})); 65 | } 66 | 67 | Ok(()) 68 | } 69 | } 70 | 71 | #[external] 72 | impl Owned { 73 | pub fn transfer_ownership(&mut self, new_owner: Address) -> Result<()> { 74 | self.only_owner()?; 75 | 76 | self.owner.set(new_owner); 77 | 78 | evm::log(OwnershipTransferred { 79 | user: msg::sender(), 80 | newOwner: new_owner, 81 | }); 82 | 83 | Ok(()) 84 | } 85 | 86 | pub fn initialize(&mut self, _owner: Address) -> Result<()> { 87 | if self.initialized.get() { 88 | return Err(OwnedError::AlreadyInitialized(AlreadyInitialized {})); 89 | } 90 | 91 | if _owner.is_zero() { 92 | return Err(OwnedError::InvalidInitialize(InvalidInitialize {})); 93 | } 94 | 95 | self.owner.set(_owner); 96 | 97 | Ok(()) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Only run this as a WASM if the export-abi feature is not set. 2 | #![cfg_attr(not(feature = "export-abi"), no_main)] 3 | extern crate alloc; 4 | 5 | /// Initializes a custom, global allocator for Rust programs compiled to WASM. 6 | #[global_allocator] 7 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; 8 | 9 | pub mod auth; 10 | pub mod mixins; 11 | pub mod tokens; 12 | pub mod utils; 13 | -------------------------------------------------------------------------------- /src/mixins/erc4626.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "export-abi"), no_main, no_std)] 2 | extern crate alloc; 3 | 4 | use crate::erc20::{ERC20Params, ERC20}; 5 | use alloc::vec::Vec; 6 | use alloy_primitives::{Address, B256, U256}; 7 | use alloy_sol_types::{sol, SolError}; 8 | use stylus_sdk::{evm, msg, prelude::*}; 9 | 10 | #[global_allocator] 11 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; 12 | 13 | mod erc20; 14 | 15 | struct ERC4626Params; 16 | 17 | /// Immutable definitions 18 | impl ERC20Params for ERC4626Params { 19 | const NAME: &'static str = "Vault"; 20 | const SYMBOL: &'static str = "VLT"; 21 | const DECIMALS: u8 = 18; 22 | const INITIAL_CHAIN_ID: u64 = 1; 23 | const INITIAL_DOMAIN_SEPARATOR: B256 = B256::ZERO; 24 | } 25 | 26 | // The contract 27 | sol_storage! { 28 | #[entrypoint] // Makes ERC4626 the entrypoint 29 | struct ERC4626 { 30 | #[borrow] // Allows ERC20 to access ERC4626's storage and make calls 31 | ERC20 erc20; 32 | address asset; 33 | bool initialized; 34 | } 35 | } 36 | 37 | sol! { 38 | event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); 39 | 40 | event Withdraw( 41 | address indexed caller, 42 | address indexed receiver, 43 | address indexed owner, 44 | uint256 assets, 45 | uint256 shares 46 | ); 47 | 48 | error Unauthorized(); 49 | error AlreadyInitialized(); 50 | error InvalidInitialize(); 51 | error ZeroShares(); 52 | } 53 | 54 | /// Represents the ways methods may fail. 55 | pub enum ERC4626Error { 56 | Unauthorized(Unauthorized), 57 | AlreadyInitialized(AlreadyInitialized), 58 | InvalidInitialize(InvalidInitialize), 59 | ZeroShares(ZeroShares), 60 | } 61 | 62 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 63 | impl From for Vec { 64 | fn from(val: ERC4626Error) -> Self { 65 | match val { 66 | ERC4626Error::Unauthorized(err) => err.encode(), 67 | ERC4626Error::AlreadyInitialized(err) => err.encode(), 68 | ERC4626Error::InvalidInitialize(err) => err.encode(), 69 | ERC4626Error::ZeroShares(err) => err.encode(), 70 | } 71 | } 72 | } 73 | 74 | /// Simplifies the result type for the contract's methods. 75 | type Result = core::result::Result; 76 | 77 | impl ERC4626 { 78 | pub fn before_withdraw(&mut self, assets: U256, shares: U256) {} 79 | 80 | pub fn after_deposit(&mut self, assets: U256, shares: U256) {} 81 | } 82 | 83 | #[external] 84 | #[inherit(ERC20)] 85 | impl ERC4626 { 86 | pub fn initialize(&mut self, _asset: Address) -> Result<()> { 87 | if self.initialized.get() { 88 | return Err(ERC4626Error::AlreadyInitialized(AlreadyInitialized {})); 89 | } 90 | 91 | if _asset.is_zero() { 92 | return Err(ERC4626Error::InvalidInitialize(InvalidInitialize {})); 93 | } 94 | 95 | self.asset.set(_asset); 96 | 97 | Ok(()) 98 | } 99 | 100 | pub fn deposit(&mut self, assets: U256, receiver: Address) -> Result { 101 | let shares = self.preview_deposit(assets)?; 102 | 103 | if shares == U256::from(0) { 104 | return Err(ERC4626Error::ZeroShares(ZeroShares {})); 105 | } 106 | 107 | // TODO: Fix below. 108 | // call!(self.asset).safe_transfer_from(msg::sender(), address!(self), assets); 109 | 110 | self.erc20.mint(receiver, shares); 111 | 112 | evm::log(Deposit { 113 | caller: msg::sender(), 114 | owner: receiver, 115 | assets, 116 | shares, 117 | }); 118 | 119 | self.after_deposit(assets, shares); 120 | 121 | Ok(shares) 122 | } 123 | 124 | pub fn mint(&mut self, shares: U256, receiver: Address) -> Result { 125 | let assets = self.preview_mint(shares)?; 126 | 127 | // TODO: Fix below. 128 | // call!(self.asset).safe_transfer_from(msg::sender(), address!(self), assets); 129 | 130 | self.erc20.mint(receiver, shares); 131 | 132 | evm::log(Deposit { 133 | caller: msg::sender(), 134 | owner: receiver, 135 | assets, 136 | shares, 137 | }); 138 | 139 | self.after_deposit(assets, shares); 140 | 141 | Ok(shares) 142 | } 143 | 144 | pub fn withdraw(&mut self, assets: U256, receiver: Address, owner: Address) -> Result { 145 | let shares = self.preview_withdraw(assets)?; 146 | 147 | if msg::sender() != owner { 148 | let allowed = self.erc20.allowance.get(owner).get(msg::sender()); 149 | 150 | if allowed != U256::MAX { 151 | self.erc20 152 | .allowance 153 | .setter(owner) 154 | .insert(msg::sender(), allowed - shares); 155 | } 156 | } 157 | 158 | self.before_withdraw(assets, shares); 159 | 160 | self.erc20.burn(owner, shares); 161 | 162 | evm::log(Withdraw { 163 | caller: msg::sender(), 164 | receiver, 165 | owner, 166 | assets, 167 | shares, 168 | }); 169 | 170 | // TODO: asset.safeTransfer(receiver, assets); 171 | 172 | Ok(shares) 173 | } 174 | 175 | pub fn redeem(&mut self, shares: U256, receiver: Address, owner: Address) -> Result { 176 | if msg::sender() != owner { 177 | let allowed = self.erc20.allowance.get(owner).get(msg::sender()); 178 | 179 | if allowed != U256::MAX { 180 | self.erc20 181 | .allowance 182 | .setter(owner) 183 | .insert(msg::sender(), allowed - shares); 184 | } 185 | } 186 | 187 | let assets = self.preview_redeem(shares)?; 188 | 189 | if assets == U256::from(0) { 190 | return Err(ERC4626Error::ZeroShares(ZeroShares {})); 191 | } 192 | 193 | self.before_withdraw(assets, shares); 194 | 195 | self.erc20.burn(owner, shares); 196 | 197 | evm::log(Withdraw { 198 | caller: msg::sender(), 199 | receiver, 200 | owner, 201 | assets, 202 | shares, 203 | }); 204 | 205 | // TODO: asset.safeTransfer(receiver, assets); 206 | 207 | Ok(assets) 208 | } 209 | 210 | pub fn total_assets() -> Result { 211 | Ok(U256::from(0)) 212 | } 213 | 214 | pub fn convert_to_shares(&mut self, assets: U256) -> Result { 215 | let supply = self.erc20.total_supply.get(); 216 | 217 | if supply == U256::from(0) { 218 | Ok(assets) 219 | } else { 220 | Ok(ERC4626::total_assets()?) 221 | // TODO: Fix with return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); 222 | } 223 | } 224 | 225 | pub fn convert_to_assets(&mut self, shares: U256) -> Result { 226 | let supply = self.erc20.total_supply.get(); 227 | 228 | if supply == U256::from(0) { 229 | Ok(shares) 230 | } else { 231 | Ok(ERC4626::total_assets()?) 232 | // TODO: Fix with return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); 233 | } 234 | } 235 | 236 | pub fn preview_deposit(&mut self, assets: U256) -> Result { 237 | Ok(self.convert_to_shares(assets)?) 238 | } 239 | 240 | pub fn preview_mint(&mut self, shares: U256) -> Result { 241 | let supply = self.erc20.total_supply.get(); 242 | 243 | if supply == U256::from(0) { 244 | Ok(shares) 245 | } else { 246 | Ok(ERC4626::total_assets()?) 247 | // TODO: Fix with shares.mulDivUp(totalAssets(), supply); 248 | } 249 | } 250 | 251 | pub fn preview_withdraw(&mut self, assets: U256) -> Result { 252 | let supply = self.erc20.total_supply.get(); 253 | 254 | if supply == U256::from(0) { 255 | Ok(assets) 256 | } else { 257 | Ok(ERC4626::total_assets()?) 258 | // TODO: Fix with assets.mulDivUp(supply, totalAssets()); 259 | } 260 | } 261 | 262 | pub fn preview_redeem(&mut self, shares: U256) -> Result { 263 | Ok(self.convert_to_assets(shares)?) 264 | } 265 | 266 | pub fn max_deposit(&mut self, _user: Address) -> Result { 267 | Ok(U256::MAX) 268 | } 269 | 270 | pub fn max_mint(&mut self, _user: Address) -> Result { 271 | Ok(U256::MAX) 272 | } 273 | 274 | pub fn max_withdraw(&mut self, owner: Address) -> Result { 275 | Ok(self.convert_to_assets(self.erc20.balance.get(owner))?) 276 | } 277 | 278 | pub fn max_redeem(&mut self, owner: Address) -> Result { 279 | Ok(self.erc20.balance.get(owner)) 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /src/mixins/mod.rs: -------------------------------------------------------------------------------- 1 | // pub mod erc4626; 2 | -------------------------------------------------------------------------------- /src/tokens/erc1155.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the ERC-1155 standard. 2 | //! 3 | //! The eponymous [`ERC1155`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! You can configure the behavior of [`ERC1155`] via the [`ERC1155Params`] trait, 7 | //! which allows specifying the name, symbol, and token uri. 8 | //! 9 | //! Note that this code is unaudited and not fit for production use. 10 | 11 | use alloc::{ 12 | string::String, 13 | vec::Vec, 14 | }; 15 | use alloy_primitives::{ 16 | Address, 17 | U256, 18 | }; 19 | use alloy_sol_types::{ 20 | sol, 21 | SolError, 22 | }; 23 | use core::{ 24 | borrow::BorrowMut, 25 | marker::PhantomData, 26 | }; 27 | use stylus_sdk::{ 28 | abi::Bytes, 29 | evm, 30 | msg, 31 | prelude::*, 32 | }; 33 | 34 | pub trait ERC1155Params { 35 | fn uri(id: U256) -> String; 36 | } 37 | 38 | sol_storage! { 39 | /// ERC1155 implements all ERC-1155 methods 40 | pub struct ERC1155 { 41 | mapping(address => mapping(uint256 => uint256)) balance_of; 42 | mapping(address => mapping(address => bool)) is_approved_for_all; 43 | 44 | PhantomData phantom; 45 | } 46 | } 47 | 48 | // Declare events and Solidity error types 49 | sol! { 50 | event TransferSingle( 51 | address indexed operator, 52 | address indexed from, 53 | address indexed to, 54 | uint256 id, 55 | uint256 amount 56 | ); 57 | event TransferBatch( 58 | address indexed operator, 59 | address indexed from, 60 | address indexed to, 61 | uint256[] ids, 62 | uint256[] amounts 63 | ); 64 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 65 | event URI(string value, uint256 indexed id); 66 | 67 | error NotAuthorized(); 68 | error UnsafeRecipient(); 69 | error LengthMismatch(); 70 | } 71 | 72 | /// Represents the ways methods may fail. 73 | pub enum ERC1155Error { 74 | NotAuthorized(NotAuthorized), 75 | CallFailed(stylus_sdk::call::Error), 76 | UnsafeRecipient(UnsafeRecipient), 77 | LengthMismatch(LengthMismatch), 78 | } 79 | 80 | impl From for ERC1155Error { 81 | fn from(err: stylus_sdk::call::Error) -> Self { 82 | Self::CallFailed(err) 83 | } 84 | } 85 | 86 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 87 | impl From for Vec { 88 | fn from(val: ERC1155Error) -> Self { 89 | match val { 90 | ERC1155Error::CallFailed(err) => err.into(), 91 | ERC1155Error::NotAuthorized(err) => err.encode(), 92 | ERC1155Error::UnsafeRecipient(err) => err.encode(), 93 | ERC1155Error::LengthMismatch(err) => err.encode(), 94 | } 95 | } 96 | } 97 | 98 | /// Simplifies the result type for the contract's methods. 99 | type Result = core::result::Result; 100 | 101 | impl ERC1155 { 102 | fn call_receiver( 103 | storage: &mut S, 104 | id: U256, 105 | from: Address, 106 | to: Address, 107 | value: U256, 108 | data: Vec, 109 | ) -> Result<()> { 110 | if to.has_code() { 111 | let receiver = IERC1155TokenReceiver::new(to); 112 | let received = receiver 113 | .on_erc_1155_received(&mut *storage, msg::sender(), from, id, value, data)? 114 | .0; 115 | 116 | // 0xf23a6e61 = bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)")) 117 | if u32::from_be_bytes(received) != 0xf23a6e61 { 118 | return Err(ERC1155Error::UnsafeRecipient(UnsafeRecipient {})); 119 | } 120 | } else if to == Address::ZERO { 121 | return Err(ERC1155Error::UnsafeRecipient(UnsafeRecipient {})); 122 | } 123 | 124 | Ok(()) 125 | } 126 | 127 | fn call_receiver_batch( 128 | storage: &mut S, 129 | ids: Vec, 130 | from: Address, 131 | to: Address, 132 | values: Vec, 133 | data: Vec, 134 | ) -> Result<()> { 135 | if to.has_code() { 136 | let receiver = IERC1155TokenReceiver::new(to); 137 | let received = receiver 138 | .on_erc_1155_batch_received(&mut *storage, msg::sender(), from, ids, values, data)? 139 | .0; 140 | 141 | // 0xbc197c81 = bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) 142 | if u32::from_be_bytes(received) != 0xbc197c81 { 143 | return Err(ERC1155Error::UnsafeRecipient(UnsafeRecipient {})); 144 | } 145 | } else if to == Address::ZERO { 146 | return Err(ERC1155Error::UnsafeRecipient(UnsafeRecipient {})); 147 | } 148 | 149 | Ok(()) 150 | } 151 | 152 | pub fn mint( 153 | &mut self, 154 | storage: &mut S, 155 | to: Address, 156 | id: U256, 157 | amount: U256, 158 | data: Bytes, 159 | ) -> Result<()> { 160 | let mut to_balance = self.balance_of.setter(to); 161 | let balance = to_balance.get(id) + amount; 162 | to_balance.insert(id, balance); 163 | 164 | evm::log(TransferSingle { 165 | operator: msg::sender(), 166 | from: Address::ZERO, 167 | to, 168 | id, 169 | amount, 170 | }); 171 | 172 | Self::call_receiver(storage, id, Address::ZERO, to, amount, data.0)?; 173 | 174 | Ok(()) 175 | } 176 | 177 | pub fn batch_mint( 178 | &mut self, 179 | storage: &mut S, 180 | to: Address, 181 | ids: Vec, 182 | amounts: Vec, 183 | data: Bytes, 184 | ) -> Result<()> { 185 | if ids.len() != amounts.len() { 186 | return Err(ERC1155Error::LengthMismatch(LengthMismatch {})); 187 | } 188 | 189 | for i in 0..ids.len() { 190 | let id: U256 = ids[i]; 191 | 192 | let mut to_balance = self.balance_of.setter(to); 193 | let balance = to_balance.get(id) + amounts[i]; 194 | to_balance.insert(id, balance); 195 | } 196 | 197 | evm::log(TransferBatch { 198 | operator: msg::sender(), 199 | from: Address::ZERO, 200 | to, 201 | ids: ids.clone(), 202 | amounts: amounts.clone(), 203 | }); 204 | 205 | Self::call_receiver_batch(storage, ids, Address::ZERO, to, amounts, data.0) 206 | } 207 | 208 | pub fn batch_burn(&mut self, from: Address, ids: Vec, amounts: Vec) -> Result<()> { 209 | if ids.len() != amounts.len() { 210 | return Err(ERC1155Error::LengthMismatch(LengthMismatch {})); 211 | } 212 | 213 | for i in 0..ids.len() { 214 | let id: U256 = ids[i]; 215 | 216 | let mut from_balance = self.balance_of.setter(from); 217 | let balance = from_balance.get(id) - amounts[i]; 218 | from_balance.insert(id, balance); 219 | } 220 | 221 | evm::log(TransferBatch { 222 | operator: msg::sender(), 223 | from, 224 | to: Address::ZERO, 225 | ids, 226 | amounts, 227 | }); 228 | 229 | Ok(()) 230 | } 231 | 232 | pub fn burn(&mut self, from: Address, id: U256, amount: U256) -> Result<()> { 233 | let mut from_balance = self.balance_of.setter(from); 234 | let balance = from_balance.get(id) - amount; 235 | from_balance.insert(id, balance); 236 | 237 | evm::log(TransferSingle { 238 | operator: msg::sender(), 239 | from, 240 | to: Address::ZERO, 241 | id, 242 | amount, 243 | }); 244 | 245 | Ok(()) 246 | } 247 | } 248 | 249 | #[external] 250 | impl ERC1155 { 251 | pub fn balance_of(&self, owner: Address, id: U256) -> Result { 252 | Ok(self.balance_of.getter(owner).get(id)) 253 | } 254 | 255 | pub fn is_approved_for_all(&self, owner: Address, operator: Address) -> Result { 256 | Ok(self.is_approved_for_all.getter(owner).get(operator)) 257 | } 258 | 259 | #[selector(name = "uri")] 260 | pub fn uri(&self, id: U256) -> Result { 261 | Ok(T::uri(id)) 262 | } 263 | 264 | pub fn set_approval_for_all(&mut self, operator: Address, approved: bool) -> Result<()> { 265 | self.is_approved_for_all 266 | .setter(msg::sender()) 267 | .insert(operator, approved); 268 | 269 | evm::log(ApprovalForAll { 270 | owner: msg::sender(), 271 | operator, 272 | approved, 273 | }); 274 | 275 | Ok(()) 276 | } 277 | 278 | pub fn safe_transfer_from>( 279 | storage: &mut S, 280 | from: Address, 281 | to: Address, 282 | id: U256, 283 | amount: U256, 284 | data: Bytes, 285 | ) -> Result<()> { 286 | if msg::sender() != from 287 | || !storage 288 | .borrow_mut() 289 | .is_approved_for_all 290 | .getter(from) 291 | .get(msg::sender()) 292 | { 293 | return Err(ERC1155Error::NotAuthorized(NotAuthorized {})); 294 | } 295 | 296 | let mut from_balance = storage.borrow_mut().balance_of.setter(from); 297 | let balance = from_balance.get(id) - amount; 298 | from_balance.insert(id, balance); 299 | 300 | let mut to_balance = storage.borrow_mut().balance_of.setter(to); 301 | let balance = to_balance.get(id) + amount; 302 | to_balance.insert(id, balance); 303 | 304 | evm::log(TransferSingle { 305 | operator: msg::sender(), 306 | from, 307 | to, 308 | id, 309 | amount, 310 | }); 311 | 312 | Self::call_receiver(storage, id, from, to, amount, data.0) 313 | } 314 | 315 | pub fn safe_batch_transfer_from>( 316 | storage: &mut S, 317 | from: Address, 318 | to: Address, 319 | ids: Vec, 320 | amounts: Vec, 321 | data: Bytes, 322 | ) -> Result<()> { 323 | if ids.len() != amounts.len() { 324 | return Err(ERC1155Error::LengthMismatch(LengthMismatch {})); 325 | } 326 | 327 | if msg::sender() != from 328 | || !storage 329 | .borrow_mut() 330 | .is_approved_for_all 331 | .getter(from) 332 | .get(msg::sender()) 333 | { 334 | return Err(ERC1155Error::NotAuthorized(NotAuthorized {})); 335 | } 336 | 337 | for i in 0..ids.len() { 338 | let id: U256 = ids[i]; 339 | let amount: U256 = amounts[i]; 340 | 341 | let mut from_balance = storage.borrow_mut().balance_of.setter(from); 342 | let balance = from_balance.get(id) - amount; 343 | from_balance.insert(id, balance); 344 | 345 | let mut to_balance = storage.borrow_mut().balance_of.setter(to); 346 | let balance = to_balance.get(id) + amount; 347 | to_balance.insert(id, balance); 348 | } 349 | 350 | evm::log(TransferBatch { 351 | operator: msg::sender(), 352 | from, 353 | to, 354 | ids: ids.clone(), 355 | amounts: amounts.clone(), 356 | }); 357 | 358 | Self::call_receiver_batch(storage, ids, from, to, amounts, data.0) 359 | } 360 | 361 | pub fn balance_of_batch(&self, owners: Vec
, ids: Vec) -> Result> { 362 | if owners.len() != ids.len() { 363 | return Err(ERC1155Error::LengthMismatch(LengthMismatch {})); 364 | } 365 | 366 | let mut balances = Vec::new(); 367 | 368 | for i in 0..owners.len() { 369 | balances.push(self.balance_of.getter(owners[i]).get(ids[i])); 370 | } 371 | 372 | Ok(balances) 373 | } 374 | 375 | pub fn supports_interface(interface: [u8; 4]) -> Result { 376 | let supported = interface == 0x01ffc9a7u32.to_be_bytes() // ERC165 Interface ID for ERC165 377 | || interface == 0xd9b67a26u32.to_be_bytes() // ERC165 Interface ID for ERC1155 378 | || interface == 0x0e89341cu32.to_be_bytes(); // ERC165 Interface ID for ERC1155MetadataURI 379 | Ok(supported) 380 | } 381 | } 382 | 383 | sol_interface! { 384 | interface IERC1155TokenReceiver { 385 | function onERC1155Received( 386 | address, 387 | address, 388 | uint256, 389 | uint256, 390 | bytes calldata 391 | ) external returns (bytes4); 392 | 393 | function onERC1155BatchReceived( 394 | address, 395 | address, 396 | uint256[] calldata, 397 | uint256[] calldata, 398 | bytes calldata 399 | ) external returns (bytes4); 400 | } 401 | } 402 | -------------------------------------------------------------------------------- /src/tokens/erc20.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the ERC-20 standard. 2 | //! 3 | //! The eponymous [`ERC20`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! You can configure the behavior of [`ERC20`] via the [`ERC20Params`] trait, 7 | //! which allows specifying the name, symbol, and token uri. 8 | //! 9 | //! Note that this code is unaudited and not fit for production use. 10 | 11 | use alloc::{ 12 | string::String, 13 | vec::Vec, 14 | }; 15 | use alloy_primitives::{ 16 | address, 17 | Address, 18 | B256, 19 | U256, 20 | }; 21 | use alloy_sol_types::{ 22 | sol, 23 | sol_data, 24 | SolError, 25 | SolType, 26 | }; 27 | use core::marker::PhantomData; 28 | use stylus_sdk::call::RawCall; 29 | use stylus_sdk::crypto; 30 | use stylus_sdk::{ 31 | block, 32 | contract, 33 | evm, 34 | msg, 35 | prelude::*, 36 | }; 37 | 38 | pub trait ERC20Params { 39 | const NAME: &'static str; 40 | 41 | const SYMBOL: &'static str; 42 | 43 | // TODO: Immutable tag? 44 | const DECIMALS: u8; 45 | 46 | const INITIAL_CHAIN_ID: u64; 47 | 48 | const INITIAL_DOMAIN_SEPARATOR: B256; 49 | } 50 | 51 | sol_storage! { 52 | /// ERC20 implements all ERC-20 methods 53 | pub struct ERC20 { 54 | uint256 total_supply; 55 | mapping(address => uint256) balance; 56 | mapping(address => mapping(address => uint256)) allowance; 57 | mapping(address => uint256) nonces; 58 | PhantomData phantom; 59 | } 60 | } 61 | 62 | // Declare events and Solidity error types 63 | sol! { 64 | event Transfer(address indexed from, address indexed to, uint256 amount); 65 | event Approval(address indexed owner, address indexed spender, uint256 amount); 66 | 67 | error PermitDeadlineExpired(); 68 | error InvalidSigner(); 69 | } 70 | 71 | /// Represents the ways methods may fail. 72 | pub enum ERC20Error { 73 | PermitDeadlineExpired(PermitDeadlineExpired), 74 | InvalidSigner(InvalidSigner), 75 | } 76 | 77 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 78 | impl From for Vec { 79 | fn from(val: ERC20Error) -> Self { 80 | match val { 81 | ERC20Error::PermitDeadlineExpired(err) => err.encode(), 82 | ERC20Error::InvalidSigner(err) => err.encode(), 83 | } 84 | } 85 | } 86 | 87 | /// Simplifies the result type for the contract's methods. 88 | type Result = core::result::Result; 89 | 90 | impl ERC20 { 91 | pub fn compute_domain_separator() -> Result { 92 | let mut digest_input = [0u8; 160]; 93 | digest_input[0..32].copy_from_slice(&crypto::keccak("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)".as_bytes())[..]); 94 | digest_input[32..64].copy_from_slice(&crypto::keccak(T::NAME.as_bytes())[..]); 95 | digest_input[64..96].copy_from_slice(&crypto::keccak("1".as_bytes())[..]); 96 | digest_input[96..128].copy_from_slice(&block::chainid().to_be_bytes()[..]); 97 | digest_input[128..160].copy_from_slice(&contract::address()[..]); 98 | 99 | Ok(crypto::keccak(digest_input)) 100 | } 101 | 102 | pub fn mint(&mut self, to: Address, amount: U256) { 103 | self.total_supply.set(self.total_supply.get() + amount); 104 | 105 | let mut balance_setter = self.balance.setter(to); 106 | let balance = balance_setter.get(); 107 | balance_setter.set(balance + amount); 108 | 109 | evm::log(Transfer { 110 | from: Address::ZERO, 111 | to, 112 | amount, 113 | }); 114 | } 115 | 116 | pub fn burn(&mut self, from: Address, amount: U256) { 117 | let mut balance_setter = self.balance.setter(from); 118 | let balance = balance_setter.get(); 119 | balance_setter.set(balance - amount); 120 | 121 | self.total_supply.set(self.total_supply.get() - amount); 122 | 123 | evm::log(Transfer { 124 | from, 125 | to: Address::ZERO, 126 | amount, 127 | }); 128 | } 129 | } 130 | 131 | #[external] 132 | impl ERC20 { 133 | pub fn name() -> Result { 134 | Ok(T::NAME.into()) 135 | } 136 | 137 | pub fn symbol() -> Result { 138 | Ok(T::SYMBOL.into()) 139 | } 140 | 141 | pub fn decimals() -> Result { 142 | Ok(T::DECIMALS) 143 | } 144 | 145 | pub fn total_supply(&self) -> Result { 146 | Ok(self.total_supply.get()) 147 | } 148 | 149 | pub fn balance_of(&self, owner: Address) -> Result { 150 | Ok(U256::from(self.balance.get(owner))) 151 | } 152 | 153 | pub fn allowance(&mut self, owner: Address, spender: Address) -> Result { 154 | Ok(self.allowance.getter(owner).get(spender)) 155 | } 156 | 157 | pub fn nonces(&self, owner: Address) -> Result { 158 | Ok(U256::from(self.nonces.get(owner))) 159 | } 160 | 161 | pub fn approve(&mut self, spender: Address, amount: U256) -> Result { 162 | self.allowance.setter(msg::sender()).insert(spender, amount); 163 | 164 | evm::log(Approval { 165 | owner: msg::sender(), 166 | spender, 167 | amount, 168 | }); 169 | 170 | Ok(true) 171 | } 172 | 173 | pub fn transfer(&mut self, to: Address, amount: U256) -> Result { 174 | let mut from_setter = self.balance.setter(msg::sender()); 175 | let from_balance = from_setter.get(); 176 | from_setter.set(from_balance - amount); 177 | 178 | let mut to_setter = self.balance.setter(to); 179 | let to_balance = to_setter.get(); 180 | to_setter.set(to_balance + amount); 181 | 182 | evm::log(Transfer { 183 | from: msg::sender(), 184 | to, 185 | amount, 186 | }); 187 | 188 | Ok(true) 189 | } 190 | 191 | pub fn transfer_from(&mut self, from: Address, to: Address, amount: U256) -> Result { 192 | let allowed = self.allowance.getter(from).get(msg::sender()); 193 | 194 | if allowed != U256::MAX { 195 | self.allowance 196 | .setter(from) 197 | .insert(msg::sender(), allowed - amount); 198 | } 199 | 200 | let mut from_setter = self.balance.setter(from); 201 | let from_balance = from_setter.get(); 202 | from_setter.set(from_balance - amount); 203 | 204 | let mut to_setter = self.balance.setter(to); 205 | let to_balance = to_setter.get(); 206 | to_setter.set(to_balance + amount); 207 | 208 | evm::log(Transfer { from, to, amount }); 209 | 210 | Ok(true) 211 | } 212 | 213 | pub fn permit( 214 | &mut self, 215 | owner: Address, 216 | spender: Address, 217 | value: U256, 218 | deadline: U256, 219 | v: u8, 220 | r: U256, 221 | s: U256, 222 | ) -> Result<()> { 223 | if deadline < U256::from(block::timestamp()) { 224 | return Err(ERC20Error::PermitDeadlineExpired(PermitDeadlineExpired {})); 225 | } 226 | 227 | let mut nonce_setter = self.balance.setter(owner); 228 | let nonce = nonce_setter.get(); 229 | nonce_setter.set(nonce + U256::from(1)); 230 | 231 | let mut struct_hash = [0u8; 192]; 232 | struct_hash[0..32].copy_from_slice(&crypto::keccak(b"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")[..]); 233 | struct_hash[32..64].copy_from_slice(&owner[..]); 234 | struct_hash[64..96].copy_from_slice(&spender[..]); 235 | struct_hash[96..128].copy_from_slice(&value.to_be_bytes_vec()[..]); 236 | // TODO: Increase nonce 237 | struct_hash[128..160].copy_from_slice(&nonce.to_be_bytes_vec()[..]); 238 | struct_hash[160..192].copy_from_slice(&deadline.to_be_bytes_vec()[..]); 239 | 240 | let mut digest_input = [0u8; 2 + 32 + 32]; 241 | digest_input[0] = 0x19; 242 | digest_input[1] = 0x01; 243 | digest_input[2..34].copy_from_slice(&self.domain_separator()?[..]); 244 | digest_input[34..66].copy_from_slice(&crypto::keccak(struct_hash)[..]); 245 | 246 | let data = ::encode(&( 247 | *crypto::keccak(digest_input), 248 | v, 249 | r, 250 | s, 251 | )); 252 | 253 | let recovered_address = RawCall::new_static() 254 | .gas(evm::gas_left()) 255 | .call(address!("0000000000000000000000000000000000000001"), &data) 256 | .map(|ret| sol_data::Address::decode_single(ret.as_slice(), false).unwrap()) 257 | .map_err(|_| ERC20Error::InvalidSigner(InvalidSigner {}))?; 258 | 259 | if recovered_address.is_zero() || recovered_address != owner { 260 | return Err(ERC20Error::InvalidSigner(InvalidSigner {})); 261 | } 262 | 263 | self.allowance 264 | .setter(recovered_address) 265 | .insert(spender, value); 266 | 267 | evm::log(Approval { 268 | owner, 269 | spender, 270 | amount: value, 271 | }); 272 | 273 | Ok(()) 274 | } 275 | 276 | pub fn domain_separator(&mut self) -> Result { 277 | if block::chainid() == T::INITIAL_CHAIN_ID { 278 | Ok(T::INITIAL_DOMAIN_SEPARATOR) 279 | } else { 280 | Ok(ERC20::::compute_domain_separator()?) 281 | } 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /src/tokens/erc6909.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the ERC-6909 standard. 2 | //! 3 | //! The eponymous [`ERC6909`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! You can configure the behavior of [`ERC6909`] via the [`ERC6909Params`] trait, 7 | //! which allows specifying the name, symbol, and token uri. 8 | //! 9 | //! Note that this code is unaudited and not fit for production use. 10 | 11 | use alloc::vec::Vec; 12 | use alloy_primitives::{ 13 | Address, 14 | U256, 15 | }; 16 | use alloy_sol_types::sol; 17 | use core::marker::PhantomData; 18 | use stylus_sdk::{ 19 | evm, 20 | msg, 21 | prelude::*, 22 | }; 23 | 24 | pub trait ERC6909Params {} 25 | 26 | sol_storage! { 27 | /// ERC6909 implements all ERC-6909 methods 28 | pub struct ERC6909 { 29 | mapping(uint256 => uint256) total_supply; 30 | mapping(address => mapping(address => bool)) is_operator; 31 | mapping(address => mapping(uint256 => uint256)) balance_of; 32 | mapping(address => mapping(address => mapping(uint256 => uint256))) allowance; 33 | PhantomData phantom; 34 | } 35 | } 36 | 37 | // Declare events and Solidity error types 38 | sol! { 39 | event OperatorSet(address indexed owner, address indexed operator, bool approved); 40 | event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount); 41 | event Transfer(address caller, address indexed from, address indexed to, uint256 indexed id, uint256 amount); 42 | } 43 | 44 | /// Represents the ways methods may fail. 45 | pub enum ERC6909Error {} 46 | 47 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 48 | impl From for Vec { 49 | fn from(val: ERC6909Error) -> Self { 50 | match val {} 51 | } 52 | } 53 | 54 | /// Simplifies the result type for the contract's methods. 55 | type Result = core::result::Result; 56 | 57 | impl ERC6909 { 58 | pub fn mint(&mut self, receiver: Address, id: U256, amount: U256) { 59 | let mut total_supply = self.total_supply.setter(id); 60 | let supply = total_supply.get() + amount; 61 | total_supply.set(supply); 62 | 63 | let mut to_balance = self.balance_of.setter(receiver); 64 | let balance = to_balance.get(id) + amount; 65 | to_balance.insert(id, balance); 66 | 67 | evm::log(Transfer { 68 | caller: msg::sender(), 69 | from: Address::ZERO, 70 | to: receiver, 71 | id, 72 | amount, 73 | }); 74 | } 75 | 76 | pub fn burn(&mut self, sender: Address, id: U256, amount: U256) { 77 | let mut from_balance = self.balance_of.setter(sender); 78 | let balance = from_balance.get(id) - amount; 79 | from_balance.insert(id, balance); 80 | 81 | let mut total_supply = self.total_supply.setter(id); 82 | let supply = total_supply.get() - amount; 83 | total_supply.set(supply); 84 | 85 | evm::log(Transfer { 86 | caller: msg::sender(), 87 | from: sender, 88 | to: Address::ZERO, 89 | id, 90 | amount, 91 | }); 92 | } 93 | } 94 | 95 | #[external] 96 | impl ERC6909 { 97 | pub fn transfer(&mut self, receiver: Address, id: U256, amount: U256) -> Result { 98 | let mut from_balance = self.balance_of.setter(msg::sender()); 99 | let balance = from_balance.get(id) - amount; 100 | from_balance.insert(id, balance); 101 | 102 | let mut to_balance = self.balance_of.setter(receiver); 103 | let balance = to_balance.get(id) + amount; 104 | to_balance.insert(id, balance); 105 | 106 | evm::log(Transfer { 107 | caller: msg::sender(), 108 | from: msg::sender(), 109 | to: receiver, 110 | id, 111 | amount, 112 | }); 113 | 114 | Ok(true) 115 | } 116 | 117 | pub fn transfer_from( 118 | &mut self, 119 | sender: Address, 120 | receiver: Address, 121 | id: U256, 122 | amount: U256, 123 | ) -> Result { 124 | if msg::sender() != sender && !self.is_operator.getter(sender).get(msg::sender()) { 125 | let allowed = self.allowance.getter(sender).getter(msg::sender()).get(id); 126 | if allowed != U256::MAX { 127 | self.allowance 128 | .setter(sender) 129 | .setter(msg::sender()) 130 | .insert(id, allowed - amount); 131 | } 132 | } 133 | 134 | let mut from_balance = self.balance_of.setter(sender); 135 | let balance = from_balance.get(id) - amount; 136 | from_balance.insert(id, balance); 137 | 138 | let mut to_balance = self.balance_of.setter(receiver); 139 | let balance = to_balance.get(id) + amount; 140 | to_balance.insert(id, balance); 141 | 142 | evm::log(Transfer { 143 | caller: msg::sender(), 144 | from: sender, 145 | to: receiver, 146 | id, 147 | amount, 148 | }); 149 | 150 | Ok(true) 151 | } 152 | 153 | pub fn approve(&mut self, spender: Address, id: U256, amount: U256) -> Result { 154 | self.allowance 155 | .setter(msg::sender()) 156 | .setter(spender) 157 | .insert(id, amount); 158 | 159 | evm::log(Approval { 160 | owner: msg::sender(), 161 | spender, 162 | id, 163 | amount, 164 | }); 165 | 166 | Ok(true) 167 | } 168 | 169 | pub fn set_operator(&mut self, operator: Address, approved: bool) -> Result { 170 | self.is_operator 171 | .setter(msg::sender()) 172 | .insert(operator, approved); 173 | 174 | evm::log(OperatorSet { 175 | owner: msg::sender(), 176 | operator, 177 | approved, 178 | }); 179 | 180 | Ok(true) 181 | } 182 | 183 | pub fn supports_interface(interface: [u8; 4]) -> Result { 184 | let supported = interface == 0x01ffc9a7u32.to_be_bytes() // ERC165 Interface ID for ERC165 185 | || interface == 0xb2e69f8au32.to_be_bytes(); // ERC165 Interface ID for ERC6909 186 | Ok(supported) 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/tokens/erc721.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the ERC-721 standard. 2 | //! 3 | //! The eponymous [`ERC721`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! You can configure the behavior of [`ERC721`] via the [`ERC721Params`] trait, 7 | //! which allows specifying the name, symbol, and token uri. 8 | //! 9 | //! Note that this code is unaudited and not fit for production use. 10 | 11 | use alloc::{ 12 | string::String, 13 | vec::Vec, 14 | }; 15 | use alloy_primitives::{ 16 | Address, 17 | U256, 18 | }; 19 | use alloy_sol_types::{ 20 | sol, 21 | SolError, 22 | }; 23 | use core::{ 24 | borrow::BorrowMut, 25 | marker::PhantomData, 26 | }; 27 | use stylus_sdk::{ 28 | abi::Bytes, 29 | evm, 30 | msg, 31 | prelude::*, 32 | }; 33 | 34 | pub trait ERC721Params { 35 | const NAME: &'static str; 36 | 37 | const SYMBOL: &'static str; 38 | 39 | fn token_uri(id: U256) -> String; 40 | } 41 | 42 | sol_storage! { 43 | /// ERC721 implements all ERC-721 methods 44 | pub struct ERC721 { 45 | mapping(uint256 => address) owner_of; 46 | mapping(address => uint256) balance_of; 47 | mapping(uint256 => address) get_approved; 48 | mapping(address => mapping(address => bool)) is_approved_for_all; 49 | PhantomData phantom; 50 | } 51 | } 52 | 53 | // Declare events and Solidity error types 54 | sol! { 55 | event Transfer(address indexed from, address indexed to, uint256 indexed id); 56 | event Approval(address indexed owner, address indexed spender, uint256 indexed id); 57 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 58 | 59 | error NotMinted(); 60 | error ZeroAddress(); 61 | error NotAuthorized(); 62 | error WrongFrom(); 63 | error InvalidRecipient(); 64 | error UnsafeRecipient(); 65 | error AlreadyMinted(); 66 | } 67 | 68 | /// Represents the ways methods may fail. 69 | pub enum ERC721Error { 70 | NotMinted(NotMinted), 71 | ZeroAddress(ZeroAddress), 72 | NotAuthorized(NotAuthorized), 73 | WrongFrom(WrongFrom), 74 | InvalidRecipient(InvalidRecipient), 75 | UnsafeRecipient(UnsafeRecipient), 76 | CallFailed(stylus_sdk::call::Error), 77 | AlreadyMinted(AlreadyMinted), 78 | } 79 | 80 | impl From for ERC721Error { 81 | fn from(err: stylus_sdk::call::Error) -> Self { 82 | Self::CallFailed(err) 83 | } 84 | } 85 | 86 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 87 | impl From for Vec { 88 | fn from(val: ERC721Error) -> Self { 89 | match val { 90 | ERC721Error::NotMinted(err) => err.encode(), 91 | ERC721Error::ZeroAddress(err) => err.encode(), 92 | ERC721Error::NotAuthorized(err) => err.encode(), 93 | ERC721Error::WrongFrom(err) => err.encode(), 94 | ERC721Error::InvalidRecipient(err) => err.encode(), 95 | ERC721Error::UnsafeRecipient(err) => err.encode(), 96 | ERC721Error::CallFailed(err) => err.into(), 97 | ERC721Error::AlreadyMinted(err) => err.encode(), 98 | } 99 | } 100 | } 101 | 102 | /// Simplifies the result type for the contract's methods. 103 | type Result = core::result::Result; 104 | 105 | impl ERC721 { 106 | fn call_receiver( 107 | storage: &mut S, 108 | id: U256, 109 | from: Address, 110 | to: Address, 111 | data: Vec, 112 | ) -> Result<()> { 113 | if to.has_code() { 114 | let receiver = IERC721TokenReceiver::new(to); 115 | let received = receiver 116 | .on_erc_721_received(&mut *storage, msg::sender(), from, id, data)? 117 | .0; 118 | 119 | // 0x150b7a02 = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) 120 | if u32::from_be_bytes(received) != 0x150b7a02 { 121 | return Err(ERC721Error::UnsafeRecipient(UnsafeRecipient {})); 122 | } 123 | } 124 | Ok(()) 125 | } 126 | 127 | pub fn safe_transfer>( 128 | storage: &mut S, 129 | id: U256, 130 | from: Address, 131 | to: Address, 132 | data: Vec, 133 | ) -> Result<()> { 134 | storage.borrow_mut().transfer_from(from, to, id)?; 135 | Self::call_receiver(storage, id, from, to, data) 136 | } 137 | 138 | pub fn mint(&mut self, to: Address, id: U256) -> Result<()> { 139 | if to.is_zero() { 140 | return Err(ERC721Error::InvalidRecipient(InvalidRecipient {})); 141 | } 142 | 143 | if self.owner_of.get(id) != Address::ZERO { 144 | return Err(ERC721Error::AlreadyMinted(AlreadyMinted {})); 145 | } 146 | 147 | let mut to_balance = self.balance_of.setter(to); 148 | let balance = to_balance.get() + U256::from(1); 149 | to_balance.set(balance); 150 | 151 | self.owner_of.setter(id).set(to); 152 | 153 | evm::log(Transfer { 154 | from: Address::ZERO, 155 | to, 156 | id, 157 | }); 158 | 159 | Ok(()) 160 | } 161 | 162 | pub fn burn(&mut self, id: U256) -> Result<()> { 163 | let owner = self.owner_of.get(id); 164 | 165 | if owner.is_zero() { 166 | return Err(ERC721Error::NotMinted(NotMinted {})); 167 | } 168 | 169 | let mut owner_balance = self.balance_of.setter(owner); 170 | let balance = owner_balance.get() - U256::from(1); 171 | owner_balance.set(balance); 172 | 173 | self.owner_of.delete(id); 174 | 175 | self.get_approved.delete(id); 176 | 177 | evm::log(Transfer { 178 | from: owner, 179 | to: Address::ZERO, 180 | id, 181 | }); 182 | 183 | Ok(()) 184 | } 185 | 186 | pub fn safe_mint( 187 | &mut self, 188 | storage: &mut S, 189 | to: Address, 190 | id: U256, 191 | ) -> Result<()> { 192 | Self::mint(self, to, id)?; 193 | 194 | Self::call_receiver(storage, id, Address::ZERO, to, vec![])?; 195 | 196 | Ok(()) 197 | } 198 | 199 | pub fn safe_mint_with_data( 200 | &mut self, 201 | storage: &mut S, 202 | to: Address, 203 | id: U256, 204 | data: Bytes, 205 | ) -> Result<()> { 206 | Self::mint(self, to, id)?; 207 | 208 | Self::call_receiver(storage, id, Address::ZERO, to, data.0)?; 209 | 210 | Ok(()) 211 | } 212 | } 213 | 214 | #[external] 215 | impl ERC721 { 216 | pub fn name() -> Result { 217 | Ok(T::NAME.into()) 218 | } 219 | 220 | pub fn symbol() -> Result { 221 | Ok(T::SYMBOL.into()) 222 | } 223 | 224 | pub fn owner_of(&self, id: U256) -> Result
{ 225 | let owner = self.owner_of.get(id); 226 | 227 | if owner.is_zero() { 228 | return Err(ERC721Error::NotMinted(NotMinted {})); 229 | } 230 | 231 | Ok(owner) 232 | } 233 | 234 | pub fn balance_of(&self, owner: Address) -> Result { 235 | if owner.is_zero() { 236 | return Err(ERC721Error::ZeroAddress(ZeroAddress {})); 237 | } 238 | 239 | Ok(self.balance_of.get(owner)) 240 | } 241 | 242 | pub fn get_approved(&self, id: U256) -> Result
{ 243 | Ok(self.get_approved.get(id)) 244 | } 245 | 246 | pub fn is_approved_for_all(&self, owner: Address, operator: Address) -> Result { 247 | Ok(self.is_approved_for_all.getter(owner).get(operator)) 248 | } 249 | 250 | #[selector(name = "tokenURI")] 251 | pub fn token_uri(&self, id: U256) -> Result { 252 | Ok(T::token_uri(id)) 253 | } 254 | 255 | pub fn approve(&mut self, spender: Address, id: U256) -> Result<()> { 256 | let owner = self.owner_of.get(id); 257 | 258 | if msg::sender() != owner || !self.is_approved_for_all.getter(owner).get(msg::sender()) { 259 | return Err(ERC721Error::NotAuthorized(NotAuthorized {})); 260 | } 261 | 262 | self.get_approved.setter(id).set(spender); 263 | 264 | evm::log(Approval { owner, spender, id }); 265 | 266 | Ok(()) 267 | } 268 | 269 | pub fn set_approval_for_all(&mut self, operator: Address, approved: bool) -> Result<()> { 270 | self.is_approved_for_all 271 | .setter(msg::sender()) 272 | .insert(operator, approved); 273 | 274 | evm::log(ApprovalForAll { 275 | owner: msg::sender(), 276 | operator, 277 | approved, 278 | }); 279 | 280 | Ok(()) 281 | } 282 | 283 | pub fn transfer_from(&mut self, from: Address, to: Address, id: U256) -> Result<()> { 284 | if from != self.owner_of.get(id) { 285 | return Err(ERC721Error::WrongFrom(WrongFrom {})); 286 | } 287 | 288 | if to.is_zero() { 289 | return Err(ERC721Error::InvalidRecipient(InvalidRecipient {})); 290 | } 291 | 292 | if msg::sender() != from 293 | && !self.is_approved_for_all.getter(from).get(msg::sender()) 294 | && msg::sender() != self.get_approved.get(id) 295 | { 296 | return Err(ERC721Error::NotAuthorized(NotAuthorized {})); 297 | } 298 | 299 | let mut from_balance = self.balance_of.setter(from); 300 | let balance = from_balance.get() - U256::from(1); 301 | from_balance.set(balance); 302 | 303 | let mut to_balance = self.balance_of.setter(to); 304 | let balance = to_balance.get() + U256::from(1); 305 | to_balance.set(balance); 306 | 307 | self.owner_of.setter(id).set(to); 308 | 309 | self.get_approved.delete(id); 310 | 311 | evm::log(Transfer { from, to, id }); 312 | 313 | Ok(()) 314 | } 315 | 316 | pub fn safe_transfer_from>( 317 | storage: &mut S, 318 | from: Address, 319 | to: Address, 320 | id: U256, 321 | ) -> Result<()> { 322 | Self::safe_transfer_from_with_data(storage, from, to, id, Bytes(vec![])) 323 | } 324 | 325 | #[selector(name = "safeTransferFrom")] 326 | pub fn safe_transfer_from_with_data>( 327 | storage: &mut S, 328 | from: Address, 329 | to: Address, 330 | id: U256, 331 | data: Bytes, 332 | ) -> Result<()> { 333 | Self::safe_transfer(storage, id, from, to, data.0) 334 | } 335 | 336 | pub fn supports_interface(interface: [u8; 4]) -> Result { 337 | let supported = interface == 0x01ffc9a7u32.to_be_bytes() // ERC165 Interface ID for ERC165 338 | || interface == 0x80ac58cdu32.to_be_bytes() // ERC165 Interface ID for ERC721 339 | || interface == 0x780e9d63u32.to_be_bytes(); // ERC165 Interface ID for ERC721Metadata 340 | Ok(supported) 341 | } 342 | } 343 | 344 | sol_interface! { 345 | interface IERC721TokenReceiver { 346 | function onERC721Received(address operator, address from, uint256 id, bytes data) external returns(bytes4); 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /src/tokens/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod erc1155; 2 | pub mod erc20; 3 | pub mod erc6909; 4 | pub mod erc721; 5 | // pub mod weth; 6 | -------------------------------------------------------------------------------- /src/tokens/weth.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "export-abi"), no_main, no_std)] 2 | extern crate alloc; 3 | 4 | mod erc20; 5 | 6 | use create::erc20::{ERC20Params, ERC20}; 7 | use alloc::vec::Vec; 8 | use alloy_primitives::{B256, U256}; 9 | use alloy_sol_types::sol; 10 | use stylus_sdk::{call, evm, msg, prelude::*}; 11 | 12 | #[global_allocator] 13 | static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; 14 | 15 | struct WETHParams; 16 | 17 | /// Immutable definitions 18 | impl ERC20Params for WETHParams { 19 | const NAME: &'static str = "Wrapped Ether"; 20 | const SYMBOL: &'static str = "WETH"; 21 | const DECIMALS: u8 = 18; 22 | const INITIAL_CHAIN_ID: u64 = 1; 23 | const INITIAL_DOMAIN_SEPARATOR: B256 = B256::ZERO; 24 | } 25 | 26 | // The contract 27 | sol_storage! { 28 | #[entrypoint] // Makes WETH the entrypoint 29 | struct WETH { 30 | #[borrow] // Allows ERC20 to access WETH's storage and make calls 31 | ERC20 erc20; 32 | } 33 | } 34 | 35 | sol! { 36 | event Deposit(address indexed from, uint256 amount); 37 | event Withdrawal(address indexed to, uint256 amount); 38 | } 39 | 40 | #[external] 41 | #[inherit(ERC20)] 42 | impl WETH { 43 | #[payable] 44 | pub fn deposit(&mut self) -> Result<(), Vec> { 45 | self.erc20.mint(msg::sender(), msg::value()); 46 | 47 | evm::log(Deposit { 48 | from: msg::sender(), 49 | amount: msg::value(), 50 | }); 51 | 52 | Ok(()) 53 | } 54 | 55 | pub fn withdraw(&mut self, amount: U256) -> Result<(), Vec> { 56 | self.erc20.burn(msg::sender(), amount); 57 | 58 | evm::log(Withdrawal { 59 | to: msg::sender(), 60 | amount: amount, 61 | }); 62 | 63 | call::transfer_eth(msg::sender(), amount) 64 | } 65 | 66 | #[payable] 67 | pub fn receive(&mut self) -> Result<(), Vec> { 68 | self.deposit() 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/utils/bytes32address.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the Bytes32AddressLib library. 2 | //! 3 | //! The eponymous [`Bytes32AddressLib`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! Note that this code is unaudited and not fit for production use. 7 | 8 | use alloy_primitives::{ 9 | Address, 10 | FixedBytes, 11 | }; 12 | use core::marker::PhantomData; 13 | use stylus_sdk::prelude::*; 14 | 15 | pub trait Bytes32AddressLibParams {} 16 | 17 | sol_storage! { 18 | pub struct Bytes32AddressLib { 19 | PhantomData phantom; 20 | } 21 | } 22 | 23 | impl Bytes32AddressLib { 24 | pub fn from_last_20_bytes(bytes_value: FixedBytes<32>) -> Address { 25 | Address::from_word(bytes_value) 26 | } 27 | 28 | pub fn fill_last_12_bytes(address_value: Address) -> FixedBytes<32> { 29 | address_value.into_word() 30 | } 31 | } 32 | 33 | #[external] 34 | impl Bytes32AddressLib {} 35 | -------------------------------------------------------------------------------- /src/utils/create3.rs: -------------------------------------------------------------------------------- 1 | //! Provides an implementation of the CREATE3 library. 2 | //! 3 | //! The eponymous [`CREATE3`] type provides all the standard methods, 4 | //! and is intended to be inherited by other contract types. 5 | //! 6 | //! Note that this code is unaudited and not fit for production use. 7 | 8 | use alloc::vec::Vec; 9 | use alloy_primitives::{ 10 | Address, 11 | B256, 12 | U256, 13 | }; 14 | use alloy_sol_types::{ 15 | sol, 16 | sol_data, 17 | SolError, 18 | SolType, 19 | }; 20 | use core::marker::PhantomData; 21 | use stylus_sdk::call::RawCall; 22 | use stylus_sdk::contract; 23 | use stylus_sdk::crypto; 24 | use stylus_sdk::deploy::RawDeploy; 25 | use stylus_sdk::{ 26 | evm, 27 | prelude::*, 28 | }; 29 | 30 | const KECCAK256_PROXY_CHILD_BYTECODE: [u8; 32] = [ 31 | 33, 195, 93, 190, 27, 52, 74, 36, 136, 207, 51, 33, 214, 206, 84, 47, 142, 159, 48, 85, 68, 32 | 255, 9, 228, 153, 58, 98, 49, 154, 73, 124, 31, 33 | ]; 34 | 35 | pub trait CREATE3Params {} 36 | 37 | sol_storage! { 38 | pub struct CREATE3 { 39 | PhantomData phantom; 40 | } 41 | } 42 | 43 | sol! { 44 | error DeploymentFailed(); 45 | error InitilizationFailed(); 46 | } 47 | 48 | /// Represents the ways methods may fail. 49 | pub enum CREATE3Error { 50 | DeploymentFailed(DeploymentFailed), 51 | InitilizationFailed(InitilizationFailed), 52 | } 53 | 54 | /// We will soon provide a `#[derive(SolidityError)]` to clean this up. 55 | impl From for Vec { 56 | fn from(val: CREATE3Error) -> Self { 57 | match val { 58 | CREATE3Error::DeploymentFailed(err) => err.encode(), 59 | CREATE3Error::InitilizationFailed(err) => err.encode(), 60 | } 61 | } 62 | } 63 | 64 | /// Simplifies the result type for the contract's methods. 65 | type Result = core::result::Result; 66 | 67 | impl CREATE3 { 68 | pub fn deploy(salt: B256, creation_code: &[u8], value: U256) -> Result
{ 69 | if let Ok(proxy) = unsafe { RawDeploy::new().salt(salt).deploy(creation_code, value) } { 70 | let deployed = Self::get_deployed(salt)?; 71 | 72 | RawCall::new_static() 73 | .gas(evm::gas_left()) 74 | .call(proxy, creation_code) 75 | .map(|ret| sol_data::Address::decode_single(ret.as_slice(), false).unwrap()) 76 | .map_err(|_| CREATE3Error::InitilizationFailed(InitilizationFailed {}))?; 77 | 78 | Ok(deployed) 79 | } else { 80 | Err(CREATE3Error::DeploymentFailed(DeploymentFailed {})) 81 | } 82 | } 83 | 84 | pub fn get_deployed(salt: B256) -> Result
{ 85 | Self::get_deployed_with_creator(salt, contract::address()) 86 | } 87 | 88 | pub fn get_deployed_with_creator(salt: B256, creator: Address) -> Result
{ 89 | let mut proxy_packed = [0u8; 1 + 20 + 32 + 32]; 90 | proxy_packed[0] = 0xFF; 91 | proxy_packed[1..21].copy_from_slice(&creator[..]); 92 | proxy_packed[21..53].copy_from_slice(&salt[..]); 93 | proxy_packed[53..85].copy_from_slice(&KECCAK256_PROXY_CHILD_BYTECODE[..]); 94 | 95 | let proxy = Address::from_word(crypto::keccak(proxy_packed)); 96 | 97 | let mut packed = [0u8; 1 + 1 + 20 + 1]; 98 | packed[0] = 0xd6; 99 | packed[1] = 0x94; 100 | packed[2..22].copy_from_slice(&proxy[..]); 101 | packed[22] = 0x01; 102 | 103 | Ok(Address::from_word(crypto::keccak(packed))) 104 | } 105 | } 106 | 107 | #[external] 108 | impl CREATE3 {} 109 | -------------------------------------------------------------------------------- /src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod bytes32address; 2 | pub mod create3; 3 | --------------------------------------------------------------------------------